aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/tegra/Makefile1
-rw-r--r--drivers/gpu/drm/tegra/drm.c57
-rw-r--r--drivers/gpu/drm/tegra/drm.h3
-rw-r--r--drivers/gpu/drm/tegra/hda.c63
-rw-r--r--drivers/gpu/drm/tegra/hda.h20
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c217
-rw-r--r--drivers/gpu/drm/tegra/output.c11
-rw-r--r--drivers/gpu/drm/tegra/sor.c64
-rw-r--r--drivers/gpu/drm/tegra/vic.c75
-rw-r--r--drivers/gpu/drm/tegra/vic.h9
-rw-r--r--drivers/gpu/host1x/bus.c35
-rw-r--r--drivers/gpu/host1x/cdma.c189
-rw-r--r--drivers/gpu/host1x/cdma.h8
-rw-r--r--drivers/gpu/host1x/dev.c49
-rw-r--r--drivers/gpu/host1x/dev.h8
-rw-r--r--drivers/gpu/host1x/hw/cdma_hw.c46
-rw-r--r--drivers/gpu/host1x/hw/channel_hw.c43
-rw-r--r--drivers/gpu/host1x/hw/host1x06_hardware.h6
-rw-r--r--drivers/gpu/host1x/hw/host1x07_hardware.h6
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x06_channel.h11
-rw-r--r--drivers/gpu/host1x/hw/hw_host1x07_channel.h11
21 files changed, 621 insertions, 311 deletions
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
index 2e0d6213f6bc..33c463e8d49f 100644
--- a/drivers/gpu/drm/tegra/Makefile
+++ b/drivers/gpu/drm/tegra/Makefile
@@ -10,6 +10,7 @@ tegra-drm-y := \
10 dc.o \ 10 dc.o \
11 output.o \ 11 output.o \
12 rgb.o \ 12 rgb.o \
13 hda.o \
13 hdmi.o \ 14 hdmi.o \
14 mipi-phy.o \ 15 mipi-phy.o \
15 dsi.o \ 16 dsi.o \
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 4b70ce664c41..0c5f1e6a0446 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -92,10 +92,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
92 return -ENOMEM; 92 return -ENOMEM;
93 93
94 if (iommu_present(&platform_bus_type)) { 94 if (iommu_present(&platform_bus_type)) {
95 u64 carveout_start, carveout_end, gem_start, gem_end;
96 struct iommu_domain_geometry *geometry;
97 unsigned long order;
98
99 tegra->domain = iommu_domain_alloc(&platform_bus_type); 95 tegra->domain = iommu_domain_alloc(&platform_bus_type);
100 if (!tegra->domain) { 96 if (!tegra->domain) {
101 err = -ENOMEM; 97 err = -ENOMEM;
@@ -105,27 +101,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
105 err = iova_cache_get(); 101 err = iova_cache_get();
106 if (err < 0) 102 if (err < 0)
107 goto domain; 103 goto domain;
108
109 geometry = &tegra->domain->geometry;
110 gem_start = geometry->aperture_start;
111 gem_end = geometry->aperture_end - CARVEOUT_SZ;
112 carveout_start = gem_end + 1;
113 carveout_end = geometry->aperture_end;
114
115 order = __ffs(tegra->domain->pgsize_bitmap);
116 init_iova_domain(&tegra->carveout.domain, 1UL << order,
117 carveout_start >> order);
118
119 tegra->carveout.shift = iova_shift(&tegra->carveout.domain);
120 tegra->carveout.limit = carveout_end >> tegra->carveout.shift;
121
122 drm_mm_init(&tegra->mm, gem_start, gem_end - gem_start + 1);
123 mutex_init(&tegra->mm_lock);
124
125 DRM_DEBUG("IOMMU apertures:\n");
126 DRM_DEBUG(" GEM: %#llx-%#llx\n", gem_start, gem_end);
127 DRM_DEBUG(" Carveout: %#llx-%#llx\n", carveout_start,
128 carveout_end);
129 } 104 }
130 105
131 mutex_init(&tegra->clients_lock); 106 mutex_init(&tegra->clients_lock);
@@ -159,6 +134,36 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
159 if (err < 0) 134 if (err < 0)
160 goto fbdev; 135 goto fbdev;
161 136
137 if (tegra->domain) {
138 u64 carveout_start, carveout_end, gem_start, gem_end;
139 u64 dma_mask = dma_get_mask(&device->dev);
140 dma_addr_t start, end;
141 unsigned long order;
142
143 start = tegra->domain->geometry.aperture_start & dma_mask;
144 end = tegra->domain->geometry.aperture_end & dma_mask;
145
146 gem_start = start;
147 gem_end = end - CARVEOUT_SZ;
148 carveout_start = gem_end + 1;
149 carveout_end = end;
150
151 order = __ffs(tegra->domain->pgsize_bitmap);
152 init_iova_domain(&tegra->carveout.domain, 1UL << order,
153 carveout_start >> order);
154
155 tegra->carveout.shift = iova_shift(&tegra->carveout.domain);
156 tegra->carveout.limit = carveout_end >> tegra->carveout.shift;
157
158 drm_mm_init(&tegra->mm, gem_start, gem_end - gem_start + 1);
159 mutex_init(&tegra->mm_lock);
160
161 DRM_DEBUG("IOMMU apertures:\n");
162 DRM_DEBUG(" GEM: %#llx-%#llx\n", gem_start, gem_end);
163 DRM_DEBUG(" Carveout: %#llx-%#llx\n", carveout_start,
164 carveout_end);
165 }
166
162 if (tegra->hub) { 167 if (tegra->hub) {
163 err = tegra_display_hub_prepare(tegra->hub); 168 err = tegra_display_hub_prepare(tegra->hub);
164 if (err < 0) 169 if (err < 0)
@@ -1041,6 +1046,7 @@ int tegra_drm_register_client(struct tegra_drm *tegra,
1041{ 1046{
1042 mutex_lock(&tegra->clients_lock); 1047 mutex_lock(&tegra->clients_lock);
1043 list_add_tail(&client->list, &tegra->clients); 1048 list_add_tail(&client->list, &tegra->clients);
1049 client->drm = tegra;
1044 mutex_unlock(&tegra->clients_lock); 1050 mutex_unlock(&tegra->clients_lock);
1045 1051
1046 return 0; 1052 return 0;
@@ -1051,6 +1057,7 @@ int tegra_drm_unregister_client(struct tegra_drm *tegra,
1051{ 1057{
1052 mutex_lock(&tegra->clients_lock); 1058 mutex_lock(&tegra->clients_lock);
1053 list_del_init(&client->list); 1059 list_del_init(&client->list);
1060 client->drm = NULL;
1054 mutex_unlock(&tegra->clients_lock); 1061 mutex_unlock(&tegra->clients_lock);
1055 1062
1056 return 0; 1063 return 0;
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index e2dee5c9c03b..70154c253d45 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -88,6 +88,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
88struct tegra_drm_client { 88struct tegra_drm_client {
89 struct host1x_client base; 89 struct host1x_client base;
90 struct list_head list; 90 struct list_head list;
91 struct tegra_drm *drm;
91 92
92 unsigned int version; 93 unsigned int version;
93 const struct tegra_drm_client_ops *ops; 94 const struct tegra_drm_client_ops *ops;
@@ -124,7 +125,7 @@ struct tegra_output {
124 struct drm_panel *panel; 125 struct drm_panel *panel;
125 struct i2c_adapter *ddc; 126 struct i2c_adapter *ddc;
126 const struct edid *edid; 127 const struct edid *edid;
127 struct cec_notifier *notifier; 128 struct cec_notifier *cec;
128 unsigned int hpd_irq; 129 unsigned int hpd_irq;
129 int hpd_gpio; 130 int hpd_gpio;
130 enum of_gpio_flags hpd_gpio_flags; 131 enum of_gpio_flags hpd_gpio_flags;
diff --git a/drivers/gpu/drm/tegra/hda.c b/drivers/gpu/drm/tegra/hda.c
new file mode 100644
index 000000000000..94245a18a043
--- /dev/null
+++ b/drivers/gpu/drm/tegra/hda.c
@@ -0,0 +1,63 @@
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright (C) 2019 NVIDIA Corporation
4 */
5
6#include <linux/bug.h>
7
8#include <sound/hda_verbs.h>
9
10#include "hda.h"
11
12void tegra_hda_parse_format(unsigned int format, struct tegra_hda_format *fmt)
13{
14 unsigned int mul, div, bits, channels;
15
16 if (format & AC_FMT_TYPE_NON_PCM)
17 fmt->pcm = false;
18 else
19 fmt->pcm = true;
20
21 if (format & AC_FMT_BASE_44K)
22 fmt->sample_rate = 44100;
23 else
24 fmt->sample_rate = 48000;
25
26 mul = (format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT;
27 div = (format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT;
28
29 fmt->sample_rate *= (mul + 1) / (div + 1);
30
31 switch (format & AC_FMT_BITS_MASK) {
32 case AC_FMT_BITS_8:
33 fmt->bits = 8;
34 break;
35
36 case AC_FMT_BITS_16:
37 fmt->bits = 16;
38 break;
39
40 case AC_FMT_BITS_20:
41 fmt->bits = 20;
42 break;
43
44 case AC_FMT_BITS_24:
45 fmt->bits = 24;
46 break;
47
48 case AC_FMT_BITS_32:
49 fmt->bits = 32;
50 break;
51
52 default:
53 bits = (format & AC_FMT_BITS_MASK) >> AC_FMT_BITS_SHIFT;
54 WARN(1, "invalid number of bits: %#x\n", bits);
55 fmt->bits = 8;
56 break;
57 }
58
59 channels = (format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT;
60
61 /* channels are encoded as n - 1 */
62 fmt->channels = channels + 1;
63}
diff --git a/drivers/gpu/drm/tegra/hda.h b/drivers/gpu/drm/tegra/hda.h
new file mode 100644
index 000000000000..77269955a4f2
--- /dev/null
+++ b/drivers/gpu/drm/tegra/hda.h
@@ -0,0 +1,20 @@
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright (C) 2019 NVIDIA Corporation
4 */
5
6#ifndef DRM_TEGRA_HDA_H
7#define DRM_TEGRA_HDA_H 1
8
9#include <linux/types.h>
10
11struct tegra_hda_format {
12 unsigned int sample_rate;
13 unsigned int channels;
14 unsigned int bits;
15 bool pcm;
16};
17
18void tegra_hda_parse_format(unsigned int format, struct tegra_hda_format *fmt);
19
20#endif
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index 78bc7c906e22..47c55974756d 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -11,6 +11,7 @@
11#include <linux/debugfs.h> 11#include <linux/debugfs.h>
12#include <linux/gpio.h> 12#include <linux/gpio.h>
13#include <linux/hdmi.h> 13#include <linux/hdmi.h>
14#include <linux/math64.h>
14#include <linux/of_device.h> 15#include <linux/of_device.h>
15#include <linux/pm_runtime.h> 16#include <linux/pm_runtime.h>
16#include <linux/regulator/consumer.h> 17#include <linux/regulator/consumer.h>
@@ -20,10 +21,7 @@
20#include <drm/drm_crtc.h> 21#include <drm/drm_crtc.h>
21#include <drm/drm_probe_helper.h> 22#include <drm/drm_probe_helper.h>
22 23
23#include <sound/hda_verbs.h> 24#include "hda.h"
24
25#include <media/cec-notifier.h>
26
27#include "hdmi.h" 25#include "hdmi.h"
28#include "drm.h" 26#include "drm.h"
29#include "dc.h" 27#include "dc.h"
@@ -71,8 +69,7 @@ struct tegra_hdmi {
71 const struct tegra_hdmi_config *config; 69 const struct tegra_hdmi_config *config;
72 70
73 unsigned int audio_source; 71 unsigned int audio_source;
74 unsigned int audio_sample_rate; 72 struct tegra_hda_format format;
75 unsigned int audio_channels;
76 73
77 unsigned int pixel_clock; 74 unsigned int pixel_clock;
78 bool stereo; 75 bool stereo;
@@ -119,68 +116,11 @@ static inline void tegra_hdmi_writel(struct tegra_hdmi *hdmi, u32 value,
119} 116}
120 117
121struct tegra_hdmi_audio_config { 118struct tegra_hdmi_audio_config {
122 unsigned int pclk;
123 unsigned int n; 119 unsigned int n;
124 unsigned int cts; 120 unsigned int cts;
125 unsigned int aval; 121 unsigned int aval;
126}; 122};
127 123
128static const struct tegra_hdmi_audio_config tegra_hdmi_audio_32k[] = {
129 { 25200000, 4096, 25200, 24000 },
130 { 27000000, 4096, 27000, 24000 },
131 { 74250000, 4096, 74250, 24000 },
132 { 148500000, 4096, 148500, 24000 },
133 { 0, 0, 0, 0 },
134};
135
136static const struct tegra_hdmi_audio_config tegra_hdmi_audio_44_1k[] = {
137 { 25200000, 5880, 26250, 25000 },
138 { 27000000, 5880, 28125, 25000 },
139 { 74250000, 4704, 61875, 20000 },
140 { 148500000, 4704, 123750, 20000 },
141 { 0, 0, 0, 0 },
142};
143
144static const struct tegra_hdmi_audio_config tegra_hdmi_audio_48k[] = {
145 { 25200000, 6144, 25200, 24000 },
146 { 27000000, 6144, 27000, 24000 },
147 { 74250000, 6144, 74250, 24000 },
148 { 148500000, 6144, 148500, 24000 },
149 { 0, 0, 0, 0 },
150};
151
152static const struct tegra_hdmi_audio_config tegra_hdmi_audio_88_2k[] = {
153 { 25200000, 11760, 26250, 25000 },
154 { 27000000, 11760, 28125, 25000 },
155 { 74250000, 9408, 61875, 20000 },
156 { 148500000, 9408, 123750, 20000 },
157 { 0, 0, 0, 0 },
158};
159
160static const struct tegra_hdmi_audio_config tegra_hdmi_audio_96k[] = {
161 { 25200000, 12288, 25200, 24000 },
162 { 27000000, 12288, 27000, 24000 },
163 { 74250000, 12288, 74250, 24000 },
164 { 148500000, 12288, 148500, 24000 },
165 { 0, 0, 0, 0 },
166};
167
168static const struct tegra_hdmi_audio_config tegra_hdmi_audio_176_4k[] = {
169 { 25200000, 23520, 26250, 25000 },
170 { 27000000, 23520, 28125, 25000 },
171 { 74250000, 18816, 61875, 20000 },
172 { 148500000, 18816, 123750, 20000 },
173 { 0, 0, 0, 0 },
174};
175
176static const struct tegra_hdmi_audio_config tegra_hdmi_audio_192k[] = {
177 { 25200000, 24576, 25200, 24000 },
178 { 27000000, 24576, 27000, 24000 },
179 { 74250000, 24576, 74250, 24000 },
180 { 148500000, 24576, 148500, 24000 },
181 { 0, 0, 0, 0 },
182};
183
184static const struct tmds_config tegra20_tmds_config[] = { 124static const struct tmds_config tegra20_tmds_config[] = {
185 { /* slow pixel clock modes */ 125 { /* slow pixel clock modes */
186 .pclk = 27000000, 126 .pclk = 27000000,
@@ -418,52 +358,53 @@ static const struct tmds_config tegra124_tmds_config[] = {
418 }, 358 },
419}; 359};
420 360
421static const struct tegra_hdmi_audio_config * 361static int
422tegra_hdmi_get_audio_config(unsigned int sample_rate, unsigned int pclk) 362tegra_hdmi_get_audio_config(unsigned int audio_freq, unsigned int pix_clock,
363 struct tegra_hdmi_audio_config *config)
423{ 364{
424 const struct tegra_hdmi_audio_config *table; 365 const unsigned int afreq = 128 * audio_freq;
425 366 const unsigned int min_n = afreq / 1500;
426 switch (sample_rate) { 367 const unsigned int max_n = afreq / 300;
427 case 32000: 368 const unsigned int ideal_n = afreq / 1000;
428 table = tegra_hdmi_audio_32k; 369 int64_t min_err = (uint64_t)-1 >> 1;
429 break; 370 unsigned int min_delta = -1;
430 371 int n;
431 case 44100: 372
432 table = tegra_hdmi_audio_44_1k; 373 memset(config, 0, sizeof(*config));
433 break; 374 config->n = -1;
434 375
435 case 48000: 376 for (n = min_n; n <= max_n; n++) {
436 table = tegra_hdmi_audio_48k; 377 uint64_t cts_f, aval_f;
437 break; 378 unsigned int delta;
438 379 int64_t cts, err;
439 case 88200: 380
440 table = tegra_hdmi_audio_88_2k; 381 /* compute aval in 48.16 fixed point */
441 break; 382 aval_f = ((int64_t)24000000 << 16) * n;
442 383 do_div(aval_f, afreq);
443 case 96000: 384 /* It should round without any rest */
444 table = tegra_hdmi_audio_96k; 385 if (aval_f & 0xFFFF)
445 break; 386 continue;
446 387
447 case 176400: 388 /* Compute cts in 48.16 fixed point */
448 table = tegra_hdmi_audio_176_4k; 389 cts_f = ((int64_t)pix_clock << 16) * n;
449 break; 390 do_div(cts_f, afreq);
450 391 /* Round it to the nearest integer */
451 case 192000: 392 cts = (cts_f & ~0xFFFF) + ((cts_f & BIT(15)) << 1);
452 table = tegra_hdmi_audio_192k; 393
453 break; 394 delta = abs(n - ideal_n);
454 395
455 default: 396 /* Compute the absolute error */
456 return NULL; 397 err = abs((int64_t)cts_f - cts);
457 } 398 if (err < min_err || (err == min_err && delta < min_delta)) {
458 399 config->n = n;
459 while (table->pclk) { 400 config->cts = cts >> 16;
460 if (table->pclk == pclk) 401 config->aval = aval_f >> 16;
461 return table; 402 min_delta = delta;
462 403 min_err = err;
463 table++; 404 }
464 } 405 }
465 406
466 return NULL; 407 return config->n != -1 ? 0 : -EINVAL;
467} 408}
468 409
469static void tegra_hdmi_setup_audio_fs_tables(struct tegra_hdmi *hdmi) 410static void tegra_hdmi_setup_audio_fs_tables(struct tegra_hdmi *hdmi)
@@ -510,7 +451,7 @@ static void tegra_hdmi_write_aval(struct tegra_hdmi *hdmi, u32 value)
510 unsigned int i; 451 unsigned int i;
511 452
512 for (i = 0; i < ARRAY_SIZE(regs); i++) { 453 for (i = 0; i < ARRAY_SIZE(regs); i++) {
513 if (regs[i].sample_rate == hdmi->audio_sample_rate) { 454 if (regs[i].sample_rate == hdmi->format.sample_rate) {
514 tegra_hdmi_writel(hdmi, value, regs[i].offset); 455 tegra_hdmi_writel(hdmi, value, regs[i].offset);
515 break; 456 break;
516 } 457 }
@@ -519,8 +460,9 @@ static void tegra_hdmi_write_aval(struct tegra_hdmi *hdmi, u32 value)
519 460
520static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi) 461static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi)
521{ 462{
522 const struct tegra_hdmi_audio_config *config; 463 struct tegra_hdmi_audio_config config;
523 u32 source, value; 464 u32 source, value;
465 int err;
524 466
525 switch (hdmi->audio_source) { 467 switch (hdmi->audio_source) {
526 case HDA: 468 case HDA:
@@ -564,7 +506,7 @@ static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi)
564 * play back system startup sounds early. It is possibly not 506 * play back system startup sounds early. It is possibly not
565 * needed on Linux at all. 507 * needed on Linux at all.
566 */ 508 */
567 if (hdmi->audio_channels == 2) 509 if (hdmi->format.channels == 2)
568 value = SOR_AUDIO_CNTRL0_INJECT_NULLSMPL; 510 value = SOR_AUDIO_CNTRL0_INJECT_NULLSMPL;
569 else 511 else
570 value = 0; 512 value = 0;
@@ -595,25 +537,28 @@ static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi)
595 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_AUDIO_SPARE0); 537 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_AUDIO_SPARE0);
596 } 538 }
597 539
598 config = tegra_hdmi_get_audio_config(hdmi->audio_sample_rate, 540 err = tegra_hdmi_get_audio_config(hdmi->format.sample_rate,
599 hdmi->pixel_clock); 541 hdmi->pixel_clock, &config);
600 if (!config) { 542 if (err < 0) {
601 dev_err(hdmi->dev, 543 dev_err(hdmi->dev,
602 "cannot set audio to %u Hz at %u Hz pixel clock\n", 544 "cannot set audio to %u Hz at %u Hz pixel clock\n",
603 hdmi->audio_sample_rate, hdmi->pixel_clock); 545 hdmi->format.sample_rate, hdmi->pixel_clock);
604 return -EINVAL; 546 return err;
605 } 547 }
606 548
549 dev_dbg(hdmi->dev, "audio: pixclk=%u, n=%u, cts=%u, aval=%u\n",
550 hdmi->pixel_clock, config.n, config.cts, config.aval);
551
607 tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_HDMI_ACR_CTRL); 552 tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_HDMI_ACR_CTRL);
608 553
609 value = AUDIO_N_RESETF | AUDIO_N_GENERATE_ALTERNATE | 554 value = AUDIO_N_RESETF | AUDIO_N_GENERATE_ALTERNATE |
610 AUDIO_N_VALUE(config->n - 1); 555 AUDIO_N_VALUE(config.n - 1);
611 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_N); 556 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_N);
612 557
613 tegra_hdmi_writel(hdmi, ACR_SUBPACK_N(config->n) | ACR_ENABLE, 558 tegra_hdmi_writel(hdmi, ACR_SUBPACK_N(config.n) | ACR_ENABLE,
614 HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH); 559 HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH);
615 560
616 tegra_hdmi_writel(hdmi, ACR_SUBPACK_CTS(config->cts), 561 tegra_hdmi_writel(hdmi, ACR_SUBPACK_CTS(config.cts),
617 HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW); 562 HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW);
618 563
619 value = SPARE_HW_CTS | SPARE_FORCE_SW_CTS | SPARE_CTS_RESET_VAL(1); 564 value = SPARE_HW_CTS | SPARE_FORCE_SW_CTS | SPARE_CTS_RESET_VAL(1);
@@ -624,7 +569,7 @@ static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi)
624 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_N); 569 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_N);
625 570
626 if (hdmi->config->has_hda) 571 if (hdmi->config->has_hda)
627 tegra_hdmi_write_aval(hdmi, config->aval); 572 tegra_hdmi_write_aval(hdmi, config.aval);
628 573
629 tegra_hdmi_setup_audio_fs_tables(hdmi); 574 tegra_hdmi_setup_audio_fs_tables(hdmi);
630 575
@@ -788,7 +733,7 @@ static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi)
788 return; 733 return;
789 } 734 }
790 735
791 frame.channels = hdmi->audio_channels; 736 frame.channels = hdmi->format.channels;
792 737
793 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer)); 738 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
794 if (err < 0) { 739 if (err < 0) {
@@ -1590,24 +1535,6 @@ static const struct of_device_id tegra_hdmi_of_match[] = {
1590}; 1535};
1591MODULE_DEVICE_TABLE(of, tegra_hdmi_of_match); 1536MODULE_DEVICE_TABLE(of, tegra_hdmi_of_match);
1592 1537
1593static void hda_format_parse(unsigned int format, unsigned int *rate,
1594 unsigned int *channels)
1595{
1596 unsigned int mul, div;
1597
1598 if (format & AC_FMT_BASE_44K)
1599 *rate = 44100;
1600 else
1601 *rate = 48000;
1602
1603 mul = (format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT;
1604 div = (format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT;
1605
1606 *rate = *rate * (mul + 1) / (div + 1);
1607
1608 *channels = (format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT;
1609}
1610
1611static irqreturn_t tegra_hdmi_irq(int irq, void *data) 1538static irqreturn_t tegra_hdmi_irq(int irq, void *data)
1612{ 1539{
1613 struct tegra_hdmi *hdmi = data; 1540 struct tegra_hdmi *hdmi = data;
@@ -1624,14 +1551,9 @@ static irqreturn_t tegra_hdmi_irq(int irq, void *data)
1624 value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH0); 1551 value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH0);
1625 1552
1626 if (value & SOR_AUDIO_HDA_CODEC_SCRATCH0_VALID) { 1553 if (value & SOR_AUDIO_HDA_CODEC_SCRATCH0_VALID) {
1627 unsigned int sample_rate, channels;
1628
1629 format = value & SOR_AUDIO_HDA_CODEC_SCRATCH0_FMT_MASK; 1554 format = value & SOR_AUDIO_HDA_CODEC_SCRATCH0_FMT_MASK;
1630 1555
1631 hda_format_parse(format, &sample_rate, &channels); 1556 tegra_hda_parse_format(format, &hdmi->format);
1632
1633 hdmi->audio_sample_rate = sample_rate;
1634 hdmi->audio_channels = channels;
1635 1557
1636 err = tegra_hdmi_setup_audio(hdmi); 1558 err = tegra_hdmi_setup_audio(hdmi);
1637 if (err < 0) { 1559 if (err < 0) {
@@ -1665,8 +1587,6 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
1665 hdmi->dev = &pdev->dev; 1587 hdmi->dev = &pdev->dev;
1666 1588
1667 hdmi->audio_source = AUTO; 1589 hdmi->audio_source = AUTO;
1668 hdmi->audio_sample_rate = 48000;
1669 hdmi->audio_channels = 2;
1670 hdmi->stereo = false; 1590 hdmi->stereo = false;
1671 hdmi->dvi = false; 1591 hdmi->dvi = false;
1672 1592
@@ -1710,10 +1630,6 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
1710 return PTR_ERR(hdmi->vdd); 1630 return PTR_ERR(hdmi->vdd);
1711 } 1631 }
1712 1632
1713 hdmi->output.notifier = cec_notifier_get(&pdev->dev);
1714 if (hdmi->output.notifier == NULL)
1715 return -ENOMEM;
1716
1717 hdmi->output.dev = &pdev->dev; 1633 hdmi->output.dev = &pdev->dev;
1718 1634
1719 err = tegra_output_probe(&hdmi->output); 1635 err = tegra_output_probe(&hdmi->output);
@@ -1772,9 +1688,6 @@ static int tegra_hdmi_remove(struct platform_device *pdev)
1772 1688
1773 tegra_output_remove(&hdmi->output); 1689 tegra_output_remove(&hdmi->output);
1774 1690
1775 if (hdmi->output.notifier)
1776 cec_notifier_put(hdmi->output.notifier);
1777
1778 return 0; 1691 return 0;
1779} 1692}
1780 1693
diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
index c662efc7e413..9c2b9dad55c3 100644
--- a/drivers/gpu/drm/tegra/output.c
+++ b/drivers/gpu/drm/tegra/output.c
@@ -36,7 +36,7 @@ int tegra_output_connector_get_modes(struct drm_connector *connector)
36 else if (output->ddc) 36 else if (output->ddc)
37 edid = drm_get_edid(connector, output->ddc); 37 edid = drm_get_edid(connector, output->ddc);
38 38
39 cec_notifier_set_phys_addr_from_edid(output->notifier, edid); 39 cec_notifier_set_phys_addr_from_edid(output->cec, edid);
40 drm_connector_update_edid_property(connector, edid); 40 drm_connector_update_edid_property(connector, edid);
41 41
42 if (edid) { 42 if (edid) {
@@ -73,7 +73,7 @@ tegra_output_connector_detect(struct drm_connector *connector, bool force)
73 } 73 }
74 74
75 if (status != connector_status_connected) 75 if (status != connector_status_connected)
76 cec_notifier_phys_addr_invalidate(output->notifier); 76 cec_notifier_phys_addr_invalidate(output->cec);
77 77
78 return status; 78 return status;
79} 79}
@@ -174,11 +174,18 @@ int tegra_output_probe(struct tegra_output *output)
174 disable_irq(output->hpd_irq); 174 disable_irq(output->hpd_irq);
175 } 175 }
176 176
177 output->cec = cec_notifier_get(output->dev);
178 if (!output->cec)
179 return -ENOMEM;
180
177 return 0; 181 return 0;
178} 182}
179 183
180void tegra_output_remove(struct tegra_output *output) 184void tegra_output_remove(struct tegra_output *output)
181{ 185{
186 if (output->cec)
187 cec_notifier_put(output->cec);
188
182 if (gpio_is_valid(output->hpd_gpio)) { 189 if (gpio_is_valid(output->hpd_gpio)) {
183 free_irq(output->hpd_irq, output); 190 free_irq(output->hpd_irq, output);
184 gpio_free(output->hpd_gpio); 191 gpio_free(output->hpd_gpio);
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 44feac2a0359..40057106f5f3 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -19,8 +19,6 @@
19 19
20#include <soc/tegra/pmc.h> 20#include <soc/tegra/pmc.h>
21 21
22#include <sound/hda_verbs.h>
23
24#include <drm/drm_atomic_helper.h> 22#include <drm/drm_atomic_helper.h>
25#include <drm/drm_dp_helper.h> 23#include <drm/drm_dp_helper.h>
26#include <drm/drm_panel.h> 24#include <drm/drm_panel.h>
@@ -28,6 +26,7 @@
28 26
29#include "dc.h" 27#include "dc.h"
30#include "drm.h" 28#include "drm.h"
29#include "hda.h"
31#include "sor.h" 30#include "sor.h"
32#include "trace.h" 31#include "trace.h"
33 32
@@ -411,6 +410,8 @@ struct tegra_sor {
411 struct clk *clk_dp; 410 struct clk *clk_dp;
412 struct clk *clk; 411 struct clk *clk;
413 412
413 u8 xbar_cfg[5];
414
414 struct drm_dp_aux *aux; 415 struct drm_dp_aux *aux;
415 416
416 struct drm_info_list *debugfs_files; 417 struct drm_info_list *debugfs_files;
@@ -429,10 +430,7 @@ struct tegra_sor {
429 struct delayed_work scdc; 430 struct delayed_work scdc;
430 bool scdc_enabled; 431 bool scdc_enabled;
431 432
432 struct { 433 struct tegra_hda_format format;
433 unsigned int sample_rate;
434 unsigned int channels;
435 } audio;
436}; 434};
437 435
438struct tegra_sor_state { 436struct tegra_sor_state {
@@ -1818,7 +1816,7 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
1818 1816
1819 /* XXX not in TRM */ 1817 /* XXX not in TRM */
1820 for (value = 0, i = 0; i < 5; i++) 1818 for (value = 0, i = 0; i < 5; i++)
1821 value |= SOR_XBAR_CTRL_LINK0_XSEL(i, sor->soc->xbar_cfg[i]) | 1819 value |= SOR_XBAR_CTRL_LINK0_XSEL(i, sor->xbar_cfg[i]) |
1822 SOR_XBAR_CTRL_LINK1_XSEL(i, i); 1820 SOR_XBAR_CTRL_LINK1_XSEL(i, i);
1823 1821
1824 tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL); 1822 tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL);
@@ -2186,7 +2184,7 @@ static int tegra_sor_hdmi_enable_audio_infoframe(struct tegra_sor *sor)
2186 return err; 2184 return err;
2187 } 2185 }
2188 2186
2189 frame.channels = sor->audio.channels; 2187 frame.channels = sor->format.channels;
2190 2188
2191 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer)); 2189 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
2192 if (err < 0) { 2190 if (err < 0) {
@@ -2215,7 +2213,7 @@ static void tegra_sor_hdmi_audio_enable(struct tegra_sor *sor)
2215 value |= SOR_AUDIO_CNTRL_SOURCE_SELECT(SOURCE_SELECT_HDA); 2213 value |= SOR_AUDIO_CNTRL_SOURCE_SELECT(SOURCE_SELECT_HDA);
2216 2214
2217 /* inject null samples */ 2215 /* inject null samples */
2218 if (sor->audio.channels != 2) 2216 if (sor->format.channels != 2)
2219 value &= ~SOR_AUDIO_CNTRL_INJECT_NULLSMPL; 2217 value &= ~SOR_AUDIO_CNTRL_INJECT_NULLSMPL;
2220 else 2218 else
2221 value |= SOR_AUDIO_CNTRL_INJECT_NULLSMPL; 2219 value |= SOR_AUDIO_CNTRL_INJECT_NULLSMPL;
@@ -2246,7 +2244,7 @@ static void tegra_sor_hdmi_audio_enable(struct tegra_sor *sor)
2246 value = SOR_HDMI_AUDIO_N_RESET | SOR_HDMI_AUDIO_N_LOOKUP; 2244 value = SOR_HDMI_AUDIO_N_RESET | SOR_HDMI_AUDIO_N_LOOKUP;
2247 tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_N); 2245 tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_N);
2248 2246
2249 value = (24000 * 4096) / (128 * sor->audio.sample_rate / 1000); 2247 value = (24000 * 4096) / (128 * sor->format.sample_rate / 1000);
2250 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0320); 2248 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0320);
2251 tegra_sor_writel(sor, 4096, SOR_AUDIO_NVAL_0320); 2249 tegra_sor_writel(sor, 4096, SOR_AUDIO_NVAL_0320);
2252 2250
@@ -2259,15 +2257,15 @@ static void tegra_sor_hdmi_audio_enable(struct tegra_sor *sor)
2259 tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_1764); 2257 tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_1764);
2260 tegra_sor_writel(sor, 18816, SOR_AUDIO_NVAL_1764); 2258 tegra_sor_writel(sor, 18816, SOR_AUDIO_NVAL_1764);
2261 2259
2262 value = (24000 * 6144) / (128 * sor->audio.sample_rate / 1000); 2260 value = (24000 * 6144) / (128 * sor->format.sample_rate / 1000);
2263 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0480); 2261 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0480);
2264 tegra_sor_writel(sor, 6144, SOR_AUDIO_NVAL_0480); 2262 tegra_sor_writel(sor, 6144, SOR_AUDIO_NVAL_0480);
2265 2263
2266 value = (24000 * 12288) / (128 * sor->audio.sample_rate / 1000); 2264 value = (24000 * 12288) / (128 * sor->format.sample_rate / 1000);
2267 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0960); 2265 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0960);
2268 tegra_sor_writel(sor, 12288, SOR_AUDIO_NVAL_0960); 2266 tegra_sor_writel(sor, 12288, SOR_AUDIO_NVAL_0960);
2269 2267
2270 value = (24000 * 24576) / (128 * sor->audio.sample_rate / 1000); 2268 value = (24000 * 24576) / (128 * sor->format.sample_rate / 1000);
2271 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_1920); 2269 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_1920);
2272 tegra_sor_writel(sor, 24576, SOR_AUDIO_NVAL_1920); 2270 tegra_sor_writel(sor, 24576, SOR_AUDIO_NVAL_1920);
2273 2271
@@ -2555,7 +2553,7 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
2555 2553
2556 /* XXX not in TRM */ 2554 /* XXX not in TRM */
2557 for (value = 0, i = 0; i < 5; i++) 2555 for (value = 0, i = 0; i < 5; i++)
2558 value |= SOR_XBAR_CTRL_LINK0_XSEL(i, sor->soc->xbar_cfg[i]) | 2556 value |= SOR_XBAR_CTRL_LINK0_XSEL(i, sor->xbar_cfg[i]) |
2559 SOR_XBAR_CTRL_LINK1_XSEL(i, i); 2557 SOR_XBAR_CTRL_LINK1_XSEL(i, i);
2560 2558
2561 tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL); 2559 tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL);
@@ -3176,6 +3174,8 @@ MODULE_DEVICE_TABLE(of, tegra_sor_of_match);
3176static int tegra_sor_parse_dt(struct tegra_sor *sor) 3174static int tegra_sor_parse_dt(struct tegra_sor *sor)
3177{ 3175{
3178 struct device_node *np = sor->dev->of_node; 3176 struct device_node *np = sor->dev->of_node;
3177 u32 xbar_cfg[5];
3178 unsigned int i;
3179 u32 value; 3179 u32 value;
3180 int err; 3180 int err;
3181 3181
@@ -3193,25 +3193,18 @@ static int tegra_sor_parse_dt(struct tegra_sor *sor)
3193 sor->pad = TEGRA_IO_PAD_HDMI_DP0 + sor->index; 3193 sor->pad = TEGRA_IO_PAD_HDMI_DP0 + sor->index;
3194 } 3194 }
3195 3195
3196 return 0; 3196 err = of_property_read_u32_array(np, "nvidia,xbar-cfg", xbar_cfg, 5);
3197} 3197 if (err < 0) {
3198 3198 /* fall back to default per-SoC XBAR configuration */
3199static void tegra_hda_parse_format(unsigned int format, unsigned int *rate, 3199 for (i = 0; i < 5; i++)
3200 unsigned int *channels) 3200 sor->xbar_cfg[i] = sor->soc->xbar_cfg[i];
3201{ 3201 } else {
3202 unsigned int mul, div; 3202 /* copy cells to SOR XBAR configuration */
3203 3203 for (i = 0; i < 5; i++)
3204 if (format & AC_FMT_BASE_44K) 3204 sor->xbar_cfg[i] = xbar_cfg[i];
3205 *rate = 44100; 3205 }
3206 else
3207 *rate = 48000;
3208
3209 mul = (format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT;
3210 div = (format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT;
3211
3212 *rate = *rate * (mul + 1) / (div + 1);
3213 3206
3214 *channels = (format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT; 3207 return 0;
3215} 3208}
3216 3209
3217static irqreturn_t tegra_sor_irq(int irq, void *data) 3210static irqreturn_t tegra_sor_irq(int irq, void *data)
@@ -3226,14 +3219,11 @@ static irqreturn_t tegra_sor_irq(int irq, void *data)
3226 value = tegra_sor_readl(sor, SOR_AUDIO_HDA_CODEC_SCRATCH0); 3219 value = tegra_sor_readl(sor, SOR_AUDIO_HDA_CODEC_SCRATCH0);
3227 3220
3228 if (value & SOR_AUDIO_HDA_CODEC_SCRATCH0_VALID) { 3221 if (value & SOR_AUDIO_HDA_CODEC_SCRATCH0_VALID) {
3229 unsigned int format, sample_rate, channels; 3222 unsigned int format;
3230 3223
3231 format = value & SOR_AUDIO_HDA_CODEC_SCRATCH0_FMT_MASK; 3224 format = value & SOR_AUDIO_HDA_CODEC_SCRATCH0_FMT_MASK;
3232 3225
3233 tegra_hda_parse_format(format, &sample_rate, &channels); 3226 tegra_hda_parse_format(format, &sor->format);
3234
3235 sor->audio.sample_rate = sample_rate;
3236 sor->audio.channels = channels;
3237 3227
3238 tegra_sor_hdmi_audio_enable(sor); 3228 tegra_sor_hdmi_audio_enable(sor);
3239 } else { 3229 } else {
diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index d47983deb1cf..39bfed9623de 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -26,6 +26,7 @@
26struct vic_config { 26struct vic_config {
27 const char *firmware; 27 const char *firmware;
28 unsigned int version; 28 unsigned int version;
29 bool supports_sid;
29}; 30};
30 31
31struct vic { 32struct vic {
@@ -105,6 +106,22 @@ static int vic_boot(struct vic *vic)
105 if (vic->booted) 106 if (vic->booted)
106 return 0; 107 return 0;
107 108
109 if (vic->config->supports_sid) {
110 struct iommu_fwspec *spec = dev_iommu_fwspec_get(vic->dev);
111 u32 value;
112
113 value = TRANSCFG_ATT(1, TRANSCFG_SID_FALCON) |
114 TRANSCFG_ATT(0, TRANSCFG_SID_HW);
115 vic_writel(vic, value, VIC_TFBIF_TRANSCFG);
116
117 if (spec && spec->num_ids > 0) {
118 value = spec->ids[0] & 0xffff;
119
120 vic_writel(vic, value, VIC_THI_STREAMID0);
121 vic_writel(vic, value, VIC_THI_STREAMID1);
122 }
123 }
124
108 /* setup clockgating registers */ 125 /* setup clockgating registers */
109 vic_writel(vic, CG_IDLE_CG_DLY_CNT(4) | 126 vic_writel(vic, CG_IDLE_CG_DLY_CNT(4) |
110 CG_IDLE_CG_EN | 127 CG_IDLE_CG_EN |
@@ -181,13 +198,6 @@ static int vic_init(struct host1x_client *client)
181 vic->domain = tegra->domain; 198 vic->domain = tegra->domain;
182 } 199 }
183 200
184 if (!vic->falcon.data) {
185 vic->falcon.data = tegra;
186 err = falcon_load_firmware(&vic->falcon);
187 if (err < 0)
188 goto detach;
189 }
190
191 vic->channel = host1x_channel_request(client->dev); 201 vic->channel = host1x_channel_request(client->dev);
192 if (!vic->channel) { 202 if (!vic->channel) {
193 err = -ENOMEM; 203 err = -ENOMEM;
@@ -246,6 +256,30 @@ static const struct host1x_client_ops vic_client_ops = {
246 .exit = vic_exit, 256 .exit = vic_exit,
247}; 257};
248 258
259static int vic_load_firmware(struct vic *vic)
260{
261 int err;
262
263 if (vic->falcon.data)
264 return 0;
265
266 vic->falcon.data = vic->client.drm;
267
268 err = falcon_read_firmware(&vic->falcon, vic->config->firmware);
269 if (err < 0)
270 goto cleanup;
271
272 err = falcon_load_firmware(&vic->falcon);
273 if (err < 0)
274 goto cleanup;
275
276 return 0;
277
278cleanup:
279 vic->falcon.data = NULL;
280 return err;
281}
282
249static int vic_open_channel(struct tegra_drm_client *client, 283static int vic_open_channel(struct tegra_drm_client *client,
250 struct tegra_drm_context *context) 284 struct tegra_drm_context *context)
251{ 285{
@@ -256,19 +290,25 @@ static int vic_open_channel(struct tegra_drm_client *client,
256 if (err < 0) 290 if (err < 0)
257 return err; 291 return err;
258 292
293 err = vic_load_firmware(vic);
294 if (err < 0)
295 goto rpm_put;
296
259 err = vic_boot(vic); 297 err = vic_boot(vic);
260 if (err < 0) { 298 if (err < 0)
261 pm_runtime_put(vic->dev); 299 goto rpm_put;
262 return err;
263 }
264 300
265 context->channel = host1x_channel_get(vic->channel); 301 context->channel = host1x_channel_get(vic->channel);
266 if (!context->channel) { 302 if (!context->channel) {
267 pm_runtime_put(vic->dev); 303 err = -ENOMEM;
268 return -ENOMEM; 304 goto rpm_put;
269 } 305 }
270 306
271 return 0; 307 return 0;
308
309rpm_put:
310 pm_runtime_put(vic->dev);
311 return err;
272} 312}
273 313
274static void vic_close_channel(struct tegra_drm_context *context) 314static void vic_close_channel(struct tegra_drm_context *context)
@@ -291,6 +331,7 @@ static const struct tegra_drm_client_ops vic_ops = {
291static const struct vic_config vic_t124_config = { 331static const struct vic_config vic_t124_config = {
292 .firmware = NVIDIA_TEGRA_124_VIC_FIRMWARE, 332 .firmware = NVIDIA_TEGRA_124_VIC_FIRMWARE,
293 .version = 0x40, 333 .version = 0x40,
334 .supports_sid = false,
294}; 335};
295 336
296#define NVIDIA_TEGRA_210_VIC_FIRMWARE "nvidia/tegra210/vic04_ucode.bin" 337#define NVIDIA_TEGRA_210_VIC_FIRMWARE "nvidia/tegra210/vic04_ucode.bin"
@@ -298,6 +339,7 @@ static const struct vic_config vic_t124_config = {
298static const struct vic_config vic_t210_config = { 339static const struct vic_config vic_t210_config = {
299 .firmware = NVIDIA_TEGRA_210_VIC_FIRMWARE, 340 .firmware = NVIDIA_TEGRA_210_VIC_FIRMWARE,
300 .version = 0x21, 341 .version = 0x21,
342 .supports_sid = false,
301}; 343};
302 344
303#define NVIDIA_TEGRA_186_VIC_FIRMWARE "nvidia/tegra186/vic04_ucode.bin" 345#define NVIDIA_TEGRA_186_VIC_FIRMWARE "nvidia/tegra186/vic04_ucode.bin"
@@ -305,6 +347,7 @@ static const struct vic_config vic_t210_config = {
305static const struct vic_config vic_t186_config = { 347static const struct vic_config vic_t186_config = {
306 .firmware = NVIDIA_TEGRA_186_VIC_FIRMWARE, 348 .firmware = NVIDIA_TEGRA_186_VIC_FIRMWARE,
307 .version = 0x18, 349 .version = 0x18,
350 .supports_sid = true,
308}; 351};
309 352
310#define NVIDIA_TEGRA_194_VIC_FIRMWARE "nvidia/tegra194/vic.bin" 353#define NVIDIA_TEGRA_194_VIC_FIRMWARE "nvidia/tegra194/vic.bin"
@@ -312,6 +355,7 @@ static const struct vic_config vic_t186_config = {
312static const struct vic_config vic_t194_config = { 355static const struct vic_config vic_t194_config = {
313 .firmware = NVIDIA_TEGRA_194_VIC_FIRMWARE, 356 .firmware = NVIDIA_TEGRA_194_VIC_FIRMWARE,
314 .version = 0x19, 357 .version = 0x19,
358 .supports_sid = true,
315}; 359};
316 360
317static const struct of_device_id vic_match[] = { 361static const struct of_device_id vic_match[] = {
@@ -372,10 +416,6 @@ static int vic_probe(struct platform_device *pdev)
372 if (err < 0) 416 if (err < 0)
373 return err; 417 return err;
374 418
375 err = falcon_read_firmware(&vic->falcon, vic->config->firmware);
376 if (err < 0)
377 goto exit_falcon;
378
379 platform_set_drvdata(pdev, vic); 419 platform_set_drvdata(pdev, vic);
380 420
381 INIT_LIST_HEAD(&vic->client.base.list); 421 INIT_LIST_HEAD(&vic->client.base.list);
@@ -393,7 +433,6 @@ static int vic_probe(struct platform_device *pdev)
393 err = host1x_client_register(&vic->client.base); 433 err = host1x_client_register(&vic->client.base);
394 if (err < 0) { 434 if (err < 0) {
395 dev_err(dev, "failed to register host1x client: %d\n", err); 435 dev_err(dev, "failed to register host1x client: %d\n", err);
396 platform_set_drvdata(pdev, NULL);
397 goto exit_falcon; 436 goto exit_falcon;
398 } 437 }
399 438
diff --git a/drivers/gpu/drm/tegra/vic.h b/drivers/gpu/drm/tegra/vic.h
index 21844817a7e1..017584340dd6 100644
--- a/drivers/gpu/drm/tegra/vic.h
+++ b/drivers/gpu/drm/tegra/vic.h
@@ -17,11 +17,20 @@
17 17
18/* VIC registers */ 18/* VIC registers */
19 19
20#define VIC_THI_STREAMID0 0x00000030
21#define VIC_THI_STREAMID1 0x00000034
22
20#define NV_PVIC_MISC_PRI_VIC_CG 0x000016d0 23#define NV_PVIC_MISC_PRI_VIC_CG 0x000016d0
21#define CG_IDLE_CG_DLY_CNT(val) ((val & 0x3f) << 0) 24#define CG_IDLE_CG_DLY_CNT(val) ((val & 0x3f) << 0)
22#define CG_IDLE_CG_EN (1 << 6) 25#define CG_IDLE_CG_EN (1 << 6)
23#define CG_WAKEUP_DLY_CNT(val) ((val & 0xf) << 16) 26#define CG_WAKEUP_DLY_CNT(val) ((val & 0xf) << 16)
24 27
28#define VIC_TFBIF_TRANSCFG 0x00002044
29#define TRANSCFG_ATT(i, v) (((v) & 0x3) << (i * 4))
30#define TRANSCFG_SID_HW 0
31#define TRANSCFG_SID_PHY 1
32#define TRANSCFG_SID_FALCON 2
33
25/* Firmware offsets */ 34/* Firmware offsets */
26 35
27#define VIC_UCODE_FCE_HEADER_OFFSET (6*4) 36#define VIC_UCODE_FCE_HEADER_OFFSET (6*4)
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
index b4c385d4a6af..103fffc1904b 100644
--- a/drivers/gpu/host1x/bus.c
+++ b/drivers/gpu/host1x/bus.c
@@ -15,8 +15,10 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18#include <linux/debugfs.h>
18#include <linux/host1x.h> 19#include <linux/host1x.h>
19#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/seq_file.h>
20#include <linux/slab.h> 22#include <linux/slab.h>
21#include <linux/of_device.h> 23#include <linux/of_device.h>
22 24
@@ -500,6 +502,36 @@ static void host1x_detach_driver(struct host1x *host1x,
500 mutex_unlock(&host1x->devices_lock); 502 mutex_unlock(&host1x->devices_lock);
501} 503}
502 504
505static int host1x_devices_show(struct seq_file *s, void *data)
506{
507 struct host1x *host1x = s->private;
508 struct host1x_device *device;
509
510 mutex_lock(&host1x->devices_lock);
511
512 list_for_each_entry(device, &host1x->devices, list) {
513 struct host1x_subdev *subdev;
514
515 seq_printf(s, "%s\n", dev_name(&device->dev));
516
517 mutex_lock(&device->subdevs_lock);
518
519 list_for_each_entry(subdev, &device->active, list)
520 seq_printf(s, " %pOFf: %s\n", subdev->np,
521 dev_name(subdev->client->dev));
522
523 list_for_each_entry(subdev, &device->subdevs, list)
524 seq_printf(s, " %pOFf:\n", subdev->np);
525
526 mutex_unlock(&device->subdevs_lock);
527 }
528
529 mutex_unlock(&host1x->devices_lock);
530
531 return 0;
532}
533DEFINE_SHOW_ATTRIBUTE(host1x_devices);
534
503/** 535/**
504 * host1x_register() - register a host1x controller 536 * host1x_register() - register a host1x controller
505 * @host1x: host1x controller 537 * @host1x: host1x controller
@@ -523,6 +555,9 @@ int host1x_register(struct host1x *host1x)
523 555
524 mutex_unlock(&drivers_lock); 556 mutex_unlock(&drivers_lock);
525 557
558 debugfs_create_file("devices", S_IRUGO, host1x->debugfs, host1x,
559 &host1x_devices_fops);
560
526 return 0; 561 return 0;
527} 562}
528 563
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index 91df51e631b2..f45b7c69b694 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -41,7 +41,17 @@
41 * means that the push buffer is full, not empty. 41 * means that the push buffer is full, not empty.
42 */ 42 */
43 43
44#define HOST1X_PUSHBUFFER_SLOTS 512 44/*
45 * Typically the commands written into the push buffer are a pair of words. We
46 * use slots to represent each of these pairs and to simplify things. Note the
47 * strange number of slots allocated here. 512 slots will fit exactly within a
48 * single memory page. We also need one additional word at the end of the push
49 * buffer for the RESTART opcode that will instruct the CDMA to jump back to
50 * the beginning of the push buffer. With 512 slots, this means that we'll use
51 * 2 memory pages and waste 4092 bytes of the second page that will never be
52 * used.
53 */
54#define HOST1X_PUSHBUFFER_SLOTS 511
45 55
46/* 56/*
47 * Clean up push buffer resources 57 * Clean up push buffer resources
@@ -143,7 +153,10 @@ static void host1x_pushbuffer_push(struct push_buffer *pb, u32 op1, u32 op2)
143 WARN_ON(pb->pos == pb->fence); 153 WARN_ON(pb->pos == pb->fence);
144 *(p++) = op1; 154 *(p++) = op1;
145 *(p++) = op2; 155 *(p++) = op2;
146 pb->pos = (pb->pos + 8) & (pb->size - 1); 156 pb->pos += 8;
157
158 if (pb->pos >= pb->size)
159 pb->pos -= pb->size;
147} 160}
148 161
149/* 162/*
@@ -153,7 +166,10 @@ static void host1x_pushbuffer_push(struct push_buffer *pb, u32 op1, u32 op2)
153static void host1x_pushbuffer_pop(struct push_buffer *pb, unsigned int slots) 166static void host1x_pushbuffer_pop(struct push_buffer *pb, unsigned int slots)
154{ 167{
155 /* Advance the next write position */ 168 /* Advance the next write position */
156 pb->fence = (pb->fence + slots * 8) & (pb->size - 1); 169 pb->fence += slots * 8;
170
171 if (pb->fence >= pb->size)
172 pb->fence -= pb->size;
157} 173}
158 174
159/* 175/*
@@ -161,7 +177,12 @@ static void host1x_pushbuffer_pop(struct push_buffer *pb, unsigned int slots)
161 */ 177 */
162static u32 host1x_pushbuffer_space(struct push_buffer *pb) 178static u32 host1x_pushbuffer_space(struct push_buffer *pb)
163{ 179{
164 return ((pb->fence - pb->pos) & (pb->size - 1)) / 8; 180 unsigned int fence = pb->fence;
181
182 if (pb->fence < pb->pos)
183 fence += pb->size;
184
185 return (fence - pb->pos) / 8;
165} 186}
166 187
167/* 188/*
@@ -210,7 +231,7 @@ unsigned int host1x_cdma_wait_locked(struct host1x_cdma *cdma,
210 cdma->event = event; 231 cdma->event = event;
211 232
212 mutex_unlock(&cdma->lock); 233 mutex_unlock(&cdma->lock);
213 down(&cdma->sem); 234 wait_for_completion(&cdma->complete);
214 mutex_lock(&cdma->lock); 235 mutex_lock(&cdma->lock);
215 } 236 }
216 237
@@ -218,6 +239,45 @@ unsigned int host1x_cdma_wait_locked(struct host1x_cdma *cdma,
218} 239}
219 240
220/* 241/*
242 * Sleep (if necessary) until the push buffer has enough free space.
243 *
244 * Must be called with the cdma lock held.
245 */
246int host1x_cdma_wait_pushbuffer_space(struct host1x *host1x,
247 struct host1x_cdma *cdma,
248 unsigned int needed)
249{
250 while (true) {
251 struct push_buffer *pb = &cdma->push_buffer;
252 unsigned int space;
253
254 space = host1x_pushbuffer_space(pb);
255 if (space >= needed)
256 break;
257
258 trace_host1x_wait_cdma(dev_name(cdma_to_channel(cdma)->dev),
259 CDMA_EVENT_PUSH_BUFFER_SPACE);
260
261 host1x_hw_cdma_flush(host1x, cdma);
262
263 /* If somebody has managed to already start waiting, yield */
264 if (cdma->event != CDMA_EVENT_NONE) {
265 mutex_unlock(&cdma->lock);
266 schedule();
267 mutex_lock(&cdma->lock);
268 continue;
269 }
270
271 cdma->event = CDMA_EVENT_PUSH_BUFFER_SPACE;
272
273 mutex_unlock(&cdma->lock);
274 wait_for_completion(&cdma->complete);
275 mutex_lock(&cdma->lock);
276 }
277
278 return 0;
279}
280/*
221 * Start timer that tracks the time spent by the job. 281 * Start timer that tracks the time spent by the job.
222 * Must be called with the cdma lock held. 282 * Must be called with the cdma lock held.
223 */ 283 */
@@ -314,7 +374,7 @@ static void update_cdma_locked(struct host1x_cdma *cdma)
314 374
315 if (signal) { 375 if (signal) {
316 cdma->event = CDMA_EVENT_NONE; 376 cdma->event = CDMA_EVENT_NONE;
317 up(&cdma->sem); 377 complete(&cdma->complete);
318 } 378 }
319} 379}
320 380
@@ -323,7 +383,7 @@ void host1x_cdma_update_sync_queue(struct host1x_cdma *cdma,
323{ 383{
324 struct host1x *host1x = cdma_to_host1x(cdma); 384 struct host1x *host1x = cdma_to_host1x(cdma);
325 u32 restart_addr, syncpt_incrs, syncpt_val; 385 u32 restart_addr, syncpt_incrs, syncpt_val;
326 struct host1x_job *job = NULL; 386 struct host1x_job *job, *next_job = NULL;
327 387
328 syncpt_val = host1x_syncpt_load(cdma->timeout.syncpt); 388 syncpt_val = host1x_syncpt_load(cdma->timeout.syncpt);
329 389
@@ -341,40 +401,37 @@ void host1x_cdma_update_sync_queue(struct host1x_cdma *cdma,
341 __func__); 401 __func__);
342 402
343 list_for_each_entry(job, &cdma->sync_queue, list) { 403 list_for_each_entry(job, &cdma->sync_queue, list) {
344 if (syncpt_val < job->syncpt_end) 404 if (syncpt_val < job->syncpt_end) {
345 break; 405
406 if (!list_is_last(&job->list, &cdma->sync_queue))
407 next_job = list_next_entry(job, list);
408
409 goto syncpt_incr;
410 }
346 411
347 host1x_job_dump(dev, job); 412 host1x_job_dump(dev, job);
348 } 413 }
349 414
415 /* all jobs have been completed */
416 job = NULL;
417
418syncpt_incr:
419
350 /* 420 /*
351 * Walk the sync_queue, first incrementing with the CPU syncpts that 421 * Increment with CPU the remaining syncpts of a partially executed job.
352 * are partially executed (the first buffer) or fully skipped while
353 * still in the current context (slots are also NOP-ed).
354 * 422 *
355 * At the point contexts are interleaved, syncpt increments must be 423 * CDMA will continue execution starting with the next job or will get
356 * done inline with the pushbuffer from a GATHER buffer to maintain 424 * into idle state.
357 * the order (slots are modified to be a GATHER of syncpt incrs).
358 *
359 * Note: save in restart_addr the location where the timed out buffer
360 * started in the PB, so we can start the refetch from there (with the
361 * modified NOP-ed PB slots). This lets things appear to have completed
362 * properly for this buffer and resources are freed.
363 */ 425 */
364 426 if (next_job)
365 dev_dbg(dev, "%s: perform CPU incr on pending same ctx buffers\n", 427 restart_addr = next_job->first_get;
366 __func__);
367
368 if (!list_empty(&cdma->sync_queue))
369 restart_addr = job->first_get;
370 else 428 else
371 restart_addr = cdma->last_pos; 429 restart_addr = cdma->last_pos;
372 430
373 /* do CPU increments as long as this context continues */ 431 /* do CPU increments for the remaining syncpts */
374 list_for_each_entry_from(job, &cdma->sync_queue, list) { 432 if (job) {
375 /* different context, gets us out of this loop */ 433 dev_dbg(dev, "%s: perform CPU incr on pending buffers\n",
376 if (job->client != cdma->timeout.client) 434 __func__);
377 break;
378 435
379 /* won't need a timeout when replayed */ 436 /* won't need a timeout when replayed */
380 job->timeout = 0; 437 job->timeout = 0;
@@ -389,21 +446,10 @@ void host1x_cdma_update_sync_queue(struct host1x_cdma *cdma,
389 syncpt_incrs, job->syncpt_end, 446 syncpt_incrs, job->syncpt_end,
390 job->num_slots); 447 job->num_slots);
391 448
392 syncpt_val += syncpt_incrs; 449 dev_dbg(dev, "%s: finished sync_queue modification\n",
450 __func__);
393 } 451 }
394 452
395 /*
396 * The following sumbits from the same client may be dependent on the
397 * failed submit and therefore they may fail. Force a small timeout
398 * to make the queue cleanup faster.
399 */
400
401 list_for_each_entry_from(job, &cdma->sync_queue, list)
402 if (job->client == cdma->timeout.client)
403 job->timeout = min_t(unsigned int, job->timeout, 500);
404
405 dev_dbg(dev, "%s: finished sync_queue modification\n", __func__);
406
407 /* roll back DMAGET and start up channel again */ 453 /* roll back DMAGET and start up channel again */
408 host1x_hw_cdma_resume(host1x, cdma, restart_addr); 454 host1x_hw_cdma_resume(host1x, cdma, restart_addr);
409} 455}
@@ -416,7 +462,7 @@ int host1x_cdma_init(struct host1x_cdma *cdma)
416 int err; 462 int err;
417 463
418 mutex_init(&cdma->lock); 464 mutex_init(&cdma->lock);
419 sema_init(&cdma->sem, 0); 465 init_completion(&cdma->complete);
420 466
421 INIT_LIST_HEAD(&cdma->sync_queue); 467 INIT_LIST_HEAD(&cdma->sync_queue);
422 468
@@ -510,6 +556,59 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, u32 op2)
510} 556}
511 557
512/* 558/*
559 * Push four words into two consecutive push buffer slots. Note that extra
560 * care needs to be taken not to split the two slots across the end of the
561 * push buffer. Otherwise the RESTART opcode at the end of the push buffer
562 * that ensures processing will restart at the beginning will break up the
563 * four words.
564 *
565 * Blocks as necessary if the push buffer is full.
566 */
567void host1x_cdma_push_wide(struct host1x_cdma *cdma, u32 op1, u32 op2,
568 u32 op3, u32 op4)
569{
570 struct host1x_channel *channel = cdma_to_channel(cdma);
571 struct host1x *host1x = cdma_to_host1x(cdma);
572 struct push_buffer *pb = &cdma->push_buffer;
573 unsigned int needed = 2, extra = 0, i;
574 unsigned int space = cdma->slots_free;
575
576 if (host1x_debug_trace_cmdbuf)
577 trace_host1x_cdma_push_wide(dev_name(channel->dev), op1, op2,
578 op3, op4);
579
580 /* compute number of extra slots needed for padding */
581 if (pb->pos + 16 > pb->size) {
582 extra = (pb->size - pb->pos) / 8;
583 needed += extra;
584 }
585
586 host1x_cdma_wait_pushbuffer_space(host1x, cdma, needed);
587 space = host1x_pushbuffer_space(pb);
588
589 cdma->slots_free = space - needed;
590 cdma->slots_used += needed;
591
592 /*
593 * Note that we rely on the fact that this is only used to submit wide
594 * gather opcodes, which consist of 3 words, and they are padded with
595 * a NOP to avoid having to deal with fractional slots (a slot always
596 * represents 2 words). The fourth opcode passed to this function will
597 * therefore always be a NOP.
598 *
599 * This works around a slight ambiguity when it comes to opcodes. For
600 * all current host1x incarnations the NOP opcode uses the exact same
601 * encoding (0x20000000), so we could hard-code the value here, but a
602 * new incarnation may change it and break that assumption.
603 */
604 for (i = 0; i < extra; i++)
605 host1x_pushbuffer_push(pb, op4, op4);
606
607 host1x_pushbuffer_push(pb, op1, op2);
608 host1x_pushbuffer_push(pb, op3, op4);
609}
610
611/*
513 * End a cdma submit 612 * End a cdma submit
514 * Kick off DMA, add job to the sync queue, and a number of slots to be freed 613 * Kick off DMA, add job to the sync queue, and a number of slots to be freed
515 * from the pushbuffer. The handles for a submit must all be pinned at the same 614 * from the pushbuffer. The handles for a submit must all be pinned at the same
diff --git a/drivers/gpu/host1x/cdma.h b/drivers/gpu/host1x/cdma.h
index e97e17b82370..3a5e0408b8d1 100644
--- a/drivers/gpu/host1x/cdma.h
+++ b/drivers/gpu/host1x/cdma.h
@@ -20,7 +20,7 @@
20#define __HOST1X_CDMA_H 20#define __HOST1X_CDMA_H
21 21
22#include <linux/sched.h> 22#include <linux/sched.h>
23#include <linux/semaphore.h> 23#include <linux/completion.h>
24#include <linux/list.h> 24#include <linux/list.h>
25 25
26struct host1x_syncpt; 26struct host1x_syncpt;
@@ -69,8 +69,8 @@ enum cdma_event {
69 69
70struct host1x_cdma { 70struct host1x_cdma {
71 struct mutex lock; /* controls access to shared state */ 71 struct mutex lock; /* controls access to shared state */
72 struct semaphore sem; /* signalled when event occurs */ 72 struct completion complete; /* signalled when event occurs */
73 enum cdma_event event; /* event that sem is waiting for */ 73 enum cdma_event event; /* event that complete is waiting for */
74 unsigned int slots_used; /* pb slots used in current submit */ 74 unsigned int slots_used; /* pb slots used in current submit */
75 unsigned int slots_free; /* pb slots free in current submit */ 75 unsigned int slots_free; /* pb slots free in current submit */
76 unsigned int first_get; /* DMAGET value, where submit begins */ 76 unsigned int first_get; /* DMAGET value, where submit begins */
@@ -90,6 +90,8 @@ int host1x_cdma_init(struct host1x_cdma *cdma);
90int host1x_cdma_deinit(struct host1x_cdma *cdma); 90int host1x_cdma_deinit(struct host1x_cdma *cdma);
91int host1x_cdma_begin(struct host1x_cdma *cdma, struct host1x_job *job); 91int host1x_cdma_begin(struct host1x_cdma *cdma, struct host1x_job *job);
92void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, u32 op2); 92void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, u32 op2);
93void host1x_cdma_push_wide(struct host1x_cdma *cdma, u32 op1, u32 op2,
94 u32 op3, u32 op4);
93void host1x_cdma_end(struct host1x_cdma *cdma, struct host1x_job *job); 95void host1x_cdma_end(struct host1x_cdma *cdma, struct host1x_job *job);
94void host1x_cdma_update(struct host1x_cdma *cdma); 96void host1x_cdma_update(struct host1x_cdma *cdma);
95void host1x_cdma_peek(struct host1x_cdma *cdma, u32 dmaget, int slot, 97void host1x_cdma_peek(struct host1x_cdma *cdma, u32 dmaget, int slot,
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 419d8929a98f..ee3c7b81a29d 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -120,6 +120,15 @@ static const struct host1x_info host1x05_info = {
120 .dma_mask = DMA_BIT_MASK(34), 120 .dma_mask = DMA_BIT_MASK(34),
121}; 121};
122 122
123static const struct host1x_sid_entry tegra186_sid_table[] = {
124 {
125 /* VIC */
126 .base = 0x1af0,
127 .offset = 0x30,
128 .limit = 0x34
129 },
130};
131
123static const struct host1x_info host1x06_info = { 132static const struct host1x_info host1x06_info = {
124 .nb_channels = 63, 133 .nb_channels = 63,
125 .nb_pts = 576, 134 .nb_pts = 576,
@@ -127,8 +136,19 @@ static const struct host1x_info host1x06_info = {
127 .nb_bases = 16, 136 .nb_bases = 16,
128 .init = host1x06_init, 137 .init = host1x06_init,
129 .sync_offset = 0x0, 138 .sync_offset = 0x0,
130 .dma_mask = DMA_BIT_MASK(34), 139 .dma_mask = DMA_BIT_MASK(40),
131 .has_hypervisor = true, 140 .has_hypervisor = true,
141 .num_sid_entries = ARRAY_SIZE(tegra186_sid_table),
142 .sid_table = tegra186_sid_table,
143};
144
145static const struct host1x_sid_entry tegra194_sid_table[] = {
146 {
147 /* VIC */
148 .base = 0x1af0,
149 .offset = 0x30,
150 .limit = 0x34
151 },
132}; 152};
133 153
134static const struct host1x_info host1x07_info = { 154static const struct host1x_info host1x07_info = {
@@ -140,6 +160,8 @@ static const struct host1x_info host1x07_info = {
140 .sync_offset = 0x0, 160 .sync_offset = 0x0,
141 .dma_mask = DMA_BIT_MASK(40), 161 .dma_mask = DMA_BIT_MASK(40),
142 .has_hypervisor = true, 162 .has_hypervisor = true,
163 .num_sid_entries = ARRAY_SIZE(tegra194_sid_table),
164 .sid_table = tegra194_sid_table,
143}; 165};
144 166
145static const struct of_device_id host1x_of_match[] = { 167static const struct of_device_id host1x_of_match[] = {
@@ -154,6 +176,19 @@ static const struct of_device_id host1x_of_match[] = {
154}; 176};
155MODULE_DEVICE_TABLE(of, host1x_of_match); 177MODULE_DEVICE_TABLE(of, host1x_of_match);
156 178
179static void host1x_setup_sid_table(struct host1x *host)
180{
181 const struct host1x_info *info = host->info;
182 unsigned int i;
183
184 for (i = 0; i < info->num_sid_entries; i++) {
185 const struct host1x_sid_entry *entry = &info->sid_table[i];
186
187 host1x_hypervisor_writel(host, entry->offset, entry->base);
188 host1x_hypervisor_writel(host, entry->limit, entry->base + 4);
189 }
190}
191
157static int host1x_probe(struct platform_device *pdev) 192static int host1x_probe(struct platform_device *pdev)
158{ 193{
159 struct host1x *host; 194 struct host1x *host;
@@ -248,6 +283,8 @@ static int host1x_probe(struct platform_device *pdev)
248 host->group = iommu_group_get(&pdev->dev); 283 host->group = iommu_group_get(&pdev->dev);
249 if (host->group) { 284 if (host->group) {
250 struct iommu_domain_geometry *geometry; 285 struct iommu_domain_geometry *geometry;
286 u64 mask = dma_get_mask(host->dev);
287 dma_addr_t start, end;
251 unsigned long order; 288 unsigned long order;
252 289
253 err = iova_cache_get(); 290 err = iova_cache_get();
@@ -275,11 +312,12 @@ static int host1x_probe(struct platform_device *pdev)
275 } 312 }
276 313
277 geometry = &host->domain->geometry; 314 geometry = &host->domain->geometry;
315 start = geometry->aperture_start & mask;
316 end = geometry->aperture_end & mask;
278 317
279 order = __ffs(host->domain->pgsize_bitmap); 318 order = __ffs(host->domain->pgsize_bitmap);
280 init_iova_domain(&host->iova, 1UL << order, 319 init_iova_domain(&host->iova, 1UL << order, start >> order);
281 geometry->aperture_start >> order); 320 host->iova_end = end;
282 host->iova_end = geometry->aperture_end;
283 } 321 }
284 322
285skip_iommu: 323skip_iommu:
@@ -316,6 +354,9 @@ skip_iommu:
316 354
317 host1x_debug_init(host); 355 host1x_debug_init(host);
318 356
357 if (host->info->has_hypervisor)
358 host1x_setup_sid_table(host);
359
319 err = host1x_register(host); 360 err = host1x_register(host);
320 if (err < 0) 361 if (err < 0)
321 goto fail_deinit_intr; 362 goto fail_deinit_intr;
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 36f44ffebe73..05216a7e4830 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -94,6 +94,12 @@ struct host1x_intr_ops {
94 int (*free_syncpt_irq)(struct host1x *host); 94 int (*free_syncpt_irq)(struct host1x *host);
95}; 95};
96 96
97struct host1x_sid_entry {
98 unsigned int base;
99 unsigned int offset;
100 unsigned int limit;
101};
102
97struct host1x_info { 103struct host1x_info {
98 unsigned int nb_channels; /* host1x: number of channels supported */ 104 unsigned int nb_channels; /* host1x: number of channels supported */
99 unsigned int nb_pts; /* host1x: number of syncpoints supported */ 105 unsigned int nb_pts; /* host1x: number of syncpoints supported */
@@ -103,6 +109,8 @@ struct host1x_info {
103 unsigned int sync_offset; /* offset of syncpoint registers */ 109 unsigned int sync_offset; /* offset of syncpoint registers */
104 u64 dma_mask; /* mask of addressable memory */ 110 u64 dma_mask; /* mask of addressable memory */
105 bool has_hypervisor; /* has hypervisor registers */ 111 bool has_hypervisor; /* has hypervisor registers */
112 unsigned int num_sid_entries;
113 const struct host1x_sid_entry *sid_table;
106}; 114};
107 115
108struct host1x { 116struct host1x {
diff --git a/drivers/gpu/host1x/hw/cdma_hw.c b/drivers/gpu/host1x/hw/cdma_hw.c
index ce320534cbed..5d61088db2bb 100644
--- a/drivers/gpu/host1x/hw/cdma_hw.c
+++ b/drivers/gpu/host1x/hw/cdma_hw.c
@@ -39,8 +39,6 @@ static void push_buffer_init(struct push_buffer *pb)
39static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr, 39static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr,
40 u32 syncpt_incrs, u32 syncval, u32 nr_slots) 40 u32 syncpt_incrs, u32 syncval, u32 nr_slots)
41{ 41{
42 struct host1x *host1x = cdma_to_host1x(cdma);
43 struct push_buffer *pb = &cdma->push_buffer;
44 unsigned int i; 42 unsigned int i;
45 43
46 for (i = 0; i < syncpt_incrs; i++) 44 for (i = 0; i < syncpt_incrs; i++)
@@ -48,18 +46,6 @@ static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr,
48 46
49 /* after CPU incr, ensure shadow is up to date */ 47 /* after CPU incr, ensure shadow is up to date */
50 host1x_syncpt_load(cdma->timeout.syncpt); 48 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} 49}
64 50
65/* 51/*
@@ -68,20 +54,31 @@ static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr,
68static void cdma_start(struct host1x_cdma *cdma) 54static void cdma_start(struct host1x_cdma *cdma)
69{ 55{
70 struct host1x_channel *ch = cdma_to_channel(cdma); 56 struct host1x_channel *ch = cdma_to_channel(cdma);
57 u64 start, end;
71 58
72 if (cdma->running) 59 if (cdma->running)
73 return; 60 return;
74 61
75 cdma->last_pos = cdma->push_buffer.pos; 62 cdma->last_pos = cdma->push_buffer.pos;
63 start = cdma->push_buffer.dma;
64 end = cdma->push_buffer.size + 4;
76 65
77 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP, 66 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP,
78 HOST1X_CHANNEL_DMACTRL); 67 HOST1X_CHANNEL_DMACTRL);
79 68
80 /* set base, put and end pointer */ 69 /* set base, put and end pointer */
81 host1x_ch_writel(ch, cdma->push_buffer.dma, HOST1X_CHANNEL_DMASTART); 70 host1x_ch_writel(ch, lower_32_bits(start), HOST1X_CHANNEL_DMASTART);
71#if HOST1X_HW >= 6
72 host1x_ch_writel(ch, upper_32_bits(start), HOST1X_CHANNEL_DMASTART_HI);
73#endif
82 host1x_ch_writel(ch, cdma->push_buffer.pos, HOST1X_CHANNEL_DMAPUT); 74 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, 75#if HOST1X_HW >= 6
84 HOST1X_CHANNEL_DMAEND); 76 host1x_ch_writel(ch, 0, HOST1X_CHANNEL_DMAPUT_HI);
77#endif
78 host1x_ch_writel(ch, lower_32_bits(end), HOST1X_CHANNEL_DMAEND);
79#if HOST1X_HW >= 6
80 host1x_ch_writel(ch, upper_32_bits(end), HOST1X_CHANNEL_DMAEND_HI);
81#endif
85 82
86 /* reset GET */ 83 /* reset GET */
87 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP | 84 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP |
@@ -104,6 +101,7 @@ static void cdma_timeout_restart(struct host1x_cdma *cdma, u32 getptr)
104{ 101{
105 struct host1x *host1x = cdma_to_host1x(cdma); 102 struct host1x *host1x = cdma_to_host1x(cdma);
106 struct host1x_channel *ch = cdma_to_channel(cdma); 103 struct host1x_channel *ch = cdma_to_channel(cdma);
104 u64 start, end;
107 105
108 if (cdma->running) 106 if (cdma->running)
109 return; 107 return;
@@ -113,10 +111,18 @@ static void cdma_timeout_restart(struct host1x_cdma *cdma, u32 getptr)
113 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP, 111 host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP,
114 HOST1X_CHANNEL_DMACTRL); 112 HOST1X_CHANNEL_DMACTRL);
115 113
114 start = cdma->push_buffer.dma;
115 end = cdma->push_buffer.size + 4;
116
116 /* set base, end pointer (all of memory) */ 117 /* set base, end pointer (all of memory) */
117 host1x_ch_writel(ch, cdma->push_buffer.dma, HOST1X_CHANNEL_DMASTART); 118 host1x_ch_writel(ch, lower_32_bits(start), HOST1X_CHANNEL_DMASTART);
118 host1x_ch_writel(ch, cdma->push_buffer.dma + cdma->push_buffer.size, 119#if HOST1X_HW >= 6
119 HOST1X_CHANNEL_DMAEND); 120 host1x_ch_writel(ch, upper_32_bits(start), HOST1X_CHANNEL_DMASTART_HI);
121#endif
122 host1x_ch_writel(ch, lower_32_bits(end), HOST1X_CHANNEL_DMAEND);
123#if HOST1X_HW >= 6
124 host1x_ch_writel(ch, upper_32_bits(end), HOST1X_CHANNEL_DMAEND_HI);
125#endif
120 126
121 /* set GET, by loading the value in PUT (then reset GET) */ 127 /* set GET, by loading the value in PUT (then reset GET) */
122 host1x_ch_writel(ch, getptr, HOST1X_CHANNEL_DMAPUT); 128 host1x_ch_writel(ch, getptr, HOST1X_CHANNEL_DMAPUT);
diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c
index 95ea81172a83..27101c04a827 100644
--- a/drivers/gpu/host1x/hw/channel_hw.c
+++ b/drivers/gpu/host1x/hw/channel_hw.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <linux/host1x.h> 19#include <linux/host1x.h>
20#include <linux/iommu.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21 22
22#include <trace/events/host1x.h> 23#include <trace/events/host1x.h>
@@ -60,15 +61,37 @@ static void trace_write_gather(struct host1x_cdma *cdma, struct host1x_bo *bo,
60static void submit_gathers(struct host1x_job *job) 61static void submit_gathers(struct host1x_job *job)
61{ 62{
62 struct host1x_cdma *cdma = &job->channel->cdma; 63 struct host1x_cdma *cdma = &job->channel->cdma;
64#if HOST1X_HW < 6
65 struct device *dev = job->channel->dev;
66#endif
63 unsigned int i; 67 unsigned int i;
64 68
65 for (i = 0; i < job->num_gathers; i++) { 69 for (i = 0; i < job->num_gathers; i++) {
66 struct host1x_job_gather *g = &job->gathers[i]; 70 struct host1x_job_gather *g = &job->gathers[i];
67 u32 op1 = host1x_opcode_gather(g->words); 71 dma_addr_t addr = g->base + g->offset;
68 u32 op2 = g->base + g->offset; 72 u32 op2, op3;
73
74 op2 = lower_32_bits(addr);
75 op3 = upper_32_bits(addr);
76
77 trace_write_gather(cdma, g->bo, g->offset, g->words);
78
79 if (op3 != 0) {
80#if HOST1X_HW >= 6
81 u32 op1 = host1x_opcode_gather_wide(g->words);
82 u32 op4 = HOST1X_OPCODE_NOP;
83
84 host1x_cdma_push_wide(cdma, op1, op2, op3, op4);
85#else
86 dev_err(dev, "invalid gather for push buffer %pad\n",
87 &addr);
88 continue;
89#endif
90 } else {
91 u32 op1 = host1x_opcode_gather(g->words);
69 92
70 trace_write_gather(cdma, g->bo, g->offset, op1 & 0xffff); 93 host1x_cdma_push(cdma, op1, op2);
71 host1x_cdma_push(cdma, op1, op2); 94 }
72 } 95 }
73} 96}
74 97
@@ -89,6 +112,16 @@ static inline void synchronize_syncpt_base(struct host1x_job *job)
89 HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(value)); 112 HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(value));
90} 113}
91 114
115static void host1x_channel_set_streamid(struct host1x_channel *channel)
116{
117#if HOST1X_HW >= 6
118 struct iommu_fwspec *spec = dev_iommu_fwspec_get(channel->dev->parent);
119 u32 sid = spec ? spec->ids[0] & 0xffff : 0x7f;
120
121 host1x_ch_writel(channel, sid, HOST1X_CHANNEL_SMMU_STREAMID);
122#endif
123}
124
92static int channel_submit(struct host1x_job *job) 125static int channel_submit(struct host1x_job *job)
93{ 126{
94 struct host1x_channel *ch = job->channel; 127 struct host1x_channel *ch = job->channel;
@@ -120,6 +153,8 @@ static int channel_submit(struct host1x_job *job)
120 goto error; 153 goto error;
121 } 154 }
122 155
156 host1x_channel_set_streamid(ch);
157
123 /* begin a CDMA submit */ 158 /* begin a CDMA submit */
124 err = host1x_cdma_begin(&ch->cdma, job); 159 err = host1x_cdma_begin(&ch->cdma, job);
125 if (err) { 160 if (err) {
diff --git a/drivers/gpu/host1x/hw/host1x06_hardware.h b/drivers/gpu/host1x/hw/host1x06_hardware.h
index 3039c92ea605..dd37b10c8d04 100644
--- a/drivers/gpu/host1x/hw/host1x06_hardware.h
+++ b/drivers/gpu/host1x/hw/host1x06_hardware.h
@@ -22,6 +22,7 @@
22#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/bitops.h> 23#include <linux/bitops.h>
24 24
25#include "hw_host1x06_channel.h"
25#include "hw_host1x06_uclass.h" 26#include "hw_host1x06_uclass.h"
26#include "hw_host1x06_vm.h" 27#include "hw_host1x06_vm.h"
27#include "hw_host1x06_hypervisor.h" 28#include "hw_host1x06_hypervisor.h"
@@ -137,6 +138,11 @@ static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
137 return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count; 138 return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
138} 139}
139 140
141static inline u32 host1x_opcode_gather_wide(unsigned count)
142{
143 return (12 << 28) | count;
144}
145
140#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0) 146#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
141 147
142#endif 148#endif
diff --git a/drivers/gpu/host1x/hw/host1x07_hardware.h b/drivers/gpu/host1x/hw/host1x07_hardware.h
index 1353e7ab71dd..9f6da4ee5443 100644
--- a/drivers/gpu/host1x/hw/host1x07_hardware.h
+++ b/drivers/gpu/host1x/hw/host1x07_hardware.h
@@ -22,6 +22,7 @@
22#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/bitops.h> 23#include <linux/bitops.h>
24 24
25#include "hw_host1x07_channel.h"
25#include "hw_host1x07_uclass.h" 26#include "hw_host1x07_uclass.h"
26#include "hw_host1x07_vm.h" 27#include "hw_host1x07_vm.h"
27#include "hw_host1x07_hypervisor.h" 28#include "hw_host1x07_hypervisor.h"
@@ -137,6 +138,11 @@ static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
137 return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count; 138 return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
138} 139}
139 140
141static inline u32 host1x_opcode_gather_wide(unsigned count)
142{
143 return (12 << 28) | count;
144}
145
140#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0) 146#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
141 147
142#endif 148#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x06_channel.h b/drivers/gpu/host1x/hw/hw_host1x06_channel.h
new file mode 100644
index 000000000000..18ae1c57bbea
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x06_channel.h
@@ -0,0 +1,11 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2019 NVIDIA Corporation.
4 */
5
6#ifndef HOST1X_HW_HOST1X06_CHANNEL_H
7#define HOST1X_HW_HOST1X06_CHANNEL_H
8
9#define HOST1X_CHANNEL_SMMU_STREAMID 0x084
10
11#endif
diff --git a/drivers/gpu/host1x/hw/hw_host1x07_channel.h b/drivers/gpu/host1x/hw/hw_host1x07_channel.h
new file mode 100644
index 000000000000..96fa72bbd7ab
--- /dev/null
+++ b/drivers/gpu/host1x/hw/hw_host1x07_channel.h
@@ -0,0 +1,11 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2019 NVIDIA Corporation.
4 */
5
6#ifndef HOST1X_HW_HOST1X07_CHANNEL_H
7#define HOST1X_HW_HOST1X07_CHANNEL_H
8
9#define HOST1X_CHANNEL_SMMU_STREAMID 0x084
10
11#endif