Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Snapshot of work in progress on support for multipl...



details:   https://anonhg.NetBSD.org/src/rev/22067e046415
branches:  trunk
changeset: 811341:22067e046415
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sun Oct 25 20:54:19 2015 +0000

description:
Snapshot of work in progress on support for multiple display outputs.
The display configuration comes from the fex script as defined
in http://linux-sunxi.org/Fex_Guide, section disp_init.
There is some code to convert lcd0_para/lcd1_para to properties but
it's not used yet.

At this time only mode 0 (debe0->tcon0->hdmi) works.
debe0->tcon1->hdmi and debe1->tcon0->hdmi both gives a valid HDMI
signal but completely blank screen. AWIN_TCON1_BLUEDATA gives a blue screen
in both cases so tcon1->hdmi works. I suspect that, for some reason
setups other than debe0->tcon0 are not configured properly, and
the tcon is reading all-1 bits instead of the expected debe output.

diffstat:

 sys/arch/arm/allwinner/awin_board.c |   41 ++++++-
 sys/arch/arm/allwinner/awin_debe.c  |   16 +-
 sys/arch/arm/allwinner/awin_hdmi.c  |   92 ++++++++-----
 sys/arch/arm/allwinner/awin_reg.h   |    6 +-
 sys/arch/arm/allwinner/awin_tcon.c  |  216 +++++++++++++++++++++++++++-------
 sys/arch/arm/allwinner/awin_var.h   |   16 +-
 sys/arch/evbarm/awin/awin_machdep.c |  226 +++++++++++++++++++++++++++++++++++-
 7 files changed, 511 insertions(+), 102 deletions(-)

diffs (truncated from 981 to 300 lines):

diff -r 8d7d18b23ed3 -r 22067e046415 sys/arch/arm/allwinner/awin_board.c
--- a/sys/arch/arm/allwinner/awin_board.c       Sun Oct 25 20:46:46 2015 +0000
+++ b/sys/arch/arm/allwinner/awin_board.c       Sun Oct 25 20:54:19 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: awin_board.c,v 1.39 2015/10/17 15:30:14 bouyer Exp $   */
+/*     $NetBSD: awin_board.c,v 1.40 2015/10/25 20:54:19 bouyer Exp $   */
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -36,7 +36,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: awin_board.c,v 1.39 2015/10/17 15:30:14 bouyer Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_board.c,v 1.40 2015/10/25 20:54:19 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -920,6 +920,43 @@
        }
 }
 
