Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/nvidia add Tegra124 HDMI support



details:   https://anonhg.NetBSD.org/src/rev/90912feb6867
branches:  trunk
changeset: 809602:90912feb6867
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Thu Jul 23 14:31:05 2015 +0000

description:
add Tegra124 HDMI support

diffstat:

 sys/arch/arm/nvidia/tegra_dc.c      |  59 +++++++++++++++++++++++++++++-------
 sys/arch/arm/nvidia/tegra_dcreg.h   |  27 ++++++++++++++++-
 sys/arch/arm/nvidia/tegra_genfb.c   |   7 +--
 sys/arch/arm/nvidia/tegra_hdmi.c    |  45 ++++++++++++++++++++++++---
 sys/arch/arm/nvidia/tegra_hdmireg.h |  18 ++++++++++-
 5 files changed, 132 insertions(+), 24 deletions(-)

diffs (truncated from 394 to 300 lines):

diff -r cb62bbcf0f88 -r 90912feb6867 sys/arch/arm/nvidia/tegra_dc.c
--- a/sys/arch/arm/nvidia/tegra_dc.c    Thu Jul 23 14:30:06 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_dc.c    Thu Jul 23 14:31:05 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_dc.c,v 1.2 2015/07/08 01:23:28 jmcneill Exp $ */
+/* $NetBSD: tegra_dc.c,v 1.3 2015/07/23 14:31:05 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_dc.c,v 1.2 2015/07/08 01:23:28 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_dc.c,v 1.3 2015/07/23 14:31:05 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -46,7 +46,7 @@
 
 #define TEGRA_DC_NPORTS                2
 #define TEGRA_DC_DEPTH         32
-#define TEGRA_DC_FBALIGN       16
+#define TEGRA_DC_FBALIGN       PAGE_SIZE
 
 static int     tegra_dc_match(device_t, cfdata_t, void *);
 static void    tegra_dc_attach(device_t, device_t, void *);
@@ -145,6 +145,8 @@
 
        sc->sc_dmasize = size;
 
+       memset(sc->sc_dmap, 0, size);
+
        return 0;
 
 destroy:
@@ -185,6 +187,10 @@
 static void
 tegra_dc_init_win(struct tegra_dc_softc *sc, const struct videomode *mode)
 {
+       /* Write access control */
+       DC_WRITE(sc, DC_CMD_STATE_ACCESS_REG,
+           DC_CMD_STATE_ACCESS_WRITE_MUX | DC_CMD_STATE_ACCESS_READ_MUX);
+
        /* Enable window A programming */
        DC_WRITE(sc, DC_CMD_DISPLAY_WINDOW_HEADER_REG,
            DC_CMD_DISPLAY_WINDOW_HEADER_WINDOW_A_SELECT);
@@ -199,6 +205,11 @@
            __SHIFTIN(DC_WINC_A_BYTE_SWAP_SWAP_NOSWAP,
                      DC_WINC_A_BYTE_SWAP_SWAP));
 
