From 10089e966678ee5e421363e3595ed2e16fb7096a Mon Sep 17 00:00:00 2001
From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Date: Tue, 19 Sep 2023 17:54:41 +0100
Subject: [PATCH] drm: Add RP1 VEC driver

Add support for the RP1 VEC hardware.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>

drm: rp1: rp1-vec: Allow non-standard modes with various crops

Tweak sync timings in the advertised modelines.

Accept other, custom modes, provided they fit within the active
area of one of the existing hardware-supported TV modes.

Instead of always padding symmetrically, try to respect the user's
[hv]sync_start values, allowing the image to be shifted around
the screen (to fine-tune overscan correction).

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>

drm/rp1: depends on, instead of select, MFD_RP1

According to kconfig-language.txt [1], select should be used only for
"non-visible symbols ... and for symbols with no dependencies". Since
MFD_RP1 both is visible and has a dependency, "select" should not be
used and "depends on" should be used instead.

In particular, this fixes the build of this kernel tree on NixOS, where
its kernel config system will try to answer 'M' to as many config as
possible.

[1] https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html

Signed-off-by: Ratchanan Srirattanamet <peathot@hotmail.com>

drm: rp1: Use tv_mode from the command line and fix for Linux 6.6

Use the standard enum drm_connector_tv_mode instead of a private
enum and switch from the legacy to the standard tv_mode property.

Remove the module parameter "tv_norm". Instead, get tv_mode from
the command line and make this the connector's default TV mode.

Don't restrict the choice of modes based on tv_mode, but interpret
nonstandard combinations as NTSC or PAL, depending on resolution.
Thus the default tv_mode=NTSC effectively means "Auto".

Tweak the advertised horizontal timings for 625/50 to match Rec.601

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>

drm: rp1: VEC and DPI drivers: Fix bug #5901

Rework probe() to use devm_drm_dev_alloc(), embedding the DRM
device in the DPI or VEC device as now seems to be recommended.

Change order of resource allocation and driver initialization.
This prevents it trying to write to an unmapped register during
clean-up, which previously could crash.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>

drm: rp1: vec: Support more video modes in the RP1 VEC driver

Support a wider range of pixel clock rates. The driver will round
pixclock up to 108MHz/n but tries to honour the desired image width
and position (of the centre of the display relative to HSYNC_STARTs).
This adds complexity but removes the need for separate 13.5MHz and
15.428MHz modes.

Support "fake" double-rate progressive modes (in which only every
2nd scanline is displayed). To work around aspect ratio issues.

Add Monochrome TV mode support. Add "vintage" modes (544x380i for
System A; 848x738i for System E) when configured for Monochrome.

Add a way to create a "custom" display mode from a module parameter.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>

drm: rp1: rp1-vec: Add DRM_FORMAT_ARGB8888 and DRM_FORMAT_ABGR8888

Android requires this.
As the underlying hardware doesn't support alpha blending,
we ignore the alpha value.

Signed-off-by: Jan Kehren <jan.kehren@emteria.com>

drivers: drm: rp1-vec: Increase width limit, for PAL 16:9 @ 18MHz

There was no technical reason for the DRM mode's width limit of 848;
increase it to 960 (720*18MHz/13.5MHz) to support ~square pixels on
16:9 screens. Tweak the PAL active window to start slightly earlier.
(The maximum number of visible columns at 18MHz is about 942.)

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
---
 drivers/gpu/drm/rp1/rp1-vec/Kconfig       |   11 +
 drivers/gpu/drm/rp1/rp1-vec/Makefile      |    5 +
 drivers/gpu/drm/rp1/rp1-vec/rp1_vec.c     |  602 +++++++++
 drivers/gpu/drm/rp1/rp1-vec/rp1_vec.h     |   72 ++
 drivers/gpu/drm/rp1/rp1-vec/rp1_vec_cfg.c |  508 ++++++++
 drivers/gpu/drm/rp1/rp1-vec/rp1_vec_hw.c  |  580 +++++++++
 drivers/gpu/drm/rp1/rp1-vec/vec_regs.h    | 1420 +++++++++++++++++++++
 7 files changed, 3198 insertions(+)
 create mode 100644 drivers/gpu/drm/rp1/rp1-vec/Kconfig
 create mode 100644 drivers/gpu/drm/rp1/rp1-vec/Makefile
 create mode 100644 drivers/gpu/drm/rp1/rp1-vec/rp1_vec.c
 create mode 100644 drivers/gpu/drm/rp1/rp1-vec/rp1_vec.h
 create mode 100644 drivers/gpu/drm/rp1/rp1-vec/rp1_vec_cfg.c
 create mode 100644 drivers/gpu/drm/rp1/rp1-vec/rp1_vec_hw.c
 create mode 100644 drivers/gpu/drm/rp1/rp1-vec/vec_regs.h

