Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/nvidia/drm2/tegra_hdmi.c
39483 views
1
/*-
2
* Copyright (c) 2015 Michal Meloun
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*/
26
27
#include <sys/param.h>
28
#include <sys/systm.h>
29
#include <sys/bus.h>
30
#include <sys/gpio.h>
31
#include <sys/kernel.h>
32
#include <sys/module.h>
33
#include <sys/malloc.h>
34
#include <sys/rman.h>
35
#include <sys/sysctl.h>
36
37
#include <machine/bus.h>
38
39
#include <dev/clk/clk.h>
40
#include <dev/hwreset/hwreset.h>
41
#include <dev/regulator/regulator.h>
42
#include <dev/drm2/drmP.h>
43
#include <dev/drm2/drm_crtc.h>
44
#include <dev/drm2/drm_crtc_helper.h>
45
#include <dev/drm2/drm_fb_helper.h>
46
#include <dev/gpio/gpiobusvar.h>
47
#include <dev/ofw/ofw_bus.h>
48
#include <dev/ofw/ofw_bus_subr.h>
49
50
#include <arm/nvidia/drm2/tegra_drm.h>
51
#include <arm/nvidia/drm2/tegra_hdmi_reg.h>
52
#include <arm/nvidia/drm2/tegra_dc_reg.h>
53
#include <arm/nvidia/drm2/hdmi.h>
54
55
#include "tegra_dc_if.h"
56
#include "tegra_drm_if.h"
57
58
#define WR4(_sc, _r, _v) bus_write_4((_sc)->mem_res, 4 * (_r), (_v))
59
#define RD4(_sc, _r) bus_read_4((_sc)->mem_res, 4 * (_r))
60
61
/* HDA stream format verb. */
62
#define AC_FMT_CHAN_GET(x) (((x) >> 0) & 0xf)
63
#define AC_FMT_CHAN_BITS_GET(x) (((x) >> 4) & 0x7)
64
#define AC_FMT_DIV_GET(x) (((x) >> 8) & 0x7)
65
#define AC_FMT_MUL_GET(x) (((x) >> 11) & 0x7)
66
#define AC_FMT_BASE_44K (1 << 14)
67
#define AC_FMT_TYPE_NON_PCM (1 << 15)
68
69
#define HDMI_REKEY_DEFAULT 56
70
#define HDMI_ELD_BUFFER_SIZE 96
71
72
#define HDMI_DC_CLOCK_MULTIPIER 2
73
74
struct audio_reg {
75
uint32_t audio_clk;
76
bus_size_t acr_reg;
77
bus_size_t nval_reg;
78
bus_size_t aval_reg;
79
};
80
81
static const struct audio_reg audio_regs[] =
82
{
83
{
84
.audio_clk = 32000,
85
.acr_reg = HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_LOW,
86
.nval_reg = HDMI_NV_PDISP_SOR_AUDIO_NVAL_0320,
87
.aval_reg = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0320,
88
},
89
{
90
.audio_clk = 44100,
91
.acr_reg = HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW,
92
.nval_reg = HDMI_NV_PDISP_SOR_AUDIO_NVAL_0441,
93
.aval_reg = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0441,
94
},
95
{
96
.audio_clk = 88200,
97
.acr_reg = HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_LOW,
98
.nval_reg = HDMI_NV_PDISP_SOR_AUDIO_NVAL_0882,
99
.aval_reg = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0882,
100
},
101
{
102
.audio_clk = 176400,
103
.acr_reg = HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_LOW,
104
.nval_reg = HDMI_NV_PDISP_SOR_AUDIO_NVAL_1764,
105
.aval_reg = HDMI_NV_PDISP_SOR_AUDIO_AVAL_1764,
106
},
107
{
108
.audio_clk = 48000,
109
.acr_reg = HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_LOW,
110
.nval_reg = HDMI_NV_PDISP_SOR_AUDIO_NVAL_0480,
111
.aval_reg = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0480,
112
},
113
{
114
.audio_clk = 96000,
115
.acr_reg = HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_LOW,
116
.nval_reg = HDMI_NV_PDISP_SOR_AUDIO_NVAL_0960,
117
.aval_reg = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0960,
118
},
119
{
120
.audio_clk = 192000,
121
.acr_reg = HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_LOW,
122
.nval_reg = HDMI_NV_PDISP_SOR_AUDIO_NVAL_1920,
123
.aval_reg = HDMI_NV_PDISP_SOR_AUDIO_AVAL_1920,
124
},
125
};
126
127
struct tmds_config {
128
uint32_t pclk;
129
uint32_t pll0;
130
uint32_t pll1;
131
uint32_t drive_c;
132
uint32_t pe_c;
133
uint32_t peak_c;
134
uint32_t pad_ctls;
135
};
136
137
static const struct tmds_config tegra124_tmds_config[] =
138
{
139
{ /* 480p/576p / 25.2MHz/27MHz */
140
.pclk = 27000000,
141
.pll0 = 0x01003010,
142
.pll1 = 0x00301B00,
143
.drive_c = 0x1F1F1F1F,
144
.pe_c = 0x00000000,
145
.peak_c = 0x03030303,
146
.pad_ctls = 0x800034BB,
147
},
148
{ /* 720p/1080i / 74.25MHz */
149
.pclk = 74250000,
150
.pll0 = 0x01003110,
151
.pll1 = 0x00301500,
152
.drive_c = 0x2C2C2C2C,
153
.pe_c = 0x00000000,
154
.peak_c = 0x07070707,
155
.pad_ctls = 0x800034BB,
156
},
157
{ /* 1080p / 148.5MHz */
158
.pclk = 148500000,
159
.pll0 = 0x01003310,
160
.pll1 = 0x00301500,
161
.drive_c = 0x33333333,
162
.pe_c = 0x00000000,
163
.peak_c = 0x0C0C0C0C,
164
.pad_ctls = 0x800034BB,
165
},
166
{ /* 2216p / 297MHz */
167
.pclk = UINT_MAX,
168
.pll0 = 0x01003F10,
169
.pll1 = 0x00300F00,
170
.drive_c = 0x37373737,
171
.pe_c = 0x00000000,
172
.peak_c = 0x17171717,
173
.pad_ctls = 0x800036BB,
174
},
175
};
176
177
struct hdmi_softc {
178
device_t dev;
179
struct resource *mem_res;
180
struct resource *irq_res;
181
void *irq_ih;
182
183
clk_t clk_parent;
184
clk_t clk_hdmi;
185
hwreset_t hwreset_hdmi;
186
regulator_t supply_hdmi;
187
regulator_t supply_pll;
188
regulator_t supply_vdd;
189
190
uint64_t pclk;
191
boolean_t hdmi_mode;
192
193
int audio_src_type;
194
int audio_freq;
195
int audio_chans;
196
197
struct tegra_drm *drm;
198
struct tegra_drm_encoder output;
199
200
const struct tmds_config *tmds_config;
201
int n_tmds_configs;
202
};
203
204
static struct ofw_compat_data compat_data[] = {
205
{"nvidia,tegra124-hdmi", 1},
206
{NULL, 0},
207
};
208
209
/* These functions have been copied from newer version of drm_edid.c */
210
/* ELD Header Block */
211
#define DRM_ELD_HEADER_BLOCK_SIZE 4
212
#define DRM_ELD_BASELINE_ELD_LEN 2 /* in dwords! */
213
static int drm_eld_size(const uint8_t *eld)
214
{
215
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
216
}
217
218
static int
219
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
220
struct drm_display_mode *mode)
221
{
222
int rv;
223
224
if (!frame || !mode)
225
return -EINVAL;
226
227
rv = hdmi_avi_infoframe_init(frame);
228
if (rv < 0)
229
return rv;
230
231
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
232
frame->pixel_repeat = 1;
233
234
frame->video_code = drm_match_cea_mode(mode);
235
236
frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
237
#ifdef FREEBSD_NOTYET
238
/*
239
* Populate picture aspect ratio from either
240
* user input (if specified) or from the CEA mode list.
241
*/
242
if (mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_4_3 ||
243
mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_16_9)
244
frame->picture_aspect = mode->picture_aspect_ratio;
245
else if (frame->video_code > 0)
246
frame->picture_aspect = drm_get_cea_aspect_ratio(
247
frame->video_code);
248
#endif
249
250
frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
251
frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
252
253
return 0;
254
}
255
/* --------------------------------------------------------------------- */
256
257
static int
258
hdmi_setup_clock(struct tegra_drm_encoder *output, clk_t clk, uint64_t pclk)
259
{
260
struct hdmi_softc *sc;
261
uint64_t freq;
262
int rv;
263
264
sc = device_get_softc(output->dev);
265
266
/* Disable consumers clock for while. */
267
rv = clk_disable(sc->clk_hdmi);
268
if (rv != 0) {
269
device_printf(sc->dev, "Cannot disable 'hdmi' clock\n");
270
return (rv);
271
}
272
rv = clk_disable(clk);
273
if (rv != 0) {
274
device_printf(sc->dev, "Cannot disable display clock\n");
275
return (rv);
276
}
277
278
/* Set frequency for Display Controller PLL. */
279
freq = HDMI_DC_CLOCK_MULTIPIER * pclk;
280
rv = clk_set_freq(sc->clk_parent, freq, 0);
281
if (rv != 0) {
282
device_printf(output->dev,
283
"Cannot set display pixel frequency\n");
284
return (rv);
285
}
286
287
/* Reparent display controller */
288
rv = clk_set_parent_by_clk(clk, sc->clk_parent);
289
if (rv != 0) {
290
device_printf(output->dev, "Cannot set parent clock\n");
291
return (rv);
292
}
293
rv = clk_set_freq(clk, freq, 0);
294
if (rv != 0) {
295
device_printf(output->dev,
296
"Cannot set display controller frequency\n");
297
return (rv);
298
}
299
rv = clk_set_freq(sc->clk_hdmi, pclk, 0);
300
if (rv != 0) {
301
device_printf(output->dev,
302
"Cannot set display controller frequency\n");
303
return (rv);
304
}
305
306
/* And reenable consumers clock. */
307
rv = clk_enable(clk);
308
if (rv != 0) {
309
device_printf(sc->dev, "Cannot enable display clock\n");
310
return (rv);
311
}
312
rv = clk_enable(sc->clk_hdmi);
313
if (rv != 0) {
314
device_printf(sc->dev, "Cannot enable 'hdmi' clock\n");
315
return (rv);
316
}
317
318
rv = clk_get_freq(clk, &freq);
319
if (rv != 0) {
320
device_printf(output->dev,
321
"Cannot get display controller frequency\n");
322
return (rv);
323
}
324
325
DRM_DEBUG_KMS("DC frequency: %llu\n", freq);
326
327
return (0);
328
}
329
330
/* -------------------------------------------------------------------
331
*
332
* Infoframes.
333
*
334
*/
335
static void
336
avi_setup_infoframe(struct hdmi_softc *sc, struct drm_display_mode *mode)
337
{
338
struct hdmi_avi_infoframe frame;
339
uint8_t buf[17], *hdr, *pb;
340
ssize_t rv;
341
342
rv = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
343
if (rv < 0) {
344
device_printf(sc->dev, "Cannot setup AVI infoframe: %zd\n", rv);
345
return;
346
}
347
rv = hdmi_avi_infoframe_pack(&frame, buf, sizeof(buf));
348
if (rv < 0) {
349
device_printf(sc->dev, "Cannot pack AVI infoframe: %zd\n", rv);
350
return;
351
}
352
hdr = buf + 0;
353
pb = buf + 3;
354
WR4(sc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER,
355
(hdr[2] << 16) | (hdr[1] << 8) | (hdr[0] << 0));
356
WR4(sc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_LOW,
357
(pb[3] << 24) |(pb[2] << 16) | (pb[1] << 8) | (pb[0] << 0));
358
WR4(sc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH,
359
(pb[6] << 16) | (pb[5] << 8) | (pb[4] << 0));
360
WR4(sc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_LOW,
361
(pb[10] << 24) |(pb[9] << 16) | (pb[8] << 8) | (pb[7] << 0));
362
WR4(sc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH,
363
(pb[13] << 16) | (pb[12] << 8) | (pb[11] << 0));
364
365
WR4(sc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL,
366
AVI_INFOFRAME_CTRL_ENABLE);
367
}
368
369
static void
370
audio_setup_infoframe(struct hdmi_softc *sc)
371
{
372
struct hdmi_audio_infoframe frame;
373
uint8_t buf[14], *hdr, *pb;
374
ssize_t rv;
375
376
rv = hdmi_audio_infoframe_init(&frame);
377
frame.channels = sc->audio_chans;
378
rv = hdmi_audio_infoframe_pack(&frame, buf, sizeof(buf));
379
if (rv < 0) {
380
device_printf(sc->dev, "Cannot pack audio infoframe\n");
381
return;
382
}
383
hdr = buf + 0;
384
pb = buf + 3;
385
WR4(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER,
386
(hdr[2] << 16) | (hdr[1] << 8) | (hdr[0] << 0));
387
WR4(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_LOW,
388
(pb[3] << 24) |(pb[2] << 16) | (pb[1] << 8) | (pb[0] << 0));
389
WR4(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_HIGH,
390
(pb[5] << 8) | (pb[4] << 0));
391
392
WR4(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL,
393
AUDIO_INFOFRAME_CTRL_ENABLE);
394
}
395
396
/* -------------------------------------------------------------------
397
*
398
* Audio
399
*
400
*/
401
static void
402
init_hda_eld(struct hdmi_softc *sc)
403
{
404
size_t size;
405
int i ;
406
uint32_t val;
407
408
size = drm_eld_size(sc->output.connector.eld);
409
for (i = 0; i < HDMI_ELD_BUFFER_SIZE; i++) {
410
val = i << 8;
411
if (i < size)
412
val |= sc->output.connector.eld[i];
413
WR4(sc, HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR, val);
414
}
415
WR4(sc,HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE,
416
SOR_AUDIO_HDA_PRESENSE_VALID | SOR_AUDIO_HDA_PRESENSE_PRESENT);
417
}
418
419
static int
420
get_audio_regs(int freq, bus_size_t *acr_reg, bus_size_t *nval_reg,
421
bus_size_t *aval_reg)
422
{
423
int i;
424
const struct audio_reg *reg;
425
426
for (i = 0; i < nitems(audio_regs) ; i++) {
427
reg = audio_regs + i;
428
if (reg->audio_clk == freq) {
429
if (acr_reg != NULL)
430
*acr_reg = reg->acr_reg;
431
if (nval_reg != NULL)
432
*nval_reg = reg->nval_reg;
433
if (aval_reg != NULL)
434
*aval_reg = reg->aval_reg;
435
return (0);
436
}
437
}
438
return (ERANGE);
439
}
440
441
#define FR_BITS 16
442
#define TO_FFP(x) (((int64_t)(x)) << FR_BITS)
443
#define TO_INT(x) ((int)((x) >> FR_BITS))
444
static int
445
get_hda_cts_n(uint32_t audio_freq_hz, uint32_t pixclk_freq_hz,
446
uint32_t *best_cts, uint32_t *best_n, uint32_t *best_a)
447
{
448
int min_n;
449
int max_n;
450
int ideal_n;
451
int n;
452
int cts;
453
int aval;
454
int64_t err_f;
455
int64_t min_err_f;
456
int64_t cts_f;
457
int64_t aval_f;
458
int64_t half_f; /* constant 0.5 */
459
bool better_n;
460
461
/*
462
* All floats are in fixed I48.16 format.
463
*
464
* Ideal ACR interval is 1000 hz (1 ms);
465
* acceptable is 300 hz .. 1500 hz
466
*/
467
min_n = 128 * audio_freq_hz / 1500;
468
max_n = 128 * audio_freq_hz / 300;
469
ideal_n = 128 * audio_freq_hz / 1000;
470
min_err_f = TO_FFP(100);
471
half_f = TO_FFP(1) / 2;
472
473
*best_n = 0;
474
*best_cts = 0;
475
*best_a = 0;
476
477
for (n = min_n; n <= max_n; n++) {
478
cts_f = TO_FFP(pixclk_freq_hz);
479
cts_f *= n;
480
cts_f /= 128 * audio_freq_hz;
481
cts = TO_INT(cts_f + half_f); /* round */
482
err_f = cts_f - TO_FFP(cts);
483
if (err_f < 0)
484
err_f = -err_f;
485
aval_f = TO_FFP(24000000);
486
aval_f *= n;
487
aval_f /= 128 * audio_freq_hz;
488
aval = TO_INT(aval_f); /* truncate */
489
490
better_n = abs(n - ideal_n) < abs((int)(*best_n) - ideal_n);
491
if (TO_FFP(aval) == aval_f &&
492
(err_f < min_err_f || (err_f == min_err_f && better_n))) {
493
min_err_f = err_f;
494
*best_n = (uint32_t)n;
495
*best_cts = (uint32_t)cts;
496
*best_a = (uint32_t)aval;
497
498
if (err_f == 0 && n == ideal_n)
499
break;
500
}
501
}
502
return (0);
503
}
504
#undef FR_BITS
505
#undef TO_FFP
506
#undef TO_INT
507
508
static int
509
audio_setup(struct hdmi_softc *sc)
510
{
511
uint32_t val;
512
uint32_t audio_n;
513
uint32_t audio_cts;
514
uint32_t audio_aval;
515
uint64_t hdmi_freq;
516
bus_size_t aval_reg;
517
int rv;
518
519
if (!sc->hdmi_mode)
520
return (ENOTSUP);
521
rv = get_audio_regs(sc->audio_freq, NULL, NULL, &aval_reg);
522
if (rv != 0) {
523
device_printf(sc->dev, "Unsupported audio frequency.\n");
524
return (rv);
525
}
526
527
rv = clk_get_freq(sc->clk_hdmi, &hdmi_freq);
528
if (rv != 0) {
529
device_printf(sc->dev, "Cannot get hdmi frequency: %d\n", rv);
530
return (rv);
531
}
532
533
rv = get_hda_cts_n(sc->audio_freq, hdmi_freq, &audio_cts, &audio_n,
534
&audio_aval);
535
if (rv != 0) {
536
device_printf(sc->dev, "Cannot compute audio coefs: %d\n", rv);
537
return (rv);
538
}
539
540
/* Audio infoframe. */
541
audio_setup_infoframe(sc);
542
/* Setup audio source */
543
WR4(sc, HDMI_NV_PDISP_SOR_AUDIO_CNTRL0,
544
SOR_AUDIO_CNTRL0_SOURCE_SELECT(sc->audio_src_type) |
545
SOR_AUDIO_CNTRL0_INJECT_NULLSMPL);
546
547
val = RD4(sc, HDMI_NV_PDISP_SOR_AUDIO_SPARE0);
548
val |= SOR_AUDIO_SPARE0_HBR_ENABLE;
549
WR4(sc, HDMI_NV_PDISP_SOR_AUDIO_SPARE0, val);
550
551
WR4(sc, HDMI_NV_PDISP_HDMI_ACR_CTRL, 0);
552
553
WR4(sc, HDMI_NV_PDISP_AUDIO_N,
554
AUDIO_N_RESETF |
555
AUDIO_N_GENERATE_ALTERNATE |
556
AUDIO_N_VALUE(audio_n - 1));
557
558
WR4(sc, HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH,
559
ACR_SUBPACK_N(audio_n) | ACR_ENABLE);
560
561
WR4(sc, HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW,
562
ACR_SUBPACK_CTS(audio_cts));
563
564
WR4(sc, HDMI_NV_PDISP_HDMI_SPARE,
565
SPARE_HW_CTS | SPARE_FORCE_SW_CTS | SPARE_CTS_RESET_VAL(1));
566
567
val = RD4(sc, HDMI_NV_PDISP_AUDIO_N);
568
val &= ~AUDIO_N_RESETF;
569
WR4(sc, HDMI_NV_PDISP_AUDIO_N, val);
570
571
WR4(sc, aval_reg, audio_aval);
572
573
return (0);
574
}
575
576
static void
577
audio_disable(struct hdmi_softc *sc) {
578
uint32_t val;
579
580
/* Disable audio */
581
val = RD4(sc, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
582
val &= ~GENERIC_CTRL_AUDIO;
583
WR4(sc, HDMI_NV_PDISP_HDMI_GENERIC_CTRL, val);
584
585
/* Disable audio infoframes */
586
val = RD4(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
587
val &= ~AUDIO_INFOFRAME_CTRL_ENABLE;
588
WR4(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL, val);
589
}
590
591
static void
592
audio_enable(struct hdmi_softc *sc) {
593
uint32_t val;
594
595
if (!sc->hdmi_mode)
596
audio_disable(sc);
597
598
/* Enable audio infoframes */
599
val = RD4(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
600
val |= AUDIO_INFOFRAME_CTRL_ENABLE;
601
WR4(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL, val);
602
603
/* Enable audio */
604
val = RD4(sc, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
605
val |= GENERIC_CTRL_AUDIO;
606
WR4(sc, HDMI_NV_PDISP_HDMI_GENERIC_CTRL, val);
607
}
608
609
/* -------------------------------------------------------------------
610
*
611
* HDMI.
612
*
613
*/
614
/* Process format change notification from HDA */
615
static void
616
hda_intr(struct hdmi_softc *sc)
617
{
618
uint32_t val;
619
int rv;
620
621
if (!sc->hdmi_mode)
622
return;
623
624
val = RD4(sc, HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH0);
625
if ((val & (1 << 30)) == 0) {
626
audio_disable(sc);
627
return;
628
}
629
630
/* XXX Move this to any header */
631
/* Keep in sync with HDA */
632
sc->audio_freq = val & 0x00FFFFFF;
633
sc->audio_chans = (val >> 24) & 0x0f;
634
DRM_DEBUG_KMS("%d channel(s) at %dHz\n", sc->audio_chans,
635
sc->audio_freq);
636
637
rv = audio_setup(sc);
638
if (rv != 0) {
639
audio_disable(sc);
640
return;
641
}
642
643
audio_enable(sc);
644
}
645
646
static void
647
tmds_init(struct hdmi_softc *sc, const struct tmds_config *tmds)
648
{
649
650
WR4(sc, HDMI_NV_PDISP_SOR_PLL0, tmds->pll0);
651
WR4(sc, HDMI_NV_PDISP_SOR_PLL1, tmds->pll1);
652
WR4(sc, HDMI_NV_PDISP_PE_CURRENT, tmds->pe_c);
653
WR4(sc, HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT, tmds->drive_c);
654
WR4(sc, HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT, tmds->peak_c);
655
WR4(sc, HDMI_NV_PDISP_SOR_PAD_CTLS0, tmds->pad_ctls);
656
}
657
658
static int
659
hdmi_sor_start(struct hdmi_softc *sc, struct drm_display_mode *mode)
660
{
661
int i;
662
uint32_t val;
663
664
/* Enable TMDS macro */
665
val = RD4(sc, HDMI_NV_PDISP_SOR_PLL0);
666
val &= ~SOR_PLL0_PWR;
667
val &= ~SOR_PLL0_VCOPD;
668
val &= ~SOR_PLL0_PULLDOWN;
669
WR4(sc, HDMI_NV_PDISP_SOR_PLL0, val);
670
DELAY(10);
671
672
val = RD4(sc, HDMI_NV_PDISP_SOR_PLL0);
673
val &= ~SOR_PLL0_PDBG;
674
WR4(sc, HDMI_NV_PDISP_SOR_PLL0, val);
675
676
WR4(sc, HDMI_NV_PDISP_SOR_PWR, SOR_PWR_SETTING_NEW);
677
WR4(sc, HDMI_NV_PDISP_SOR_PWR, 0);
678
679
/* Wait until SOR is ready */
680
for (i = 1000; i > 0; i--) {
681
val = RD4(sc, HDMI_NV_PDISP_SOR_PWR);
682
if ((val & SOR_PWR_SETTING_NEW) == 0)
683
break;
684
DELAY(10);
685
}
686
if (i <= 0) {
687
device_printf(sc->dev, "Timeouted while enabling SOR power.\n");
688
return (ETIMEDOUT);
689
}
690
691
val = SOR_STATE2_ASY_OWNER(ASY_OWNER_HEAD0) |
692
SOR_STATE2_ASY_SUBOWNER(SUBOWNER_BOTH) |
693
SOR_STATE2_ASY_CRCMODE(ASY_CRCMODE_COMPLETE) |
694
SOR_STATE2_ASY_PROTOCOL(ASY_PROTOCOL_SINGLE_TMDS_A);
695
if (mode->flags & DRM_MODE_FLAG_NHSYNC)
696
val |= SOR_STATE2_ASY_HSYNCPOL_NEG;
697
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
698
val |= SOR_STATE2_ASY_VSYNCPOL_NEG;
699
WR4(sc, HDMI_NV_PDISP_SOR_STATE2, val);
700
701
WR4(sc, HDMI_NV_PDISP_SOR_STATE1, SOR_STATE1_ASY_ORMODE_NORMAL |
702
SOR_STATE1_ASY_HEAD_OPMODE(ASY_HEAD_OPMODE_AWAKE));
703
704
WR4(sc, HDMI_NV_PDISP_SOR_STATE0, 0);
705
WR4(sc, HDMI_NV_PDISP_SOR_STATE0, SOR_STATE0_UPDATE);
706
707
val = RD4(sc, HDMI_NV_PDISP_SOR_STATE1);
708
val |= SOR_STATE1_ATTACHED;
709
WR4(sc, HDMI_NV_PDISP_SOR_STATE1, val);
710
711
WR4(sc, HDMI_NV_PDISP_SOR_STATE0, 0);
712
713
return 0;
714
}
715
716
static int
717
hdmi_disable(struct hdmi_softc *sc)
718
{
719
struct tegra_crtc *crtc;
720
device_t dc;
721
uint32_t val;
722
723
dc = NULL;
724
if (sc->output.encoder.crtc != NULL) {
725
crtc = container_of(sc->output.encoder.crtc, struct tegra_crtc,
726
drm_crtc);
727
dc = crtc->dev;
728
}
729
730
if (dc != NULL) {
731
TEGRA_DC_HDMI_ENABLE(dc, false);
732
TEGRA_DC_DISPLAY_ENABLE(dc, false);
733
}
734
audio_disable(sc);
735
val = RD4(sc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
736
val &= ~AVI_INFOFRAME_CTRL_ENABLE;
737
WR4(sc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL, val);
738
739
/* Disable interrupts */
740
WR4(sc, HDMI_NV_PDISP_INT_ENABLE, 0);
741
WR4(sc, HDMI_NV_PDISP_INT_MASK, 0);
742
743
return (0);
744
}
745
746
static int
747
hdmi_enable(struct hdmi_softc *sc)
748
{
749
uint64_t freq;
750
struct drm_display_mode *mode;
751
struct tegra_crtc *crtc;
752
uint32_t val, h_sync_width, h_back_porch, h_front_porch, h_pulse_start;
753
uint32_t h_max_ac_packet, div8_2;
754
device_t dc;
755
int i, rv;
756
757
mode = &sc->output.encoder.crtc->mode;
758
crtc = container_of(sc->output.encoder.crtc, struct tegra_crtc,
759
drm_crtc);
760
dc = crtc->dev;
761
762
/* Compute all timings first. */
763
sc->pclk = mode->clock * 1000;
764
h_sync_width = mode->hsync_end - mode->hsync_start;
765
h_back_porch = mode->htotal - mode->hsync_end;
766
h_front_porch = mode->hsync_start - mode->hdisplay;
767
h_pulse_start = 1 + h_sync_width + h_back_porch - 10;
768
h_max_ac_packet = (h_sync_width + h_back_porch + h_front_porch -
769
HDMI_REKEY_DEFAULT - 18) / 32;
770
771
/* Check if HDMI device is connected and detected. */
772
if (sc->output.connector.edid_blob_ptr == NULL) {
773
sc->hdmi_mode = false;
774
} else {
775
sc->hdmi_mode = drm_detect_hdmi_monitor(
776
(struct edid *)sc->output.connector.edid_blob_ptr->data);
777
}
778
779
/* Get exact HDMI pixel frequency. */
780
rv = clk_get_freq(sc->clk_hdmi, &freq);
781
if (rv != 0) {
782
device_printf(sc->dev,
783
"Cannot get 'hdmi' clock frequency\n");
784
return (rv);
785
}
786
DRM_DEBUG_KMS("HDMI frequency: %llu Hz\n", freq);
787
788
/* Wakeup SOR power */
789
val = RD4(sc, HDMI_NV_PDISP_SOR_PLL0);
790
val &= ~SOR_PLL0_PDBG;
791
WR4(sc, HDMI_NV_PDISP_SOR_PLL0, val);
792
DELAY(10);
793
794
val = RD4(sc, HDMI_NV_PDISP_SOR_PLL0);
795
val &= ~SOR_PLL0_PWR;
796
WR4(sc, HDMI_NV_PDISP_SOR_PLL0, val);
797
798
/* Setup timings */
799
TEGRA_DC_SETUP_TIMING(dc, h_pulse_start);
800
WR4(sc, HDMI_NV_PDISP_HDMI_VSYNC_WINDOW,
801
VSYNC_WINDOW_START(0x200) | VSYNC_WINDOW_END(0x210) |
802
VSYNC_WINDOW_ENABLE);
803
804
/* Setup video source and adjust video range */
805
val = 0;
806
if (crtc->nvidia_head != 0)
807
HDMI_SRC_DISPLAYB;
808
if ((mode->hdisplay != 640) || (mode->vdisplay != 480))
809
val |= ARM_VIDEO_RANGE_LIMITED;
810
WR4(sc, HDMI_NV_PDISP_INPUT_CONTROL, val);
811
812
/* Program SOR reference clock - it uses 8.2 fractional divisor */
813
div8_2 = (freq * 4) / 1000000;
814
val = SOR_REFCLK_DIV_INT(div8_2 >> 2) | SOR_REFCLK_DIV_FRAC(div8_2);
815
WR4(sc, HDMI_NV_PDISP_SOR_REFCLK, val);
816
817
/* Setup audio */
818
if (sc->hdmi_mode) {
819
rv = audio_setup(sc);
820
if (rv != 0)
821
sc->hdmi_mode = false;
822
}
823
824
/* Init HDA ELD */
825
init_hda_eld(sc);
826
val = HDMI_CTRL_REKEY(HDMI_REKEY_DEFAULT);
827
val |= HDMI_CTRL_MAX_AC_PACKET(h_max_ac_packet);
828
if (sc->hdmi_mode)
829
val |= HDMI_CTRL_ENABLE;
830
WR4(sc, HDMI_NV_PDISP_HDMI_CTRL, val);
831
832
/* Setup TMDS */
833
for (i = 0; i < sc->n_tmds_configs; i++) {
834
if (sc->pclk <= sc->tmds_config[i].pclk) {
835
tmds_init(sc, sc->tmds_config + i);
836
break;
837
}
838
}
839
840
/* Program sequencer. */
841
WR4(sc, HDMI_NV_PDISP_SOR_SEQ_CTL,
842
SOR_SEQ_PU_PC(0) | SOR_SEQ_PU_PC_ALT(0) |
843
SOR_SEQ_PD_PC(8) | SOR_SEQ_PD_PC_ALT(8));
844
845
val = SOR_SEQ_INST_WAIT_TIME(1) |
846
SOR_SEQ_INST_WAIT_UNITS(WAIT_UNITS_VSYNC) |
847
SOR_SEQ_INST_HALT |
848
SOR_SEQ_INST_DRIVE_PWM_OUT_LO;
849
WR4(sc, HDMI_NV_PDISP_SOR_SEQ_INST(0), val);
850
WR4(sc, HDMI_NV_PDISP_SOR_SEQ_INST(8), val);
851
852
val = RD4(sc,HDMI_NV_PDISP_SOR_CSTM);
853
val &= ~SOR_CSTM_LVDS_ENABLE;
854
val &= ~SOR_CSTM_ROTCLK(~0);
855
val |= SOR_CSTM_ROTCLK(2);
856
val &= ~SOR_CSTM_MODE(~0);
857
val |= SOR_CSTM_MODE(CSTM_MODE_TMDS);
858
val |= SOR_CSTM_PLLDIV;
859
WR4(sc, HDMI_NV_PDISP_SOR_CSTM, val);
860
861
TEGRA_DC_DISPLAY_ENABLE(dc, false);
862
863
rv = hdmi_sor_start(sc, mode);
864
if (rv != 0)
865
return (rv);
866
867
TEGRA_DC_HDMI_ENABLE(dc, true);
868
TEGRA_DC_DISPLAY_ENABLE(dc, true);
869
870
/* Enable HDA codec interrupt */
871
WR4(sc, HDMI_NV_PDISP_INT_MASK, INT_CODEC_SCRATCH0);
872
WR4(sc, HDMI_NV_PDISP_INT_ENABLE, INT_CODEC_SCRATCH0);
873
874
if (sc->hdmi_mode) {
875
avi_setup_infoframe(sc, mode);
876
audio_enable(sc);
877
}
878
879
return (0);
880
}
881
882
/* -------------------------------------------------------------------
883
*
884
* DRM Interface.
885
*
886
*/
887
static enum drm_mode_status
888
hdmi_connector_mode_valid(struct drm_connector *connector,
889
struct drm_display_mode *mode)
890
{
891
struct tegra_drm_encoder *output;
892
struct hdmi_softc *sc;
893
int rv;
894
uint64_t freq;
895
896
output = container_of(connector, struct tegra_drm_encoder,
897
connector);
898
sc = device_get_softc(output->dev);
899
900
freq = HDMI_DC_CLOCK_MULTIPIER * mode->clock * 1000;
901
rv = clk_test_freq(sc->clk_parent, freq, 0);
902
DRM_DEBUG_KMS("Test HDMI frequency: %u kHz, rv: %d\n", mode->clock, rv);
903
if (rv != 0)
904
return (MODE_NOCLOCK);
905
906
return (MODE_OK);
907
}
908
909
static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
910
.get_modes = tegra_drm_connector_get_modes,
911
.mode_valid = hdmi_connector_mode_valid,
912
.best_encoder = tegra_drm_connector_best_encoder,
913
};
914
915
static const struct drm_connector_funcs hdmi_connector_funcs = {
916
.dpms = drm_helper_connector_dpms,
917
.detect = tegra_drm_connector_detect,
918
.fill_modes = drm_helper_probe_single_connector_modes,
919
.destroy = drm_connector_cleanup,
920
};
921
922
static const struct drm_encoder_funcs hdmi_encoder_funcs = {
923
.destroy = drm_encoder_cleanup,
924
};
925
926
static void
927
hdmi_encoder_dpms(struct drm_encoder *encoder, int mode)
928
{
929
930
/* Empty function. */
931
}
932
933
static bool
934
hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
935
const struct drm_display_mode *mode,
936
struct drm_display_mode *adjusted)
937
{
938
939
return (true);
940
}
941
942
static void
943
hdmi_encoder_prepare(struct drm_encoder *encoder)
944
{
945
946
/* Empty function. */
947
}
948
949
static void
950
hdmi_encoder_commit(struct drm_encoder *encoder)
951
{
952
953
/* Empty function. */
954
}
955
956
static void
957
hdmi_encoder_mode_set(struct drm_encoder *encoder,
958
struct drm_display_mode *mode, struct drm_display_mode *adjusted)
959
{
960
struct tegra_drm_encoder *output;
961
struct hdmi_softc *sc;
962
int rv;
963
964
output = container_of(encoder, struct tegra_drm_encoder, encoder);
965
sc = device_get_softc(output->dev);
966
rv = hdmi_enable(sc);
967
if (rv != 0)
968
device_printf(sc->dev, "Cannot enable HDMI port\n");
969
970
}
971
972
static void
973
hdmi_encoder_disable(struct drm_encoder *encoder)
974
{
975
struct tegra_drm_encoder *output;
976
struct hdmi_softc *sc;
977
int rv;
978
979
output = container_of(encoder, struct tegra_drm_encoder, encoder);
980
sc = device_get_softc(output->dev);
981
if (sc == NULL)
982
return;
983
rv = hdmi_disable(sc);
984
if (rv != 0)
985
device_printf(sc->dev, "Cannot disable HDMI port\n");
986
}
987
988
static const struct drm_encoder_helper_funcs hdmi_encoder_helper_funcs = {
989
.dpms = hdmi_encoder_dpms,
990
.mode_fixup = hdmi_encoder_mode_fixup,
991
.prepare = hdmi_encoder_prepare,
992
.commit = hdmi_encoder_commit,
993
.mode_set = hdmi_encoder_mode_set,
994
.disable = hdmi_encoder_disable,
995
};
996
997
/* -------------------------------------------------------------------
998
*
999
* Bus and infrastructure.
1000
*
1001
*/
1002
static int
1003
hdmi_init_client(device_t dev, device_t host1x, struct tegra_drm *drm)
1004
{
1005
struct hdmi_softc *sc;
1006
phandle_t node;
1007
int rv;
1008
1009
sc = device_get_softc(dev);
1010
node = ofw_bus_get_node(sc->dev);
1011
sc->drm = drm;
1012
sc->output.setup_clock = &hdmi_setup_clock;
1013
1014
rv = tegra_drm_encoder_attach(&sc->output, node);
1015
if (rv != 0) {
1016
device_printf(dev, "Cannot attach output connector\n");
1017
return(ENXIO);
1018
}
1019
1020
/* Connect this encoder + connector to DRM. */
1021
drm_connector_init(&drm->drm_dev, &sc->output.connector,
1022
&hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
1023
1024
drm_connector_helper_add(&sc->output.connector,
1025
&hdmi_connector_helper_funcs);
1026
1027
sc->output.connector.dpms = DRM_MODE_DPMS_OFF;
1028
1029
drm_encoder_init(&drm->drm_dev, &sc->output.encoder,
1030
&hdmi_encoder_funcs, DRM_MODE_ENCODER_TMDS);
1031
1032
drm_encoder_helper_add(&sc->output.encoder, &hdmi_encoder_helper_funcs);
1033
1034
drm_mode_connector_attach_encoder(&sc->output.connector,
1035
&sc->output.encoder);
1036
1037
rv = tegra_drm_encoder_init(&sc->output, drm);
1038
if (rv < 0) {
1039
device_printf(sc->dev, "Unable to init HDMI output\n");
1040
return (rv);
1041
}
1042
sc->output.encoder.possible_crtcs = 0x3;
1043
return (0);
1044
}
1045
1046
static int
1047
hdmi_exit_client(device_t dev, device_t host1x, struct tegra_drm *drm)
1048
{
1049
struct hdmi_softc *sc;
1050
1051
sc = device_get_softc(dev);
1052
tegra_drm_encoder_exit(&sc->output, drm);
1053
return (0);
1054
}
1055
1056
static int
1057
get_fdt_resources(struct hdmi_softc *sc, phandle_t node)
1058
{
1059
int rv;
1060
1061
rv = regulator_get_by_ofw_property(sc->dev, 0, "hdmi-supply",
1062
&sc->supply_hdmi);
1063
if (rv != 0) {
1064
device_printf(sc->dev, "Cannot get 'hdmi' regulator\n");
1065
return (ENXIO);
1066
}
1067
rv = regulator_get_by_ofw_property(sc->dev,0, "pll-supply",
1068
&sc->supply_pll);
1069
if (rv != 0) {
1070
device_printf(sc->dev, "Cannot get 'pll' regulator\n");
1071
return (ENXIO);
1072
}
1073
rv = regulator_get_by_ofw_property(sc->dev, 0, "vdd-supply",
1074
&sc->supply_vdd);
1075
if (rv != 0) {
1076
device_printf(sc->dev, "Cannot get 'vdd' regulator\n");
1077
return (ENXIO);
1078
}
1079
1080
rv = hwreset_get_by_ofw_name(sc->dev, 0, "hdmi", &sc->hwreset_hdmi);
1081
if (rv != 0) {
1082
device_printf(sc->dev, "Cannot get 'hdmi' reset\n");
1083
return (ENXIO);
1084
}
1085
rv = clk_get_by_ofw_name(sc->dev, 0, "parent", &sc->clk_parent);
1086
if (rv != 0) {
1087
device_printf(sc->dev, "Cannot get 'parent' clock\n");
1088
return (ENXIO);
1089
}
1090
rv = clk_get_by_ofw_name(sc->dev, 0, "hdmi", &sc->clk_hdmi);
1091
if (rv != 0) {
1092
device_printf(sc->dev, "Cannot get 'hdmi' clock\n");
1093
return (ENXIO);
1094
}
1095
1096
return (0);
1097
}
1098
1099
static int
1100
enable_fdt_resources(struct hdmi_softc *sc)
1101
{
1102
int rv;
1103
1104
rv = clk_set_parent_by_clk(sc->clk_hdmi, sc->clk_parent);
1105
if (rv != 0) {
1106
device_printf(sc->dev,
1107
"Cannot set parent for 'hdmi' clock\n");
1108
return (rv);
1109
}
1110
1111
/* 594 MHz is arbitrarily selected value */
1112
rv = clk_set_freq(sc->clk_parent, 594000000, 0);
1113
if (rv != 0) {
1114
device_printf(sc->dev,
1115
"Cannot set frequency for 'hdmi' parent clock\n");
1116
return (rv);
1117
}
1118
rv = clk_set_freq(sc->clk_hdmi, 594000000 / 4, 0);
1119
if (rv != 0) {
1120
device_printf(sc->dev,
1121
"Cannot set frequency for 'hdmi' parent clock\n");
1122
return (rv);
1123
}
1124
1125
rv = regulator_enable(sc->supply_hdmi);
1126
if (rv != 0) {
1127
device_printf(sc->dev, "Cannot enable 'hdmi' regulator\n");
1128
return (rv);
1129
}
1130
rv = regulator_enable(sc->supply_pll);
1131
if (rv != 0) {
1132
device_printf(sc->dev, "Cannot enable 'pll' regulator\n");
1133
return (rv);
1134
}
1135
rv = regulator_enable(sc->supply_vdd);
1136
if (rv != 0) {
1137
device_printf(sc->dev, "Cannot enable 'vdd' regulator\n");
1138
return (rv);
1139
}
1140
1141
rv = clk_enable(sc->clk_hdmi);
1142
if (rv != 0) {
1143
device_printf(sc->dev, "Cannot enable 'hdmi' clock\n");
1144
return (rv);
1145
}
1146
1147
rv = hwreset_deassert(sc->hwreset_hdmi);
1148
if (rv != 0) {
1149
device_printf(sc->dev, "Cannot unreset 'hdmi' reset\n");
1150
return (rv);
1151
}
1152
return (0);
1153
}
1154
1155
static void
1156
hdmi_intr(void *arg)
1157
{
1158
struct hdmi_softc *sc;
1159
uint32_t status;
1160
1161
sc = arg;
1162
1163
/* Confirm interrupt */
1164
status = RD4(sc, HDMI_NV_PDISP_INT_STATUS);
1165
WR4(sc, HDMI_NV_PDISP_INT_STATUS, status);
1166
1167
/* process audio verb from HDA */
1168
if (status & INT_CODEC_SCRATCH0)
1169
hda_intr(sc);
1170
}
1171
1172
static int
1173
hdmi_probe(device_t dev)
1174
{
1175
1176
if (!ofw_bus_status_okay(dev))
1177
return (ENXIO);
1178
1179
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
1180
return (ENXIO);
1181
1182
device_set_desc(dev, "Tegra HDMI");
1183
return (BUS_PROBE_DEFAULT);
1184
}
1185
1186
static int
1187
hdmi_attach(device_t dev)
1188
{
1189
struct hdmi_softc *sc;
1190
phandle_t node;
1191
int rid, rv;
1192
1193
sc = device_get_softc(dev);
1194
sc->dev = dev;
1195
sc->output.dev = sc->dev;
1196
node = ofw_bus_get_node(sc->dev);
1197
1198
sc->audio_src_type = SOURCE_SELECT_AUTO;
1199
sc->audio_freq = 44100;
1200
sc->audio_chans = 2;
1201
sc->hdmi_mode = false;
1202
1203
sc->tmds_config = tegra124_tmds_config;
1204
sc->n_tmds_configs = nitems(tegra124_tmds_config);
1205
1206
rid = 0;
1207
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
1208
RF_ACTIVE);
1209
if (sc->mem_res == NULL) {
1210
device_printf(dev, "Cannot allocate memory resources\n");
1211
goto fail;
1212
}
1213
1214
rid = 0;
1215
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
1216
if (sc->irq_res == NULL) {
1217
device_printf(dev, "Cannot allocate IRQ resources\n");
1218
goto fail;
1219
}
1220
1221
rv = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
1222
NULL, hdmi_intr, sc, &sc->irq_ih);
1223
if (rv != 0) {
1224
device_printf(dev,
1225
"WARNING: unable to register interrupt handler\n");
1226
goto fail;
1227
}
1228
1229
rv = get_fdt_resources(sc, node);
1230
if (rv != 0) {
1231
device_printf(dev, "Cannot parse FDT resources\n");
1232
goto fail;
1233
}
1234
rv = enable_fdt_resources(sc);
1235
if (rv != 0) {
1236
device_printf(dev, "Cannot enable FDT resources\n");
1237
goto fail;
1238
}
1239
1240
rv = TEGRA_DRM_REGISTER_CLIENT(device_get_parent(sc->dev), sc->dev);
1241
if (rv != 0) {
1242
device_printf(dev, "Cannot register DRM device\n");
1243
goto fail;
1244
}
1245
bus_attach_children(dev);
1246
return (0);
1247
1248
fail:
1249
TEGRA_DRM_DEREGISTER_CLIENT(device_get_parent(sc->dev), sc->dev);
1250
1251
if (sc->irq_ih != NULL)
1252
bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
1253
if (sc->clk_parent != NULL)
1254
clk_release(sc->clk_parent);
1255
if (sc->clk_hdmi != NULL)
1256
clk_release(sc->clk_hdmi);
1257
if (sc->hwreset_hdmi != NULL)
1258
hwreset_release(sc->hwreset_hdmi);
1259
if (sc->supply_hdmi != NULL)
1260
regulator_release(sc->supply_hdmi);
1261
if (sc->supply_pll != NULL)
1262
regulator_release(sc->supply_pll);
1263
if (sc->supply_vdd != NULL)
1264
regulator_release(sc->supply_vdd);
1265
if (sc->irq_res != NULL)
1266
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
1267
if (sc->mem_res != NULL)
1268
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
1269
return (ENXIO);
1270
}
1271
1272
static int
1273
hdmi_detach(device_t dev)
1274
{
1275
struct hdmi_softc *sc;
1276
int error;
1277
1278
error = bus_generic_detach(dev);
1279
if (error != 0)
1280
return (error);
1281
1282
sc = device_get_softc(dev);
1283
1284
TEGRA_DRM_DEREGISTER_CLIENT(device_get_parent(sc->dev), sc->dev);
1285
1286
if (sc->irq_ih != NULL)
1287
bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
1288
if (sc->clk_parent != NULL)
1289
clk_release(sc->clk_parent);
1290
if (sc->clk_hdmi != NULL)
1291
clk_release(sc->clk_hdmi);
1292
if (sc->hwreset_hdmi != NULL)
1293
hwreset_release(sc->hwreset_hdmi);
1294
if (sc->supply_hdmi != NULL)
1295
regulator_release(sc->supply_hdmi);
1296
if (sc->supply_pll != NULL)
1297
regulator_release(sc->supply_pll);
1298
if (sc->supply_vdd != NULL)
1299
regulator_release(sc->supply_vdd);
1300
if (sc->irq_res != NULL)
1301
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
1302
if (sc->mem_res != NULL)
1303
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
1304
return (0);
1305
}
1306
1307
static device_method_t tegra_hdmi_methods[] = {
1308
/* Device interface */
1309
DEVMETHOD(device_probe, hdmi_probe),
1310
DEVMETHOD(device_attach, hdmi_attach),
1311
DEVMETHOD(device_detach, hdmi_detach),
1312
1313
/* tegra drm interface */
1314
DEVMETHOD(tegra_drm_init_client, hdmi_init_client),
1315
DEVMETHOD(tegra_drm_exit_client, hdmi_exit_client),
1316
1317
DEVMETHOD_END
1318
};
1319
1320
DEFINE_CLASS_0(tegra_hdmi, tegra_hdmi_driver, tegra_hdmi_methods,
1321
sizeof(struct hdmi_softc));
1322
DRIVER_MODULE(tegra_hdmi, host1x, tegra_hdmi_driver, 0, 0);
1323
1324