+       /* Initial DDA */
+       DC_WRITE(sc, DC_WINC_A_H_INITIAL_DDA_REG, 0);
+       DC_WRITE(sc, DC_WINC_A_V_INITIAL_DDA_REG, 0);
+       DC_WRITE(sc, DC_WINC_A_DDA_INCREMENT_REG, 0x10001000);
+
        /* Window position, size, stride */
        DC_WRITE(sc, DC_WINC_A_POSITION_REG,
            __SHIFTIN(0, DC_WINC_A_POSITION_V) |
@@ -218,6 +229,10 @@
        DC_WRITE(sc, DC_WINBUF_A_START_ADDR_REG,
            (uint32_t)sc->sc_dmamap->dm_segs[0].ds_addr);
 
+       /* Offsets */
+       DC_WRITE(sc, DC_WINBUF_A_ADDR_H_OFFSET_REG, 0);
+       DC_WRITE(sc, DC_WINBUF_A_ADDR_V_OFFSET_REG, 0);
+
        /* Surface kind */
        DC_WRITE(sc, DC_WINBUF_A_SURFACE_KIND_REG,
            __SHIFTIN(DC_WINBUF_A_SURFACE_KIND_SURFACE_KIND_PITCH,
@@ -232,14 +247,35 @@
 tegra_dc_init_disp(struct tegra_dc_softc *sc, const struct videomode *mode)
 {
        const u_int hspw = mode->hsync_end - mode->hsync_start;
-       const u_int hbp = mode->htotal - mode->hsync_start;
+       const u_int hbp = mode->htotal - mode->hsync_end;
        const u_int hfp = mode->hsync_start - mode->hdisplay;
        const u_int vspw = mode->vsync_end - mode->vsync_start;
-       const u_int vbp = mode->vtotal - mode->vsync_start;
+       const u_int vbp = mode->vtotal - mode->vsync_end;
        const u_int vfp = mode->vsync_start - mode->vdisplay;
 
+       DC_WRITE(sc, DC_DISP_DISP_TIMING_OPTIONS_REG,
+           __SHIFTIN(1, DC_DISP_DISP_TIMING_OPTIONS_VSYNC_POS));
+       DC_WRITE(sc, DC_DISP_DISP_COLOR_CONTROL_REG,
+           __SHIFTIN(DC_DISP_DISP_COLOR_CONTROL_BASE_COLOR_SIZE_888,
+                     DC_DISP_DISP_COLOR_CONTROL_BASE_COLOR_SIZE));
+       DC_WRITE(sc, DC_DISP_DISP_SIGNAL_OPTIONS0_REG,
+           DC_DISP_DISP_SIGNAL_OPTIONS0_H_PULSE2_ENABLE);
+       DC_WRITE(sc, DC_DISP_H_PULSE2_CONTROL_REG,
+           __SHIFTIN(DC_DISP_H_PULSE2_CONTROL_V_QUAL_VACTIVE,
+                     DC_DISP_H_PULSE2_CONTROL_V_QUAL) |
+           __SHIFTIN(DC_DISP_H_PULSE2_CONTROL_LAST_END_A,
+                     DC_DISP_H_PULSE2_CONTROL_LAST));
+
+       u_int pulse_start = 1 + hspw + hbp - 10;
+       DC_WRITE(sc, DC_DISP_H_PULSE2_POSITION_A_REG,
+           __SHIFTIN(pulse_start, DC_DISP_H_PULSE2_POSITION_A_START) |
+           __SHIFTIN(pulse_start + 8, DC_DISP_H_PULSE2_POSITION_A_END));
+
        /* Pixel clock */
-       DC_WRITE(sc, DC_DISP_DISP_CLOCK_CONTROL_REG, 0);
+       const u_int div = (tegra_car_plld2_rate() * 2) / (mode->dot_clock * 1000) - 2;
+       DC_WRITE(sc, DC_DISP_DISP_CLOCK_CONTROL_REG,
+           __SHIFTIN(0, DC_DISP_DISP_CLOCK_CONTROL_PIXEL_CLK_DIVIDER) |
+           __SHIFTIN(div, DC_DISP_DISP_CLOCK_CONTROL_SHIFT_CLK_DIVIDER));
 
        /* Mode timings */
        DC_WRITE(sc, DC_DISP_REF_TO_SYNC_REG,
@@ -259,10 +295,9 @@
            __SHIFTIN(mode->hdisplay, DC_DISP_DISP_ACTIVE_H));
 
        /* Enable continus display mode */
-       DC_SET_CLEAR(sc, DC_CMD_DISPLAY_COMMAND_REG,
+       DC_WRITE(sc, DC_CMD_DISPLAY_COMMAND_REG,
            __SHIFTIN(DC_CMD_DISPLAY_COMMAND_DISPLAY_CTRL_MODE_C_DISPLAY,
-                     DC_CMD_DISPLAY_COMMAND_DISPLAY_CTRL_MODE),
-           DC_CMD_DISPLAY_COMMAND_DISPLAY_CTRL_MODE);
+                     DC_CMD_DISPLAY_COMMAND_DISPLAY_CTRL_MODE));
 
        /* Enable power */
        DC_SET_CLEAR(sc, DC_CMD_DISPLAY_POWER_CONTROL_REG,
@@ -281,9 +316,9 @@
 {
        /* Commit settings */
        DC_WRITE(sc, DC_CMD_STATE_CONTROL_REG,
-           DC_CMD_STATE_CONTROL_GENERAL_UPDATE);
+           DC_CMD_STATE_CONTROL_GENERAL_UPDATE | DC_CMD_STATE_CONTROL_WIN_A_UPDATE);
        DC_WRITE(sc, DC_CMD_STATE_CONTROL_REG,
-           DC_CMD_STATE_CONTROL_GENERAL_ACT_REQ);
+           DC_CMD_STATE_CONTROL_GENERAL_ACT_REQ | DC_CMD_STATE_CONTROL_WIN_A_ACT_REQ);
 }
 
 int
@@ -309,7 +344,7 @@
 
        const uint32_t depth = TEGRA_DC_DEPTH;
        const uint32_t fbsize = mode->vdisplay * mode->hdisplay * (depth / 8);
-       const bus_size_t dmasize = (fbsize + 3) & ~3;
+       const bus_size_t dmasize = (fbsize + PAGE_MASK) & ~PAGE_MASK;
        error = tegra_dc_allocmem(sc, dmasize);
        if (error) {
                aprint_error_dev(dev,
diff -r cb62bbcf0f88 -r 90912feb6867 sys/arch/arm/nvidia/tegra_dcreg.h
--- a/sys/arch/arm/nvidia/tegra_dcreg.h Thu Jul 23 14:30:06 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_dcreg.h Thu Jul 23 14:31:05 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_dcreg.h,v 1.1 2015/05/18 19:32:48 jmcneill Exp $ */
+/* $NetBSD: tegra_dcreg.h,v 1.2 2015/07/23 14:31:05 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -78,7 +78,10 @@
 #define DC_CMD_SIGNAL_RAISE1_REG                       0x0f0
 #define DC_CMD_SIGNAL_RAISE2_REG                       0x0f4
 #define DC_CMD_SIGNAL_RAISE3_REG                       0x0f8
+
 #define DC_CMD_STATE_ACCESS_REG                                0x100
+#define DC_CMD_STATE_ACCESS_WRITE_MUX                  __BIT(2)
+#define DC_CMD_STATE_ACCESS_READ_MUX                   __BIT(0)
 
 #define DC_CMD_STATE_CONTROL_REG                       0x104
 #define DC_CMD_STATE_CONTROL_NC_HOST_TRIG_ENABLE       __BIT(24)
@@ -136,6 +139,7 @@
  * Display DISP registers
  */
 #define DC_DISP_DISP_SIGNAL_OPTIONS0_REG               0x1000
+#define DC_DISP_DISP_SIGNAL_OPTIONS0_H_PULSE2_ENABLE   __BIT(12)
 
 #define DC_DISP_DISP_WIN_OPTIONS_REG                   0x1008
 #define DC_DISP_DISP_WIN_OPTIONS_HDMI_ENABLE           __BIT(30)
@@ -144,6 +148,7 @@
 #define DC_DISP_DISP_WIN_OPTIONS_CURSOR_ENABLE         __BIT(16)
 
 #define DC_DISP_DISP_TIMING_OPTIONS_REG                        0x1014
+#define DC_DISP_DISP_TIMING_OPTIONS_VSYNC_POS          __BITS(11,0)
 
 #define DC_DISP_REF_TO_SYNC_REG                                0x1018
 #define DC_DISP_REF_TO_SYNC_V                          __BITS(28,16)
@@ -175,8 +180,19 @@
 #define DC_DISP_H_PULSE1_POSITION_B_REG                        0x1048
 #define DC_DISP_H_PULSE1_POSITION_C_REG                        0x104c
 #define DC_DISP_H_PULSE1_POSITION_D_REG                        0x1050
+
 #define DC_DISP_H_PULSE2_CONTROL_REG                   0x1054
+#define DC_DISP_H_PULSE2_CONTROL_LAST                  __BITS(11,8)
+#define DC_DISP_H_PULSE2_CONTROL_LAST_END_A            1
+#define DC_DISP_H_PULSE2_CONTROL_V_QUAL                        __BITS(7,6)
+#define DC_DISP_H_PULSE2_CONTROL_V_QUAL_VACTIVE                2
+#define DC_DISP_H_PULSE2_CONTROL_POLARITY              __BIT(4)
+#define DC_DISP_H_PULSE2_CONTROL_MODE                  __BIT(3)
+
 #define DC_DISP_H_PULSE2_POSITION_A_REG                        0x1058
+#define DC_DISP_H_PULSE2_POSITION_A_END                        __BITS(28,16)
+#define DC_DISP_H_PULSE2_POSITION_A_START              __BITS(12,0)
+
 #define DC_DISP_H_PULSE2_POSITION_B_REG                        0x105c
 #define DC_DISP_H_PULSE2_POSITION_C_REG                        0x1060
 #define DC_DISP_H_PULSE2_POSITION_D_REG                        0x1064
@@ -192,9 +208,17 @@
 #define DC_DISP_V_PULSE2_POSITION_A_REG                        0x108c
 #define DC_DISP_V_PULSE3_CONTROL_REG                   0x1090
 #define DC_DISP_V_PULSE3_POSITION_A_REG                        0x1094
+
 #define DC_DISP_DISP_CLOCK_CONTROL_REG                 0x10b8
+#define DC_DISP_DISP_CLOCK_CONTROL_PIXEL_CLK_DIVIDER   __BITS(11,8)
+#define DC_DISP_DISP_CLOCK_CONTROL_SHIFT_CLK_DIVIDER   __BITS(7,0)
+
 #define DC_DISP_DISP_INTERFACE_CONTROL_REG             0x10bc
+
 #define DC_DISP_DISP_COLOR_CONTROL_REG                 0x10c0
+#define DC_DISP_DISP_COLOR_CONTROL_BASE_COLOR_SIZE     __BITS(3,0)
+#define DC_DISP_DISP_COLOR_CONTROL_BASE_COLOR_SIZE_888 8
+
 #define DC_DISP_COLOR_KEY0_LOWER_REG                   0x10d8
 #define DC_DISP_COLOR_KEY0_UPPER_REG                   0x10dc
 #define DC_DISP_COLOR_KEY1_LOWER_REG                   0x10e0
@@ -333,6 +357,7 @@
 #define DC_WINC_A_COLOR_DEPTH_REG                      0x1c0c
 #define DC_WINC_A_COLOR_DEPTH_DEPTH                    __BITS(6,0)
 #define DC_WINC_A_COLOR_DEPTH_DEPTH_T_A8R8G8B8         12
+#define DC_WINC_A_COLOR_DEPTH_DEPTH_T_X8R8G8B8         37
 
 #define DC_WINC_A_POSITION_REG                         0x1c10
 #define DC_WINC_A_POSITION_V                           __BITS(28,16)
diff -r cb62bbcf0f88 -r 90912feb6867 sys/arch/arm/nvidia/tegra_genfb.c
--- a/sys/arch/arm/nvidia/tegra_genfb.c Thu Jul 23 14:30:06 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_genfb.c Thu Jul 23 14:31:05 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_genfb.c,v 1.1 2015/05/18 19:32:48 jmcneill Exp $ */
+/* $NetBSD: tegra_genfb.c,v 1.2 2015/07/23 14:31:05 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_genfb.c,v 1.1 2015/05/18 19:32:48 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_genfb.c,v 1.2 2015/07/23 14:31:05 jmcneill Exp $");
 
 #include "opt_ddb.h"
 
@@ -95,8 +95,7 @@
        prop_dictionary_set_uint32(prop, "height", tfb->tfb_height);
        prop_dictionary_set_uint8(prop, "depth", tfb->tfb_depth);
        prop_dictionary_set_uint32(prop, "linebytes", tfb->tfb_stride);
-       prop_dictionary_set_uint64(prop, "address",
-           tfb->tfb_dmamap->dm_segs[0].ds_addr);
+       prop_dictionary_set_uint64(prop, "address", 0);
        prop_dictionary_set_uint64(prop, "virtual_address",
            (uintptr_t)tfb->tfb_dmap);
 
diff -r cb62bbcf0f88 -r 90912feb6867 sys/arch/arm/nvidia/tegra_hdmi.c
--- a/sys/arch/arm/nvidia/tegra_hdmi.c  Thu Jul 23 14:30:06 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_hdmi.c  Thu Jul 23 14:31:05 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_hdmi.c,v 1.3 2015/07/08 01:23:28 jmcneill Exp $ */
+/* $NetBSD: tegra_hdmi.c,v 1.4 2015/07/23 14:31:05 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_hdmi.c,v 1.3 2015/07/08 01:23:28 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_hdmi.c,v 1.4 2015/07/23 14:31:05 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -67,8 +67,8 @@
        { 74250,      0x01003110, 0x00301500, 0x2c2c2c2c,
          0x00000000, 0x07070707, 0x800034bb, 0x40400820 },
        /* 1080p */
-       { 148500,     0x01003310, 0300301500, 0x33333333,
-         0x00000000, 0x0c0c0c0c, 0x800034bb, 0x40400820 },
+       { 148500,     0x01003310, 0x00301500, 0x2d2d2d2d,
+         0x00000000, 0x05050505, 0x800034bb, 0x40400820 },
        /* 2160p */
        { 297000,     0x01003f10, 0x00300f00, 0x37373737,
          0x00000000, 0x17171717, 0x800036bb, 0x40400f20 },
@@ -135,6 +135,8 @@
                sc->sc_pin_pll = tegra_gpio_acquire(pin, GPIO_PIN_OUTPUT);
                if (sc->sc_pin_pll) {
                        tegra_gpio_write(sc->sc_pin_pll, 0);
+               } else {
+                       panic("couldn't get pll-gpio pin");
                }
        }
        if (prop_dictionary_get_cstring_nocopy(prop, "power-gpio", &pin)) {
@@ -245,7 +247,6 @@
        u_int n;
 
        KASSERT(sc->sc_curmode != NULL);
-
        tegra_pmc_hdmi_enable();
 
        tegra_car_hdmi_enable(mode->dot_clock * 1000);
@@ -278,8 +279,19 @@



Home | Main Index | Thread Index | Old Index