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 Add support for interlaced video modes.
details: https://anonhg.NetBSD.org/src/rev/22e7dce665f1
branches: trunk
changeset: 333688:22e7dce665f1
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Fri Nov 14 00:31:54 2014 +0000
description:
Add support for interlaced video modes.
diffstat:
sys/arch/arm/allwinner/awin_debe.c | 26 ++++++++++++++++--------
sys/arch/arm/allwinner/awin_fb.c | 11 ++++++---
sys/arch/arm/allwinner/awin_hdmi.c | 18 ++++------------
sys/arch/arm/allwinner/awin_reg.h | 5 ++++
sys/arch/arm/allwinner/awin_tcon.c | 40 ++++++++++++++++++++++++++++++++++---
5 files changed, 70 insertions(+), 30 deletions(-)
diffs (270 lines):
diff -r b21998f99ff7 -r 22e7dce665f1 sys/arch/arm/allwinner/awin_debe.c
--- a/sys/arch/arm/allwinner/awin_debe.c Thu Nov 13 22:32:53 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_debe.c Fri Nov 14 00:31:54 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_debe.c,v 1.5 2014/11/12 23:12:27 jmcneill Exp $ */
+/* $NetBSD: awin_debe.c,v 1.6 2014/11/14 00:31:54 jmcneill Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -34,7 +34,7 @@
#endif
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_debe.c,v 1.5 2014/11/12 23:12:27 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_debe.c,v 1.6 2014/11/14 00:31:54 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -221,10 +221,11 @@
awin_debe_setup_fbdev(struct awin_debe_softc *sc, const struct videomode *mode)
{
if (mode && sc->sc_fbdev == NULL) {
+ const u_int interlace_p = !!(mode->flags & VID_INTERLACE);
struct awinfb_attach_args afb = {
.afb_fb = sc->sc_dmap,
.afb_width = mode->hdisplay,
- .afb_height = mode->vdisplay,
+ .afb_height = (mode->vdisplay << interlace_p),
.afb_dmat = sc->sc_dmat,
.afb_dmasegs = sc->sc_dmasegs,
.afb_ndmasegs = 1
@@ -283,13 +284,15 @@
sc = device_private(dev);
if (mode) {
- uint32_t vmem = mode->vdisplay * mode->hdisplay * 4;
+ const u_int interlace_p = !!(mode->flags & VID_INTERLACE);
+ const u_int width = mode->hdisplay;
+ const u_int height = (mode->vdisplay << interlace_p);
+ uint32_t vmem = width * height * 4;
if (vmem > sc->sc_dmasize) {
device_printf(sc->sc_dev,
"not enough memory for %ux%u fb (req %u have %u)\n",
- mode->hdisplay, mode->vdisplay,
- vmem, (unsigned int)sc->sc_dmasize);
+ width, height, vmem, (unsigned int)sc->sc_dmasize);
return;
}
@@ -305,10 +308,10 @@
awin_debe_setup_fbdev(sc, mode);
DEBE_WRITE(sc, AWIN_DEBE_DISSIZE_REG,
- ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
+ ((height - 1) << 16) | (width - 1));
DEBE_WRITE(sc, AWIN_DEBE_LAYSIZE_REG,
- ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
- DEBE_WRITE(sc, AWIN_DEBE_LAYLINEWIDTH_REG, mode->hdisplay << 5);
+ ((height - 1) << 16) | (width - 1));
+ DEBE_WRITE(sc, AWIN_DEBE_LAYLINEWIDTH_REG, (width << 5));
DEBE_WRITE(sc, AWIN_DEBE_LAYFB_L32ADD_REG, pa << 3);
DEBE_WRITE(sc, AWIN_DEBE_LAYFB_H4ADD_REG, pa >> 29);
@@ -322,6 +325,11 @@
val = DEBE_READ(sc, AWIN_DEBE_MODCTL_REG);
val |= AWIN_DEBE_MODCTL_LAY0_EN;
+ if (interlace_p) {
+ val |= AWIN_DEBE_MODCTL_ITLMOD_EN;
+ } else {
+ val &= ~AWIN_DEBE_MODCTL_ITLMOD_EN;
+ }
DEBE_WRITE(sc, AWIN_DEBE_MODCTL_REG, val);
} else {
/* disable */
diff -r b21998f99ff7 -r 22e7dce665f1 sys/arch/arm/allwinner/awin_fb.c
--- a/sys/arch/arm/allwinner/awin_fb.c Thu Nov 13 22:32:53 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_fb.c Fri Nov 14 00:31:54 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_fb.c,v 1.3 2014/11/10 17:55:25 jmcneill Exp $ */
+/* $NetBSD: awin_fb.c,v 1.4 2014/11/14 00:31:54 jmcneill Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_fb.c,v 1.3 2014/11/10 17:55:25 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_fb.c,v 1.4 2014/11/14 00:31:54 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -189,8 +189,11 @@
if (mode == NULL)
return;
- if (sc->sc_gen.sc_width != mode->hdisplay ||
- sc->sc_gen.sc_height != mode->vdisplay) {
+ const u_int interlace_p = !!(mode->flags & VID_INTERLACE);
+ const u_int width = mode->hdisplay;
+ const u_int height = (mode->vdisplay << interlace_p);
+
+ if (sc->sc_gen.sc_width != width || sc->sc_gen.sc_height != height) {
device_printf(sc->sc_gen.sc_dev,
"mode switching not yet supported\n");
}
diff -r b21998f99ff7 -r 22e7dce665f1 sys/arch/arm/allwinner/awin_hdmi.c
--- a/sys/arch/arm/allwinner/awin_hdmi.c Thu Nov 13 22:32:53 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_hdmi.c Fri Nov 14 00:31:54 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_hdmi.c,v 1.10 2014/11/12 17:38:14 jmcneill Exp $ */
+/* $NetBSD: awin_hdmi.c,v 1.11 2014/11/14 00:31:54 jmcneill Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -32,7 +32,7 @@
#define AWIN_HDMI_PLL 3 /* PLL7 or PLL3 */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_hdmi.c,v 1.10 2014/11/12 17:38:14 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_hdmi.c,v 1.11 2014/11/14 00:31:54 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -601,29 +601,21 @@
val = HDMI_READ(sc, AWIN_HDMI_VID_CTRL_REG);
val |= __SHIFTIN(AWIN_HDMI_VID_CTRL_HDMI_MODE_HDMI,
AWIN_HDMI_VID_CTRL_HDMI_MODE);
+ val &= ~AWIN_HDMI_VID_CTRL_OUTPUT_FMT;
if (dblscan_p) {
val |= __SHIFTIN(AWIN_HDMI_VID_CTRL_REPEATER_SEL_2X,
AWIN_HDMI_VID_CTRL_REPEATER_SEL);
- } else {
- val &= ~AWIN_HDMI_VID_CTRL_REPEATER_SEL;
}
if (interlace_p) {
val |= __SHIFTIN(AWIN_HDMI_VID_CTRL_OUTPUT_FMT_INTERLACE,
AWIN_HDMI_VID_CTRL_OUTPUT_FMT);
- } else {
- val &= ~AWIN_HDMI_VID_CTRL_OUTPUT_FMT;
}
HDMI_WRITE(sc, AWIN_HDMI_VID_CTRL_REG, val);
val = __SHIFTIN((mode->hdisplay << dblscan_p) - 1,
AWIN_HDMI_VID_TIMING_0_ACT_H);
- if (interlace_p) {
- val |= __SHIFTIN((mode->vdisplay / 2) - 1,
- AWIN_HDMI_VID_TIMING_0_ACT_V);
- } else {
- val |= __SHIFTIN(mode->vdisplay - 1,
- AWIN_HDMI_VID_TIMING_0_ACT_V);
- }
+ val |= __SHIFTIN(mode->vdisplay - 1,
+ AWIN_HDMI_VID_TIMING_0_ACT_V);
HDMI_WRITE(sc, AWIN_HDMI_VID_TIMING_0_REG, val);
val = __SHIFTIN((hbp << dblscan_p) - 1,
diff -r b21998f99ff7 -r 22e7dce665f1 sys/arch/arm/allwinner/awin_reg.h
--- a/sys/arch/arm/allwinner/awin_reg.h Thu Nov 13 22:32:53 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_reg.h Fri Nov 14 00:31:54 2014 +0000
@@ -1747,12 +1747,17 @@
#define AWIN_TCON_GINT1_TCON1_LINENO __BITS(11,0)
#define AWIN_TCON_CTL_EN __BIT(31)
+#define AWIN_TCON_CTL_INTERLACE_EN __BIT(20)
#define AWIN_TCON_CTL_START_DELAY __BITS(8,4)
#define AWIN_TCON_CTL_SRC_SEL __BITS(1,0)
#define AWIN_TCON_CTL_SRC_SEL_DE0 0
#define AWIN_TCON_CTL_SRC_SEL_DE1 1
#define AWIN_TCON_CTL_SRC_SEL_BLUEDATA 2
+#define AWIN_TCON_IO_POL_IO2_INV __BIT(26)
+#define AWIN_TCON_IO_POL_PVSYNC __BIT(25)
+#define AWIN_TCON_IO_POL_PHSYNC __BIT(24)
+
#define AWIN_TCON_IO_TRI_IO3 __BIT(27)
#define AWIN_TCON_IO_TRI_IO2 __BIT(26)
#define AWIN_TCON_IO_TRI_IO1 __BIT(25)
diff -r b21998f99ff7 -r 22e7dce665f1 sys/arch/arm/allwinner/awin_tcon.c
--- a/sys/arch/arm/allwinner/awin_tcon.c Thu Nov 13 22:32:53 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_tcon.c Fri Nov 14 00:31:54 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_tcon.c,v 1.4 2014/11/11 19:22:32 jmcneill Exp $ */
+/* $NetBSD: awin_tcon.c,v 1.5 2014/11/14 00:31:54 jmcneill Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include "opt_allwinner.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_tcon.c,v 1.4 2014/11/11 19:22:32 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_tcon.c,v 1.5 2014/11/14 00:31:54 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -45,6 +45,8 @@
#include <dev/videomode/videomode.h>
+#define DIVIDE(x,y) (((x) + ((y) / 2)) / (y))
+
struct awin_tcon_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
@@ -234,10 +236,17 @@
sc = device_private(dev);
if (mode) {
+ const u_int interlace_p = !!(mode->flags & VID_INTERLACE);
+ const u_int phsync_p = !!(mode->flags & VID_PHSYNC);
+ const u_int pvsync_p = !!(mode->flags & VID_PVSYNC);
const u_int hspw = mode->hsync_end - mode->hsync_start;
const u_int hbp = mode->htotal - mode->hsync_start;
const u_int vspw = mode->vsync_end - mode->vsync_start;
const u_int vbp = mode->vtotal - mode->vsync_start;
+ const u_int vblank_len =
+ ((mode->vtotal << interlace_p) >> 1) - mode->vdisplay - 2;
+ const u_int start_delay =
+ vblank_len >= 32 ? 30 : vblank_len - 2;
val = TCON_READ(sc, AWIN_TCON_GCTL_REG);
val |= AWIN_TCON_GCTL_IO_MAP_SEL;
@@ -245,7 +254,9 @@
/* enable */
val = AWIN_TCON_CTL_EN;
- val |= __SHIFTIN(0x1e, AWIN_TCON_CTL_START_DELAY);
+ if (interlace_p)
+ val |= AWIN_TCON_CTL_INTERLACE_EN;
+ val |= __SHIFTIN(start_delay, AWIN_TCON_CTL_START_DELAY);
#ifdef AWIN_TCON_BLUEDATA
val |= __SHIFTIN(AWIN_TCON_CTL_SRC_SEL_BLUEDATA,
AWIN_TCON_CTL_SRC_SEL);
@@ -268,11 +279,32 @@
TCON_WRITE(sc, AWIN_TCON1_BASIC3_REG,
((mode->htotal - 1) << 16) | (hbp - 1));
/* Vertical total + back porch */
+ u_int vtotal = mode->vtotal * 2;
+ if (interlace_p) {
+ u_int framerate =
+ DIVIDE(DIVIDE(mode->dot_clock * 1000, mode->htotal),
+ mode->vtotal);
+ u_int clk = mode->htotal * (mode->vtotal * 2 + 1) *
+ framerate;
+ if ((clk / 2) == mode->dot_clock * 1000)
+ vtotal += 1;
+ }
TCON_WRITE(sc, AWIN_TCON1_BASIC4_REG,
- ((mode->vtotal * 2) << 16) | (vbp - 1));
+ (vtotal << 16) | (vbp - 1));
+
/* Sync */
TCON_WRITE(sc, AWIN_TCON1_BASIC5_REG,
((hspw - 1) << 16) | (vspw - 1));
+ /* Polarity */
+ val = AWIN_TCON_IO_POL_IO2_INV;
+ if (phsync_p)
+ val |= AWIN_TCON_IO_POL_PHSYNC;
+ if (pvsync_p)
+ val |= AWIN_TCON_IO_POL_PVSYNC;
+ TCON_WRITE(sc, AWIN_TCON1_IO_POL_REG, val);
+
+ TCON_WRITE(sc, AWIN_TCON_GINT1_REG,
+ __SHIFTIN(start_delay + 2, AWIN_TCON_GINT1_TCON1_LINENO));
/* Setup LCDx CH1 PLL */
awin_tcon_set_pll(sc, mode);
Home |
Main Index |
Thread Index |
Old Index