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