The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/nvidia/drm2/tegra_hdmi.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 273ab7be927d06ec64cd005facceb779


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.