+void
+awin_pll7_set_rate(uint32_t rate)
+{
+       const uint32_t ocfg = CCM_READ4(AWIN_PLL7_CFG_REG);
+
+       uint32_t ncfg = ocfg;
+       if (rate == 0) {
+               ncfg &= ~AWIN_PLL_CFG_ENABLE;
+       } else {
+               if (awin_chip_id() == AWIN_CHIP_ID_A31) {
+                       unsigned int m = 8;
+                       unsigned int n = rate / (AWIN_REF_FREQ / m);
+                       ncfg |= AWIN_A31_PLL7_CFG_MODE_SEL;
+                       ncfg &= ~AWIN_A31_PLL7_CFG_FACTOR_N;
+                       ncfg |= __SHIFTIN(n - 1, AWIN_A31_PLL7_CFG_FACTOR_N);
+                       ncfg &= ~AWIN_A31_PLL7_CFG_PREDIV_M;
+                       ncfg |= __SHIFTIN(m - 1, AWIN_A31_PLL7_CFG_PREDIV_M);
+               } else {
+                       unsigned int m = rate / 3000000;
+                       ncfg |= AWIN_PLL7_MODE_SEL;
+                       ncfg &= ~AWIN_PLL7_FACTOR_M;
+                       ncfg |= __SHIFTIN(m, AWIN_PLL7_FACTOR_M);
+               }
+               ncfg |= AWIN_PLL_CFG_ENABLE;
+       }
+
+       if (ncfg != ocfg) {
+               CCM_WRITE4(AWIN_PLL7_CFG_REG, ncfg);
+
+               if (awin_chip_id() == AWIN_CHIP_ID_A31) {
+                       do {
+                               ncfg = CCM_READ4(AWIN_PLL7_CFG_REG);
+                       } while ((ncfg & AWIN_A31_PLL7_CFG_LOCK) == 0);
+               }
+       }
+}
+
 uint32_t
 awin_pll5x_get_rate(void)
 {
diff -r 8d7d18b23ed3 -r 22067e046415 sys/arch/arm/allwinner/awin_debe.c
--- a/sys/arch/arm/allwinner/awin_debe.c        Sun Oct 25 20:46:46 2015 +0000
+++ b/sys/arch/arm/allwinner/awin_debe.c        Sun Oct 25 20:54:19 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_debe.c,v 1.16 2015/10/09 07:23:33 bouyer Exp $ */
+/* $NetBSD: awin_debe.c,v 1.17 2015/10/25 20:54:19 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -37,7 +37,7 @@
 #define AWIN_DEBE_CURMAX       64
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_debe.c,v 1.16 2015/10/09 07:23:33 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_debe.c,v 1.17 2015/10/25 20:54:19 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -249,8 +249,8 @@
 #endif
 
 #ifdef AWIN_DEBE_FWINIT
-       awin_debe_set_videomode(&mode);
-       awin_debe_enable(true);
+       awin_debe_set_videomode(device_unit(self), &mode);
+       awin_debe_enable(device_unit(self), true);
 #endif
 }
 
@@ -443,13 +443,13 @@
 }
 
 void
-awin_debe_enable(bool enable)
+awin_debe_enable(int unit, bool enable)
 {
        struct awin_debe_softc *sc;
        device_t dev;
        uint32_t val;
 
-       dev = device_find_by_driver_unit("awindebe", 0);
+       dev = device_find_by_driver_unit("awindebe", unit);
        if (dev == NULL) {
                printf("DEBE: no driver found\n");
                return;
@@ -472,13 +472,13 @@
 }
 
 void
-awin_debe_set_videomode(const struct videomode *mode)
+awin_debe_set_videomode(int unit, const struct videomode *mode)
 {
        struct awin_debe_softc *sc;
        device_t dev;
        uint32_t val;
 
-       dev = device_find_by_driver_unit("awindebe", 0);
+       dev = device_find_by_driver_unit("awindebe", unit);
        if (dev == NULL) {
                printf("DEBE: no driver found\n");
                return;
diff -r 8d7d18b23ed3 -r 22067e046415 sys/arch/arm/allwinner/awin_hdmi.c
--- a/sys/arch/arm/allwinner/awin_hdmi.c        Sun Oct 25 20:46:46 2015 +0000
+++ b/sys/arch/arm/allwinner/awin_hdmi.c        Sun Oct 25 20:54:19 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_hdmi.c,v 1.16 2015/07/25 15:19:54 jmcneill Exp $ */
+/* $NetBSD: awin_hdmi.c,v 1.17 2015/10/25 20:54:19 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,10 +29,8 @@
 #include "opt_allwinner.h"
 #include "opt_ddb.h"
 
-#define AWIN_HDMI_PLL  3       /* PLL7 or PLL3 */
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_hdmi.c,v 1.16 2015/07/25 15:19:54 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_hdmi.c,v 1.17 2015/10/25 20:54:19 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -72,6 +70,9 @@
 #define DISPLAY_MODE_AUTO      0
 #define DISPLAY_MODE_HDMI      1
 #define DISPLAY_MODE_DVI       2
+       
+       int   sc_tcon_unit;
+       unsigned int sc_tcon_pll;
 
        uint32_t sc_ver;
        unsigned int sc_i2c_blklen;
@@ -141,30 +142,39 @@
        const struct awin_locators * const loc = &aio->aio_loc;
        prop_dictionary_t cfg = device_properties(self);
        uint32_t ver, clk;
+       int8_t  tcon_unit = -1;
 
        sc->sc_dev = self;
        sc->sc_bst = aio->aio_core_bst;
        bus_space_subregion(sc->sc_bst, aio->aio_core_bsh,
            loc->loc_offset, loc->loc_size, &sc->sc_bsh);
 
-#if AWIN_HDMI_PLL == 3
-       awin_pll3_enable();
-#elif AWIN_HDMI_PLL == 7
-       awin_pll7_enable();
-#else
-#error AWIN_HDMI_PLL must be 3 or 7
-#endif
+       if (prop_dictionary_get_int8(cfg, "tcon_unit", &tcon_unit)) {
+               sc->sc_tcon_unit = tcon_unit;
+       } else {
+               sc->sc_tcon_unit = 0; /* default value */
+       }
+       sc->sc_tcon_pll = awin_tcon_get_clk_pll(sc->sc_tcon_unit);
+       switch (sc->sc_tcon_pll) {
+       case 3:
+               awin_pll3_enable();
+               clk =
+                  __SHIFTIN(AWIN_HDMI_CLK_SRC_SEL_PLL3, AWIN_HDMI_CLK_SRC_SEL);
+               break;
+       case 7:
+               awin_pll7_enable();
+               clk =
+                  __SHIFTIN(AWIN_HDMI_CLK_SRC_SEL_PLL7, AWIN_HDMI_CLK_SRC_SEL);
+               break;
+       default:
+               panic("awin_hdmi pll");
+       }
 
        if (awin_chip_id() == AWIN_CHIP_ID_A31) {
                awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
                    AWIN_A31_AHB_RESET1_REG, AWIN_A31_AHB_RESET1_HDMI_RST, 0);
        }
 
