Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/allwinner HDMI framebuffer support, tested on C...
details: https://anonhg.NetBSD.org/src/rev/6529e650f025
branches: trunk
changeset: 333596:6529e650f025
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Mon Nov 10 17:55:25 2014 +0000
description:
HDMI framebuffer support, tested on Cubieboard2 and Hummingbird A31.
diffstat:
sys/arch/arm/allwinner/awin_board.c | 80 +++++++++++--
sys/arch/arm/allwinner/awin_debe.c | 94 +++++++++++------
sys/arch/arm/allwinner/awin_fb.c | 10 +-
sys/arch/arm/allwinner/awin_hdmi.c | 193 ++++++++++++++++++++---------------
sys/arch/arm/allwinner/awin_reg.h | 1 +
sys/arch/arm/allwinner/awin_tcon.c | 173 ++++++++++++++++++++++---------
sys/arch/arm/allwinner/awin_var.h | 8 +-
7 files changed, 370 insertions(+), 189 deletions(-)
diffs (truncated from 995 to 300 lines):
diff -r 8541f15e82f7 -r 6529e650f025 sys/arch/arm/allwinner/awin_board.c
--- a/sys/arch/arm/allwinner/awin_board.c Mon Nov 10 16:32:21 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_board.c Mon Nov 10 17:55:25 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_board.c,v 1.26 2014/11/09 14:10:54 jmcneill Exp $ */
+/* $NetBSD: awin_board.c,v 1.27 2014/11/10 17:55:25 jmcneill 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.26 2014/11/09 14:10:54 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_board.c,v 1.27 2014/11/10 17:55:25 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -411,9 +411,6 @@
ncfg &= ~AWIN_A31_PLL3_CFG_MODE;
ncfg &= ~AWIN_A31_PLL3_CFG_MODE_SEL;
ncfg |= AWIN_A31_PLL3_CFG_FRAC_CLK_OUT;
- /* 24MHz*N/M - for 29.7MHz, N=99, M=8 */
- ncfg |= __SHIFTIN(98, AWIN_A31_PLL3_CFG_FACTOR_N);
- ncfg |= __SHIFTIN(7, AWIN_A31_PLL3_CFG_PREDIV_M);
ncfg |= AWIN_PLL_CFG_ENABLE;
} else {
ncfg &= ~AWIN_PLL3_MODE_SEL;
@@ -424,6 +421,13 @@
if (ncfg != ocfg) {
bus_space_write_4(bst, bsh,
AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG, ncfg);
+
+ if (awin_chip_id() == AWIN_CHIP_ID_A31) {
+ do {
+ ncfg = bus_space_read_4(bst, bsh,
+ AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG);
+ } while ((ncfg & AWIN_A31_PLL3_CFG_LOCK) == 0);
+ }
}
}
@@ -445,11 +449,6 @@
ncfg &= ~AWIN_A31_PLL7_CFG_MODE;
ncfg &= ~AWIN_A31_PLL7_CFG_MODE_SEL;
ncfg |= AWIN_A31_PLL7_CFG_FRAC_CLK_OUT;
- /* 24MHz*N/M - for 29.7MHz, N=99, M=8 */
- ncfg &= ~AWIN_A31_PLL7_CFG_FACTOR_N;
- ncfg &= ~AWIN_A31_PLL7_CFG_PREDIV_M;
- ncfg |= __SHIFTIN(98, AWIN_A31_PLL7_CFG_FACTOR_N);
- ncfg |= __SHIFTIN(7, AWIN_A31_PLL7_CFG_PREDIV_M);
ncfg |= AWIN_PLL_CFG_ENABLE;
} else {
ncfg &= ~AWIN_PLL7_MODE_SEL;
@@ -477,18 +476,18 @@
ncfg &= ~AWIN_PLL_CFG_ENABLE;
} else {
if (awin_chip_id() == AWIN_CHIP_ID_A31) {
- unsigned int m = rate / 3000000;
- ncfg |= AWIN_PLL3_MODE_SEL;
- ncfg &= ~AWIN_PLL3_FACTOR_M;
- ncfg |= __SHIFTIN(m, AWIN_PLL3_FACTOR_M);
- } else {
unsigned int m = 8;
- unsigned int n = rate / 3000000;
+ unsigned int n = rate / (AWIN_REF_FREQ / m);
ncfg |= AWIN_A31_PLL3_CFG_MODE_SEL;
ncfg &= ~AWIN_A31_PLL3_CFG_FACTOR_N;
ncfg |= __SHIFTIN(n - 1, AWIN_A31_PLL3_CFG_FACTOR_N);
ncfg &= ~AWIN_A31_PLL3_CFG_PREDIV_M;
ncfg |= __SHIFTIN(m - 1, AWIN_A31_PLL3_CFG_PREDIV_M);
+ } else {
+ unsigned int m = rate / 3000000;
+ ncfg |= AWIN_PLL3_MODE_SEL;
+ ncfg &= ~AWIN_PLL3_FACTOR_M;
+ ncfg |= __SHIFTIN(m, AWIN_PLL3_FACTOR_M);
}
ncfg |= AWIN_PLL_CFG_ENABLE;
}
@@ -496,5 +495,54 @@
if (ncfg != ocfg) {
bus_space_write_4(bst, bsh,
AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG, ncfg);
+
+ if (awin_chip_id() == AWIN_CHIP_ID_A31) {
+ do {
+ ncfg = bus_space_read_4(bst, bsh,
+ AWIN_CCM_OFFSET + AWIN_PLL3_CFG_REG);
+ } while ((ncfg & AWIN_A31_PLL3_CFG_LOCK) == 0);
+ }
}
}
+
+uint32_t
+awin_pll5x_get_rate(void)
+{
+ bus_space_tag_t bst = &awin_bs_tag;
+ bus_space_handle_t bsh = awin_core_bsh;
+ unsigned int n, k, p;
+
+ KASSERT(awin_chip_id() != AWIN_CHIP_ID_A31);
+
+ const uint32_t cfg = bus_space_read_4(bst, bsh,
+ AWIN_CCM_OFFSET + AWIN_PLL5_CFG_REG);
+
+ n = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_N);
+ k = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_K);
+ p = __SHIFTOUT(cfg, AWIN_PLL5_OUT_EXT_DIV_P);
+
+ return (AWIN_REF_FREQ * n * k) >> p;
+}
+
+uint32_t
+awin_pll6_get_rate(void)
+{
+ bus_space_tag_t bst = &awin_bs_tag;
+ bus_space_handle_t bsh = awin_core_bsh;
+ unsigned int n, k, m;
+
+ const uint32_t cfg = bus_space_read_4(bst, bsh,
+ AWIN_CCM_OFFSET + AWIN_PLL6_CFG_REG);
+
+ if (awin_chip_id() == AWIN_CHIP_ID_A31) {
+ n = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_N) + 1;
+ k = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_K) + 1;
+ m = 2;
+ } else {
+ n = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_N);
+ k = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_K) + 1;
+ m = __SHIFTOUT(cfg, AWIN_PLL_CFG_FACTOR_M) + 1;
+ }
+
+ return (AWIN_REF_FREQ * n * k) / m;
+}
diff -r 8541f15e82f7 -r 6529e650f025 sys/arch/arm/allwinner/awin_debe.c
--- a/sys/arch/arm/allwinner/awin_debe.c Mon Nov 10 16:32:21 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_debe.c Mon Nov 10 17:55:25 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_debe.c,v 1.2 2014/11/09 14:30:55 jmcneill Exp $ */
+/* $NetBSD: awin_debe.c,v 1.3 2014/11/10 17:55:25 jmcneill Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -33,7 +33,7 @@
#include "genfb.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_debe.c,v 1.2 2014/11/09 14:30:55 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_debe.c,v 1.3 2014/11/10 17:55:25 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -109,33 +109,48 @@
&sc->sc_ccm_bsh);
aprint_naive("\n");
- aprint_normal(": Display Engine Backend\n");
+ aprint_normal(": Display Engine Backend (BE%d)\n", loc->loc_port);
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_BE0_RST << loc->loc_port,
0);
+ } else {
+ awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
+ AWIN_BE0_SCLK_CFG_REG + (loc->loc_port * 4),
+ AWIN_BEx_CLK_RST,
+ 0);
}
if (awin_chip_id() == AWIN_CHIP_ID_A31) {
+ uint32_t pll6_freq = awin_pll6_get_rate() * 2;
+ unsigned int clk_div = (pll6_freq + 299999999) / 300000000;
+
+#ifdef AWIN_DEBE_DEBUG
+ device_printf(sc->sc_dev, "PLL6 @ %u Hz\n", pll6_freq);
+ device_printf(sc->sc_dev, "div %d\n", clk_div);
+#endif
awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
AWIN_BE0_SCLK_CFG_REG + (loc->loc_port * 4),
__SHIFTIN(AWIN_A31_BEx_CLK_SRC_SEL_PLL6_2X,
- AWIN_A31_BEx_CLK_SRC_SEL),
- AWIN_A31_BEx_CLK_SRC_SEL);
+ AWIN_A31_BEx_CLK_SRC_SEL) |
+ __SHIFTIN(clk_div - 1, AWIN_BEx_CLK_DIV_RATIO_M),
+ AWIN_A31_BEx_CLK_SRC_SEL | AWIN_BEx_CLK_DIV_RATIO_M);
+ } else {
+ uint32_t pll5x_freq = awin_pll5x_get_rate();
+ unsigned int clk_div = (pll5x_freq + 299999999) / 300000000;
+
+#ifdef AWIN_DEBE_DEBUG
+ device_printf(sc->sc_dev, "PLL5x @ %u Hz\n", pll5x_freq);
+ device_printf(sc->sc_dev, "div %d\n", clk_div);
+#endif
+
awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
AWIN_BE0_SCLK_CFG_REG + (loc->loc_port * 4),
- 4 - 1, AWIN_BEx_CLK_DIV_RATIO_M);
- } else {
- awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
- AWIN_BE0_SCLK_CFG_REG + (loc->loc_port * 4),
- AWIN_BEx_CLK_RST |
- __SHIFTIN(AWIN_BEx_CLK_SRC_SEL_PLL5, AWIN_BEx_CLK_SRC_SEL),
- AWIN_BEx_CLK_SRC_SEL);
- awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
- AWIN_BE0_SCLK_CFG_REG + (loc->loc_port * 4),
- 0 /* XXX */, AWIN_BEx_CLK_DIV_RATIO_M);
+ __SHIFTIN(AWIN_BEx_CLK_SRC_SEL_PLL5, AWIN_BEx_CLK_SRC_SEL) |
+ __SHIFTIN(clk_div - 1, AWIN_BEx_CLK_DIV_RATIO_M),
+ AWIN_BEx_CLK_SRC_SEL | AWIN_BEx_CLK_DIV_RATIO_M);
}
awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
@@ -209,7 +224,6 @@
.afb_fb = sc->sc_dmap,
.afb_width = mode->hdisplay,
.afb_height = mode->vdisplay,
- .afb_console = false, /* XXX */
.afb_dmat = sc->sc_dmat,
.afb_dmasegs = sc->sc_dmasegs,
.afb_ndmasegs = 1
@@ -225,6 +239,35 @@
}
void
+awin_debe_enable(bool enable)
+{
+ struct awin_debe_softc *sc;
+ device_t dev;
+ uint32_t val;
+
+ dev = device_find_by_driver_unit("awindebe", 0);
+ if (dev == NULL) {
+ printf("DEBE: no driver found\n");
+ return;
+ }
+ sc = device_private(dev);
+
+ if (enable) {
+ val = DEBE_READ(sc, AWIN_DEBE_REGBUFFCTL_REG);
+ val |= AWIN_DEBE_REGBUFFCTL_REGLOADCTL;
+ DEBE_WRITE(sc, AWIN_DEBE_REGBUFFCTL_REG, val);
+
+ val = DEBE_READ(sc, AWIN_DEBE_MODCTL_REG);
+ val |= AWIN_DEBE_MODCTL_START_CTL;
+ DEBE_WRITE(sc, AWIN_DEBE_MODCTL_REG, val);
+ } else {
+ val = DEBE_READ(sc, AWIN_DEBE_MODCTL_REG);
+ val &= ~AWIN_DEBE_MODCTL_START_CTL;
+ DEBE_WRITE(sc, AWIN_DEBE_MODCTL_REG, val);
+ }
+}
+
+void
awin_debe_set_videomode(const struct videomode *mode)
{
struct awin_debe_softc *sc;
@@ -249,11 +292,6 @@
return;
}
- /* disable */
- val = DEBE_READ(sc, AWIN_DEBE_MODCTL_REG);
- val &= ~AWIN_DEBE_MODCTL_LAY0_EN;
- DEBE_WRITE(sc, AWIN_DEBE_MODCTL_REG, val);
-
/* notify fb */
awin_debe_setup_fbdev(sc, mode);
@@ -269,7 +307,8 @@
val = DEBE_READ(sc, AWIN_DEBE_ATTCTL1_REG);
val &= ~AWIN_DEBE_ATTCTL1_LAY_FBFMT;
- val |= AWIN_DEBE_ATTCTL1_LAY_FBFMT_XRGB8888;
+ val |= __SHIFTIN(AWIN_DEBE_ATTCTL1_LAY_FBFMT_XRGB8888,
+ AWIN_DEBE_ATTCTL1_LAY_FBFMT);
val &= ~AWIN_DEBE_ATTCTL1_LAY_BRSWAPEN;
val &= ~AWIN_DEBE_ATTCTL1_LAY_FBPS;
DEBE_WRITE(sc, AWIN_DEBE_ATTCTL1_REG, val);
@@ -277,17 +316,6 @@
val = DEBE_READ(sc, AWIN_DEBE_MODCTL_REG);
val |= AWIN_DEBE_MODCTL_LAY0_EN;
DEBE_WRITE(sc, AWIN_DEBE_MODCTL_REG, val);
-
- val = DEBE_READ(sc, AWIN_DEBE_REGBUFFCTL_REG);
- val |= AWIN_DEBE_REGBUFFCTL_REGLOADCTL;
- DEBE_WRITE(sc, AWIN_DEBE_REGBUFFCTL_REG, val);
-
- delay(50000);
-
- /* enable */
- val = DEBE_READ(sc, AWIN_DEBE_MODCTL_REG);
- val |= AWIN_DEBE_MODCTL_START_CTL;
- DEBE_WRITE(sc, AWIN_DEBE_MODCTL_REG, val);
} else {
/* disable */
val = DEBE_READ(sc, AWIN_DEBE_MODCTL_REG);
diff -r 8541f15e82f7 -r 6529e650f025 sys/arch/arm/allwinner/awin_fb.c
--- a/sys/arch/arm/allwinner/awin_fb.c Mon Nov 10 16:32:21 2014 +0000
Home |
Main Index |
Thread Index |
Old Index