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