-#if AWIN_HDMI_PLL == 3
-       clk = __SHIFTIN(AWIN_HDMI_CLK_SRC_SEL_PLL3, AWIN_HDMI_CLK_SRC_SEL);
-#else
-       clk = __SHIFTIN(AWIN_HDMI_CLK_SRC_SEL_PLL7, AWIN_HDMI_CLK_SRC_SEL);
-#endif
        clk |= AWIN_CLK_ENABLE;
        if (awin_chip_id() == AWIN_CHIP_ID_A31) {
                clk |= AWIN_A31_HDMI_CLK_DDC_GATING;
@@ -181,6 +191,10 @@
 
        aprint_naive("\n");
        aprint_normal(": HDMI %d.%d\n", vmaj, vmin);
+       if (tcon_unit >= 0) {
+               aprint_verbose_dev(self, ": using TCON%d, pll%d\n",
+                   sc->sc_tcon_unit, sc->sc_tcon_pll);
+       }
 
        sc->sc_ver = ver;
        sc->sc_i2c_blklen = 16;
@@ -479,12 +493,16 @@
                HDMI_WRITE(sc, AWIN_HDMI_PAD_CTRL0_REG, 0x7e80000f);
                HDMI_WRITE(sc, AWIN_HDMI_PAD_CTRL1_REG, 0x01ded030);
        }
-#if AWIN_HDMI_PLL == 7
-       HDMI_WRITE(sc, AWIN_HDMI_PLL_DBG0_REG, (1<<21));
-#elif AWIN_HDMI_PLL == 3
-       HDMI_WRITE(sc, AWIN_HDMI_PLL_DBG0_REG, (0<<21));
-#endif
-
+       switch(sc->sc_tcon_pll) {
+       case 3:
+               HDMI_WRITE(sc, AWIN_HDMI_PLL_DBG0_REG, (0<<21));
+               break;
+       case 7:
+               HDMI_WRITE(sc, AWIN_HDMI_PLL_DBG0_REG, (1<<21));
+               break;
+       default:
+               panic("awin_hdmi pll");
+       }
        delay(1000);
 }
 
@@ -562,16 +580,13 @@
 
        if (mode != NULL) {
                awin_hdmi_video_enable(sc, false);
-               awin_tcon_enable(false);
+               awin_tcon_enable(sc->sc_tcon_unit, false);
                delay(20000);
 
-               awin_debe_set_videomode(mode);
-               awin_tcon_set_videomode(mode);
+               awin_tcon_set_videomode(sc->sc_tcon_unit, mode);
                awin_hdmi_set_videomode(sc, mode, display_mode);
                awin_hdmi_set_audiomode(sc, mode, display_mode);
-               awin_debe_enable(true);
-               delay(20000);
-               awin_tcon_enable(true);
+               awin_tcon_enable(sc->sc_tcon_unit, true);
                delay(20000);
                awin_hdmi_video_enable(sc, true);
        }
@@ -715,8 +730,8 @@
 
        HDMI_WRITE(sc, AWIN_HDMI_INT_STATUS_REG, 0xffffffff);
 
-       u_int clk_div = awin_tcon_get_clk_div();
-       bool clk_dbl = awin_tcon_get_clk_dbl();
+       u_int clk_div = awin_tcon_get_clk_div(sc->sc_tcon_unit);
+       bool clk_dbl = awin_tcon_get_clk_dbl(sc->sc_tcon_unit);
 
 #ifdef AWIN_HDMI_DEBUG
        device_printf(sc->sc_dev, "dot_clock: %d\n", mode->dot_clock);
@@ -747,11 +762,16 @@
        HDMI_WRITE(sc, AWIN_HDMI_PAD_CTRL0_REG, pad_ctrl0);
        HDMI_WRITE(sc, AWIN_HDMI_PAD_CTRL1_REG, pad_ctrl1);
        HDMI_WRITE(sc, AWIN_HDMI_PLL_CTRL_REG, pll_ctrl);
-#if AWIN_HDMI_PLL == 7
-       HDMI_WRITE(sc, AWIN_HDMI_PLL_DBG0_REG, (1<<21));
-#elif AWIN_HDMI_PLL == 3
-       HDMI_WRITE(sc, AWIN_HDMI_PLL_DBG0_REG, (0<<21));
-#endif
+       switch(sc->sc_tcon_pll) {
+       case 3:
+               HDMI_WRITE(sc, AWIN_HDMI_PLL_DBG0_REG, (0<<21));
+               break;
+       case 7:
+               HDMI_WRITE(sc, AWIN_HDMI_PLL_DBG0_REG, (1<<21));
+               break;
+       default:
+               panic("awin_hdmi pll");
+       }
 
        val = HDMI_READ(sc, AWIN_HDMI_VID_CTRL_REG);
        val &= ~AWIN_HDMI_VID_CTRL_HDMI_MODE;
@@ -908,7 +928,7 @@
                awin_hdmi_read_edid(sc);
        } else {
                device_printf(sc->sc_dev, "display disconnected\n");
-               awin_tcon_set_videomode(NULL);
+               awin_tcon_set_videomode(sc->sc_tcon_unit, NULL);
        }



Home | Main Index | Thread Index | Old Index