--- /dev/null
+++ b/drivers/gpu/drm/rp1/rp1-vec/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config DRM_RP1_VEC
+	tristate "DRM Support for RP1 VEC"
+	depends on DRM && MFD_RP1
+	select DRM_GEM_DMA_HELPER
+	select DRM_KMS_HELPER
+	select DRM_VRAM_HELPER
+	select DRM_TTM
+	select DRM_TTM_HELPER
+	help
+	  Choose this option to enable Video Out on RP1
--- /dev/null
+++ b/drivers/gpu/drm/rp1/rp1-vec/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+drm-rp1-vec-y := rp1_vec.o rp1_vec_hw.o rp1_vec_cfg.o
+
+obj-$(CONFIG_DRM_RP1_VEC) += drm-rp1-vec.o
--- /dev/null
+++ b/drivers/gpu/drm/rp1/rp1-vec/rp1_vec.c
@@ -0,0 +1,602 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * DRM Driver for VEC output on Raspberry Pi RP1
+ *
+ * Copyright (c) 2023 Raspberry Pi Limited.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/cred.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_mm.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_encoder.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_fbdev_ttm.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem.h>
+#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_gem_dma_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_vblank.h>
+#include <drm/drm_of.h>
+
+#include "rp1_vec.h"
+
+/*
+ * Linux doesn't make it easy to create custom video modes for the console
+ * with non-CVT timings; so add a module parameter for it. The format is:
+ * "<pclk>,<hact>,<hfp>,<hsync>,<hbp>,<vact>,<vfp>,<vsync>,<vbp>[,i]"
+ * (where each comma may be replaced by any sequence of punctuation).
+ * pclk should be 108000/n for 5 <= n <= 16 (twice this for "fake" modes).
+ */
+
+static char *rp1vec_cmode_str;
+module_param_named(cmode, rp1vec_cmode_str, charp, 0600);
+MODULE_PARM_DESC(cmode, "Custom video mode:\n"
+		 "\t\t<pclk>,<hact>,<hfp>,<hsync>,<hbp>,<vact>,<vfp>,<vsync>,<vbp>[,i]\n");
+
+static struct drm_display_mode *rp1vec_parse_custom_mode(struct drm_device *dev)
+{
+	char const *p = rp1vec_cmode_str;
+	struct drm_display_mode *mode;
+	unsigned int n, vals[9];
+
+	if (!p)
+		return NULL;
+
+	for (n = 0; n < 9; n++) {
+		unsigned int v = 0;
+
+		if (!isdigit(*p))
+			return NULL;
+		do {
+			v = 10u * v + (*p - '0');
+		} while (isdigit(*++p));
+
+		vals[n] = v;
+		while (ispunct(*p))
+			p++;
+	}
+
+	mode = drm_mode_create(dev);
+	if (!mode)
+		return NULL;
+
+	mode->clock	  = vals[0];
+	mode->hdisplay	  = vals[1];
+	mode->hsync_start = mode->hdisplay + vals[2];
+	mode->hsync_end	  = mode->hsync_start + vals[3];
+	mode->htotal	  = mode->hsync_end + vals[4];
+	mode->vdisplay	  = vals[5];
+	mode->vsync_start = mode->vdisplay + vals[6];
+	mode->vsync_end	  = mode->vsync_start + vals[7];
+	mode->vtotal	  = mode->vsync_end + vals[8];
+	mode->type  = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+	mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC;
+	if (strchr(p, 'i'))
+		mode->flags |= DRM_MODE_FLAG_INTERLACE;
+
+	return mode;
+}
+
+static void rp1vec_pipe_update(struct drm_simple_display_pipe *pipe,
+			       struct drm_plane_state *old_state)
+{
+	struct drm_pending_vblank_event *event;
+	unsigned long flags;
+	struct drm_framebuffer *fb = pipe->plane.state->fb;
+	struct rp1_vec *vec = pipe->crtc.dev->dev_private;
+	struct drm_gem_object *gem = fb ? drm_gem_fb_get_obj(fb, 0) : NULL;
+	struct drm_gem_dma_object *dma_obj = gem ? to_drm_gem_dma_obj(gem) : NULL;
+	bool can_update = fb && dma_obj && vec && vec->pipe_enabled;
+
+	/* (Re-)start VEC where required; and update FB address */
+	if (can_update) {
+		if (!vec->vec_running || fb->format->format != vec->cur_fmt) {
+			if (vec->vec_running && fb->format->format != vec->cur_fmt) {
+				rp1vec_hw_stop(vec);
+				vec->vec_running = false;
+			}
+			if (!vec->vec_running) {
+				rp1vec_hw_setup(vec,
+						fb->format->format,
+						&pipe->crtc.state->mode,
+						vec->connector.state->tv.mode);
+				vec->vec_running = true;
+			}
+			vec->cur_fmt  = fb->format->format;
+			drm_crtc_vblank_on(&pipe->crtc);
+		}
+		rp1vec_hw_update(vec, dma_obj->dma_addr, fb->offsets[0], fb->pitches[0]);
+	}
+
+	/* Check if VBLANK callback needs to be armed (or sent immediately in some error cases).
+	 * Note there is a tiny probability of a race between rp1vec_dma_update() and IRQ;
+	 * ordering it this way around is safe, but theoretically might delay an extra frame.
+	 */
+	spin_lock_irqsave(&pipe->crtc.dev->event_lock, flags);
+	event = pipe->crtc.state->event;
+	if (event) {
+		pipe->crtc.state->event = NULL;
+		if (can_update && drm_crtc_vblank_get(&pipe->crtc) == 0)
+			drm_crtc_arm_vblank_event(&pipe->crtc, event);
+		else
+			drm_crtc_send_vblank_event(&pipe->crtc, event);
+	}
+	spin_unlock_irqrestore(&pipe->crtc.dev->event_lock, flags);
+}
+
+static void rp1vec_pipe_enable(struct drm_simple_display_pipe *pipe,
+			       struct drm_crtc_state *crtc_state,
+			       struct drm_plane_state *plane_state)
+{
+	struct rp1_vec *vec = pipe->crtc.dev->dev_private;
+
+	dev_info(&vec->pdev->dev, __func__);
+	vec->pipe_enabled = true;
+	vec->cur_fmt = 0xdeadbeef;
+	rp1vec_vidout_setup(vec);
+	rp1vec_pipe_update(pipe, 0);
+}
+
+static void rp1vec_pipe_disable(struct drm_simple_display_pipe *pipe)
+{
+	struct rp1_vec *vec = pipe->crtc.dev->dev_private;
+
+	dev_info(&vec->pdev->dev, __func__);
+	drm_crtc_vblank_off(&pipe->crtc);
+	if (vec) {
+		if (vec->vec_running) {
+			rp1vec_hw_stop(vec);
+			vec->vec_running = false;
+		}
+		vec->pipe_enabled = false;
+	}
+}
+
+static int rp1vec_pipe_enable_vblank(struct drm_simple_display_pipe *pipe)
+{
+	if (pipe && pipe->crtc.dev) {
+		struct rp1_vec *vec = pipe->crtc.dev->dev_private;
+
+		if (vec)
+			rp1vec_hw_vblank_ctrl(vec, 1);
+	}
+	return 0;
+}
+
+static void rp1vec_pipe_disable_vblank(struct drm_simple_display_pipe *pipe)
+{
+	if (pipe && pipe->crtc.dev) {
+		struct rp1_vec *vec = pipe->crtc.dev->dev_private;
+
+		if (vec)
+			rp1vec_hw_vblank_ctrl(vec, 0);
+	}
+}
+
+static const struct drm_simple_display_pipe_funcs rp1vec_pipe_funcs = {
+	.enable	    = rp1vec_pipe_enable,
+	.update	    = rp1vec_pipe_update,
+	.disable    = rp1vec_pipe_disable,
+	.enable_vblank	= rp1vec_pipe_enable_vblank,
+	.disable_vblank = rp1vec_pipe_disable_vblank,
+};
+
+static void rp1vec_connector_destroy(struct drm_connector *connector)
+{
+	drm_connector_unregister(connector);
+	drm_connector_cleanup(connector);
+}
+
+/*
+ * Check the mode roughly matches something we can generate.
+ * The choice of hardware TV mode depends on total lines and frame rate.
+ * Within each hardware mode, allow pixel clock, image size and offsets
+ * to vary, up to a maximum horizontal active period and line count.
+ * Don't check sync timings here: the HW driver will sanitize them.
+ */
+
+static enum drm_mode_status rp1vec_mode_valid(struct drm_device *dev,
+					      const struct drm_display_mode *mode)
+{
+	int prog	  = !(mode->flags & DRM_MODE_FLAG_INTERLACE);
+	int fake_31khz	  = prog && mode->vtotal >= 500;
+	int vtotal_2fld	  = mode->vtotal << (prog && !fake_31khz);
+	int vdisplay_2fld = mode->vdisplay << (prog && !fake_31khz);
+	int real_clock	  = mode->clock >> fake_31khz;
+
+	/* Check pixel clock is in the permitted range */
+	if (real_clock < 6750)
+		return MODE_CLOCK_LOW;
+	else if (real_clock > 21600)
+		return MODE_CLOCK_HIGH;
+
+	/* Try to match against the 525-line 60Hz mode (System M) */
+	if (vtotal_2fld >= 524 && vtotal_2fld <= 526 && vdisplay_2fld <= 486 &&
+	    mode->htotal * vtotal_2fld > 32 * real_clock &&
+	    mode->htotal * vtotal_2fld < 34 * real_clock &&
+	    37 * mode->hdisplay <= 2 * real_clock) /* 54us */
+		return MODE_OK;
+
+	/* All other supported TV Systems (625-, 405-, 819-line) are 50Hz */
+	if (mode->htotal * vtotal_2fld > 39 * real_clock &&
+	    mode->htotal * vtotal_2fld < 41 * real_clock) {
+		if (vtotal_2fld >= 624 && vtotal_2fld <= 626 && vdisplay_2fld <= 576 &&
+		    37 * mode->hdisplay <= 2 * real_clock) /* 54us */
+			return MODE_OK;
+
+		if (vtotal_2fld == 405 && vdisplay_2fld <= 380 &&
+		    49 * mode->hdisplay <= 4 * real_clock) /* 81.6us */
+			return MODE_OK;
+
+		if (vtotal_2fld == 819 && vdisplay_2fld <= 738 &&
+		    25 * mode->hdisplay <= real_clock) /* 40us */
+			return MODE_OK;
+	}
+
+	return MODE_BAD;
+}
+
+static const struct drm_display_mode rp1vec_modes[6] = {
+	{ /* Full size 525/60i with Rec.601 pixel rate */
+		DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
+			 720, 720 + 16, 720 + 16 + 64, 858, 0,
+			 480, 480 + 6, 480 + 6 + 6, 525, 0,
+			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+			 DRM_MODE_FLAG_INTERLACE)
+	},
+	{ /* Cropped and horizontally squashed to be TV-safe */
+		DRM_MODE("704x432i", DRM_MODE_TYPE_DRIVER, 15429,
+			 704, 704 + 76, 704 + 76 + 72, 980, 0,
+			 432, 432 + 30, 432 + 30 + 6, 525, 0,
+			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+			 DRM_MODE_FLAG_INTERLACE)
+	},
+	{ /* Full size 625/50i with Rec.601 pixel rate */
+		DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
+			 720, 720 + 12, 720 + 12 + 64, 864, 0,
+			 576, 576 + 5, 576 + 5 + 5, 625, 0,
+			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+			 DRM_MODE_FLAG_INTERLACE)
+	},
+	{ /* Cropped and squashed, for square(ish) pixels */
+		DRM_MODE("704x512i", DRM_MODE_TYPE_DRIVER, 15429,
+			 704, 704 + 72, 704 + 72 + 72, 987, 0,
+			 512, 512 + 37, 512 + 37 + 5, 625, 0,
+			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+			 DRM_MODE_FLAG_INTERLACE)
+	},
+	{ /* System A (405 lines) */
+		DRM_MODE("544x380i", DRM_MODE_TYPE_DRIVER, 6750,
+			 544, 544 + 12, 544 + 12 + 60, 667, 0,
+			 380, 380 + 0,	380 + 0 + 8, 405, 0,
+			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+			 DRM_MODE_FLAG_INTERLACE)
+	},
+	{ /* System E (819 lines) */
+		DRM_MODE("848x738i", DRM_MODE_TYPE_DRIVER, 21600,
+			 848, 848 + 12, 848 + 12 + 54, 1055, 0,
+			 738, 738 + 6, 738 + 6 + 1, 819, 0,
+			 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+			 DRM_MODE_FLAG_INTERLACE)
+	}
+};
+
+/*
+ * Advertise a custom mode, if specified; then those from the table above.
+ * From each interlaced mode above, derive a half-height progressive one.
+ *
+ * This driver always supports all 525-line and 625-line standard modes
+ * regardless of connector's tv_mode; non-standard combinations generally
+ * default to PAL[-BDGHIK] or NTSC[-M] (with a special case for "PAL60").
+ *
+ * The "vintage" standards (System A, System E) are advertised only when
+ * the default tv_mode was DRM_MODE_TV_MODE_MONOCHROME, and only interlaced.
+ */
+
+static int rp1vec_connector_get_modes(struct drm_connector *connector)
+{
+	u64 tvstd;
+	int i, prog, limit, n = 0, preferred_lines = 525;
+	struct drm_display_mode *mode;
+
+	if (!drm_object_property_get_default_value(&connector->base,
+						   connector->dev->mode_config.tv_mode_property,
+						   &tvstd))
+		preferred_lines = (tvstd == DRM_MODE_TV_MODE_PAL   ||
+				   tvstd == DRM_MODE_TV_MODE_PAL_N ||
+				   tvstd >= DRM_MODE_TV_MODE_SECAM) ? 625 : 525;
+
+	mode = rp1vec_parse_custom_mode(connector->dev);
+	if (mode) {
+		if (rp1vec_mode_valid(connector->dev, mode) == 0) {
+			drm_mode_set_name(mode);
+			drm_mode_probed_add(connector, mode);
+			n++;
+			preferred_lines = 0;
+		} else {
+			drm_mode_destroy(connector->dev, mode);
+		}
+	}
+
+	limit = (tvstd < DRM_MODE_TV_MODE_MONOCHROME) ? 4 : ARRAY_SIZE(rp1vec_modes);
+	for (i = 0; i < limit; i++) {
+		for (prog = 0; prog < 2; prog++) {
+			mode = drm_mode_duplicate(connector->dev, &rp1vec_modes[i]);
+			if (!mode)
+				return n;
+
+			if (prog) {
+				mode->flags &= ~DRM_MODE_FLAG_INTERLACE;
+				mode->vdisplay	  >>= 1;
+				mode->vsync_start >>= 1;
+				mode->vsync_end	  >>= 1;
+				mode->vtotal	  >>= 1;
+			} else if (mode->hdisplay == 704 && mode->vtotal == preferred_lines) {
+				mode->type |= DRM_MODE_TYPE_PREFERRED;
+			}
+			drm_mode_set_name(mode);
+			drm_mode_probed_add(connector, mode);
+			n++;
+
+			if (mode->vtotal == 405 || mode->vtotal == 819)
+				break; /* Don't offer progressive for Systems A, E */
+		}
+	}
+
+	return n;
+}
+
+static void rp1vec_connector_reset(struct drm_connector *connector)
+{
+	drm_atomic_helper_connector_reset(connector);
+	drm_atomic_helper_connector_tv_reset(connector);
+}
+
+static int rp1vec_connector_atomic_check(struct drm_connector *conn,
+					 struct drm_atomic_state *state)
+{	struct drm_connector_state *old_state =
+		drm_atomic_get_old_connector_state(state, conn);
+	struct drm_connector_state *new_state =
+		drm_atomic_get_new_connector_state(state, conn);
+
+	if (new_state->crtc && old_state->tv.mode != new_state->tv.mode) {
+		struct drm_crtc_state *crtc_state =
+			drm_atomic_get_new_crtc_state(state, new_state->crtc);
+
+		crtc_state->mode_changed = true;
+	}
+
+	return 0;
+}
+
+static const struct drm_connector_helper_funcs rp1vec_connector_helper_funcs = {
+	.get_modes = rp1vec_connector_get_modes,
+	.atomic_check = rp1vec_connector_atomic_check,
+};
+
+static const struct drm_connector_funcs rp1vec_connector_funcs = {
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = rp1vec_connector_destroy,
+	.reset = rp1vec_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static const struct drm_mode_config_funcs rp1vec_mode_funcs = {
+	.fb_create = drm_gem_fb_create,
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = drm_atomic_helper_commit,
+	.mode_valid = rp1vec_mode_valid,
+};
+
+static const u32 rp1vec_formats[] = {
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB565
+};
+
+static void rp1vec_stopall(struct drm_device *drm)
+{
+	if (drm->dev_private) {
+		struct rp1_vec *vec = drm->dev_private;
+
+		if (vec->vec_running || rp1vec_hw_busy(vec)) {
+			rp1vec_hw_stop(vec);
+			vec->vec_running = false;
+		}
+		rp1vec_vidout_poweroff(vec);
+	}
+}
+
+DEFINE_DRM_GEM_DMA_FOPS(rp1vec_fops);
+
+static struct drm_driver rp1vec_driver = {
+	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
+	.fops			= &rp1vec_fops,
+	.name			= "drm-rp1-vec",
+	.desc			= "drm-rp1-vec",
+	.date			= "0",
+	.major			= 1,
+	.minor			= 0,
+	DRM_GEM_DMA_DRIVER_OPS,
+	.release		= rp1vec_stopall,
+};
+
+static int rp1vec_platform_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rp1_vec *vec;
+	int i, ret;
+
+	dev_info(dev, __func__);
+	vec = devm_drm_dev_alloc(dev, &rp1vec_driver, struct rp1_vec, drm);
+	if (IS_ERR(vec)) {
+		ret = PTR_ERR(vec);
+		dev_err(dev, "%s devm_drm_dev_alloc %d", __func__, ret);
+		return ret;
+	}
+	vec->pdev = pdev;
+
+	for (i = 0; i < RP1VEC_NUM_HW_BLOCKS; i++) {
+		vec->hw_base[i] =
+			devm_ioremap_resource(dev,
+					      platform_get_resource(vec->pdev, IORESOURCE_MEM, i));
+		if (IS_ERR(vec->hw_base[i])) {
+			ret = PTR_ERR(vec->hw_base[i]);
+			dev_err(dev, "Error memory mapping regs[%d]\n", i);
+			goto done_err;
+		}
+	}
+	ret = platform_get_irq(vec->pdev, 0);
+	if (ret > 0)
+		ret = devm_request_irq(dev, ret, rp1vec_hw_isr,
+				       IRQF_SHARED, "rp1-vec", vec);
+	if (ret) {
+		dev_err(dev, "Unable to request interrupt\n");
+		ret = -EINVAL;
+		goto done_err;
+	}
+
+	vec->vec_clock = devm_clk_get(dev, NULL);
+	if (IS_ERR(vec->vec_clock)) {
+		ret = PTR_ERR(vec->vec_clock);
+		goto done_err;
+	}
+	ret = clk_prepare_enable(vec->vec_clock);
+
+	ret = drmm_mode_config_init(&vec->drm);
+	if (ret)
+		goto done_err;
+
+	/* Now we have all our resources, finish driver initialization */
+	dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+	init_completion(&vec->finished);
+	vec->drm.dev_private = vec;
+	platform_set_drvdata(pdev, &vec->drm);
+
+	vec->drm.mode_config.min_width	= 256;
+	vec->drm.mode_config.min_height = 128;
+	vec->drm.mode_config.max_width	= 960; /* for "widescreen" @ 18MHz */
+	vec->drm.mode_config.max_height = 738; /* for System E only */
+	vec->drm.mode_config.preferred_depth = 32;
+	vec->drm.mode_config.prefer_shadow = 0;
+	vec->drm.mode_config.quirk_addfb_prefer_host_byte_order = true;
+	vec->drm.mode_config.funcs = &rp1vec_mode_funcs;
+	drm_vblank_init(&vec->drm, 1);
+
+	ret = drm_mode_create_tv_properties(&vec->drm, RP1VEC_SUPPORTED_TV_MODES);
+	if (ret)
+		goto done_err;
+
+	drm_connector_init(&vec->drm, &vec->connector, &rp1vec_connector_funcs,
+			   DRM_MODE_CONNECTOR_Composite);
+	if (ret)
+		goto done_err;
+
+	vec->connector.interlace_allowed = true;
+	drm_connector_helper_add(&vec->connector, &rp1vec_connector_helper_funcs);
+
+	drm_object_attach_property(&vec->connector.base,
+				   vec->drm.mode_config.tv_mode_property,
+				   (vec->connector.cmdline_mode.tv_mode_specified) ?
+					   vec->connector.cmdline_mode.tv_mode :
+					   DRM_MODE_TV_MODE_NTSC);
+
+	ret = drm_simple_display_pipe_init(&vec->drm,
+					   &vec->pipe,
+					   &rp1vec_pipe_funcs,
+					   rp1vec_formats,
+					   ARRAY_SIZE(rp1vec_formats),
+					   NULL,
+					   &vec->connector);
+	if (ret)
+		goto done_err;
+
+	drm_mode_config_reset(&vec->drm);
+
+	ret = drm_dev_register(&vec->drm, 0);
+	if (ret)
+		goto done_err;
+
+	drm_fbdev_ttm_setup(&vec->drm, 32);
+	return ret;
+
+done_err:
+	dev_err(dev, "%s fail %d", __func__, ret);
+	return ret;
+}
+
+static void rp1vec_platform_remove(struct platform_device *pdev)
+{
+	struct drm_device *drm = platform_get_drvdata(pdev);
+
+	rp1vec_stopall(drm);
+	drm_dev_unregister(drm);
+	drm_atomic_helper_shutdown(drm);
+	drm_dev_put(drm);
+}
+
+static void rp1vec_platform_shutdown(struct platform_device *pdev)
+{
+	struct drm_device *drm = platform_get_drvdata(pdev);
+
+	rp1vec_stopall(drm);
+}
+
+static const struct of_device_id rp1vec_of_match[] = {
+	{
+		.compatible = "raspberrypi,rp1vec",
+	},
+	{ /* sentinel */ },
+};
+
+MODULE_DEVICE_TABLE(of, rp1vec_of_match);
+
+static struct platform_driver rp1vec_platform_driver = {
+	.probe		= rp1vec_platform_probe,
+	.remove		= rp1vec_platform_remove,
+	.shutdown	= rp1vec_platform_shutdown,
+	.driver		= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = rp1vec_of_match,
+	},
+};
+
+module_platform_driver(rp1vec_platform_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DRM driver for Composite Video on Raspberry Pi RP1");
+MODULE_AUTHOR("Nick Hollinghurst");
--- /dev/null
+++ b/drivers/gpu/drm/rp1/rp1-vec/rp1_vec.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * DRM Driver for DSI output on Raspberry Pi RP1
+ *
+ * Copyright (c) 2023 Raspberry Pi Limited.
+ */
+
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <drm/drm_device.h>
+#include <drm/drm_simple_kms_helper.h>
+
+#define MODULE_NAME "drm-rp1-vec"
+#define DRIVER_NAME "drm-rp1-vec"
+
+/* ---------------------------------------------------------------------- */
+
+#define RP1VEC_HW_BLOCK_VEC   0
+#define RP1VEC_HW_BLOCK_CFG   1
+#define RP1VEC_NUM_HW_BLOCKS  2
+
+#define RP1VEC_SUPPORTED_TV_MODES	  \
+	(BIT(DRM_MODE_TV_MODE_NTSC)	| \
+	 BIT(DRM_MODE_TV_MODE_NTSC_443) | \
+	 BIT(DRM_MODE_TV_MODE_NTSC_J)	| \
+	 BIT(DRM_MODE_TV_MODE_PAL)	| \
+	 BIT(DRM_MODE_TV_MODE_PAL_M)	| \
+	 BIT(DRM_MODE_TV_MODE_PAL_N)	| \
+	 BIT(DRM_MODE_TV_MODE_MONOCHROME))
+
+#define RP1VEC_VDAC_KHZ 108000
+
+/* ---------------------------------------------------------------------- */
+
+struct rp1_vec {
+	/* DRM base and platform device pointer */
+	struct drm_device drm;
+	struct platform_device *pdev;
+
+	/* Framework and helper objects */
+	struct drm_simple_display_pipe pipe;
+	struct drm_connector connector;
+
+	/* Clock. We assume this is always at 108 MHz. */
+	struct clk *vec_clock;
+
+	/* Block (VCC, CFG) base addresses, and current state */
+	void __iomem *hw_base[RP1VEC_NUM_HW_BLOCKS];
+	u32 cur_fmt;
+	bool fake_31khz, vec_running, pipe_enabled;
+	struct completion finished;
+};
+
+/* ---------------------------------------------------------------------- */
+/* Functions to control the VEC/DMA block				  */
+
+void rp1vec_hw_setup(struct rp1_vec *vec,
+		     u32 in_format,
+		     struct drm_display_mode const *mode,
+		     int tvstd);
+void rp1vec_hw_update(struct rp1_vec *vec, dma_addr_t addr, u32 offset, u32 stride);
+void rp1vec_hw_stop(struct rp1_vec *vec);
+int rp1vec_hw_busy(struct rp1_vec *vec);
+irqreturn_t rp1vec_hw_isr(int irq, void *dev);
+void rp1vec_hw_vblank_ctrl(struct rp1_vec *vec, int enable);
+
+/* ---------------------------------------------------------------------- */
+/* Functions to control the VIDEO OUT CFG block and check RP1 platform	  */
+
+void rp1vec_vidout_setup(struct rp1_vec *vec);
+void rp1vec_vidout_poweroff(struct rp1_vec *vec);
--- /dev/null
+++ b/drivers/gpu/drm/rp1/rp1-vec/rp1_vec_cfg.c
@@ -0,0 +1,508 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * DRM Driver for DSI output on Raspberry Pi RP1
+ *
+ * Copyright (c) 2023 Raspberry Pi Limited.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+#include <linux/rp1_platform.h>
+
+#include "rp1_vec.h"
+
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_SEL
+// JTAG access : synchronous
+// Description : Selects source: VEC or DPI
+#define VIDEO_OUT_CFG_SEL_OFFSET 0x00000000
+#define VIDEO_OUT_CFG_SEL_BITS	 0x00000013
+#define VIDEO_OUT_CFG_SEL_RESET	 0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_SEL_PCLK_INV
+// Description : Select dpi_pclk output port polarity inversion.
+#define VIDEO_OUT_CFG_SEL_PCLK_INV_RESET  0x0
+#define VIDEO_OUT_CFG_SEL_PCLK_INV_BITS	  0x00000010
+#define VIDEO_OUT_CFG_SEL_PCLK_INV_MSB	  4
+#define VIDEO_OUT_CFG_SEL_PCLK_INV_LSB	  4
+#define VIDEO_OUT_CFG_SEL_PCLK_INV_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_SEL_PAD_MUX
+// Description : VEC 1 DPI 0
+#define VIDEO_OUT_CFG_SEL_PAD_MUX_RESET	 0x0
+#define VIDEO_OUT_CFG_SEL_PAD_MUX_BITS	 0x00000002
+#define VIDEO_OUT_CFG_SEL_PAD_MUX_MSB	 1
+#define VIDEO_OUT_CFG_SEL_PAD_MUX_LSB	 1
+#define VIDEO_OUT_CFG_SEL_PAD_MUX_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_SEL_VDAC_MUX
+// Description : VEC 1 DPI 0
+#define VIDEO_OUT_CFG_SEL_VDAC_MUX_RESET  0x0
+#define VIDEO_OUT_CFG_SEL_VDAC_MUX_BITS	  0x00000001
+#define VIDEO_OUT_CFG_SEL_VDAC_MUX_MSB	  0
+#define VIDEO_OUT_CFG_SEL_VDAC_MUX_LSB	  0
+#define VIDEO_OUT_CFG_SEL_VDAC_MUX_ACCESS "RW"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_VDAC_CFG
+// JTAG access : synchronous
+// Description : Configure SNPS VDAC
+#define VIDEO_OUT_CFG_VDAC_CFG_OFFSET 0x00000004
+#define VIDEO_OUT_CFG_VDAC_CFG_BITS   0x1fffffff
+#define VIDEO_OUT_CFG_VDAC_CFG_RESET  0x0003ffff
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_VDAC_CFG_ENCTR
+// Description : None
+#define VIDEO_OUT_CFG_VDAC_CFG_ENCTR_RESET  0x0
+#define VIDEO_OUT_CFG_VDAC_CFG_ENCTR_BITS   0x1c000000
+#define VIDEO_OUT_CFG_VDAC_CFG_ENCTR_MSB    28
+#define VIDEO_OUT_CFG_VDAC_CFG_ENCTR_LSB    26
+#define VIDEO_OUT_CFG_VDAC_CFG_ENCTR_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_VDAC_CFG_ENSC
+// Description : None
+#define VIDEO_OUT_CFG_VDAC_CFG_ENSC_RESET  0x0
+#define VIDEO_OUT_CFG_VDAC_CFG_ENSC_BITS   0x03800000
+#define VIDEO_OUT_CFG_VDAC_CFG_ENSC_MSB	   25
+#define VIDEO_OUT_CFG_VDAC_CFG_ENSC_LSB	   23
+#define VIDEO_OUT_CFG_VDAC_CFG_ENSC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_VDAC_CFG_ENDAC
+// Description : None
+#define VIDEO_OUT_CFG_VDAC_CFG_ENDAC_RESET  0x0
+#define VIDEO_OUT_CFG_VDAC_CFG_ENDAC_BITS   0x00700000
+#define VIDEO_OUT_CFG_VDAC_CFG_ENDAC_MSB    22
+#define VIDEO_OUT_CFG_VDAC_CFG_ENDAC_LSB    20
+#define VIDEO_OUT_CFG_VDAC_CFG_ENDAC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_VDAC_CFG_ENVBG
+// Description : None
+#define VIDEO_OUT_CFG_VDAC_CFG_ENVBG_RESET  0x0
+#define VIDEO_OUT_CFG_VDAC_CFG_ENVBG_BITS   0x00080000
+#define VIDEO_OUT_CFG_VDAC_CFG_ENVBG_MSB    19
+#define VIDEO_OUT_CFG_VDAC_CFG_ENVBG_LSB    19
+#define VIDEO_OUT_CFG_VDAC_CFG_ENVBG_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_VDAC_CFG_ENEXTREF
+// Description : None
+#define VIDEO_OUT_CFG_VDAC_CFG_ENEXTREF_RESET  0x0
+#define VIDEO_OUT_CFG_VDAC_CFG_ENEXTREF_BITS   0x00040000
+#define VIDEO_OUT_CFG_VDAC_CFG_ENEXTREF_MSB    18
+#define VIDEO_OUT_CFG_VDAC_CFG_ENEXTREF_LSB    18
+#define VIDEO_OUT_CFG_VDAC_CFG_ENEXTREF_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_VDAC_CFG_DAC2GC
+// Description : dac2 gain control
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC2GC_RESET  0x3f
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC2GC_BITS   0x0003f000
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC2GC_MSB    17
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC2GC_LSB    12
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC2GC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_VDAC_CFG_DAC1GC
+// Description : dac1 gain control
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC1GC_RESET  0x3f
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC1GC_BITS   0x00000fc0
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC1GC_MSB    11
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC1GC_LSB    6
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC1GC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_VDAC_CFG_DAC0GC
+// Description : dac0 gain control
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC0GC_RESET  0x3f
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC0GC_BITS   0x0000003f
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC0GC_MSB    5
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC0GC_LSB    0
+#define VIDEO_OUT_CFG_VDAC_CFG_DAC0GC_ACCESS "RW"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_VDAC_STATUS
+// JTAG access : synchronous
+// Description : Read VDAC status
+#define VIDEO_OUT_CFG_VDAC_STATUS_OFFSET 0x00000008
+#define VIDEO_OUT_CFG_VDAC_STATUS_BITS	 0x00000017
+#define VIDEO_OUT_CFG_VDAC_STATUS_RESET	 0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_VDAC_STATUS_ENCTR3
+// Description : None
+#define VIDEO_OUT_CFG_VDAC_STATUS_ENCTR3_RESET	0x0
+#define VIDEO_OUT_CFG_VDAC_STATUS_ENCTR3_BITS	0x00000010
+#define VIDEO_OUT_CFG_VDAC_STATUS_ENCTR3_MSB	4
+#define VIDEO_OUT_CFG_VDAC_STATUS_ENCTR3_LSB	4
+#define VIDEO_OUT_CFG_VDAC_STATUS_ENCTR3_ACCESS "RO"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_VDAC_STATUS_CABLEOUT
+// Description : None
+#define VIDEO_OUT_CFG_VDAC_STATUS_CABLEOUT_RESET  "-"
+#define VIDEO_OUT_CFG_VDAC_STATUS_CABLEOUT_BITS	  0x00000007
+#define VIDEO_OUT_CFG_VDAC_STATUS_CABLEOUT_MSB	  2
+#define VIDEO_OUT_CFG_VDAC_STATUS_CABLEOUT_LSB	  0
+#define VIDEO_OUT_CFG_VDAC_STATUS_CABLEOUT_ACCESS "RO"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_MEM_PD
+// JTAG access : synchronous
+// Description : Control memory power down
+#define VIDEO_OUT_CFG_MEM_PD_OFFSET 0x0000000c
+#define VIDEO_OUT_CFG_MEM_PD_BITS   0x00000003
+#define VIDEO_OUT_CFG_MEM_PD_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_MEM_PD_VEC
+// Description : None
+#define VIDEO_OUT_CFG_MEM_PD_VEC_RESET	0x0
+#define VIDEO_OUT_CFG_MEM_PD_VEC_BITS	0x00000002
+#define VIDEO_OUT_CFG_MEM_PD_VEC_MSB	1
+#define VIDEO_OUT_CFG_MEM_PD_VEC_LSB	1
+#define VIDEO_OUT_CFG_MEM_PD_VEC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_MEM_PD_DPI
+// Description : None
+#define VIDEO_OUT_CFG_MEM_PD_DPI_RESET	0x0
+#define VIDEO_OUT_CFG_MEM_PD_DPI_BITS	0x00000001
+#define VIDEO_OUT_CFG_MEM_PD_DPI_MSB	0
+#define VIDEO_OUT_CFG_MEM_PD_DPI_LSB	0
+#define VIDEO_OUT_CFG_MEM_PD_DPI_ACCESS "RW"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_TEST_OVERRIDE
+// JTAG access : synchronous
+// Description : None
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_OFFSET 0x00000010
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_BITS   0xffffffff
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_TEST_OVERRIDE_PAD
+// Description : None
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_PAD_RESET  0x0
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_PAD_BITS   0x80000000
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_PAD_MSB    31
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_PAD_LSB    31
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_PAD_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_TEST_OVERRIDE_VDAC
+// Description : None
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_VDAC_RESET	0x0
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_VDAC_BITS	0x40000000
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_VDAC_MSB	30
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_VDAC_LSB	30
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_VDAC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_TEST_OVERRIDE_RGBVAL
+// Description : None
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_RGBVAL_RESET  0x00000000
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_RGBVAL_BITS	  0x3fffffff
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_RGBVAL_MSB	  29
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_RGBVAL_LSB	  0
+#define VIDEO_OUT_CFG_TEST_OVERRIDE_RGBVAL_ACCESS "RW"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_INTR
+// JTAG access : synchronous
+// Description : Raw Interrupts
+#define VIDEO_OUT_CFG_INTR_OFFSET 0x00000014
+#define VIDEO_OUT_CFG_INTR_BITS	  0x00000003
+#define VIDEO_OUT_CFG_INTR_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_INTR_DPI
+// Description : None
+#define VIDEO_OUT_CFG_INTR_DPI_RESET  0x0
+#define VIDEO_OUT_CFG_INTR_DPI_BITS   0x00000002
+#define VIDEO_OUT_CFG_INTR_DPI_MSB    1
+#define VIDEO_OUT_CFG_INTR_DPI_LSB    1
+#define VIDEO_OUT_CFG_INTR_DPI_ACCESS "RO"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_INTR_VEC
+// Description : None
+#define VIDEO_OUT_CFG_INTR_VEC_RESET  0x0
+#define VIDEO_OUT_CFG_INTR_VEC_BITS   0x00000001
+#define VIDEO_OUT_CFG_INTR_VEC_MSB    0
+#define VIDEO_OUT_CFG_INTR_VEC_LSB    0
+#define VIDEO_OUT_CFG_INTR_VEC_ACCESS "RO"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_INTE
+// JTAG access : synchronous
+// Description : Interrupt Enable
+#define VIDEO_OUT_CFG_INTE_OFFSET 0x00000018
+#define VIDEO_OUT_CFG_INTE_BITS	  0x00000003
+#define VIDEO_OUT_CFG_INTE_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_INTE_DPI
+// Description : None
+#define VIDEO_OUT_CFG_INTE_DPI_RESET  0x0
+#define VIDEO_OUT_CFG_INTE_DPI_BITS   0x00000002
+#define VIDEO_OUT_CFG_INTE_DPI_MSB    1
+#define VIDEO_OUT_CFG_INTE_DPI_LSB    1
+#define VIDEO_OUT_CFG_INTE_DPI_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_INTE_VEC
+// Description : None
+#define VIDEO_OUT_CFG_INTE_VEC_RESET  0x0
+#define VIDEO_OUT_CFG_INTE_VEC_BITS   0x00000001
+#define VIDEO_OUT_CFG_INTE_VEC_MSB    0
+#define VIDEO_OUT_CFG_INTE_VEC_LSB    0
+#define VIDEO_OUT_CFG_INTE_VEC_ACCESS "RW"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_INTF
+// JTAG access : synchronous
+// Description : Interrupt Force
+#define VIDEO_OUT_CFG_INTF_OFFSET 0x0000001c
+#define VIDEO_OUT_CFG_INTF_BITS	  0x00000003
+#define VIDEO_OUT_CFG_INTF_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_INTF_DPI
+// Description : None
+#define VIDEO_OUT_CFG_INTF_DPI_RESET  0x0
+#define VIDEO_OUT_CFG_INTF_DPI_BITS   0x00000002
+#define VIDEO_OUT_CFG_INTF_DPI_MSB    1
+#define VIDEO_OUT_CFG_INTF_DPI_LSB    1
+#define VIDEO_OUT_CFG_INTF_DPI_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_INTF_VEC
+// Description : None
+#define VIDEO_OUT_CFG_INTF_VEC_RESET  0x0
+#define VIDEO_OUT_CFG_INTF_VEC_BITS   0x00000001
+#define VIDEO_OUT_CFG_INTF_VEC_MSB    0
+#define VIDEO_OUT_CFG_INTF_VEC_LSB    0
+#define VIDEO_OUT_CFG_INTF_VEC_ACCESS "RW"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_INTS
+// JTAG access : synchronous
+// Description : Interrupt status after masking & forcing
+#define VIDEO_OUT_CFG_INTS_OFFSET 0x00000020
+#define VIDEO_OUT_CFG_INTS_BITS	  0x00000003
+#define VIDEO_OUT_CFG_INTS_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_INTS_DPI
+// Description : None
+#define VIDEO_OUT_CFG_INTS_DPI_RESET  0x0
+#define VIDEO_OUT_CFG_INTS_DPI_BITS   0x00000002
+#define VIDEO_OUT_CFG_INTS_DPI_MSB    1
+#define VIDEO_OUT_CFG_INTS_DPI_LSB    1
+#define VIDEO_OUT_CFG_INTS_DPI_ACCESS "RO"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_INTS_VEC
+// Description : None
+#define VIDEO_OUT_CFG_INTS_VEC_RESET  0x0
+#define VIDEO_OUT_CFG_INTS_VEC_BITS   0x00000001
+#define VIDEO_OUT_CFG_INTS_VEC_MSB    0
+#define VIDEO_OUT_CFG_INTS_VEC_LSB    0
+#define VIDEO_OUT_CFG_INTS_VEC_ACCESS "RO"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_BLOCK_ID
+// JTAG access : synchronous
+// Description : Block Identifier
+//		 Hexadecimal representation of "VOCF"
+#define VIDEO_OUT_CFG_BLOCK_ID_OFFSET 0x00000024
+#define VIDEO_OUT_CFG_BLOCK_ID_BITS   0xffffffff
+#define VIDEO_OUT_CFG_BLOCK_ID_RESET  0x564f4346
+#define VIDEO_OUT_CFG_BLOCK_ID_MSB    31
+#define VIDEO_OUT_CFG_BLOCK_ID_LSB    0
+#define VIDEO_OUT_CFG_BLOCK_ID_ACCESS "RO"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_INSTANCE_ID
+// JTAG access : synchronous
+// Description : Block Instance Identifier
+#define VIDEO_OUT_CFG_INSTANCE_ID_OFFSET 0x00000028
+#define VIDEO_OUT_CFG_INSTANCE_ID_BITS	 0x0000000f
+#define VIDEO_OUT_CFG_INSTANCE_ID_RESET	 0x00000000
+#define VIDEO_OUT_CFG_INSTANCE_ID_MSB	 3
+#define VIDEO_OUT_CFG_INSTANCE_ID_LSB	 0
+#define VIDEO_OUT_CFG_INSTANCE_ID_ACCESS "RO"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_RSTSEQ_AUTO
+// JTAG access : synchronous
+// Description : None
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_OFFSET 0x0000002c
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_BITS	 0x00000007
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_RESET	 0x00000007
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_AUTO_VEC
+// Description : 1 = reset is controlled by the sequencer
+//		 0 = reset is controlled by rstseq_ctrl
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_VEC_RESET  0x1
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_VEC_BITS   0x00000004
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_VEC_MSB    2
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_VEC_LSB    2
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_VEC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_AUTO_DPI
+// Description : 1 = reset is controlled by the sequencer
+//		 0 = reset is controlled by rstseq_ctrl
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_DPI_RESET  0x1
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_DPI_BITS   0x00000002
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_DPI_MSB    1
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_DPI_LSB    1
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_DPI_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_AUTO_BUSADAPTER
+// Description : 1 = reset is controlled by the sequencer
+//		 0 = reset is controlled by rstseq_ctrl
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_BUSADAPTER_RESET  0x1
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_BUSADAPTER_BITS   0x00000001
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_BUSADAPTER_MSB    0
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_BUSADAPTER_LSB    0
+#define VIDEO_OUT_CFG_RSTSEQ_AUTO_BUSADAPTER_ACCESS "RW"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_RSTSEQ_PARALLEL
+// JTAG access : synchronous
+// Description : None
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_OFFSET 0x00000030
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_BITS   0x00000007
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_RESET  0x00000006
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_PARALLEL_VEC
+// Description : Is this reset parallel (i.e. not part of the sequence)
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_VEC_RESET	 0x1
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_VEC_BITS	 0x00000004
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_VEC_MSB	 2
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_VEC_LSB	 2
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_VEC_ACCESS "RO"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_PARALLEL_DPI
+// Description : Is this reset parallel (i.e. not part of the sequence)
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_DPI_RESET	 0x1
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_DPI_BITS	 0x00000002
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_DPI_MSB	 1
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_DPI_LSB	 1
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_DPI_ACCESS "RO"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_PARALLEL_BUSADAPTER
+// Description : Is this reset parallel (i.e. not part of the sequence)
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_BUSADAPTER_RESET	0x0
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_BUSADAPTER_BITS	0x00000001
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_BUSADAPTER_MSB	0
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_BUSADAPTER_LSB	0
+#define VIDEO_OUT_CFG_RSTSEQ_PARALLEL_BUSADAPTER_ACCESS "RO"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_RSTSEQ_CTRL
+// JTAG access : synchronous
+// Description : None
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_OFFSET 0x00000034
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_BITS	 0x00000007
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_RESET	 0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_CTRL_VEC
+// Description : 1 = keep the reset asserted
+//		 0 = keep the reset deasserted
+//		 This is ignored if rstseq_auto=1
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_VEC_RESET  0x0
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_VEC_BITS   0x00000004
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_VEC_MSB    2
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_VEC_LSB    2
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_VEC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_CTRL_DPI
+// Description : 1 = keep the reset asserted
+//		 0 = keep the reset deasserted
+//		 This is ignored if rstseq_auto=1
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_DPI_RESET  0x0
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_DPI_BITS   0x00000002
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_DPI_MSB    1
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_DPI_LSB    1
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_DPI_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_CTRL_BUSADAPTER
+// Description : 1 = keep the reset asserted
+//		 0 = keep the reset deasserted
+//		 This is ignored if rstseq_auto=1
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_BUSADAPTER_RESET  0x0
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_BUSADAPTER_BITS   0x00000001
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_BUSADAPTER_MSB    0
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_BUSADAPTER_LSB    0
+#define VIDEO_OUT_CFG_RSTSEQ_CTRL_BUSADAPTER_ACCESS "RW"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_RSTSEQ_TRIG
+// JTAG access : synchronous
+// Description : None
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_OFFSET 0x00000038
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_BITS	 0x00000007
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_RESET	 0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_TRIG_VEC
+// Description : Pulses the reset output
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_VEC_RESET  0x0
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_VEC_BITS   0x00000004
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_VEC_MSB    2
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_VEC_LSB    2
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_VEC_ACCESS "SC"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_TRIG_DPI
+// Description : Pulses the reset output
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_DPI_RESET  0x0
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_DPI_BITS   0x00000002
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_DPI_MSB    1
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_DPI_LSB    1
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_DPI_ACCESS "SC"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_TRIG_BUSADAPTER
+// Description : Pulses the reset output
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_BUSADAPTER_RESET  0x0
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_BUSADAPTER_BITS   0x00000001
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_BUSADAPTER_MSB    0
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_BUSADAPTER_LSB    0
+#define VIDEO_OUT_CFG_RSTSEQ_TRIG_BUSADAPTER_ACCESS "SC"
+// =============================================================================
+// Register    : VIDEO_OUT_CFG_RSTSEQ_DONE
+// JTAG access : synchronous
+// Description : None
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_OFFSET 0x0000003c
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_BITS	 0x00000007
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_RESET	 0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_DONE_VEC
+// Description : Indicates the current state of the reset
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_VEC_RESET  0x0
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_VEC_BITS   0x00000004
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_VEC_MSB    2
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_VEC_LSB    2
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_VEC_ACCESS "RO"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_DONE_DPI
+// Description : Indicates the current state of the reset
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_DPI_RESET  0x0
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_DPI_BITS   0x00000002
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_DPI_MSB    1
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_DPI_LSB    1
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_DPI_ACCESS "RO"
+// -----------------------------------------------------------------------------
+// Field       : VIDEO_OUT_CFG_RSTSEQ_DONE_BUSADAPTER
+// Description : Indicates the current state of the reset
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_BUSADAPTER_RESET  0x0
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_BUSADAPTER_BITS   0x00000001
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_BUSADAPTER_MSB    0
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_BUSADAPTER_LSB    0
+#define VIDEO_OUT_CFG_RSTSEQ_DONE_BUSADAPTER_ACCESS "RO"
+// =============================================================================
+
+#define CFG_WRITE(reg, val)  writel((val),  vec->hw_base[RP1VEC_HW_BLOCK_CFG] + (reg ## _OFFSET))
+#define CFG_READ(reg)	     readl(vec->hw_base[RP1VEC_HW_BLOCK_CFG] + (reg ## _OFFSET))
+
+void rp1vec_vidout_setup(struct rp1_vec *vec)
+{
+	/*
+	 * We assume DPI and VEC can't be used at the same time (due to
+	 * clashing requirements for PLL_VIDEO, and potentially for VDAC).
+	 * We therefore leave DPI memories powered down.
+	 */
+	CFG_WRITE(VIDEO_OUT_CFG_MEM_PD, VIDEO_OUT_CFG_MEM_PD_DPI_BITS);
+	CFG_WRITE(VIDEO_OUT_CFG_TEST_OVERRIDE, 0x00000000);
+
+	/* DPI->Pads; VEC->VDAC */
+	CFG_WRITE(VIDEO_OUT_CFG_SEL, VIDEO_OUT_CFG_SEL_VDAC_MUX_BITS);
+
+	/* configure VDAC for 1 channel, bandgap on, 1.28V swing */
+	CFG_WRITE(VIDEO_OUT_CFG_VDAC_CFG, 0x0019ffff);
+
+	/* enable VEC interrupt */
+	CFG_WRITE(VIDEO_OUT_CFG_INTE, VIDEO_OUT_CFG_INTE_VEC_BITS);
+}
+
+void rp1vec_vidout_poweroff(struct rp1_vec *vec)
+{
+	/* disable VEC interrupt */
+	CFG_WRITE(VIDEO_OUT_CFG_INTE, 0);
+
+	/* Ensure VDAC is turned off; power down DPI,VEC memories */
+	CFG_WRITE(VIDEO_OUT_CFG_VDAC_CFG, 0);
+	CFG_WRITE(VIDEO_OUT_CFG_MEM_PD, VIDEO_OUT_CFG_MEM_PD_BITS);
+}
--- /dev/null
+++ b/drivers/gpu/drm/rp1/rp1-vec/rp1_vec_hw.c
@@ -0,0 +1,580 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * DRM Driver for VEC output on Raspberry Pi RP1
+ *
+ * Copyright (c) 2023 Raspberry Pi Limited.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_print.h>
+#include <drm/drm_vblank.h>
+
+#include "rp1_vec.h"
+#include "vec_regs.h"
+
+#define BITS(field, val)    (((val) << (field ## _LSB)) & (field ## _BITS))
+#define VEC_WRITE(reg, val) writel((val), vec->hw_base[RP1VEC_HW_BLOCK_VEC] + (reg ## _OFFSET))
+#define VEC_READ(reg)	    readl(vec->hw_base[RP1VEC_HW_BLOCK_VEC] + (reg ## _OFFSET))
+
+static void rp1vec_write_regs(struct rp1_vec *vec, u32 offset, u32 const *vals, u32 num)
+{
+	while (num--) {
+		writel(*vals++, vec->hw_base[RP1VEC_HW_BLOCK_VEC] + offset);
+		offset += 4;
+	}
+}
+
+int rp1vec_hw_busy(struct rp1_vec *vec)
+{
+	/* Read the undocumented "pline_busy" flag */
+	return VEC_READ(VEC_STATUS) & 1;
+}
+
+/* Table of supported input (in-memory/DMA) pixel formats. */
+struct rp1vec_ipixfmt {
+	u32 format; /* DRM format code				 */
+	u32 mask;   /* RGB masks (10 bits each, left justified)	 */
+	u32 shift;  /* RGB MSB positions in the memory word	 */
+	u32 rgbsz;  /* Shifts used for scaling; also (BPP/8-1)	 */
+};
+
+#define MASK_RGB(r, g, b) \
+	(BITS(VEC_IMASK_MASK_R, r) | BITS(VEC_IMASK_MASK_G, g) | BITS(VEC_IMASK_MASK_B, b))
+#define SHIFT_RGB(r, g, b) \
+	(BITS(VEC_SHIFT_SHIFT_R, r) | BITS(VEC_SHIFT_SHIFT_G, g) | BITS(VEC_SHIFT_SHIFT_B, b))
+
+static const struct rp1vec_ipixfmt my_formats[] = {
+	{
+		.format = DRM_FORMAT_XRGB8888,
+		.mask	= MASK_RGB(0x3fc, 0x3fc, 0x3fc),
+		.shift	= SHIFT_RGB(23, 15, 7),
+		.rgbsz	= BITS(VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1, 3),
+	},
+	{
+		.format = DRM_FORMAT_XBGR8888,
+		.mask	= MASK_RGB(0x3fc, 0x3fc, 0x3fc),
+		.shift	= SHIFT_RGB(7, 15, 23),
+		.rgbsz	= BITS(VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1, 3),
+	},
+	{
+		.format = DRM_FORMAT_ARGB8888,
+		.mask	= MASK_RGB(0x3fc, 0x3fc, 0x3fc),
+		.shift	= SHIFT_RGB(23, 15, 7),
+		.rgbsz	= BITS(VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1, 3),
+	},
+	{
+		.format = DRM_FORMAT_ABGR8888,
+		.mask	= MASK_RGB(0x3fc, 0x3fc, 0x3fc),
+		.shift	= SHIFT_RGB(7, 15, 23),
+		.rgbsz	= BITS(VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1, 3),
+	},
+	{
+		.format = DRM_FORMAT_RGB888,
+		.mask	= MASK_RGB(0x3fc, 0x3fc, 0x3fc),
+		.shift	= SHIFT_RGB(23, 15, 7),
+		.rgbsz	= BITS(VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1, 2),
+	},
+	{
+		.format = DRM_FORMAT_BGR888,
+		.mask	= MASK_RGB(0x3fc, 0x3fc, 0x3fc),
+		.shift	= SHIFT_RGB(7, 15, 23),
+		.rgbsz	= BITS(VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1, 2),
+	},
+	{
+		.format = DRM_FORMAT_RGB565,
+		.mask	= MASK_RGB(0x3e0, 0x3f0, 0x3e0),
+		.shift	= SHIFT_RGB(15, 10, 4),
+		.rgbsz	= BITS(VEC_RGBSZ_SCALE_R, 5) |
+			  BITS(VEC_RGBSZ_SCALE_G, 6) |
+			  BITS(VEC_RGBSZ_SCALE_B, 5) |
+			  BITS(VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1, 1),
+	}
+};
+
+/*
+ * Hardware mode descriptions (@ 108 MHz VDAC clock)
+ * See "vec_regs.h" for further descriptions of these registers and fields.
+ * Driver should adjust some values for other TV standards and for pixel rate,
+ * and must ensure that ((de_end - de_bgn) % rate) == 0.
+ */
+
+struct rp1vec_hwmode {
+	u16  max_rows_per_field;   /* active lines per field (including partial ones)  */
+	u16  ref_vfp;		   /* nominal (vsync_start - vdisplay) when max height */
+	bool interlaced;	   /* set for interlaced			       */
+	bool first_field_odd;	   /* depends confusingly on line numbering convention */
+	s16  scale_v;		   /* V scale in 2.8 format (for power-of-2 CIC rates) */
+	s16  scale_u;		   /* U scale in 2.8 format (for power-of-2 CIC rates) */
+	u16  scale_y;		   /* Y scale in 2.8 format (for power-of-2 CIC rates) */
+	u16  de_end;		   /* end of horizontal Data Active period at 108MHz   */
+	u16  de_bgn;		   /* start of horizontal Data Active period	       */
+	u16  half_lines_per_field; /* number of half lines per field		       */
+	s16  pedestal;		   /* pedestal (1024 = 100IRE) including FIR overshoot */
+	u16  scale_luma;	   /* back end luma scaling in 1.15 format wrt DAC FSD */
+	u16  scale_sync;	   /* back end sync scaling / blanking level as above  */
+	u32  scale_burst_chroma;   /* back end { burst, chroma } scaling	       */
+	u32  misc;		   /* Contents of the "EC" register except rate,shift  */
+	u64  nco_freq;		   /* colour carrier frequency * (2**64) / 108MHz      */
+	u32  timing_regs[14];	   /* other back end registers 0x84 .. 0xB8	       */
+};
+
+/* { NTSC, PAL, PAL-M } x { progressive, interlaced } */
+static const struct rp1vec_hwmode rp1vec_hwmodes[3][2] = {
+	{
+		/* NTSC */
+		{
+			.max_rows_per_field = 240,
+			.ref_vfp = 2,
+			.interlaced = false,
+			.first_field_odd = false,
+			.scale_v = 0x0cf,
+			.scale_u = 0x074,
+			.scale_y = 0x107,
+			.de_end	 = 0x1a4f,
+			.de_bgn	 = 0x038f,
+			.half_lines_per_field = 524, /* also works with 526/2 lines */
+			.pedestal = 0x04c,
+			.scale_luma = 0x8c9a,
+			.scale_sync = 0x3851,
+			.scale_burst_chroma = 0x11195561,
+			.misc = 0x00090c00, /* 5-tap FIR, SEQ_EN, 4 fld sync */
+			.nco_freq = 0x087c1f07c1f07c1f,
+			.timing_regs = {
+				0x03e10cc6, 0x0d6801fb, 0x023d034c, 0x00f80b6d,
+				0x00000005, 0x0006000b, 0x000c0011, 0x000a0106,
+				0x00000000, 0x00000000, 0x00000000, 0x00000000,
+				0x00170106, 0x00000000
+			},
+		}, {
+			.max_rows_per_field = 243,
+			.ref_vfp = 3,
+			.interlaced = true,
+			.first_field_odd = true,
+			.scale_v = 0x0cf,
+			.scale_u = 0x074,
+			.scale_y = 0x107,
+			.de_end = 0x1a4f,
+			.de_bgn = 0x038f,
+			.half_lines_per_field = 525,
+			.pedestal = 0x04c,
+			.scale_luma = 0x8c9a,
+			.scale_sync = 0x3851,
+			.scale_burst_chroma = 0x11195561,
+			.misc = 0x00094c02, /* 5-tap FIR, SEQ_EN, 2 flds, 4 fld sync, ilace */
+			.nco_freq = 0x087c1f07c1f07c1f,
+			.timing_regs = {
+				0x03e10cc6, 0x0d6801fb, 0x023d034c, 0x00f80b6d,
+				0x00000005, 0x0006000b, 0x000c0011, 0x000a0107,
+				0x0111020d, 0x00000000, 0x00000000, 0x011c020d,
+				0x00150106, 0x0107011b,
+			},
+		},
+	}, {
+		/* PAL */
+		{
+			.max_rows_per_field = 288,
+			.ref_vfp = 2,
+			.interlaced = false,
+			.first_field_odd = false,
+			.scale_v = 0x0e0,
+			.scale_u = 0x07e,
+			.scale_y = 0x11c,
+			.de_end = 0x1ab6,
+			.de_bgn = 0x03f6,
+			.half_lines_per_field = 624,
+			.pedestal = 0x00a, /* nonzero for max FIR overshoot after CIC */
+			.scale_luma = 0x89d8,
+			.scale_sync = 0x3c00,
+			.scale_burst_chroma = 0x0caf53b5,
+			.misc = 0x00091c01, /* 5-tap FIR, SEQ_EN, 8 fld sync, PAL */
+			.nco_freq = 0x0a8262b2cc48c1d1,
+			.timing_regs = {
+				0x04660cee, 0x0d8001fb, 0x025c034f, 0x00fd0b84,
+				0x026c0270, 0x00000004, 0x00050009, 0x00070135,
+				0x00000000, 0x00000000, 0x00000000, 0x00000000,
+				0x00170136, 0x00000000,
+			},
+		}, {
+			.max_rows_per_field = 288,
+			.ref_vfp = 5,
+			.interlaced = true,
+			.first_field_odd = false,
+			.scale_v = 0x0e0,
+			.scale_u = 0x07e,
+			.scale_y = 0x11c,
+			.de_end = 0x1ab6,
+			.de_bgn = 0x03f6,
+			.half_lines_per_field = 625,
+			.pedestal = 0x00a,
+			.scale_luma = 0x89d8,
+			.scale_sync = 0x3c00,
+			.scale_burst_chroma = 0x0caf53b5,
+			.misc = 0x0009dc03, /* 5-tap FIR, SEQ_EN, 4 flds, 8 fld sync, ilace, PAL */
+			.nco_freq = 0x0a8262b2cc48c1d1,
+			.timing_regs = {
+				0x04660cee, 0x0d8001fb, 0x025c034f, 0x00fd0b84,
+				0x026c0270, 0x00000004, 0x00050009, 0x00070135,
+				0x013f026d, 0x00060136, 0x0140026e, 0x0150026e,
+				0x00180136, 0x026f0017,
+			},
+		},
+	}, {
+		/* PAL-M */
+		{
+			.max_rows_per_field = 240,
+			.ref_vfp = 2,
+			.interlaced = false,
+			.first_field_odd = false,
+			.scale_v = 0x0e0,
+			.scale_u = 0x07e,
+			.scale_y = 0x11c,
+			.de_end = 0x1a4f,
+			.de_bgn = 0x038f,
+			.half_lines_per_field = 524,
+			.pedestal = 0x00a,
+			.scale_luma = 0x89d8,
+			.scale_sync = 0x3851,
+			.scale_burst_chroma = 0x0d5c53b5,
+			.misc = 0x00091c01, /* 5-tap FIR, SEQ_EN, 8 fld sync PAL */
+			.nco_freq = 0x0879bbf8d6d33ea8,
+			.timing_regs = {
+				0x03e10cc6, 0x0d6801fb, 0x023c034c, 0x00f80b6e,
+				0x00000005, 0x0006000b, 0x000c0011, 0x000a0106,
+				0x00000000, 0x00000000, 0x00000000, 0x00000000,
+				0x00170106, 0x00000000,
+			},
+		}, {
+			.max_rows_per_field = 243,
+			.ref_vfp = 3,
+			.interlaced = true,
+			.first_field_odd = true,
+			.scale_v = 0x0e0,
+			.scale_u = 0x07e,
+			.scale_y = 0x11c,
+			.de_end = 0x1a4f,
+			.de_bgn = 0x038f,
+			.half_lines_per_field = 525,
+			.pedestal = 0x00a,
+			.scale_luma = 0x89d8,
+			.scale_sync = 0x3851,
+			.scale_burst_chroma = 0x0d5c53b5,
+			.misc = 0x0009dc03, /* 5-tap FIR, SEQ_EN, 4 flds, 8 fld sync, ilace, PAL */
+			.nco_freq = 0x0879bbf8d6d33ea8,
+			.timing_regs = {
+				0x03e10cc6, 0x0d6801fb, 0x023c034c, 0x00f80b6e,
+				0x00140019, 0x00000005, 0x0006000b, 0x00090103,
+				0x010f0209, 0x00080102, 0x010e020a, 0x0119020a,
+				0x00120103, 0x01040118,
+			},
+		},
+	},
+};
+
+/* System A, System E */
+static const struct rp1vec_hwmode rp1vec_vintage_modes[2] = {
+	{
+		.max_rows_per_field = 190,
+		.ref_vfp = 0,
+		.interlaced = true,
+		.first_field_odd = true,
+		.scale_v = 0,
+		.scale_u = 0,
+		.scale_y = 0x11c,
+		.de_end = 0x2920,
+		.de_bgn = 0x06a0,
+		.half_lines_per_field = 405,
+		.pedestal = 0x00a,
+		.scale_luma = 0x89d8,
+		.scale_sync = 0x3c00,
+		.scale_burst_chroma = 0,
+		.misc = 0x00084002, /* 5-tap FIR, 2 fields, interlace */
+		.nco_freq = 0,
+		.timing_regs = {
+			0x06f01430, 0x14d503cc, 0x00000000, 0x000010de,
+			0x00000000, 0x00000007, 0x00000000, 0x00000000,
+			0x00000000, 0x00000000, 0x00000000, 0x00d90195,
+			0x000e00ca, 0x00cb00d8,
+		},
+	}, {
+		.max_rows_per_field = 369,
+		.ref_vfp = 6,
+		.interlaced = true,
+		.first_field_odd = true,
+		.scale_v = 0,
+		.scale_u = 0,
+		.scale_y = 0x11c,
+		.de_end = 0x145f,
+		.de_bgn = 0x03a7,
+		.half_lines_per_field = 819,
+		.pedestal = 0x0010,
+		.scale_luma = 0x89d8,
+		.scale_sync = 0x3b13,
+		.scale_burst_chroma = 0,
+		.misc = 0x00084002, /* 5-tap FIR, 2 fields, interlace */
+		.nco_freq = 0,
+		.timing_regs = {
+			0x03c10a08, 0x0a4d0114, 0x00000000, 0x000008a6,
+			0x00000000, 0x00000000, 0x00000000, 0x00000000,
+			0x00000000, 0x00000000, 0x00000000, 0x01c10330,
+			0x00270196, 0x019701c0,
+		},
+	},
+};
+
+static const u32 rp1vec_fir_regs[4] = {
+	0x00000000, 0x0be20200, 0x20f0f800, 0x265c7f00,
+};
+
+/*
+ * Correction for the 4th order CIC filter's gain of (rate ** 4)
+ * expressed as a right-shift and a reciprocal scale factor (Q12).
+ * These arrays are indexed by [rate - 4] where 4 <= rate <= 16.
+ */
+
+static const int rp1vec_scale_table[13] = {
+	4096, 6711, 6473, 6988,
+	4096, 5114, 6711, 4584,
+	6473, 4699, 6988, 5302,
+	4096
+};
+
+static const u32 rp1vec_rate_shift_table[13] = {
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1,  3) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1,	7),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1,  4) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1,	9),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1,  5) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1, 10),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1,  6) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1, 11),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1,  7) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1, 11),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1,  8) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1, 12),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1,  9) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1, 13),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1, 10) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1, 13),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1, 11) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1, 14),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1, 12) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1, 14),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1, 13) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1, 15),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1, 14) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1, 15),
+	BITS(VEC_DAC_EC_INTERP_RATE_MINUS1, 15) | BITS(VEC_DAC_EC_INTERP_SHIFT_MINUS1, 15),
+};
+
+void rp1vec_hw_setup(struct rp1_vec *vec,
+		     u32 in_format,
+		     struct drm_display_mode const *mode,
+		     int tvstd)
+{
+	int i, mode_family, w, h;
+	const struct rp1vec_hwmode *hwm;
+	int wmax, hpad_r, vpad_b, rate, ref_2mid, usr_2mid;
+	u32 misc;
+
+	/* Input pixel format conversion */
+	for (i = 0; i < ARRAY_SIZE(my_formats); ++i) {
+		if (my_formats[i].format == in_format)
+			break;
+	}
+	if (i >= ARRAY_SIZE(my_formats)) {
+		dev_err(&vec->pdev->dev, "%s: bad input format\n", __func__);
+		i = 0;
+	}
+	VEC_WRITE(VEC_IMASK, my_formats[i].mask);
+	VEC_WRITE(VEC_SHIFT, my_formats[i].shift);
+	VEC_WRITE(VEC_RGBSZ, my_formats[i].rgbsz);
+
+	/* Pick an appropriate "base" mode, which we may modify.
+	 * Note that this driver supports a limited selection of video modes.
+	 * (A complete TV mode cannot be directly inferred from a DRM display mode:
+	 * features such as chroma burst sequence, half-lines and equalizing pulses
+	 * would be under-specified, and timings prone to rounding errors.)
+	 */
+	if (mode->vtotal == 405 || mode->vtotal == 819) {
+		/* Systems A and E (interlaced only) */
+		vec->fake_31khz = false;
+		mode_family = 1;
+		hwm = &rp1vec_vintage_modes[(mode->vtotal == 819) ? 1 : 0];
+	} else {
+		/* 525- and 625-line modes, with half-height and "fake" progressive variants */
+		vec->fake_31khz = mode->vtotal >= 500 && !(mode->flags & DRM_MODE_FLAG_INTERLACE);
+		h = (mode->vtotal >= 500) ? (mode->vtotal >> 1) : mode->vtotal;
+		if (h >= 272)
+			mode_family = 1; /* PAL-625 */
+		else if (tvstd == DRM_MODE_TV_MODE_PAL_M || tvstd == DRM_MODE_TV_MODE_PAL)
+			mode_family = 2; /* PAL-525 */
+		else
+			mode_family = 0; /* NTSC-525 */
+		hwm = &rp1vec_hwmodes[mode_family][(mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0];
+	}
+
+	/*
+	 * Choose the upsampling rate (to 108MHz) in the range 4..16.
+	 * Clip dimensions to the limits of the chosen hardware mode, then add
+	 * padding as required, making some attempt to respect the DRM mode's
+	 * display position (relative to H and V sync start). Note that "wmax"
+	 * should be wider than the horizontal active region, to avoid boundary
+	 * artifacts (e.g. wmax = 728, w = 720, active ~= 704 in Rec.601 modes).
+	 */
+	i = (vec->fake_31khz) ? (mode->clock >> 1) : mode->clock;
+	rate = (i < (RP1VEC_VDAC_KHZ / 16)) ? 16 : max(4, (RP1VEC_VDAC_KHZ + 256) / i);
+	wmax = min((hwm->de_end - hwm->de_bgn) / rate, 1020);
+	w = min(mode->hdisplay, wmax);
+	ref_2mid = (hwm->de_bgn + hwm->de_end) / rate + 4; /* + 4 for FIR delay */
+	usr_2mid = (2 * (mode->htotal - mode->hsync_start) + w) * 2 * (hwm->timing_regs[1] >> 16) /
+		(rate * mode->htotal);
+	hpad_r = (wmax - w + ref_2mid - usr_2mid) >> 1;
+	hpad_r = min(max(0, hpad_r), wmax - w);
+	h = mode->vdisplay >> (hwm->interlaced || vec->fake_31khz);
+	h = min(h, 0 + hwm->max_rows_per_field);
+	vpad_b = ((mode->vsync_start - hwm->ref_vfp) >> (hwm->interlaced || vec->fake_31khz)) - h;
+	vpad_b = min(max(0, vpad_b), hwm->max_rows_per_field - h);
+
+	/* Configure the hardware "front end" (in the sysclock domain) */
+	VEC_WRITE(VEC_APB_TIMEOUT, 0x38);
+	VEC_WRITE(VEC_QOS,
+		  BITS(VEC_QOS_DQOS, 0x0) |
+		  BITS(VEC_QOS_ULEV, 0x8) |
+		  BITS(VEC_QOS_UQOS, 0x2) |
+		  BITS(VEC_QOS_LLEV, 0x4) |
+		  BITS(VEC_QOS_LQOS, 0x7));
+	VEC_WRITE(VEC_DMA_AREA,
+		  BITS(VEC_DMA_AREA_COLS_MINUS1, w - 1) |
+		  BITS(VEC_DMA_AREA_ROWS_PER_FIELD_MINUS1, h - 1));
+	VEC_WRITE(VEC_YUV_SCALING,
+		  BITS(VEC_YUV_SCALING_U10_SCALE_Y,
+		       (hwm->scale_y * rp1vec_scale_table[rate - 4] + 2048) >> 12) |
+		  BITS(VEC_YUV_SCALING_S10_SCALE_U,
+		       (hwm->scale_u * rp1vec_scale_table[rate - 4] + 2048) >> 12) |
+		  BITS(VEC_YUV_SCALING_S10_SCALE_V,
+		       (hwm->scale_v * rp1vec_scale_table[rate - 4] + 2048) >> 12));
+	VEC_WRITE(VEC_BACK_PORCH,
+		  BITS(VEC_BACK_PORCH_HBP_MINUS1, wmax - w - hpad_r - 1) |
+		  BITS(VEC_BACK_PORCH_VBP_MINUS1, hwm->max_rows_per_field - h - vpad_b - 1));
+	VEC_WRITE(VEC_FRONT_PORCH,
+		  BITS(VEC_FRONT_PORCH_HFP_MINUS1, hpad_r - 1) |
+		  BITS(VEC_FRONT_PORCH_VFP_MINUS1, vpad_b - 1));
+	VEC_WRITE(VEC_MODE,
+		  BITS(VEC_MODE_HIGH_WATER, 0xE0)				|
+		  BITS(VEC_MODE_ALIGN16, !((w | mode->hdisplay) & 15))		|
+		  BITS(VEC_MODE_VFP_EN, (vpad_b > 0))				|
+		  BITS(VEC_MODE_VBP_EN, (hwm->max_rows_per_field > h + vpad_b)) |
+		  BITS(VEC_MODE_HFP_EN, (hpad_r > 0))				|
+		  BITS(VEC_MODE_HBP_EN, (wmax > w + hpad_r))			|
+		  BITS(VEC_MODE_FIELDS_PER_FRAME_MINUS1, hwm->interlaced)	|
+		  BITS(VEC_MODE_FIRST_FIELD_ODD, hwm->first_field_odd));
+
+	/* Configure the hardware "back end" (in the VDAC clock domain) */
+	VEC_WRITE(VEC_DAC_80,
+		  BITS(VEC_DAC_80_U14_DE_BGN, hwm->de_bgn) |
+		  BITS(VEC_DAC_80_U14_DE_END, hwm->de_bgn + wmax * rate));
+	rp1vec_write_regs(vec, 0x84, hwm->timing_regs, ARRAY_SIZE(hwm->timing_regs));
+	VEC_WRITE(VEC_DAC_C0, 0x0); /* DAC control/status -- not wired up in RP1 */
+	VEC_WRITE(VEC_DAC_C4, 0x007bffff); /* DAC control -- not wired up in RP1 */
+	misc = hwm->half_lines_per_field;
+	if (misc == 524 && (mode->vtotal >> vec->fake_31khz) == 263)
+		misc += 2;
+	if (tvstd == DRM_MODE_TV_MODE_NTSC_J && mode_family == 0) {
+		/* NTSC-J modification: reduce pedestal and increase gain */
+		VEC_WRITE(VEC_DAC_BC,
+			  BITS(VEC_DAC_BC_U11_HALF_LINES_PER_FIELD, misc) |
+			  BITS(VEC_DAC_BC_S11_PEDESTAL, 0x00a));
+		VEC_WRITE(VEC_DAC_C8,
+			  BITS(VEC_DAC_C8_U16_SCALE_LUMA, 0x9400) |
+			  BITS(VEC_DAC_C8_U16_SCALE_SYNC, hwm->scale_sync));
+	} else {
+		VEC_WRITE(VEC_DAC_BC,
+			  BITS(VEC_DAC_BC_U11_HALF_LINES_PER_FIELD, misc) |
+			  BITS(VEC_DAC_BC_S11_PEDESTAL, hwm->pedestal));
+		VEC_WRITE(VEC_DAC_C8,
+			  BITS(VEC_DAC_C8_U16_SCALE_LUMA, hwm->scale_luma) |
+			  BITS(VEC_DAC_C8_U16_SCALE_SYNC, hwm->scale_sync));
+	}
+	VEC_WRITE(VEC_DAC_CC, (tvstd >= DRM_MODE_TV_MODE_SECAM) ? 0 : hwm->scale_burst_chroma);
+	VEC_WRITE(VEC_DAC_D0, 0x02000000); /* ADC offsets -- not needed in RP1? */
+	misc = hwm->misc;
+	if ((tvstd == DRM_MODE_TV_MODE_NTSC_443 || tvstd == DRM_MODE_TV_MODE_PAL) &&
+	    mode_family != 1) {
+		/* Change colour carrier frequency to 4433618.75 Hz; disable hard sync */
+		VEC_WRITE(VEC_DAC_D4, 0xcc48c1d1);
+		VEC_WRITE(VEC_DAC_D8, 0x0a8262b2);
+		misc &= ~VEC_DAC_EC_SEQ_EN_BITS;
+	} else if (tvstd == DRM_MODE_TV_MODE_PAL_N && mode_family == 1) {
+		/* Change colour carrier frequency to 3582056.25 Hz */
+		VEC_WRITE(VEC_DAC_D4, 0x9ce075f7);
+		VEC_WRITE(VEC_DAC_D8, 0x087da511);
+	} else {
+		VEC_WRITE(VEC_DAC_D4, (u32)(hwm->nco_freq));
+		VEC_WRITE(VEC_DAC_D8, (u32)(hwm->nco_freq >> 32));
+	}
+	VEC_WRITE(VEC_DAC_EC, misc | rp1vec_rate_shift_table[rate - 4]);
+	rp1vec_write_regs(vec, 0xDC, rp1vec_fir_regs, ARRAY_SIZE(rp1vec_fir_regs));
+
+	/* Set up interrupts and initialise VEC. It will start on the next rp1vec_hw_update() */
+	VEC_WRITE(VEC_IRQ_FLAGS, 0xFFFFFFFFu);
+	rp1vec_hw_vblank_ctrl(vec, 1);
+	i = rp1vec_hw_busy(vec);
+	if (i)
+		dev_warn(&vec->pdev->dev,
+			 "%s: VEC unexpectedly busy at start (0x%08x)",
+			__func__, VEC_READ(VEC_STATUS));
+
+	VEC_WRITE(VEC_CONTROL,
+		  BITS(VEC_CONTROL_START_ARM, (!i)) |
+		  BITS(VEC_CONTROL_AUTO_REPEAT, 1));
+}
+
+void rp1vec_hw_update(struct rp1_vec *vec, dma_addr_t addr, u32 offset, u32 stride)
+{
+	/*
+	 * Update STRIDE, DMAH and DMAL only. When called after rp1vec_hw_setup(),
+	 * DMA starts immediately; if already running, the buffer will flip at
+	 * the next vertical sync event.
+	 */
+	u64 a = addr + offset;
+
+	if (vec->fake_31khz) {
+		a += stride;
+		stride *= 2;
+	}
+	VEC_WRITE(VEC_DMA_STRIDE, stride);
+	VEC_WRITE(VEC_DMA_ADDR_H, a >> 32);
+	VEC_WRITE(VEC_DMA_ADDR_L, a & 0xFFFFFFFFu);
+}
+
+void rp1vec_hw_stop(struct rp1_vec *vec)
+{
+	/*
+	 * Stop DMA by turning off the Auto-Repeat flag, and wait up to 100ms for
+	 * the current and any queued frame to end. "Force drain" flags are not used,
+	 * as they seem to prevent DMA from re-starting properly; it's safer to wait.
+	 */
+
+	reinit_completion(&vec->finished);
+	VEC_WRITE(VEC_CONTROL, 0);
+	if (!wait_for_completion_timeout(&vec->finished, HZ / 10))
+		drm_err(&vec->drm, "%s: timed out waiting for idle\n", __func__);
+	VEC_WRITE(VEC_IRQ_ENABLES, 0);
+}
+
+void rp1vec_hw_vblank_ctrl(struct rp1_vec *vec, int enable)
+{
+	VEC_WRITE(VEC_IRQ_ENABLES,
+		  BITS(VEC_IRQ_ENABLES_DONE, 1) |
+		  BITS(VEC_IRQ_ENABLES_DMA, (enable ? 1 : 0)) |
+		  BITS(VEC_IRQ_ENABLES_MATCH_ROW, 1023));
+}
+
+irqreturn_t rp1vec_hw_isr(int irq, void *dev)
+{
+	struct rp1_vec *vec = dev;
+	u32 u = VEC_READ(VEC_IRQ_FLAGS);
+
+	if (u) {
+		VEC_WRITE(VEC_IRQ_FLAGS, u);
+		if (u & VEC_IRQ_FLAGS_DMA_BITS)
+			drm_crtc_handle_vblank(&vec->pipe.crtc);
+		if (u & VEC_IRQ_FLAGS_DONE_BITS)
+			complete(&vec->finished);
+	}
+	return u ? IRQ_HANDLED : IRQ_NONE;
+}
--- /dev/null
+++ b/drivers/gpu/drm/rp1/rp1-vec/vec_regs.h
@@ -0,0 +1,1420 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+// =============================================================================
+// Copyright Raspberry Pi Ltd. 2023
+// vrbuild version: 56aac1a23c016cbbd229108f3b6efc1343842156-clean
+// THIS FILE IS GENERATED BY VRBUILD - DO NOT EDIT
+// =============================================================================
+// Register block : VEC
+// Version        : 1
+// Bus type       : apb
+// Description    : None
+// =============================================================================
+#ifndef VEC_REGS_DEFINED
+#define VEC_REGS_DEFINED
+#define VEC_REGS_RWTYPE_MSB 13
+#define VEC_REGS_RWTYPE_LSB 12
+// =============================================================================
+// Register    : VEC_CONTROL
+// JTAG access : synchronous
+// Description : None
+#define VEC_CONTROL_OFFSET 0x00000000
+#define VEC_CONTROL_BITS   0x00000007
+#define VEC_CONTROL_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_CONTROL_BARS
+// Description : Write '1' to display colour bar test pattern
+#define VEC_CONTROL_BARS_RESET  0x0
+#define VEC_CONTROL_BARS_BITS   0x00000004
+#define VEC_CONTROL_BARS_MSB    2
+#define VEC_CONTROL_BARS_LSB    2
+#define VEC_CONTROL_BARS_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_CONTROL_AUTO_REPEAT
+// Description : Write '1' to re-display same frame continuously
+#define VEC_CONTROL_AUTO_REPEAT_RESET  0x0
+#define VEC_CONTROL_AUTO_REPEAT_BITS   0x00000002
+#define VEC_CONTROL_AUTO_REPEAT_MSB    1
+#define VEC_CONTROL_AUTO_REPEAT_LSB    1
+#define VEC_CONTROL_AUTO_REPEAT_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_CONTROL_START_ARM
+// Description : Write '1' before first DMA address is written This bit always
+//               reads back as '0'
+#define VEC_CONTROL_START_ARM_RESET  0x0
+#define VEC_CONTROL_START_ARM_BITS   0x00000001
+#define VEC_CONTROL_START_ARM_MSB    0
+#define VEC_CONTROL_START_ARM_LSB    0
+#define VEC_CONTROL_START_ARM_ACCESS "SC"
+// =============================================================================
+// Register    : VEC_IRQ_ENABLES
+// JTAG access : synchronous
+// Description : None
+#define VEC_IRQ_ENABLES_OFFSET 0x00000004
+#define VEC_IRQ_ENABLES_BITS   0x03ff003f
+#define VEC_IRQ_ENABLES_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_ENABLES_MATCH_ROW
+// Description : Raster line at which MATCH interrupt is signalled
+#define VEC_IRQ_ENABLES_MATCH_ROW_RESET  0x000
+#define VEC_IRQ_ENABLES_MATCH_ROW_BITS   0x03ff0000
+#define VEC_IRQ_ENABLES_MATCH_ROW_MSB    25
+#define VEC_IRQ_ENABLES_MATCH_ROW_LSB    16
+#define VEC_IRQ_ENABLES_MATCH_ROW_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_ENABLES_MATCH
+// Description : Output raster == match_row reached
+#define VEC_IRQ_ENABLES_MATCH_RESET  0x0
+#define VEC_IRQ_ENABLES_MATCH_BITS   0x00000020
+#define VEC_IRQ_ENABLES_MATCH_MSB    5
+#define VEC_IRQ_ENABLES_MATCH_LSB    5
+#define VEC_IRQ_ENABLES_MATCH_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_ENABLES_ERROR
+// Description : DMA address overwritten before it was taken
+#define VEC_IRQ_ENABLES_ERROR_RESET  0x0
+#define VEC_IRQ_ENABLES_ERROR_BITS   0x00000010
+#define VEC_IRQ_ENABLES_ERROR_MSB    4
+#define VEC_IRQ_ENABLES_ERROR_LSB    4
+#define VEC_IRQ_ENABLES_ERROR_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_ENABLES_DONE
+// Description : Last word sent to DAC after end of video (= all clear)
+#define VEC_IRQ_ENABLES_DONE_RESET  0x0
+#define VEC_IRQ_ENABLES_DONE_BITS   0x00000008
+#define VEC_IRQ_ENABLES_DONE_MSB    3
+#define VEC_IRQ_ENABLES_DONE_LSB    3
+#define VEC_IRQ_ENABLES_DONE_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_ENABLES_FRAME
+// Description : Start of frame
+#define VEC_IRQ_ENABLES_FRAME_RESET  0x0
+#define VEC_IRQ_ENABLES_FRAME_BITS   0x00000004
+#define VEC_IRQ_ENABLES_FRAME_MSB    2
+#define VEC_IRQ_ENABLES_FRAME_LSB    2
+#define VEC_IRQ_ENABLES_FRAME_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_ENABLES_UNDERFLOW
+// Description : Underflow has occurred
+#define VEC_IRQ_ENABLES_UNDERFLOW_RESET  0x0
+#define VEC_IRQ_ENABLES_UNDERFLOW_BITS   0x00000002
+#define VEC_IRQ_ENABLES_UNDERFLOW_MSB    1
+#define VEC_IRQ_ENABLES_UNDERFLOW_LSB    1
+#define VEC_IRQ_ENABLES_UNDERFLOW_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_ENABLES_DMA
+// Description : DMA ready to accept next frame start address
+#define VEC_IRQ_ENABLES_DMA_RESET  0x0
+#define VEC_IRQ_ENABLES_DMA_BITS   0x00000001
+#define VEC_IRQ_ENABLES_DMA_MSB    0
+#define VEC_IRQ_ENABLES_DMA_LSB    0
+#define VEC_IRQ_ENABLES_DMA_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_IRQ_FLAGS
+// JTAG access : synchronous
+// Description : None
+#define VEC_IRQ_FLAGS_OFFSET 0x00000008
+#define VEC_IRQ_FLAGS_BITS   0x0000003f
+#define VEC_IRQ_FLAGS_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_FLAGS_MATCH
+// Description : Output raster == match_row reached
+#define VEC_IRQ_FLAGS_MATCH_RESET  0x0
+#define VEC_IRQ_FLAGS_MATCH_BITS   0x00000020
+#define VEC_IRQ_FLAGS_MATCH_MSB    5
+#define VEC_IRQ_FLAGS_MATCH_LSB    5
+#define VEC_IRQ_FLAGS_MATCH_ACCESS "WC"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_FLAGS_ERROR
+// Description : DMA address overwritten before it was taken
+#define VEC_IRQ_FLAGS_ERROR_RESET  0x0
+#define VEC_IRQ_FLAGS_ERROR_BITS   0x00000010
+#define VEC_IRQ_FLAGS_ERROR_MSB    4
+#define VEC_IRQ_FLAGS_ERROR_LSB    4
+#define VEC_IRQ_FLAGS_ERROR_ACCESS "WC"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_FLAGS_DONE
+// Description : Last word sent to DAC after end of video (= all clear)
+#define VEC_IRQ_FLAGS_DONE_RESET  0x0
+#define VEC_IRQ_FLAGS_DONE_BITS   0x00000008
+#define VEC_IRQ_FLAGS_DONE_MSB    3
+#define VEC_IRQ_FLAGS_DONE_LSB    3
+#define VEC_IRQ_FLAGS_DONE_ACCESS "WC"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_FLAGS_FRAME
+// Description : Start of frame
+#define VEC_IRQ_FLAGS_FRAME_RESET  0x0
+#define VEC_IRQ_FLAGS_FRAME_BITS   0x00000004
+#define VEC_IRQ_FLAGS_FRAME_MSB    2
+#define VEC_IRQ_FLAGS_FRAME_LSB    2
+#define VEC_IRQ_FLAGS_FRAME_ACCESS "WC"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_FLAGS_UNDERFLOW
+// Description : Underflow has occurred
+#define VEC_IRQ_FLAGS_UNDERFLOW_RESET  0x0
+#define VEC_IRQ_FLAGS_UNDERFLOW_BITS   0x00000002
+#define VEC_IRQ_FLAGS_UNDERFLOW_MSB    1
+#define VEC_IRQ_FLAGS_UNDERFLOW_LSB    1
+#define VEC_IRQ_FLAGS_UNDERFLOW_ACCESS "WC"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IRQ_FLAGS_DMA
+// Description : DMA ready to accept next frame start address
+#define VEC_IRQ_FLAGS_DMA_RESET  0x0
+#define VEC_IRQ_FLAGS_DMA_BITS   0x00000001
+#define VEC_IRQ_FLAGS_DMA_MSB    0
+#define VEC_IRQ_FLAGS_DMA_LSB    0
+#define VEC_IRQ_FLAGS_DMA_ACCESS "WC"
+// =============================================================================
+// Register    : VEC_QOS
+// JTAG access : synchronous
+// Description : This register configures panic levels for the AXI ar_qos
+//               quality of service field. Panic status is driven by the number
+//               of rows held in the SRAM cache:
+#define VEC_QOS_OFFSET 0x0000000c
+#define VEC_QOS_BITS   0x000fffff
+#define VEC_QOS_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_QOS_UQOS
+// Description : Upper AXI QOS
+#define VEC_QOS_UQOS_RESET  0x0
+#define VEC_QOS_UQOS_BITS   0x000f0000
+#define VEC_QOS_UQOS_MSB    19
+#define VEC_QOS_UQOS_LSB    16
+#define VEC_QOS_UQOS_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_QOS_ULEV
+// Description : Upper trip level (resolution = 1 / 16 of cache size)
+#define VEC_QOS_ULEV_RESET  0x0
+#define VEC_QOS_ULEV_BITS   0x0000f000
+#define VEC_QOS_ULEV_MSB    15
+#define VEC_QOS_ULEV_LSB    12
+#define VEC_QOS_ULEV_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_QOS_LQOS
+// Description : Lower AXI QOS
+#define VEC_QOS_LQOS_RESET  0x0
+#define VEC_QOS_LQOS_BITS   0x00000f00
+#define VEC_QOS_LQOS_MSB    11
+#define VEC_QOS_LQOS_LSB    8
+#define VEC_QOS_LQOS_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_QOS_LLEV
+// Description : Lower trip level (resolution = 1 / 16 of cache size)
+#define VEC_QOS_LLEV_RESET  0x0
+#define VEC_QOS_LLEV_BITS   0x000000f0
+#define VEC_QOS_LLEV_MSB    7
+#define VEC_QOS_LLEV_LSB    4
+#define VEC_QOS_LLEV_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_QOS_DQOS
+// Description : Default QOS
+#define VEC_QOS_DQOS_RESET  0x0
+#define VEC_QOS_DQOS_BITS   0x0000000f
+#define VEC_QOS_DQOS_MSB    3
+#define VEC_QOS_DQOS_LSB    0
+#define VEC_QOS_DQOS_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DMA_ADDR_L
+// JTAG access : synchronous
+// Description : Lower 32-bits
+#define VEC_DMA_ADDR_L_OFFSET 0x00000010
+#define VEC_DMA_ADDR_L_BITS   0xffffffff
+#define VEC_DMA_ADDR_L_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DMA_ADDR_L_AXI_ADDR
+// Description : Byte address of DMA transfer frame buffer.
+#define VEC_DMA_ADDR_L_AXI_ADDR_RESET  0x00000000
+#define VEC_DMA_ADDR_L_AXI_ADDR_BITS   0xffffffff
+#define VEC_DMA_ADDR_L_AXI_ADDR_MSB    31
+#define VEC_DMA_ADDR_L_AXI_ADDR_LSB    0
+#define VEC_DMA_ADDR_L_AXI_ADDR_ACCESS "RWF"
+// =============================================================================
+// Register    : VEC_DMA_STRIDE
+// JTAG access : synchronous
+// Description : This register sets the line byte stride.
+#define VEC_DMA_STRIDE_OFFSET 0x00000014
+#define VEC_DMA_STRIDE_BITS   0xffffffff
+#define VEC_DMA_STRIDE_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DMA_STRIDE_STRIDE
+// Description : Byte stride
+#define VEC_DMA_STRIDE_STRIDE_RESET  0x00000000
+#define VEC_DMA_STRIDE_STRIDE_BITS   0xffffffff
+#define VEC_DMA_STRIDE_STRIDE_MSB    31
+#define VEC_DMA_STRIDE_STRIDE_LSB    0
+#define VEC_DMA_STRIDE_STRIDE_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DMA_AREA
+// JTAG access : synchronous
+// Description : Interlaced pixel area. See example driver code.
+#define VEC_DMA_AREA_OFFSET 0x00000018
+#define VEC_DMA_AREA_BITS   0x03ff03ff
+#define VEC_DMA_AREA_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DMA_AREA_COLS_MINUS1
+// Description : Width
+#define VEC_DMA_AREA_COLS_MINUS1_RESET  0x000
+#define VEC_DMA_AREA_COLS_MINUS1_BITS   0x03ff0000
+#define VEC_DMA_AREA_COLS_MINUS1_MSB    25
+#define VEC_DMA_AREA_COLS_MINUS1_LSB    16
+#define VEC_DMA_AREA_COLS_MINUS1_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DMA_AREA_ROWS_PER_FIELD_MINUS1
+// Description : Lines per field = half of lines per interlaced frame
+#define VEC_DMA_AREA_ROWS_PER_FIELD_MINUS1_RESET  0x000
+#define VEC_DMA_AREA_ROWS_PER_FIELD_MINUS1_BITS   0x000003ff
+#define VEC_DMA_AREA_ROWS_PER_FIELD_MINUS1_MSB    9
+#define VEC_DMA_AREA_ROWS_PER_FIELD_MINUS1_LSB    0
+#define VEC_DMA_AREA_ROWS_PER_FIELD_MINUS1_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_YUV_SCALING
+// JTAG access : synchronous
+// Description : None
+#define VEC_YUV_SCALING_OFFSET 0x0000001c
+#define VEC_YUV_SCALING_BITS   0x3fffffff
+#define VEC_YUV_SCALING_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_YUV_SCALING_U10_SCALE_Y
+// Description : Y unsigned scaling factor - 8 binary places
+#define VEC_YUV_SCALING_U10_SCALE_Y_RESET  0x000
+#define VEC_YUV_SCALING_U10_SCALE_Y_BITS   0x3ff00000
+#define VEC_YUV_SCALING_U10_SCALE_Y_MSB    29
+#define VEC_YUV_SCALING_U10_SCALE_Y_LSB    20
+#define VEC_YUV_SCALING_U10_SCALE_Y_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_YUV_SCALING_S10_SCALE_U
+// Description : U signed scaling factor - 8 binary places
+#define VEC_YUV_SCALING_S10_SCALE_U_RESET  0x000
+#define VEC_YUV_SCALING_S10_SCALE_U_BITS   0x000ffc00
+#define VEC_YUV_SCALING_S10_SCALE_U_MSB    19
+#define VEC_YUV_SCALING_S10_SCALE_U_LSB    10
+#define VEC_YUV_SCALING_S10_SCALE_U_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_YUV_SCALING_S10_SCALE_V
+// Description : V signed scaling factor - 8 binary please
+#define VEC_YUV_SCALING_S10_SCALE_V_RESET  0x000
+#define VEC_YUV_SCALING_S10_SCALE_V_BITS   0x000003ff
+#define VEC_YUV_SCALING_S10_SCALE_V_MSB    9
+#define VEC_YUV_SCALING_S10_SCALE_V_LSB    0
+#define VEC_YUV_SCALING_S10_SCALE_V_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_BACK_PORCH
+// JTAG access : synchronous
+// Description : None
+#define VEC_BACK_PORCH_OFFSET 0x00000020
+#define VEC_BACK_PORCH_BITS   0x03ff03ff
+#define VEC_BACK_PORCH_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_BACK_PORCH_HBP_MINUS1
+// Description : Horizontal back porch
+#define VEC_BACK_PORCH_HBP_MINUS1_RESET  0x000
+#define VEC_BACK_PORCH_HBP_MINUS1_BITS   0x03ff0000
+#define VEC_BACK_PORCH_HBP_MINUS1_MSB    25
+#define VEC_BACK_PORCH_HBP_MINUS1_LSB    16
+#define VEC_BACK_PORCH_HBP_MINUS1_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_BACK_PORCH_VBP_MINUS1
+// Description : Vertical back porch
+#define VEC_BACK_PORCH_VBP_MINUS1_RESET  0x000
+#define VEC_BACK_PORCH_VBP_MINUS1_BITS   0x000003ff
+#define VEC_BACK_PORCH_VBP_MINUS1_MSB    9
+#define VEC_BACK_PORCH_VBP_MINUS1_LSB    0
+#define VEC_BACK_PORCH_VBP_MINUS1_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_FRONT_PORCH
+// JTAG access : synchronous
+// Description : None
+#define VEC_FRONT_PORCH_OFFSET 0x00000024
+#define VEC_FRONT_PORCH_BITS   0x03ff03ff
+#define VEC_FRONT_PORCH_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_FRONT_PORCH_HFP_MINUS1
+// Description : Horizontal front porch
+#define VEC_FRONT_PORCH_HFP_MINUS1_RESET  0x000
+#define VEC_FRONT_PORCH_HFP_MINUS1_BITS   0x03ff0000
+#define VEC_FRONT_PORCH_HFP_MINUS1_MSB    25
+#define VEC_FRONT_PORCH_HFP_MINUS1_LSB    16
+#define VEC_FRONT_PORCH_HFP_MINUS1_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_FRONT_PORCH_VFP_MINUS1
+// Description : Vertical front porch
+#define VEC_FRONT_PORCH_VFP_MINUS1_RESET  0x000
+#define VEC_FRONT_PORCH_VFP_MINUS1_BITS   0x000003ff
+#define VEC_FRONT_PORCH_VFP_MINUS1_MSB    9
+#define VEC_FRONT_PORCH_VFP_MINUS1_LSB    0
+#define VEC_FRONT_PORCH_VFP_MINUS1_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_SHIFT
+// JTAG access : synchronous
+// Description : Positions of R,G,B MS bits in the memory word. Note: due to an
+//               unintended red/blue swap, these fields have been renamed since
+//               a previous version. There is no functional change.
+#define VEC_SHIFT_OFFSET 0x00000028
+#define VEC_SHIFT_BITS   0x00007fff
+#define VEC_SHIFT_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_SHIFT_SHIFT_R
+// Description : Red MSB
+#define VEC_SHIFT_SHIFT_R_RESET  0x00
+#define VEC_SHIFT_SHIFT_R_BITS   0x00007c00
+#define VEC_SHIFT_SHIFT_R_MSB    14
+#define VEC_SHIFT_SHIFT_R_LSB    10
+#define VEC_SHIFT_SHIFT_R_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_SHIFT_SHIFT_G
+// Description : Green MSB
+#define VEC_SHIFT_SHIFT_G_RESET  0x00
+#define VEC_SHIFT_SHIFT_G_BITS   0x000003e0
+#define VEC_SHIFT_SHIFT_G_MSB    9
+#define VEC_SHIFT_SHIFT_G_LSB    5
+#define VEC_SHIFT_SHIFT_G_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_SHIFT_SHIFT_B
+// Description : Blue MSB
+#define VEC_SHIFT_SHIFT_B_RESET  0x00
+#define VEC_SHIFT_SHIFT_B_BITS   0x0000001f
+#define VEC_SHIFT_SHIFT_B_MSB    4
+#define VEC_SHIFT_SHIFT_B_LSB    0
+#define VEC_SHIFT_SHIFT_B_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_IMASK
+// JTAG access : synchronous
+// Description : Masks for R,G,B significant bits, left-justified within 10-bit
+//               fields.
+#define VEC_IMASK_OFFSET 0x0000002c
+#define VEC_IMASK_BITS   0x3fffffff
+#define VEC_IMASK_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_IMASK_MASK_R
+// Description : Red mask
+#define VEC_IMASK_MASK_R_RESET  0x000
+#define VEC_IMASK_MASK_R_BITS   0x3ff00000
+#define VEC_IMASK_MASK_R_MSB    29
+#define VEC_IMASK_MASK_R_LSB    20
+#define VEC_IMASK_MASK_R_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IMASK_MASK_G
+// Description : Green mask
+#define VEC_IMASK_MASK_G_RESET  0x000
+#define VEC_IMASK_MASK_G_BITS   0x000ffc00
+#define VEC_IMASK_MASK_G_MSB    19
+#define VEC_IMASK_MASK_G_LSB    10
+#define VEC_IMASK_MASK_G_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_IMASK_MASK_B
+// Description : Blue mask
+#define VEC_IMASK_MASK_B_RESET  0x000
+#define VEC_IMASK_MASK_B_BITS   0x000003ff
+#define VEC_IMASK_MASK_B_MSB    9
+#define VEC_IMASK_MASK_B_LSB    0
+#define VEC_IMASK_MASK_B_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_MODE
+// JTAG access : synchronous
+// Description : None
+#define VEC_MODE_OFFSET 0x00000030
+#define VEC_MODE_BITS   0x01ff003f
+#define VEC_MODE_RESET  0x01c00000
+// -----------------------------------------------------------------------------
+// Field       : VEC_MODE_HIGH_WATER
+// Description : ALWAYS WRITE 8'hE0
+#define VEC_MODE_HIGH_WATER_RESET  0xe0
+#define VEC_MODE_HIGH_WATER_BITS   0x01fe0000
+#define VEC_MODE_HIGH_WATER_MSB    24
+#define VEC_MODE_HIGH_WATER_LSB    17
+#define VEC_MODE_HIGH_WATER_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_MODE_ALIGN16
+// Description : Data: 0=BYTE aligned; 1=BEAT aligned
+#define VEC_MODE_ALIGN16_RESET  0x0
+#define VEC_MODE_ALIGN16_BITS   0x00010000
+#define VEC_MODE_ALIGN16_MSB    16
+#define VEC_MODE_ALIGN16_LSB    16
+#define VEC_MODE_ALIGN16_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_MODE_VFP_EN
+// Description : Enable vertical front porch
+#define VEC_MODE_VFP_EN_RESET  0x0
+#define VEC_MODE_VFP_EN_BITS   0x00000020
+#define VEC_MODE_VFP_EN_MSB    5
+#define VEC_MODE_VFP_EN_LSB    5
+#define VEC_MODE_VFP_EN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_MODE_VBP_EN
+// Description : Enable vertical back porch
+#define VEC_MODE_VBP_EN_RESET  0x0
+#define VEC_MODE_VBP_EN_BITS   0x00000010
+#define VEC_MODE_VBP_EN_MSB    4
+#define VEC_MODE_VBP_EN_LSB    4
+#define VEC_MODE_VBP_EN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_MODE_HFP_EN
+// Description : Enable horizontal front porch
+#define VEC_MODE_HFP_EN_RESET  0x0
+#define VEC_MODE_HFP_EN_BITS   0x00000008
+#define VEC_MODE_HFP_EN_MSB    3
+#define VEC_MODE_HFP_EN_LSB    3
+#define VEC_MODE_HFP_EN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_MODE_HBP_EN
+// Description : Enable horizontal back porch
+#define VEC_MODE_HBP_EN_RESET  0x0
+#define VEC_MODE_HBP_EN_BITS   0x00000004
+#define VEC_MODE_HBP_EN_MSB    2
+#define VEC_MODE_HBP_EN_LSB    2
+#define VEC_MODE_HBP_EN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_MODE_FIELDS_PER_FRAME_MINUS1
+// Description : Interlaced / progressive
+#define VEC_MODE_FIELDS_PER_FRAME_MINUS1_RESET  0x0
+#define VEC_MODE_FIELDS_PER_FRAME_MINUS1_BITS   0x00000002
+#define VEC_MODE_FIELDS_PER_FRAME_MINUS1_MSB    1
+#define VEC_MODE_FIELDS_PER_FRAME_MINUS1_LSB    1
+#define VEC_MODE_FIELDS_PER_FRAME_MINUS1_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_MODE_FIRST_FIELD_ODD
+// Description : Interlacing order: odd/even or even/odd
+#define VEC_MODE_FIRST_FIELD_ODD_RESET  0x0
+#define VEC_MODE_FIRST_FIELD_ODD_BITS   0x00000001
+#define VEC_MODE_FIRST_FIELD_ODD_MSB    0
+#define VEC_MODE_FIRST_FIELD_ODD_LSB    0
+#define VEC_MODE_FIRST_FIELD_ODD_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_RGBSZ
+// JTAG access : synchronous
+// Description : None
+#define VEC_RGBSZ_OFFSET 0x00000034
+#define VEC_RGBSZ_BITS   0x00030fff
+#define VEC_RGBSZ_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1
+// Description : Pixel stride
+#define VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1_RESET  0x0
+#define VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1_BITS   0x00030000
+#define VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1_MSB    17
+#define VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1_LSB    16
+#define VEC_RGBSZ_BYTES_PER_PIXEL_MINUS1_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_RGBSZ_SCALE_R
+// Description : Red number of bits for shift-and-OR scaling
+#define VEC_RGBSZ_SCALE_R_RESET  0x0
+#define VEC_RGBSZ_SCALE_R_BITS   0x00000f00
+#define VEC_RGBSZ_SCALE_R_MSB    11
+#define VEC_RGBSZ_SCALE_R_LSB    8
+#define VEC_RGBSZ_SCALE_R_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_RGBSZ_SCALE_G
+// Description : Green number of bits for shift-and-OR scaling
+#define VEC_RGBSZ_SCALE_G_RESET  0x0
+#define VEC_RGBSZ_SCALE_G_BITS   0x000000f0
+#define VEC_RGBSZ_SCALE_G_MSB    7
+#define VEC_RGBSZ_SCALE_G_LSB    4
+#define VEC_RGBSZ_SCALE_G_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_RGBSZ_SCALE_B
+// Description : Blue number of bits for shift-and-OR scaling
+#define VEC_RGBSZ_SCALE_B_RESET  0x0
+#define VEC_RGBSZ_SCALE_B_BITS   0x0000000f
+#define VEC_RGBSZ_SCALE_B_MSB    3
+#define VEC_RGBSZ_SCALE_B_LSB    0
+#define VEC_RGBSZ_SCALE_B_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_PANICS
+// JTAG access : synchronous
+// Description : None
+#define VEC_PANICS_OFFSET 0x00000038
+#define VEC_PANICS_BITS   0xffffffff
+#define VEC_PANICS_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_PANICS_UCOUNT
+// Description : Upper panic count
+#define VEC_PANICS_UCOUNT_RESET  0x0000
+#define VEC_PANICS_UCOUNT_BITS   0xffff0000
+#define VEC_PANICS_UCOUNT_MSB    31
+#define VEC_PANICS_UCOUNT_LSB    16
+#define VEC_PANICS_UCOUNT_ACCESS "WC"
+// -----------------------------------------------------------------------------
+// Field       : VEC_PANICS_LCOUNT
+// Description : Lower panic count
+#define VEC_PANICS_LCOUNT_RESET  0x0000
+#define VEC_PANICS_LCOUNT_BITS   0x0000ffff
+#define VEC_PANICS_LCOUNT_MSB    15
+#define VEC_PANICS_LCOUNT_LSB    0
+#define VEC_PANICS_LCOUNT_ACCESS "WC"
+// =============================================================================
+// Register    : VEC_STATUS
+// JTAG access : synchronous
+// Description : None
+#define VEC_STATUS_OFFSET 0x0000003c
+#define VEC_STATUS_BITS   0xff000000
+#define VEC_STATUS_RESET  0x0d000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_STATUS_VERSION
+// Description : VEC module version code
+#define VEC_STATUS_VERSION_RESET  0x0d
+#define VEC_STATUS_VERSION_BITS   0xff000000
+#define VEC_STATUS_VERSION_MSB    31
+#define VEC_STATUS_VERSION_LSB    24
+#define VEC_STATUS_VERSION_ACCESS "RO"
+// =============================================================================
+// Register    : VEC_DMA_ADDR_H
+// JTAG access : synchronous
+// Description : Upper 32-bits
+#define VEC_DMA_ADDR_H_OFFSET 0x00000040
+#define VEC_DMA_ADDR_H_BITS   0xffffffff
+#define VEC_DMA_ADDR_H_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DMA_ADDR_H_AXI_ADDR
+// Description : Byte address of DMA transfer frame buffer.
+#define VEC_DMA_ADDR_H_AXI_ADDR_RESET  0x00000000
+#define VEC_DMA_ADDR_H_AXI_ADDR_BITS   0xffffffff
+#define VEC_DMA_ADDR_H_AXI_ADDR_MSB    31
+#define VEC_DMA_ADDR_H_AXI_ADDR_LSB    0
+#define VEC_DMA_ADDR_H_AXI_ADDR_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_BURST_ADDR_L
+// JTAG access : synchronous
+// Description : None
+#define VEC_BURST_ADDR_L_OFFSET 0x00000044
+#define VEC_BURST_ADDR_L_BITS   0xffffffff
+#define VEC_BURST_ADDR_L_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_BURST_ADDR_L_BURST_ADDR
+// Description : the lower 32-bits of the most recent read request sent to AXI
+//               memory.
+#define VEC_BURST_ADDR_L_BURST_ADDR_RESET  0x00000000
+#define VEC_BURST_ADDR_L_BURST_ADDR_BITS   0xffffffff
+#define VEC_BURST_ADDR_L_BURST_ADDR_MSB    31
+#define VEC_BURST_ADDR_L_BURST_ADDR_LSB    0
+#define VEC_BURST_ADDR_L_BURST_ADDR_ACCESS "RO"
+// =============================================================================
+// Register    : VEC_APB_TIMEOUT
+// JTAG access : synchronous
+// Description : None
+#define VEC_APB_TIMEOUT_OFFSET 0x00000048
+#define VEC_APB_TIMEOUT_BITS   0x000103ff
+#define VEC_APB_TIMEOUT_RESET  0x00000014
+// -----------------------------------------------------------------------------
+// Field       : VEC_APB_TIMEOUT_SLVERR_EN
+// Description : 1 = Assert PREADY and PSLVERR on timeout 0 = Assert PREADY only
+#define VEC_APB_TIMEOUT_SLVERR_EN_RESET  0x0
+#define VEC_APB_TIMEOUT_SLVERR_EN_BITS   0x00010000
+#define VEC_APB_TIMEOUT_SLVERR_EN_MSB    16
+#define VEC_APB_TIMEOUT_SLVERR_EN_LSB    16
+#define VEC_APB_TIMEOUT_SLVERR_EN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_APB_TIMEOUT_TIMEOUT
+// Description : Maximum AXI clock cycles to wait for responses from DAC clock
+//               domain APB block
+#define VEC_APB_TIMEOUT_TIMEOUT_RESET  0x014
+#define VEC_APB_TIMEOUT_TIMEOUT_BITS   0x000003ff
+#define VEC_APB_TIMEOUT_TIMEOUT_MSB    9
+#define VEC_APB_TIMEOUT_TIMEOUT_LSB    0
+#define VEC_APB_TIMEOUT_TIMEOUT_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_80
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_80_OFFSET 0x00000080
+#define VEC_DAC_80_BITS   0x3fff3fff
+#define VEC_DAC_80_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_80_U14_DE_BGN
+// Description : Beginning of active data enable within each visible line
+#define VEC_DAC_80_U14_DE_BGN_RESET  0x0000
+#define VEC_DAC_80_U14_DE_BGN_BITS   0x3fff0000
+#define VEC_DAC_80_U14_DE_BGN_MSB    29
+#define VEC_DAC_80_U14_DE_BGN_LSB    16
+#define VEC_DAC_80_U14_DE_BGN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_80_U14_DE_END
+// Description : End of active data enable within each visible line
+#define VEC_DAC_80_U14_DE_END_RESET  0x0000
+#define VEC_DAC_80_U14_DE_END_BITS   0x00003fff
+#define VEC_DAC_80_U14_DE_END_MSB    13
+#define VEC_DAC_80_U14_DE_END_LSB    0
+#define VEC_DAC_80_U14_DE_END_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_84
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_84_OFFSET 0x00000084
+#define VEC_DAC_84_BITS   0x1fff1fff
+#define VEC_DAC_84_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_84_U13_ACTIVE_RISE
+// Description : Horizontal blanking interval
+#define VEC_DAC_84_U13_ACTIVE_RISE_RESET  0x0000
+#define VEC_DAC_84_U13_ACTIVE_RISE_BITS   0x1fff0000
+#define VEC_DAC_84_U13_ACTIVE_RISE_MSB    28
+#define VEC_DAC_84_U13_ACTIVE_RISE_LSB    16
+#define VEC_DAC_84_U13_ACTIVE_RISE_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_84_U13_ACTIVE_FALL
+// Description : Horizontal blanking interval
+#define VEC_DAC_84_U13_ACTIVE_FALL_RESET  0x0000
+#define VEC_DAC_84_U13_ACTIVE_FALL_BITS   0x00001fff
+#define VEC_DAC_84_U13_ACTIVE_FALL_MSB    12
+#define VEC_DAC_84_U13_ACTIVE_FALL_LSB    0
+#define VEC_DAC_84_U13_ACTIVE_FALL_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_88
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_88_OFFSET 0x00000088
+#define VEC_DAC_88_BITS   0x1fff1fff
+#define VEC_DAC_88_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_88_U13_HALF_LINE_PERIOD
+// Description : Ratio of DAC clock to horizontal line rate, halved
+#define VEC_DAC_88_U13_HALF_LINE_PERIOD_RESET  0x0000
+#define VEC_DAC_88_U13_HALF_LINE_PERIOD_BITS   0x1fff0000
+#define VEC_DAC_88_U13_HALF_LINE_PERIOD_MSB    28
+#define VEC_DAC_88_U13_HALF_LINE_PERIOD_LSB    16
+#define VEC_DAC_88_U13_HALF_LINE_PERIOD_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_88_U13_HORZ_SYNC
+// Description : Width of horizontal sync pulses
+#define VEC_DAC_88_U13_HORZ_SYNC_RESET  0x0000
+#define VEC_DAC_88_U13_HORZ_SYNC_BITS   0x00001fff
+#define VEC_DAC_88_U13_HORZ_SYNC_MSB    12
+#define VEC_DAC_88_U13_HORZ_SYNC_LSB    0
+#define VEC_DAC_88_U13_HORZ_SYNC_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_8C
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_8C_OFFSET 0x0000008c
+#define VEC_DAC_8C_BITS   0x1fff1fff
+#define VEC_DAC_8C_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_8C_U13_BURST_RISE
+// Description : Start of raised-cosine colour burst envelope
+#define VEC_DAC_8C_U13_BURST_RISE_RESET  0x0000
+#define VEC_DAC_8C_U13_BURST_RISE_BITS   0x1fff0000
+#define VEC_DAC_8C_U13_BURST_RISE_MSB    28
+#define VEC_DAC_8C_U13_BURST_RISE_LSB    16
+#define VEC_DAC_8C_U13_BURST_RISE_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_8C_U13_BURST_FALL
+// Description : End of raised-cosine colour burst envelope
+#define VEC_DAC_8C_U13_BURST_FALL_RESET  0x0000
+#define VEC_DAC_8C_U13_BURST_FALL_BITS   0x00001fff
+#define VEC_DAC_8C_U13_BURST_FALL_MSB    12
+#define VEC_DAC_8C_U13_BURST_FALL_LSB    0
+#define VEC_DAC_8C_U13_BURST_FALL_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_90
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_90_OFFSET 0x00000090
+#define VEC_DAC_90_BITS   0x1fff3fff
+#define VEC_DAC_90_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_90_U13_VERT_EQ
+// Description : Width of vertical equalisation pulses (= half line minus
+//               serration)
+#define VEC_DAC_90_U13_VERT_EQ_RESET  0x0000
+#define VEC_DAC_90_U13_VERT_EQ_BITS   0x1fff0000
+#define VEC_DAC_90_U13_VERT_EQ_MSB    28
+#define VEC_DAC_90_U13_VERT_EQ_LSB    16
+#define VEC_DAC_90_U13_VERT_EQ_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_90_U14_VERT_SYNC
+// Description : Width of vertical sync pulses
+#define VEC_DAC_90_U14_VERT_SYNC_RESET  0x0000
+#define VEC_DAC_90_U14_VERT_SYNC_BITS   0x00003fff
+#define VEC_DAC_90_U14_VERT_SYNC_MSB    13
+#define VEC_DAC_90_U14_VERT_SYNC_LSB    0
+#define VEC_DAC_90_U14_VERT_SYNC_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_94
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_94_OFFSET 0x00000094
+#define VEC_DAC_94_BITS   0x03ff03ff
+#define VEC_DAC_94_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_94_U10_PRE_EQ_BGN
+// Description : Half-lines, inclusive, relative to field datum, where vertical
+//               pre-equalisation pulses start
+#define VEC_DAC_94_U10_PRE_EQ_BGN_RESET  0x000
+#define VEC_DAC_94_U10_PRE_EQ_BGN_BITS   0x03ff0000
+#define VEC_DAC_94_U10_PRE_EQ_BGN_MSB    25
+#define VEC_DAC_94_U10_PRE_EQ_BGN_LSB    16
+#define VEC_DAC_94_U10_PRE_EQ_BGN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_94_U10_PRE_EQ_END
+// Description : Half-lines, inclusive, relative to field datum, where vertical
+//               pre-equalisation pulses end
+#define VEC_DAC_94_U10_PRE_EQ_END_RESET  0x000
+#define VEC_DAC_94_U10_PRE_EQ_END_BITS   0x000003ff
+#define VEC_DAC_94_U10_PRE_EQ_END_MSB    9
+#define VEC_DAC_94_U10_PRE_EQ_END_LSB    0
+#define VEC_DAC_94_U10_PRE_EQ_END_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_98
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_98_OFFSET 0x00000098
+#define VEC_DAC_98_BITS   0x03ff03ff
+#define VEC_DAC_98_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_98_U10_FIELD_SYNC_BGN
+// Description : Half-lines containing vertical sync pulses (inclusive)
+#define VEC_DAC_98_U10_FIELD_SYNC_BGN_RESET  0x000
+#define VEC_DAC_98_U10_FIELD_SYNC_BGN_BITS   0x03ff0000
+#define VEC_DAC_98_U10_FIELD_SYNC_BGN_MSB    25
+#define VEC_DAC_98_U10_FIELD_SYNC_BGN_LSB    16
+#define VEC_DAC_98_U10_FIELD_SYNC_BGN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_98_U10_FIELD_SYNC_END
+// Description : Half-lines containing vertical sync pulses (inclusive)
+#define VEC_DAC_98_U10_FIELD_SYNC_END_RESET  0x000
+#define VEC_DAC_98_U10_FIELD_SYNC_END_BITS   0x000003ff
+#define VEC_DAC_98_U10_FIELD_SYNC_END_MSB    9
+#define VEC_DAC_98_U10_FIELD_SYNC_END_LSB    0
+#define VEC_DAC_98_U10_FIELD_SYNC_END_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_9C
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_9C_OFFSET 0x0000009c
+#define VEC_DAC_9C_BITS   0x03ff03ff
+#define VEC_DAC_9C_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_9C_U10_POST_EQ_BGN
+// Description : Half-lines containing vertical post-equalisation pulses
+#define VEC_DAC_9C_U10_POST_EQ_BGN_RESET  0x000
+#define VEC_DAC_9C_U10_POST_EQ_BGN_BITS   0x03ff0000
+#define VEC_DAC_9C_U10_POST_EQ_BGN_MSB    25
+#define VEC_DAC_9C_U10_POST_EQ_BGN_LSB    16
+#define VEC_DAC_9C_U10_POST_EQ_BGN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_9C_U10_POST_EQ_END
+// Description : Half-lines containing vertical post-equalisation pulses
+#define VEC_DAC_9C_U10_POST_EQ_END_RESET  0x000
+#define VEC_DAC_9C_U10_POST_EQ_END_BITS   0x000003ff
+#define VEC_DAC_9C_U10_POST_EQ_END_MSB    9
+#define VEC_DAC_9C_U10_POST_EQ_END_LSB    0
+#define VEC_DAC_9C_U10_POST_EQ_END_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_A0
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_A0_OFFSET 0x000000a0
+#define VEC_DAC_A0_BITS   0x03ff03ff
+#define VEC_DAC_A0_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_A0_U10_FLD1_BURST_BGN
+// Description : First and last full frame lines (1-based numbering) within the
+//               PAL/NTSC four field sequence which require a colour burst
+#define VEC_DAC_A0_U10_FLD1_BURST_BGN_RESET  0x000
+#define VEC_DAC_A0_U10_FLD1_BURST_BGN_BITS   0x03ff0000
+#define VEC_DAC_A0_U10_FLD1_BURST_BGN_MSB    25
+#define VEC_DAC_A0_U10_FLD1_BURST_BGN_LSB    16
+#define VEC_DAC_A0_U10_FLD1_BURST_BGN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_A0_U10_FLD1_BURST_END
+// Description : First and last full frame lines (1-based numbering) within the
+//               PAL/NTSC four field sequence which require a colour burst
+#define VEC_DAC_A0_U10_FLD1_BURST_END_RESET  0x000
+#define VEC_DAC_A0_U10_FLD1_BURST_END_BITS   0x000003ff
+#define VEC_DAC_A0_U10_FLD1_BURST_END_MSB    9
+#define VEC_DAC_A0_U10_FLD1_BURST_END_LSB    0
+#define VEC_DAC_A0_U10_FLD1_BURST_END_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_A4
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_A4_OFFSET 0x000000a4
+#define VEC_DAC_A4_BITS   0x03ff03ff
+#define VEC_DAC_A4_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_A4_U10_FLD2_BURST_BGN
+// Description : First and last full frame lines (1-based numbering) within the
+//               PAL/NTSC four field sequence which require a colour burst
+#define VEC_DAC_A4_U10_FLD2_BURST_BGN_RESET  0x000
+#define VEC_DAC_A4_U10_FLD2_BURST_BGN_BITS   0x03ff0000
+#define VEC_DAC_A4_U10_FLD2_BURST_BGN_MSB    25
+#define VEC_DAC_A4_U10_FLD2_BURST_BGN_LSB    16
+#define VEC_DAC_A4_U10_FLD2_BURST_BGN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_A4_U10_FLD2_BURST_END
+// Description : First and last full frame lines (1-based numbering) within the
+//               PAL/NTSC four field sequence which require a colour burst
+#define VEC_DAC_A4_U10_FLD2_BURST_END_RESET  0x000
+#define VEC_DAC_A4_U10_FLD2_BURST_END_BITS   0x000003ff
+#define VEC_DAC_A4_U10_FLD2_BURST_END_MSB    9
+#define VEC_DAC_A4_U10_FLD2_BURST_END_LSB    0
+#define VEC_DAC_A4_U10_FLD2_BURST_END_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_A8
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_A8_OFFSET 0x000000a8
+#define VEC_DAC_A8_BITS   0x03ff03ff
+#define VEC_DAC_A8_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_A8_U10_FLD3_BURST_BGN
+// Description : First and last full frame lines (1-based numbering) within the
+//               PAL/NTSC four field sequence which require a colour burst
+#define VEC_DAC_A8_U10_FLD3_BURST_BGN_RESET  0x000
+#define VEC_DAC_A8_U10_FLD3_BURST_BGN_BITS   0x03ff0000
+#define VEC_DAC_A8_U10_FLD3_BURST_BGN_MSB    25
+#define VEC_DAC_A8_U10_FLD3_BURST_BGN_LSB    16
+#define VEC_DAC_A8_U10_FLD3_BURST_BGN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_A8_U10_FLD3_BURST_END
+// Description : First and last full frame lines (1-based numbering) within the
+//               PAL/NTSC four field sequence which require a colour burst
+#define VEC_DAC_A8_U10_FLD3_BURST_END_RESET  0x000
+#define VEC_DAC_A8_U10_FLD3_BURST_END_BITS   0x000003ff
+#define VEC_DAC_A8_U10_FLD3_BURST_END_MSB    9
+#define VEC_DAC_A8_U10_FLD3_BURST_END_LSB    0
+#define VEC_DAC_A8_U10_FLD3_BURST_END_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_AC
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_AC_OFFSET 0x000000ac
+#define VEC_DAC_AC_BITS   0x03ff03ff
+#define VEC_DAC_AC_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_AC_U10_FLD4_BURST_BGN
+// Description : First and last full frame lines (1-based numbering) within the
+//               PAL/NTSC four field sequence which require a colour burst
+#define VEC_DAC_AC_U10_FLD4_BURST_BGN_RESET  0x000
+#define VEC_DAC_AC_U10_FLD4_BURST_BGN_BITS   0x03ff0000
+#define VEC_DAC_AC_U10_FLD4_BURST_BGN_MSB    25
+#define VEC_DAC_AC_U10_FLD4_BURST_BGN_LSB    16
+#define VEC_DAC_AC_U10_FLD4_BURST_BGN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_AC_U10_FLD4_BURST_END
+// Description : First and last full frame lines (1-based numbering) within the
+//               PAL/NTSC four field sequence which require a colour burst
+#define VEC_DAC_AC_U10_FLD4_BURST_END_RESET  0x000
+#define VEC_DAC_AC_U10_FLD4_BURST_END_BITS   0x000003ff
+#define VEC_DAC_AC_U10_FLD4_BURST_END_MSB    9
+#define VEC_DAC_AC_U10_FLD4_BURST_END_LSB    0
+#define VEC_DAC_AC_U10_FLD4_BURST_END_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_B0
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_B0_OFFSET 0x000000b0
+#define VEC_DAC_B0_BITS   0x03ff03ff
+#define VEC_DAC_B0_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_B0_U10_FLD24_FULL_LINE_BGN
+// Description : First and last full visible lines (1-based numbering) in the
+//               PAL/NTSC four field sequence
+#define VEC_DAC_B0_U10_FLD24_FULL_LINE_BGN_RESET  0x000
+#define VEC_DAC_B0_U10_FLD24_FULL_LINE_BGN_BITS   0x03ff0000
+#define VEC_DAC_B0_U10_FLD24_FULL_LINE_BGN_MSB    25
+#define VEC_DAC_B0_U10_FLD24_FULL_LINE_BGN_LSB    16
+#define VEC_DAC_B0_U10_FLD24_FULL_LINE_BGN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_B0_U10_FLD24_FULL_LINE_END
+// Description : First and last full visible lines (1-based numbering) in the
+//               PAL/NTSC four field sequence
+#define VEC_DAC_B0_U10_FLD24_FULL_LINE_END_RESET  0x000
+#define VEC_DAC_B0_U10_FLD24_FULL_LINE_END_BITS   0x000003ff
+#define VEC_DAC_B0_U10_FLD24_FULL_LINE_END_MSB    9
+#define VEC_DAC_B0_U10_FLD24_FULL_LINE_END_LSB    0
+#define VEC_DAC_B0_U10_FLD24_FULL_LINE_END_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_B4
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_B4_OFFSET 0x000000b4
+#define VEC_DAC_B4_BITS   0x03ff03ff
+#define VEC_DAC_B4_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_B4_U10_FLD13_FULL_LINE_BGN
+// Description : First and last full visible lines (1-based numbering) in the
+//               PAL/NTSC four field sequence
+#define VEC_DAC_B4_U10_FLD13_FULL_LINE_BGN_RESET  0x000
+#define VEC_DAC_B4_U10_FLD13_FULL_LINE_BGN_BITS   0x03ff0000
+#define VEC_DAC_B4_U10_FLD13_FULL_LINE_BGN_MSB    25
+#define VEC_DAC_B4_U10_FLD13_FULL_LINE_BGN_LSB    16
+#define VEC_DAC_B4_U10_FLD13_FULL_LINE_BGN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_B4_U10_FLD13_FULL_LINE_END
+// Description : First and last full visible lines (1-based numbering) in the
+//               PAL/NTSC four field sequence
+#define VEC_DAC_B4_U10_FLD13_FULL_LINE_END_RESET  0x000
+#define VEC_DAC_B4_U10_FLD13_FULL_LINE_END_BITS   0x000003ff
+#define VEC_DAC_B4_U10_FLD13_FULL_LINE_END_MSB    9
+#define VEC_DAC_B4_U10_FLD13_FULL_LINE_END_LSB    0
+#define VEC_DAC_B4_U10_FLD13_FULL_LINE_END_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_B8
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_B8_OFFSET 0x000000b8
+#define VEC_DAC_B8_BITS   0x03ff03ff
+#define VEC_DAC_B8_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_B8_U10_BOT_HALF_LINE
+// Description : Top and bottom visible half-lines in 1-based standard full
+//               frame numbering, for interlaced modes. Set to zero to disable.
+#define VEC_DAC_B8_U10_BOT_HALF_LINE_RESET  0x000
+#define VEC_DAC_B8_U10_BOT_HALF_LINE_BITS   0x03ff0000
+#define VEC_DAC_B8_U10_BOT_HALF_LINE_MSB    25
+#define VEC_DAC_B8_U10_BOT_HALF_LINE_LSB    16
+#define VEC_DAC_B8_U10_BOT_HALF_LINE_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_B8_U10_TOP_HALF_LINE
+// Description : Top and bottom visible half-lines in 1-based standard full
+//               frame numbering, for interlaced modes. Set to zero to disable.
+#define VEC_DAC_B8_U10_TOP_HALF_LINE_RESET  0x000
+#define VEC_DAC_B8_U10_TOP_HALF_LINE_BITS   0x000003ff
+#define VEC_DAC_B8_U10_TOP_HALF_LINE_MSB    9
+#define VEC_DAC_B8_U10_TOP_HALF_LINE_LSB    0
+#define VEC_DAC_B8_U10_TOP_HALF_LINE_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_BC
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_BC_OFFSET 0x000000bc
+#define VEC_DAC_BC_BITS   0x07ff07ff
+#define VEC_DAC_BC_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_BC_S11_PEDESTAL
+// Description : NTSC pedestal. For 7.5 IRE, this field is 1024 * 7.5/100. For
+//               PAL, or Japanese NTSC, this field should be zero.
+#define VEC_DAC_BC_S11_PEDESTAL_RESET  0x000
+#define VEC_DAC_BC_S11_PEDESTAL_BITS   0x07ff0000
+#define VEC_DAC_BC_S11_PEDESTAL_MSB    26
+#define VEC_DAC_BC_S11_PEDESTAL_LSB    16
+#define VEC_DAC_BC_S11_PEDESTAL_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_BC_U11_HALF_LINES_PER_FIELD
+// Description : Mode = 625 PAL, Lines per field = 312.5,
+//               u11_half_lines_per_field = 1+2*312 Mode = 525 NTSC, Lines per
+//               field = 262.5, u11_half_lines_per_field = 1+2*262
+#define VEC_DAC_BC_U11_HALF_LINES_PER_FIELD_RESET  0x000
+#define VEC_DAC_BC_U11_HALF_LINES_PER_FIELD_BITS   0x000007ff
+#define VEC_DAC_BC_U11_HALF_LINES_PER_FIELD_MSB    10
+#define VEC_DAC_BC_U11_HALF_LINES_PER_FIELD_LSB    0
+#define VEC_DAC_BC_U11_HALF_LINES_PER_FIELD_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_C0
+// JTAG access : synchronous
+// Description : Synopsis DesignWare control
+#define VEC_DAC_C0_OFFSET 0x000000c0
+#define VEC_DAC_C0_BITS   0x000fffff
+#define VEC_DAC_C0_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C0_DWC_CABLE_ENCTR3
+// Description : Synopsis test input
+#define VEC_DAC_C0_DWC_CABLE_ENCTR3_RESET  0x0
+#define VEC_DAC_C0_DWC_CABLE_ENCTR3_BITS   0x00080000
+#define VEC_DAC_C0_DWC_CABLE_ENCTR3_MSB    19
+#define VEC_DAC_C0_DWC_CABLE_ENCTR3_LSB    19
+#define VEC_DAC_C0_DWC_CABLE_ENCTR3_ACCESS "RO"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C0_DWC_CABLE_CABLEOUT
+// Description : cable detect state
+#define VEC_DAC_C0_DWC_CABLE_CABLEOUT_RESET  0x0
+#define VEC_DAC_C0_DWC_CABLE_CABLEOUT_BITS   0x00070000
+#define VEC_DAC_C0_DWC_CABLE_CABLEOUT_MSB    18
+#define VEC_DAC_C0_DWC_CABLE_CABLEOUT_LSB    16
+#define VEC_DAC_C0_DWC_CABLE_CABLEOUT_ACCESS "RO"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C0_DWC_MUX_2
+// Description : Select DAC channel 2 output
+#define VEC_DAC_C0_DWC_MUX_2_RESET  0x0
+#define VEC_DAC_C0_DWC_MUX_2_BITS   0x0000c000
+#define VEC_DAC_C0_DWC_MUX_2_MSB    15
+#define VEC_DAC_C0_DWC_MUX_2_LSB    14
+#define VEC_DAC_C0_DWC_MUX_2_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C0_DWC_MUX_1
+// Description : Select DAC channel 1 output
+#define VEC_DAC_C0_DWC_MUX_1_RESET  0x0
+#define VEC_DAC_C0_DWC_MUX_1_BITS   0x00003000
+#define VEC_DAC_C0_DWC_MUX_1_MSB    13
+#define VEC_DAC_C0_DWC_MUX_1_LSB    12
+#define VEC_DAC_C0_DWC_MUX_1_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C0_DWC_MUX_0
+// Description : Select DAC channel 0 output
+#define VEC_DAC_C0_DWC_MUX_0_RESET  0x0
+#define VEC_DAC_C0_DWC_MUX_0_BITS   0x00000c00
+#define VEC_DAC_C0_DWC_MUX_0_MSB    11
+#define VEC_DAC_C0_DWC_MUX_0_LSB    10
+#define VEC_DAC_C0_DWC_MUX_0_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C0_DWC_TEST
+// Description : Fixed DAC command word
+#define VEC_DAC_C0_DWC_TEST_RESET  0x000
+#define VEC_DAC_C0_DWC_TEST_BITS   0x000003ff
+#define VEC_DAC_C0_DWC_TEST_MSB    9
+#define VEC_DAC_C0_DWC_TEST_LSB    0
+#define VEC_DAC_C0_DWC_TEST_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_C4
+// JTAG access : synchronous
+// Description : Synopsis DAC control
+#define VEC_DAC_C4_OFFSET 0x000000c4
+#define VEC_DAC_C4_BITS   0x1fffffff
+#define VEC_DAC_C4_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C4_ENCTR
+// Description : Always write3'b000
+#define VEC_DAC_C4_ENCTR_RESET  0x0
+#define VEC_DAC_C4_ENCTR_BITS   0x1c000000
+#define VEC_DAC_C4_ENCTR_MSB    28
+#define VEC_DAC_C4_ENCTR_LSB    26
+#define VEC_DAC_C4_ENCTR_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C4_ENSC
+// Description : Enable cable detect - write 3'b000
+#define VEC_DAC_C4_ENSC_RESET  0x0
+#define VEC_DAC_C4_ENSC_BITS   0x03800000
+#define VEC_DAC_C4_ENSC_MSB    25
+#define VEC_DAC_C4_ENSC_LSB    23
+#define VEC_DAC_C4_ENSC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C4_ENDAC
+// Description : Enable DAC channel
+#define VEC_DAC_C4_ENDAC_RESET  0x0
+#define VEC_DAC_C4_ENDAC_BITS   0x00700000
+#define VEC_DAC_C4_ENDAC_MSB    22
+#define VEC_DAC_C4_ENDAC_LSB    20
+#define VEC_DAC_C4_ENDAC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C4_ENVBG
+// Description : Enable internal bandgap reference - write '1'
+#define VEC_DAC_C4_ENVBG_RESET  0x0
+#define VEC_DAC_C4_ENVBG_BITS   0x00080000
+#define VEC_DAC_C4_ENVBG_MSB    19
+#define VEC_DAC_C4_ENVBG_LSB    19
+#define VEC_DAC_C4_ENVBG_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C4_ENEXTREF
+// Description : Enable external reference - write '0'
+#define VEC_DAC_C4_ENEXTREF_RESET  0x0
+#define VEC_DAC_C4_ENEXTREF_BITS   0x00040000
+#define VEC_DAC_C4_ENEXTREF_MSB    18
+#define VEC_DAC_C4_ENEXTREF_LSB    18
+#define VEC_DAC_C4_ENEXTREF_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C4_DAC2GC
+// Description : DAC channel 2 gain control - write 6'd63
+#define VEC_DAC_C4_DAC2GC_RESET  0x00
+#define VEC_DAC_C4_DAC2GC_BITS   0x0003f000
+#define VEC_DAC_C4_DAC2GC_MSB    17
+#define VEC_DAC_C4_DAC2GC_LSB    12
+#define VEC_DAC_C4_DAC2GC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C4_DAC1GC
+// Description : DAC channel 1 gain control - write 6'd63
+#define VEC_DAC_C4_DAC1GC_RESET  0x00
+#define VEC_DAC_C4_DAC1GC_BITS   0x00000fc0
+#define VEC_DAC_C4_DAC1GC_MSB    11
+#define VEC_DAC_C4_DAC1GC_LSB    6
+#define VEC_DAC_C4_DAC1GC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C4_DAC0GC
+// Description : DAC channel 0 gain control - write 6'd63
+#define VEC_DAC_C4_DAC0GC_RESET  0x00
+#define VEC_DAC_C4_DAC0GC_BITS   0x0000003f
+#define VEC_DAC_C4_DAC0GC_MSB    5
+#define VEC_DAC_C4_DAC0GC_LSB    0
+#define VEC_DAC_C4_DAC0GC_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_C8
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_C8_OFFSET 0x000000c8
+#define VEC_DAC_C8_BITS   0xffffffff
+#define VEC_DAC_C8_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C8_U16_SCALE_SYNC
+// Description : Scaling applied prior to final summation to form the DAC
+//               command word(s)
+#define VEC_DAC_C8_U16_SCALE_SYNC_RESET  0x0000
+#define VEC_DAC_C8_U16_SCALE_SYNC_BITS   0xffff0000
+#define VEC_DAC_C8_U16_SCALE_SYNC_MSB    31
+#define VEC_DAC_C8_U16_SCALE_SYNC_LSB    16
+#define VEC_DAC_C8_U16_SCALE_SYNC_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_C8_U16_SCALE_LUMA
+// Description : Scaling applied prior to final summation to form the DAC
+//               command word(s)
+#define VEC_DAC_C8_U16_SCALE_LUMA_RESET  0x0000
+#define VEC_DAC_C8_U16_SCALE_LUMA_BITS   0x0000ffff
+#define VEC_DAC_C8_U16_SCALE_LUMA_MSB    15
+#define VEC_DAC_C8_U16_SCALE_LUMA_LSB    0
+#define VEC_DAC_C8_U16_SCALE_LUMA_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_CC
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_CC_OFFSET 0x000000cc
+#define VEC_DAC_CC_BITS   0xffffffff
+#define VEC_DAC_CC_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_CC_S16_SCALE_BURST
+// Description : Scaling applied prior to final summation to form the DAC
+//               command word(s)
+#define VEC_DAC_CC_S16_SCALE_BURST_RESET  0x0000
+#define VEC_DAC_CC_S16_SCALE_BURST_BITS   0xffff0000
+#define VEC_DAC_CC_S16_SCALE_BURST_MSB    31
+#define VEC_DAC_CC_S16_SCALE_BURST_LSB    16
+#define VEC_DAC_CC_S16_SCALE_BURST_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_CC_S16_SCALE_CHROMA
+// Description : Scaling applied prior to final summation to form the DAC
+//               command word(s)
+#define VEC_DAC_CC_S16_SCALE_CHROMA_RESET  0x0000
+#define VEC_DAC_CC_S16_SCALE_CHROMA_BITS   0x0000ffff
+#define VEC_DAC_CC_S16_SCALE_CHROMA_MSB    15
+#define VEC_DAC_CC_S16_SCALE_CHROMA_LSB    0
+#define VEC_DAC_CC_S16_SCALE_CHROMA_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_D0
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_D0_OFFSET 0x000000d0
+#define VEC_DAC_D0_BITS   0xffffffff
+#define VEC_DAC_D0_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_D0_S16_OFFSET_LUMA
+// Description : These offsets are applied to the chroma and luma channels
+//               before the final MUX
+#define VEC_DAC_D0_S16_OFFSET_LUMA_RESET  0x0000
+#define VEC_DAC_D0_S16_OFFSET_LUMA_BITS   0xffff0000
+#define VEC_DAC_D0_S16_OFFSET_LUMA_MSB    31
+#define VEC_DAC_D0_S16_OFFSET_LUMA_LSB    16
+#define VEC_DAC_D0_S16_OFFSET_LUMA_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_D0_S16_OFFSET_CHRO
+// Description : These offsets are applied to the chroma and luma channels
+//               before the final MUX
+#define VEC_DAC_D0_S16_OFFSET_CHRO_RESET  0x0000
+#define VEC_DAC_D0_S16_OFFSET_CHRO_BITS   0x0000ffff
+#define VEC_DAC_D0_S16_OFFSET_CHRO_MSB    15
+#define VEC_DAC_D0_S16_OFFSET_CHRO_LSB    0
+#define VEC_DAC_D0_S16_OFFSET_CHRO_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_D4
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_D4_OFFSET 0x000000d4
+#define VEC_DAC_D4_BITS   0xffffffff
+#define VEC_DAC_D4_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_D4_NCO_FREQ
+// Description : This 64-bit frequency command is applied to the phase
+//               accumulator of the NCO (numerically controlled oscillator)
+//               which generates the colour sub-carrier. This value is computed
+//               as ratio of sub-carrier frequency to DAC clock multiplied by
+//               2^64.
+#define VEC_DAC_D4_NCO_FREQ_RESET  0x00000000
+#define VEC_DAC_D4_NCO_FREQ_BITS   0xffffffff
+#define VEC_DAC_D4_NCO_FREQ_MSB    31
+#define VEC_DAC_D4_NCO_FREQ_LSB    0
+#define VEC_DAC_D4_NCO_FREQ_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_D8
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_D8_OFFSET 0x000000d8
+#define VEC_DAC_D8_BITS   0xffffffff
+#define VEC_DAC_D8_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_D8_NCO_FREQ
+// Description : This 64-bit frequency command is applied to the phase
+//               accumulator of the NCO (numerically controlled oscillator)
+//               which generates the colour sub-carrier. This value is computed
+//               as ratio of sub-carrier frequency to DAC clock multiplied by
+//               2^64.
+#define VEC_DAC_D8_NCO_FREQ_RESET  0x00000000
+#define VEC_DAC_D8_NCO_FREQ_BITS   0xffffffff
+#define VEC_DAC_D8_NCO_FREQ_MSB    31
+#define VEC_DAC_D8_NCO_FREQ_LSB    0
+#define VEC_DAC_D8_NCO_FREQ_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_DC
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_DC_OFFSET 0x000000dc
+#define VEC_DAC_DC_BITS   0xffffffff
+#define VEC_DAC_DC_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_DC_FIR_COEFF_CHROMA_0_6
+// Description : FIR filter coefficients
+#define VEC_DAC_DC_FIR_COEFF_CHROMA_0_6_RESET  0x0000
+#define VEC_DAC_DC_FIR_COEFF_CHROMA_0_6_BITS   0xffff0000
+#define VEC_DAC_DC_FIR_COEFF_CHROMA_0_6_MSB    31
+#define VEC_DAC_DC_FIR_COEFF_CHROMA_0_6_LSB    16
+#define VEC_DAC_DC_FIR_COEFF_CHROMA_0_6_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_DC_FIR_COEFF_LUMA_0_6
+// Description : FIR filter coefficients
+#define VEC_DAC_DC_FIR_COEFF_LUMA_0_6_RESET  0x0000
+#define VEC_DAC_DC_FIR_COEFF_LUMA_0_6_BITS   0x0000ffff
+#define VEC_DAC_DC_FIR_COEFF_LUMA_0_6_MSB    15
+#define VEC_DAC_DC_FIR_COEFF_LUMA_0_6_LSB    0
+#define VEC_DAC_DC_FIR_COEFF_LUMA_0_6_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_E0
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_E0_OFFSET 0x000000e0
+#define VEC_DAC_E0_BITS   0xffffffff
+#define VEC_DAC_E0_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_E0_FIR_COEFF_CHROMA_1_5
+// Description : FIR filter coefficients
+#define VEC_DAC_E0_FIR_COEFF_CHROMA_1_5_RESET  0x0000
+#define VEC_DAC_E0_FIR_COEFF_CHROMA_1_5_BITS   0xffff0000
+#define VEC_DAC_E0_FIR_COEFF_CHROMA_1_5_MSB    31
+#define VEC_DAC_E0_FIR_COEFF_CHROMA_1_5_LSB    16
+#define VEC_DAC_E0_FIR_COEFF_CHROMA_1_5_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_E0_FIR_COEFF_LUMA_1_5
+// Description : FIR filter coefficients
+#define VEC_DAC_E0_FIR_COEFF_LUMA_1_5_RESET  0x0000
+#define VEC_DAC_E0_FIR_COEFF_LUMA_1_5_BITS   0x0000ffff
+#define VEC_DAC_E0_FIR_COEFF_LUMA_1_5_MSB    15
+#define VEC_DAC_E0_FIR_COEFF_LUMA_1_5_LSB    0
+#define VEC_DAC_E0_FIR_COEFF_LUMA_1_5_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_E4
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_E4_OFFSET 0x000000e4
+#define VEC_DAC_E4_BITS   0xffffffff
+#define VEC_DAC_E4_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_E4_FIR_COEFF_CHROMA_2_4
+// Description : FIR filter coefficients
+#define VEC_DAC_E4_FIR_COEFF_CHROMA_2_4_RESET  0x0000
+#define VEC_DAC_E4_FIR_COEFF_CHROMA_2_4_BITS   0xffff0000
+#define VEC_DAC_E4_FIR_COEFF_CHROMA_2_4_MSB    31
+#define VEC_DAC_E4_FIR_COEFF_CHROMA_2_4_LSB    16
+#define VEC_DAC_E4_FIR_COEFF_CHROMA_2_4_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_E4_FIR_COEFF_LUMA_2_4
+// Description : FIR filter coefficients
+#define VEC_DAC_E4_FIR_COEFF_LUMA_2_4_RESET  0x0000
+#define VEC_DAC_E4_FIR_COEFF_LUMA_2_4_BITS   0x0000ffff
+#define VEC_DAC_E4_FIR_COEFF_LUMA_2_4_MSB    15
+#define VEC_DAC_E4_FIR_COEFF_LUMA_2_4_LSB    0
+#define VEC_DAC_E4_FIR_COEFF_LUMA_2_4_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_E8
+// JTAG access : synchronous
+// Description : None
+#define VEC_DAC_E8_OFFSET 0x000000e8
+#define VEC_DAC_E8_BITS   0xffffffff
+#define VEC_DAC_E8_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_E8_FIR_COEFF_CHROMA_3
+// Description : FIR filter coefficients
+#define VEC_DAC_E8_FIR_COEFF_CHROMA_3_RESET  0x0000
+#define VEC_DAC_E8_FIR_COEFF_CHROMA_3_BITS   0xffff0000
+#define VEC_DAC_E8_FIR_COEFF_CHROMA_3_MSB    31
+#define VEC_DAC_E8_FIR_COEFF_CHROMA_3_LSB    16
+#define VEC_DAC_E8_FIR_COEFF_CHROMA_3_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_E8_FIR_COEFF_LUMA_3
+// Description : FIR filter coefficients
+#define VEC_DAC_E8_FIR_COEFF_LUMA_3_RESET  0x0000
+#define VEC_DAC_E8_FIR_COEFF_LUMA_3_BITS   0x0000ffff
+#define VEC_DAC_E8_FIR_COEFF_LUMA_3_MSB    15
+#define VEC_DAC_E8_FIR_COEFF_LUMA_3_LSB    0
+#define VEC_DAC_E8_FIR_COEFF_LUMA_3_ACCESS "RW"
+// =============================================================================
+// Register    : VEC_DAC_EC
+// JTAG access : synchronous
+// Description : Misc. control
+#define VEC_DAC_EC_OFFSET 0x000000ec
+#define VEC_DAC_EC_BITS   0x001fffff
+#define VEC_DAC_EC_RESET  0x00000000
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_EC_SLOW_CLOCK
+// Description : Doubles the raised-cosine rate
+#define VEC_DAC_EC_SLOW_CLOCK_RESET  0x0
+#define VEC_DAC_EC_SLOW_CLOCK_BITS   0x00100000
+#define VEC_DAC_EC_SLOW_CLOCK_MSB    20
+#define VEC_DAC_EC_SLOW_CLOCK_LSB    20
+#define VEC_DAC_EC_SLOW_CLOCK_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_EC_FIR_RMINUS1
+// Description : Select 1, 3, 5 or 7 FIR taps
+#define VEC_DAC_EC_FIR_RMINUS1_RESET  0x0
+#define VEC_DAC_EC_FIR_RMINUS1_BITS   0x000c0000
+#define VEC_DAC_EC_FIR_RMINUS1_MSB    19
+#define VEC_DAC_EC_FIR_RMINUS1_LSB    18
+#define VEC_DAC_EC_FIR_RMINUS1_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_EC_VERT_FULL_NOT_HALF
+// Description : Disable half-line pulses during VBI
+#define VEC_DAC_EC_VERT_FULL_NOT_HALF_RESET  0x0
+#define VEC_DAC_EC_VERT_FULL_NOT_HALF_BITS   0x00020000
+#define VEC_DAC_EC_VERT_FULL_NOT_HALF_MSB    17
+#define VEC_DAC_EC_VERT_FULL_NOT_HALF_LSB    17
+#define VEC_DAC_EC_VERT_FULL_NOT_HALF_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_EC_SEQ_EN
+// Description : Enable NCO reset
+#define VEC_DAC_EC_SEQ_EN_RESET  0x0
+#define VEC_DAC_EC_SEQ_EN_BITS   0x00010000
+#define VEC_DAC_EC_SEQ_EN_MSB    16
+#define VEC_DAC_EC_SEQ_EN_LSB    16
+#define VEC_DAC_EC_SEQ_EN_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_EC_U2_FLD_MASK
+// Description : Field sequence
+#define VEC_DAC_EC_U2_FLD_MASK_RESET  0x0
+#define VEC_DAC_EC_U2_FLD_MASK_BITS   0x0000c000
+#define VEC_DAC_EC_U2_FLD_MASK_MSB    15
+#define VEC_DAC_EC_U2_FLD_MASK_LSB    14
+#define VEC_DAC_EC_U2_FLD_MASK_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_EC_U4_SEQ_MASK
+// Description : NCO reset sequence
+#define VEC_DAC_EC_U4_SEQ_MASK_RESET  0x0
+#define VEC_DAC_EC_U4_SEQ_MASK_BITS   0x00003c00
+#define VEC_DAC_EC_U4_SEQ_MASK_MSB    13
+#define VEC_DAC_EC_U4_SEQ_MASK_LSB    10
+#define VEC_DAC_EC_U4_SEQ_MASK_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_EC_INTERP_RATE_MINUS1
+// Description : Interpolation rate 2<=R<=16
+#define VEC_DAC_EC_INTERP_RATE_MINUS1_RESET  0x0
+#define VEC_DAC_EC_INTERP_RATE_MINUS1_BITS   0x000003c0
+#define VEC_DAC_EC_INTERP_RATE_MINUS1_MSB    9
+#define VEC_DAC_EC_INTERP_RATE_MINUS1_LSB    6
+#define VEC_DAC_EC_INTERP_RATE_MINUS1_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_EC_INTERP_SHIFT_MINUS1
+// Description : Power-of-2 scaling after interpolation
+#define VEC_DAC_EC_INTERP_SHIFT_MINUS1_RESET  0x0
+#define VEC_DAC_EC_INTERP_SHIFT_MINUS1_BITS   0x0000003c
+#define VEC_DAC_EC_INTERP_SHIFT_MINUS1_MSB    5
+#define VEC_DAC_EC_INTERP_SHIFT_MINUS1_LSB    2
+#define VEC_DAC_EC_INTERP_SHIFT_MINUS1_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_EC_FIELDS_PER_FRAME_MINUS1
+// Description : Interlaced / progressive
+#define VEC_DAC_EC_FIELDS_PER_FRAME_MINUS1_RESET  0x0
+#define VEC_DAC_EC_FIELDS_PER_FRAME_MINUS1_BITS   0x00000002
+#define VEC_DAC_EC_FIELDS_PER_FRAME_MINUS1_MSB    1
+#define VEC_DAC_EC_FIELDS_PER_FRAME_MINUS1_LSB    1
+#define VEC_DAC_EC_FIELDS_PER_FRAME_MINUS1_ACCESS "RW"
+// -----------------------------------------------------------------------------
+// Field       : VEC_DAC_EC_PAL_EN
+// Description : Enable phase alternate line (PAL) mode
+#define VEC_DAC_EC_PAL_EN_RESET  0x0
+#define VEC_DAC_EC_PAL_EN_BITS   0x00000001
+#define VEC_DAC_EC_PAL_EN_MSB    0
+#define VEC_DAC_EC_PAL_EN_LSB    0
+#define VEC_DAC_EC_PAL_EN_ACCESS "RW"
+// =============================================================================
+#endif // VEC_REGS_DEFINED
