On Fri, Nov 25, 2016 at 05:03:09PM +0100, Neil Armstrong wrote: > The Amlogic Meson Display controller is composed of several components : > > DMC|---------------VPU (Video Processing Unit)----------------|------HHI------| > | vd1 _______ _____________ _________________ | | > D |-------| |----| | | | | HDMI PLL | > D | vd2 | VIU | | Video Post | | Video Encoders |<---|-----VCLK | > R |-------| |----| Processing | | | | | > | osd2 | | | |---| Enci ----------|----|-----VDAC------| > R |-------| CSC |----| Scalers | | Encp ----------|----|----HDMI-TX----| > A | osd1 | | | Blenders | | Encl ----------|----|---------------| > M |-------|______|----|____________| |________________| | | > ___|__________________________________________________________|_______________| > > > VIU: Video Input Unit > --------------------- > > The Video Input Unit is in charge of the pixel scanout from the DDR memory. > It fetches the frames addresses, stride and parameters from the "Canvas" memory. > This part is also in charge of the CSC (Colorspace Conversion). > It can handle 2 OSD Planes and 2 Video Planes. > > VPP: Video Processing Unit > -------------------------- > > The Video Processing Unit is in charge if the scaling and blending of the > various planes into a single pixel stream. > There is a special "pre-blending" used by the video planes with a dedicated > scaler and a "post-blending" to merge with the OSD Planes. > The OSD planes also have a dedicated scaler for one of the OSD. > > VENC: Video Encoders > -------------------- > > The VENC is composed of the multiple pixel encoders : > - ENCI : Interlace Video encoder for CVBS and Interlace HDMI > - ENCP : Progressive Video Encoder for HDMI > - ENCL : LCD LVDS Encoder > The VENC Unit gets a Pixel Clocks (VCLK) from a dedicated HDMI PLL and clock > tree and provides the scanout clock to the VPP and VIU. > The ENCI is connected to a single VDAC for Composite Output. > The ENCI and ENCP are connected to an on-chip HDMI Transceiver. > > This driver is a DRM/KMS driver using the following DRM components : > - GEM-CMA > - PRIME-CMA > - Atomic Modesetting > - FBDev-CMA > > For the following SoCs : > - GXBB Family (S905) > - GXL Family (S905X, S905D) > - GXM Family (S912) > > The current driver only supports the CVBS PAL/NTSC output modes, but the > CRTC/Planes management should support bigger modes. > But Advanced Colorspace Conversion, Scaling and HDMI Modes will be added in > a second time. > > The Device Tree bindings makes use of the endpoints video interface definitions > to connect to the optional CVBS and in the future the HDMI Connector nodes. > > HDMI Support is planned for a next release. > > Signed-off-by: Neil Armstrong <narmstrong@xxxxxxxxxxxx> Few small comments below, but looks reasonable overall. Once you have acks for the DT part pls submit the entire series as a pull request to Dave Airlie (with an additional patch to add a MAINTAINERS entry). Cheers, Daniel > --- > drivers/gpu/drm/Kconfig | 2 + > drivers/gpu/drm/Makefile | 1 + > drivers/gpu/drm/meson/Kconfig | 8 + > drivers/gpu/drm/meson/Makefile | 5 + > drivers/gpu/drm/meson/meson_canvas.c | 96 +++ > drivers/gpu/drm/meson/meson_canvas.h | 31 + > drivers/gpu/drm/meson/meson_crtc.c | 176 ++++ > drivers/gpu/drm/meson/meson_crtc.h | 34 + > drivers/gpu/drm/meson/meson_cvbs.c | 293 +++++++ > drivers/gpu/drm/meson/meson_cvbs.h | 32 + > drivers/gpu/drm/meson/meson_drv.c | 383 +++++++++ > drivers/gpu/drm/meson/meson_drv.h | 68 ++ > drivers/gpu/drm/meson/meson_plane.c | 150 ++++ > drivers/gpu/drm/meson/meson_plane.h | 32 + > drivers/gpu/drm/meson/meson_registers.h | 1395 +++++++++++++++++++++++++++++++ > drivers/gpu/drm/meson/meson_vclk.c | 169 ++++ > drivers/gpu/drm/meson/meson_vclk.h | 36 + > drivers/gpu/drm/meson/meson_venc.c | 286 +++++++ > drivers/gpu/drm/meson/meson_venc.h | 77 ++ > drivers/gpu/drm/meson/meson_viu.c | 497 +++++++++++ > drivers/gpu/drm/meson/meson_viu.h | 37 + > drivers/gpu/drm/meson/meson_vpp.c | 189 +++++ > drivers/gpu/drm/meson/meson_vpp.h | 43 + > 23 files changed, 4040 insertions(+) > create mode 100644 drivers/gpu/drm/meson/Kconfig > create mode 100644 drivers/gpu/drm/meson/Makefile > create mode 100644 drivers/gpu/drm/meson/meson_canvas.c > create mode 100644 drivers/gpu/drm/meson/meson_canvas.h > create mode 100644 drivers/gpu/drm/meson/meson_crtc.c > create mode 100644 drivers/gpu/drm/meson/meson_crtc.h > create mode 100644 drivers/gpu/drm/meson/meson_cvbs.c > create mode 100644 drivers/gpu/drm/meson/meson_cvbs.h > create mode 100644 drivers/gpu/drm/meson/meson_drv.c > create mode 100644 drivers/gpu/drm/meson/meson_drv.h > create mode 100644 drivers/gpu/drm/meson/meson_plane.c > create mode 100644 drivers/gpu/drm/meson/meson_plane.h > create mode 100644 drivers/gpu/drm/meson/meson_registers.h > create mode 100644 drivers/gpu/drm/meson/meson_vclk.c > create mode 100644 drivers/gpu/drm/meson/meson_vclk.h > create mode 100644 drivers/gpu/drm/meson/meson_venc.c > create mode 100644 drivers/gpu/drm/meson/meson_venc.h > create mode 100644 drivers/gpu/drm/meson/meson_viu.c > create mode 100644 drivers/gpu/drm/meson/meson_viu.h > create mode 100644 drivers/gpu/drm/meson/meson_vpp.c > create mode 100644 drivers/gpu/drm/meson/meson_vpp.h > > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig > index 483059a..344ced6 100644 > --- a/drivers/gpu/drm/Kconfig > +++ b/drivers/gpu/drm/Kconfig > @@ -223,6 +223,8 @@ source "drivers/gpu/drm/hisilicon/Kconfig" > > source "drivers/gpu/drm/mediatek/Kconfig" > > +source "drivers/gpu/drm/meson/Kconfig" > + > # Keep legacy drivers last > > menuconfig DRM_LEGACY > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index 25c7204..47e7c45 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -79,6 +79,7 @@ obj-$(CONFIG_DRM_TEGRA) += tegra/ > obj-$(CONFIG_DRM_STI) += sti/ > obj-$(CONFIG_DRM_IMX) += imx/ > obj-$(CONFIG_DRM_MEDIATEK) += mediatek/ > +obj-$(CONFIG_DRM_MESON) += meson/ > obj-y += i2c/ > obj-y += panel/ > obj-y += bridge/ > diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig > new file mode 100644 > index 0000000..8e5aa22 > --- /dev/null > +++ b/drivers/gpu/drm/meson/Kconfig > @@ -0,0 +1,8 @@ > +config DRM_MESON > + tristate "DRM Support for Amlogic Meson Display Controller" > + depends on DRM && OF && (ARM || ARM64) > + select DRM_KMS_HELPER > + select DRM_KMS_CMA_HELPER > + select DRM_GEM_CMA_HELPER > + select VIDEOMODE_HELPERS > + select REGMAP_MMIO > diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile > new file mode 100644 > index 0000000..ab1abfa > --- /dev/null > +++ b/drivers/gpu/drm/meson/Makefile > @@ -0,0 +1,5 @@ > +meson-y := meson_drv.o meson_plane.o meson_crtc.o > +meson-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o > + > +obj-$(CONFIG_DRM_MESON) += meson.o > +obj-$(CONFIG_DRM_MESON) += meson_cvbs.o > diff --git a/drivers/gpu/drm/meson/meson_canvas.c b/drivers/gpu/drm/meson/meson_canvas.c > new file mode 100644 > index 0000000..fe4f50f > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_canvas.c > @@ -0,0 +1,96 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <drm/drmP.h> > +#include <drm/drm_gem_cma_helper.h> > +#include <drm/drm_fb_cma_helper.h> > +#include "meson_drv.h" > +#include "meson_canvas.h" > +#include "meson_registers.h" > + > +/* > + * CANVAS is a memory zone where physical memory frames information > + * are stored for the VIU to scanout. > + */ > + > +/* DMC Registers */ > +#define DMC_CAV_LUT_DATAL 0x48 /* 0x12 offset in data sheet */ > +#define CANVAS_WIDTH_LBIT 29 > +#define CANVAS_WIDTH_LWID 3 > +#define DMC_CAV_LUT_DATAH 0x4c /* 0x13 offset in data sheet */ > +#define CANVAS_WIDTH_HBIT 0 > +#define CANVAS_HEIGHT_BIT 9 > +#define CANVAS_BLKMODE_BIT 24 > +#define DMC_CAV_LUT_ADDR 0x50 /* 0x14 offset in data sheet */ > +#define CANVAS_LUT_WR_EN (0x2 << 8) > +#define CANVAS_LUT_RD_EN (0x1 << 8) > + > +/* Canvas configuration. */ > +#define MESON_CANVAS_WRAP_NONE 0x00 > +#define MESON_CANVAS_WRAP_X 0x01 > +#define MESON_CANVAS_WRAP_Y 0x02 > + > +#define MESON_CANVAS_BLKMODE_LINEAR 0x00 > +#define MESON_CANVAS_BLKMODE_32x32 0x01 > +#define MESON_CANVAS_BLKMODE_64x64 0x02 > + > +static void meson_canvas_setup(struct meson_drm *priv, > + uint32_t canvas_index, uint32_t addr, > + uint32_t stride, uint32_t height, > + unsigned int wrap, > + unsigned int blkmode) > +{ > + unsigned int val; > + > + regmap_write(priv->dmc, DMC_CAV_LUT_DATAL, > + (((addr + 7) >> 3)) | > + (((stride + 7) >> 3) << CANVAS_WIDTH_LBIT)); > + > + regmap_write(priv->dmc, DMC_CAV_LUT_DATAH, > + ((((stride + 7) >> 3) >> CANVAS_WIDTH_LWID) << > + CANVAS_WIDTH_HBIT) | > + (height << CANVAS_HEIGHT_BIT) | > + (wrap << 22) | > + (blkmode << CANVAS_BLKMODE_BIT)); > + > + regmap_write(priv->dmc, DMC_CAV_LUT_ADDR, > + CANVAS_LUT_WR_EN | canvas_index); > + > + /* Force a read-back to make sure everything is flushed. */ > + regmap_read(priv->dmc, DMC_CAV_LUT_DATAH, &val); > +} > + > +void meson_canvas_update_osd1_buffer(struct meson_drm *priv, > + struct drm_plane *plane) > +{ > + struct drm_plane_state *state = plane->state; > + struct drm_framebuffer *fb = state->fb; > + struct drm_gem_cma_object *gem; > + > + gem = drm_fb_cma_get_gem_obj(fb, 0); > + > + /* Swap out the OSD canvas with the new addr. */ > + meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1, > + gem->paddr, fb->pitches[0], > + fb->height, MESON_CANVAS_WRAP_NONE, > + MESON_CANVAS_BLKMODE_LINEAR); > +} > diff --git a/drivers/gpu/drm/meson/meson_canvas.h b/drivers/gpu/drm/meson/meson_canvas.h > new file mode 100644 > index 0000000..542f615 > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_canvas.h > @@ -0,0 +1,31 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + */ > + > +/* Canvas LUT Memory */ > + > +#ifndef __MESON_CANVAS_H > +#define __MESON_CANVAS_H > + > +#define MESON_CANVAS_ID_OSD1 0x4e > + > +void meson_canvas_update_osd1_buffer(struct meson_drm *priv, > + struct drm_plane *plane); > + > +#endif /* __MESON_VIU_H */ > diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c > new file mode 100644 > index 0000000..d0bf04b > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_crtc.c > @@ -0,0 +1,176 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * Copyright (C) 2014 Endless Mobile > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + * > + * Written by: > + * Jasper St. Pierre <jstpierre@xxxxxxxxxxx> > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/mutex.h> > +#include <linux/platform_device.h> > +#include <drm/drmP.h> > +#include <drm/drm_atomic.h> > +#include <drm/drm_atomic_helper.h> > +#include <drm/drm_flip_work.h> > +#include <drm/drm_crtc_helper.h> > + > +#include "meson_crtc.h" > +#include "meson_plane.h" > +#include "meson_vpp.h" > +#include "meson_viu.h" > +#include "meson_venc.h" > + > +/* CRTC definition */ > + > +struct meson_crtc { > + struct drm_crtc base; > + struct drm_pending_vblank_event *event; > + struct meson_drm *priv; > +}; > +#define to_meson_crtc(x) container_of(x, struct meson_crtc, base) > + > +/* CRTC */ > + > +static const struct drm_crtc_funcs meson_crtc_funcs = { > + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, > + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, > + .destroy = drm_crtc_cleanup, > + .page_flip = drm_atomic_helper_page_flip, > + .reset = drm_atomic_helper_crtc_reset, > + .set_config = drm_atomic_helper_set_config, > +}; > + > +static void meson_crtc_enable(struct drm_crtc *crtc) > +{ > + struct meson_crtc *meson_crtc = to_meson_crtc(crtc); > + struct drm_plane *plane = meson_crtc->priv->primary_plane; > + > + meson_vpp_enable_postblend(meson_crtc->priv, plane->state->crtc_w); > + > + meson_crtc->priv->viu.osd1_enabled = true; > +} > + > +static void meson_crtc_disable(struct drm_crtc *crtc) > +{ > + struct meson_crtc *meson_crtc = to_meson_crtc(crtc); > + > + meson_crtc->priv->viu.osd1_enabled = false; > + > + meson_vpp_disable_postblend(meson_crtc->priv); > + > + if (crtc->state->event && !crtc->state->active) { > + spin_lock_irq(&crtc->dev->event_lock); > + drm_crtc_send_vblank_event(crtc, crtc->state->event); > + spin_unlock_irq(&crtc->dev->event_lock); > + > + crtc->state->event = NULL; > + } > +} > + > +static void meson_crtc_atomic_begin(struct drm_crtc *crtc, > + struct drm_crtc_state *state) > +{ > + struct meson_crtc *meson_crtc = to_meson_crtc(crtc); > + unsigned long flags; > + > + if (crtc->state->event) { > + WARN_ON(drm_crtc_vblank_get(crtc) != 0); > + > + spin_lock_irqsave(&crtc->dev->event_lock, flags); > + meson_crtc->event = crtc->state->event; > + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); > + crtc->state->event = NULL; If you set this to NULL here > + } > +} > + > +static void meson_crtc_atomic_flush(struct drm_crtc *crtc, > + struct drm_crtc_state *old_crtc_state) > +{ > + struct meson_crtc *meson_crtc = to_meson_crtc(crtc); > + struct drm_pending_vblank_event *event = crtc->state->event; > + > + if (meson_crtc->priv->viu.osd1_enabled) > + meson_crtc->priv->viu.osd1_commit = true; > + > + if (event) { > + crtc->state->event = NULL; > + > + spin_lock_irq(&crtc->dev->event_lock); > + if (drm_crtc_vblank_get(crtc) == 0) > + drm_crtc_arm_vblank_event(crtc, event); > + else > + drm_crtc_send_vblank_event(crtc, event); > + spin_unlock_irq(&crtc->dev->event_lock); > + } This here becomes dead code. And indeed it is, since you have your own special crtc/vblank irq handling code right below. Please remove to avoid confusion. > +} > + > +static const struct drm_crtc_helper_funcs meson_crtc_helper_funcs = { > + .enable = meson_crtc_enable, > + .disable = meson_crtc_disable, > + .atomic_begin = meson_crtc_atomic_begin, > + .atomic_flush = meson_crtc_atomic_flush, > +}; > + > +void meson_crtc_irq(struct meson_drm *priv) > +{ > + struct meson_crtc *meson_crtc = to_meson_crtc(priv->crtc); > + unsigned long flags; > + > + meson_viu_sync_osd1(priv); > + > + drm_crtc_handle_vblank(priv->crtc); > + > + spin_lock_irqsave(&priv->drm->event_lock, flags); > + if (meson_crtc->event) { > + drm_crtc_send_vblank_event(priv->crtc, meson_crtc->event); > + drm_crtc_vblank_put(priv->crtc); > + meson_crtc->event = NULL; > + } > + spin_unlock_irqrestore(&priv->drm->event_lock, flags); > +} > + > +int meson_crtc_create(struct meson_drm *priv) > +{ > + struct meson_crtc *meson_crtc; > + struct drm_crtc *crtc; > + int ret; > + > + meson_crtc = devm_kzalloc(priv->drm->dev, sizeof(*meson_crtc), > + GFP_KERNEL); > + if (!meson_crtc) > + return -ENOMEM; > + > + meson_crtc->priv = priv; > + crtc = &meson_crtc->base; > + ret = drm_crtc_init_with_planes(priv->drm, crtc, > + priv->primary_plane, NULL, > + &meson_crtc_funcs, "meson_crtc"); > + if (ret) { > + dev_err(priv->drm->dev, "Failed to init CRTC\n"); > + return ret; > + } > + > + drm_crtc_helper_add(crtc, &meson_crtc_helper_funcs); > + > + priv->crtc = crtc; > + > + return 0; > +} > diff --git a/drivers/gpu/drm/meson/meson_crtc.h b/drivers/gpu/drm/meson/meson_crtc.h > new file mode 100644 > index 0000000..9f0c20b > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_crtc.h > @@ -0,0 +1,34 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * Copyright (C) 2014 Endless Mobile > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + * > + * Written by: > + * Jasper St. Pierre <jstpierre@xxxxxxxxxxx> > + */ > + > +#ifndef __MESON_CRTC_H > +#define __MESON_CRTC_H > + > +#include "meson_drv.h" > + > +int meson_crtc_create(struct meson_drm *priv); > + > +void meson_crtc_irq(struct meson_drm *priv); > + > +#endif /* __MESON_CRTC_H */ > diff --git a/drivers/gpu/drm/meson/meson_cvbs.c b/drivers/gpu/drm/meson/meson_cvbs.c > new file mode 100644 > index 0000000..d5f2441 > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_cvbs.c > @@ -0,0 +1,293 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * Copyright (C) 2014 Endless Mobile > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + * > + * Written by: > + * Jasper St. Pierre <jstpierre@xxxxxxxxxxx> > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/component.h> > + > +#include <drm/drmP.h> > +#include <drm/drm_edid.h> > +#include <drm/drm_crtc_helper.h> > +#include <drm/drm_atomic_helper.h> > + > +#include "meson_cvbs.h" > +#include "meson_venc.h" > + > +struct meson_cvbs_mode { > + struct meson_cvbs_enci_mode *enci; > + struct drm_display_mode mode; > +}; > +struct meson_cvbs { > + struct drm_connector connector; > + struct drm_encoder encoder; > + struct meson_drm *priv; > + struct meson_cvbs_mode *mode; > +}; > +#define connector_to_meson_cvbs(x) \ > + container_of(x, struct meson_cvbs, connector) > +#define encoder_to_meson_cvbs(x) \ > + container_of(x, struct meson_cvbs, encoder) > + > +/* Supported Modes */ > + > +struct meson_cvbs_mode meson_cvbs_modes[] = { > + { /* PAL */ > + .enci = &meson_cvbs_enci_pal, > + .mode = { > + DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, > + 720, 732, 795, 864, 0, 576, 580, 586, 625, 0, > + DRM_MODE_FLAG_INTERLACE), > + .vrefresh = 50, > + .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, > + }, > + }, > + { /* NTSC */ > + .enci = &meson_cvbs_enci_ntsc, > + .mode = { > + DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, > + 720, 739, 801, 858, 0, 480, 488, 494, 525, 0, > + DRM_MODE_FLAG_INTERLACE), > + .vrefresh = 60, > + .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, > + }, > + }, > +}; > + > +/* Encoder */ > + > +static void meson_cvbs_encoder_destroy(struct drm_encoder *encoder) > +{ > + drm_encoder_cleanup(encoder); > +} > + > +static const struct drm_encoder_funcs meson_cvbs_encoder_funcs = { > + .destroy = meson_cvbs_encoder_destroy, > +}; > + > +static int meson_cvbs_encoder_atomic_check(struct drm_encoder *encoder, > + struct drm_crtc_state *crtc_state, > + struct drm_connector_state *conn_state) > +{ > + return 0; > +} Dummy atomic_check isn't needed, pls remove. > + > +static void meson_cvbs_encoder_disable(struct drm_encoder *encoder) > +{ > + struct meson_cvbs *meson_cvbs = encoder_to_meson_cvbs(encoder); > + > + meson_venci_cvbs_disable(meson_cvbs->priv); > +} > + > +static void meson_cvbs_encoder_enable(struct drm_encoder *encoder) > +{ > + struct meson_cvbs *meson_cvbs = encoder_to_meson_cvbs(encoder); > + > + meson_venci_cvbs_enable(meson_cvbs->priv); > +} Personally I'd remove the indirection above, more direct code is easier to read. > + > +static void meson_cvbs_encoder_mode_set(struct drm_encoder *encoder, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > +{ > + struct meson_cvbs *meson_cvbs = encoder_to_meson_cvbs(encoder); > + int i; > + > + drm_mode_debug_printmodeline(mode); > + > + for (i = 0; i < ARRAY_SIZE(meson_cvbs_modes); ++i) { > + struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; > + > + if (drm_mode_equal(mode, &meson_mode->mode)) { > + meson_cvbs->mode = meson_mode; > + > + meson_venci_cvbs_mode_set(meson_cvbs->priv, > + meson_mode->enci); > + break; > + } > + } > +} What happens if userspace sets a mode you don't have? I guess you do need a real atomic_check, so you can return -EINVAL if that's the case ;-) > + > +static const struct drm_encoder_helper_funcs meson_cvbs_encoder_helper_funcs = { > + .atomic_check = meson_cvbs_encoder_atomic_check, > + .disable = meson_cvbs_encoder_disable, > + .enable = meson_cvbs_encoder_enable, > + .mode_set = meson_cvbs_encoder_mode_set, > +}; > + > +/* Connector */ > + > +static void meson_cvbs_connector_destroy(struct drm_connector *connector) > +{ > + drm_connector_cleanup(connector); > +} > + > +static enum drm_connector_status > +meson_cvbs_connector_detect(struct drm_connector *connector, bool force) > +{ FIXME: Implement load-detect? > + return connector_status_connected; > +} > + > +static int meson_cvbs_connector_get_modes(struct drm_connector *connector) > +{ > + struct drm_device *dev = connector->dev; > + struct drm_display_mode *mode; > + int i; > + > + for (i = 0; i < ARRAY_SIZE(meson_cvbs_modes); ++i) { > + struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; > + > + mode = drm_mode_duplicate(dev, &meson_mode->mode); > + if (!mode) { > + DRM_ERROR("Failed to create a new display mode\n"); > + return 0; > + } > + > + drm_mode_probed_add(connector, mode); > + } > + > + return i; > +} > + > +static int meson_cvbs_connector_mode_valid(struct drm_connector *connector, > + struct drm_display_mode *mode) > +{ > + int i; > + > + for (i = 0; i < ARRAY_SIZE(meson_cvbs_modes); ++i) { > + struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; > + > + if (drm_mode_equal(mode, &meson_mode->mode)) > + return MODE_OK; > + } > + > + return MODE_BAD; > +} Ok, this is confusion, but I thought the docs explain this. mode_valid is only to validate the modes added in get_modes. This is useful for outputs which add modes from an EDID, but not in this case. Having a mode_valid unfortunately doesn't ensure that these modes will be rejected in a modeset, for that you need a separate mode_fixup or atomic_check on the encoder. It's a bit a long-standing issue, but not entirely non-trivial to fix up: In the general case the atomic_check is for a specific configuration, whereaas mode_valid must only filter modes that won't work in any configuration. For display blocks with lots of shared resources there's a big difference between the two. Please double-check the kerneldoc for all these hooks, and if this is not clearly enough explained for you then pls raise this (or even better, submit at patch). > + > +static const struct drm_connector_funcs meson_cvbs_connector_funcs = { > + .dpms = drm_atomic_helper_connector_dpms, > + .detect = meson_cvbs_connector_detect, > + .fill_modes = drm_helper_probe_single_connector_modes, > + .destroy = meson_cvbs_connector_destroy, > + .reset = drm_atomic_helper_connector_reset, > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, > + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, > +}; > + > +static const > +struct drm_connector_helper_funcs meson_cvbs_connector_helper_funcs = { > + .get_modes = meson_cvbs_connector_get_modes, > + .mode_valid = meson_cvbs_connector_mode_valid, > +}; > + > +static int meson_cvbs_bind(struct device *dev, struct device *master, > + void *data) > +{ > + struct drm_device *drm = data; > + struct meson_drm *priv = drm->dev_private; > + struct meson_cvbs *meson_cvbs; > + struct drm_connector *connector; > + struct drm_encoder *encoder; > + int ret; > + > + meson_cvbs = devm_kzalloc(dev, sizeof(*meson_cvbs), GFP_KERNEL); > + if (!meson_cvbs) > + return -ENOMEM; > + > + meson_cvbs->priv = priv; > + connector = &meson_cvbs->connector; > + encoder = &meson_cvbs->encoder; > + > + /* Encoder */ > + > + drm_encoder_helper_add(encoder, &meson_cvbs_encoder_helper_funcs); > + > + ret = drm_encoder_init(drm, encoder, &meson_cvbs_encoder_funcs, > + DRM_MODE_ENCODER_TVDAC, "meson_cvbs"); > + if (ret) { > + dev_err(dev, "Failed to init CVBS encoder\n"); > + return ret; > + } > + > + encoder->possible_crtcs = BIT(0); > + > + /* Connector */ > + > + drm_connector_helper_add(connector, > + &meson_cvbs_connector_helper_funcs); > + > + drm_connector_init(drm, connector, &meson_cvbs_connector_funcs, > + DRM_MODE_CONNECTOR_Composite); > + if (ret) { > + dev_err(dev, "Failed to init CVBS connector\n"); > + return ret; > + } > + > + connector->interlace_allowed = 1; > + > + drm_mode_connector_attach_encoder(connector, encoder); > + > + return 0; > +} > + > +static void meson_cvbs_unbind(struct device *dev, struct device *master, > + void *data) > +{ > + /* Nothing to do yet */ > +} > + > +static const struct component_ops meson_cvbs_ops = { > + .bind = meson_cvbs_bind, > + .unbind = meson_cvbs_unbind, > +}; > + > +static int meson_cvbs_probe(struct platform_device *pdev) > +{ > + return component_add(&pdev->dev, &meson_cvbs_ops); > +} > + > +static int meson_cvbs_remove(struct platform_device *pdev) > +{ > + component_del(&pdev->dev, &meson_cvbs_ops); > + > + return 0; > +} > + > +static const struct of_device_id meson_cvbs_of_table[] = { > + { .compatible = "amlogic,meson-gx-venc-cvbs" }, > + { .compatible = "amlogic,meson-gxl-venc-cvbs" }, > + { .compatible = "amlogic,meson-gxm-venc-cvbs" }, > + { .compatible = "amlogic,meson-gxbb-venc-cvbs" }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, meson_cvbs_of_table); > + > +static struct platform_driver meson_cvbs_platform_driver = { > + .probe = meson_cvbs_probe, > + .remove = meson_cvbs_remove, > + .driver = { > + .name = "meson-cvbs", > + .of_match_table = meson_cvbs_of_table, > + }, > +}; > +module_platform_driver(meson_cvbs_platform_driver); > diff --git a/drivers/gpu/drm/meson/meson_cvbs.h b/drivers/gpu/drm/meson/meson_cvbs.h > new file mode 100644 > index 0000000..6d5ade7 > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_cvbs.h > @@ -0,0 +1,32 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * Copyright (C) 2014 Endless Mobile > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + * > + * Written by: > + * Jasper St. Pierre <jstpierre@xxxxxxxxxxx> > + */ > + > +#ifndef __MESON_CVBS_H > +#define __MESON_CVBS_H > + > +#include "meson_drv.h" > + > +int meson_cvbs_create(struct meson_drm *priv); > + > +#endif /* __MESON_CVBS_H */ > diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c > new file mode 100644 > index 0000000..8b4a5bf > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_drv.c > @@ -0,0 +1,383 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * Copyright (C) 2014 Endless Mobile > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + * > + * Written by: > + * Jasper St. Pierre <jstpierre@xxxxxxxxxxx> > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/mutex.h> > +#include <linux/platform_device.h> > +#include <linux/component.h> > +#include <linux/of_graph.h> > + > +#include <drm/drmP.h> > +#include <drm/drm_atomic.h> > +#include <drm/drm_atomic_helper.h> > +#include <drm/drm_flip_work.h> > +#include <drm/drm_crtc_helper.h> > +#include <drm/drm_plane_helper.h> > +#include <drm/drm_gem_cma_helper.h> > +#include <drm/drm_fb_cma_helper.h> > +#include <drm/drm_rect.h> > +#include <drm/drm_fb_helper.h> > + > +#include "meson_drv.h" > +#include "meson_cvbs.h" > +#include "meson_plane.h" > +#include "meson_crtc.h" > + > +#include "meson_vpp.h" > +#include "meson_viu.h" > +#include "meson_venc.h" > +#include "meson_canvas.h" > +#include "meson_registers.h" > + > +#define DRIVER_NAME "meson" > +#define DRIVER_DESC "Amlogic Meson DRM driver" > + > +/* > + * Video Procesing unig > + * > + * VPU Handles the Global Video Processing, it includes management of the > + * clocks gates, blocks reset lines and power domains. > + * > + * What is missing : > + * - Full reset of entire video processing HW blocks > + * - Scaling and setup of the VPU clock > + * - Bus clock gates > + * - Powering up video processing HW blocks > + * - Powering Up HDMI controller and PHY > + */ > + > +static void meson_fb_output_poll_changed(struct drm_device *dev) > +{ > + struct meson_drm *priv = dev->dev_private; > + > + drm_fbdev_cma_hotplug_event(priv->fbdev); > +} > + > +static const struct drm_mode_config_funcs meson_mode_config_funcs = { > + .output_poll_changed = meson_fb_output_poll_changed, > + .atomic_check = drm_atomic_helper_check, > + .atomic_commit = drm_atomic_helper_commit, > + .fb_create = drm_fb_cma_create, > +}; > + > +static int meson_enable_vblank(struct drm_device *dev, unsigned int crtc) > +{ > + struct meson_drm *priv = dev->dev_private; > + > + meson_venc_enable_vsync(priv); > + > + return 0; > +} > + > +static void meson_disable_vblank(struct drm_device *dev, unsigned int crtc) > +{ > + struct meson_drm *priv = dev->dev_private; > + > + meson_venc_disable_vsync(priv); > +} > + > +static irqreturn_t meson_irq(int irq, void *arg) > +{ > + struct drm_device *dev = arg; > + struct meson_drm *priv = dev->dev_private; > + > + (void)readl_relaxed(priv->io_base + _REG(VENC_INTFLAG)); > + > + meson_crtc_irq(priv); > + > + return IRQ_HANDLED; > +} > + > +static const struct file_operations fops = { > + .owner = THIS_MODULE, > + .open = drm_open, > + .release = drm_release, > + .unlocked_ioctl = drm_ioctl, > +#ifdef CONFIG_COMPAT > + .compat_ioctl = drm_compat_ioctl, > +#endif > + .poll = drm_poll, > + .read = drm_read, > + .llseek = no_llseek, > + .mmap = drm_gem_cma_mmap, > +}; > + > +static struct drm_driver meson_driver = { > + .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | > + DRIVER_MODESET | DRIVER_PRIME | > + DRIVER_ATOMIC, > + > + /* Vblank */ > + .enable_vblank = meson_enable_vblank, > + .disable_vblank = meson_disable_vblank, > + .get_vblank_counter = drm_vblank_no_hw_counter, > + > + /* IRQ */ > + .irq_handler = meson_irq, > + > + /* PRIME Ops */ > + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, > + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, > + .gem_prime_import = drm_gem_prime_import, > + .gem_prime_export = drm_gem_prime_export, > + .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, > + .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, > + .gem_prime_vmap = drm_gem_cma_prime_vmap, > + .gem_prime_vunmap = drm_gem_cma_prime_vunmap, > + .gem_prime_mmap = drm_gem_cma_prime_mmap, > + > + /* GEM Ops */ > + .dumb_create = drm_gem_cma_dumb_create, > + .dumb_destroy = drm_gem_dumb_destroy, > + .dumb_map_offset = drm_gem_cma_dumb_map_offset, > + .gem_free_object_unlocked = drm_gem_cma_free_object, > + .gem_vm_ops = &drm_gem_cma_vm_ops, > + > + /* Misc */ > + .fops = &fops, > + .name = DRIVER_NAME, > + .desc = DRIVER_DESC, > + .date = "20161109", > + .major = 1, > + .minor = 0, > +}; > + > +static struct regmap_config meson_regmap_config = { > + .reg_bits = 32, > + .val_bits = 32, > + .reg_stride = 4, > + .max_register = 0x1000, > +}; > + > +static int meson_drv_bind(struct device *dev) > +{ > + struct platform_device *pdev = to_platform_device(dev); > + struct meson_drm *priv; > + struct drm_device *drm; > + struct resource *res; > + void __iomem *regs; > + int ret; > + > + drm = drm_dev_alloc(&meson_driver, dev); > + if (IS_ERR(drm)) > + return PTR_ERR(drm); > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) { > + ret = -ENOMEM; > + goto free_drm; > + } > + drm->dev_private = priv; > + priv->drm = drm; > + priv->dev = dev; > + > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base"); > + regs = devm_ioremap_resource(dev, res); > + if (IS_ERR(regs)) > + return PTR_ERR(regs); > + > + priv->io_base = regs; > + > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi"); > + /* Simply ioremap since it may be a shared register zone */ > + regs = devm_ioremap(dev, res->start, resource_size(res)); > + if (!regs) > + return -EADDRNOTAVAIL; > + > + priv->hhi = devm_regmap_init_mmio(dev, regs, > + &meson_regmap_config); > + if (IS_ERR(priv->hhi)) { > + dev_err(&pdev->dev, "Couldn't create the HHI regmap\n"); > + return PTR_ERR(priv->hhi); > + } > + > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc"); > + /* Simply ioremap since it may be a shared register zone */ > + regs = devm_ioremap(dev, res->start, resource_size(res)); > + if (!regs) > + return -EADDRNOTAVAIL; > + > + priv->dmc = devm_regmap_init_mmio(dev, regs, > + &meson_regmap_config); > + if (IS_ERR(priv->dmc)) { > + dev_err(&pdev->dev, "Couldn't create the DMC regmap\n"); > + return PTR_ERR(priv->dmc); > + } > + > + priv->vsync_irq = platform_get_irq(pdev, 0); > + > + /* Hardware Initialization */ > + > + meson_vpp_init(priv); > + meson_viu_init(priv); > + meson_venc_init(priv); > + > + drm_vblank_init(drm, 1); > + drm_mode_config_init(drm); > + > + /* Components Initialization */ > + > + ret = component_bind_all(drm->dev, drm); > + if (ret) { > + dev_err(drm->dev, "Couldn't bind all components\n"); > + goto free_drm; > + } > + > + ret = meson_plane_create(priv); > + if (ret) > + goto free_drm; > + > + ret = meson_crtc_create(priv); > + if (ret) > + goto free_drm; > + > + ret = drm_irq_install(drm, priv->vsync_irq); > + if (ret) > + goto free_drm; > + > + drm_mode_config_reset(drm); > + drm->mode_config.max_width = 8192; > + drm->mode_config.max_height = 8192; > + drm->mode_config.funcs = &meson_mode_config_funcs; > + > + priv->fbdev = drm_fbdev_cma_init(drm, 32, > + drm->mode_config.num_crtc, > + drm->mode_config.num_connector); > + if (IS_ERR(priv->fbdev)) { > + ret = PTR_ERR(priv->fbdev); > + goto free_drm; > + } > + > + drm_kms_helper_poll_init(drm); > + > + ret = drm_dev_register(drm, 0); > + if (ret) > + goto free_drm; > + > + platform_set_drvdata(pdev, priv); You need this before the drm_dev_register call I think. > + > + return 0; > + > +free_drm: > + drm_dev_unref(drm); > + > + return ret; > +} > + > +static void meson_drv_unbind(struct device *dev) > +{ > + struct drm_device *drm = dev_get_drvdata(dev); > + struct meson_drm *priv = drm->dev_private; > + > + drm_dev_unregister(drm); > + drm_kms_helper_poll_fini(drm); > + drm_fbdev_cma_fini(priv->fbdev); > + drm_mode_config_cleanup(drm); > + drm_vblank_cleanup(drm); > + drm_dev_unref(drm); > +} > + > +static const struct component_master_ops meson_drv_master_ops = { > + .bind = meson_drv_bind, > + .unbind = meson_drv_unbind, > +}; > + > +static int compare_of(struct device *dev, void *data) > +{ > + DRM_DEBUG_DRIVER("Comparing of node %s with %s\n", > + of_node_full_name(dev->of_node), > + of_node_full_name(data)); > + > + return dev->of_node == data; > +} > + > +static int meson_pdev_probe(struct platform_device *pdev) > +{ > + struct component_match *match = NULL; > + struct device_node *np = pdev->dev.of_node; > + struct device_node *port, *ep, *remote; > + int count = 0; > + > + /* Get output port */ > + port = of_graph_get_port_by_id(np, 1); > + if (!port) { > + dev_err(&pdev->dev, "No output to bind\n"); > + return 0; > + } > + > + /* Get each output endpoints, and connect them is available */ > + for_each_available_child_of_node(port, ep) { > + remote = of_graph_get_remote_port_parent(ep); > + if (!remote) { > + dev_err(&pdev->dev, "Error retrieving the output node\n"); > + of_node_put(remote); > + continue; > + } > + > + if (!of_device_is_available(remote)) > + continue; > + > + component_match_add(&pdev->dev, &match, compare_of, remote); > + > + ++count; > + > + of_node_put(remote); > + } > + > + /* If some endpoints were found, initialize the nodes */ > + if (count) { > + dev_info(&pdev->dev, "Queued %d outputs on vpu\n", count); > + > + return component_master_add_with_match(&pdev->dev, > + &meson_drv_master_ops, > + match); > + } > + > + /* If no output endpoints were available, simply bail out */ > + return 0; > +}; > + > +static const struct of_device_id dt_match[] = { > + { .compatible = "amlogic,meson-gxbb-vpu" }, > + { .compatible = "amlogic,meson-gxl-vpu" }, > + { .compatible = "amlogic,meson-gxm-vpu" }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, dt_match); > + > +static struct platform_driver meson_drm_platform_driver = { > + .probe = meson_pdev_probe, > + .driver = { > + .owner = THIS_MODULE, > + .name = DRIVER_NAME, > + .of_match_table = dt_match, > + }, > +}; > + > +module_platform_driver(meson_drm_platform_driver); > + > +MODULE_AUTHOR("Jasper St. Pierre <jstpierre@xxxxxxxxxxx>"); > +MODULE_DESCRIPTION(DRIVER_DESC); > +MODULE_LICENSE("GPL"); > diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h > new file mode 100644 > index 0000000..db15eff > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_drv.h > @@ -0,0 +1,68 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + */ > + > +#ifndef __MESON_DRV_H > +#define __MESON_DRV_H > + > +#include <linux/platform_device.h> > +#include <linux/regmap.h> > +#include <linux/of.h> > +#include <drm/drmP.h> > + > +struct meson_drm { > + struct device *dev; > + void __iomem *io_base; > + struct regmap *hhi; > + struct regmap *dmc; > + int vsync_irq; > + > + struct drm_device *drm; > + struct drm_crtc *crtc; > + struct drm_fbdev_cma *fbdev; > + struct drm_plane *primary_plane; > + > + /* VPU Clocks */ > + struct clk *clk_vpu; > + struct clk *clk_vpu0; > + struct clk *clk_fclk_div; > + > + /* Components Data */ > + struct { > + bool osd1_enabled; > + bool osd1_interlace; > + bool osd1_commit; > + uint32_t osd1_ctrl_stat; > + uint32_t osd1_blk0_cfg[5]; > + } viu; > + > + struct { > + unsigned int current_mode; > + bool cvbs_enabled; > + } venc; > +}; > + > +static inline int meson_vpu_is_compatible(struct meson_drm *priv, > + const char *compat) > +{ > + return of_device_is_compatible(priv->dev->of_node, compat); > +} > + > + > +#endif /* __MESON_DRV_H */ > diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c > new file mode 100644 > index 0000000..fa0178f > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_plane.c > @@ -0,0 +1,150 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * Copyright (C) 2014 Endless Mobile > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + * > + * Written by: > + * Jasper St. Pierre <jstpierre@xxxxxxxxxxx> > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/mutex.h> > +#include <linux/platform_device.h> > +#include <drm/drmP.h> > +#include <drm/drm_atomic.h> > +#include <drm/drm_atomic_helper.h> > +#include <drm/drm_plane_helper.h> > +#include <drm/drm_rect.h> > + > +#include "meson_plane.h" > +#include "meson_vpp.h" > +#include "meson_viu.h" > +#include "meson_canvas.h" > + > +struct meson_plane { > + struct drm_plane base; > + struct meson_drm *priv; > +}; > +#define to_meson_plane(x) container_of(x, struct meson_plane, base) > + > +static int meson_plane_atomic_check(struct drm_plane *plane, > + struct drm_plane_state *state) > +{ > + struct drm_rect src = { > + .x1 = state->src_x, > + .y1 = state->src_y, > + .x2 = state->src_x + state->src_w, > + .y2 = state->src_y + state->src_h, > + }; > + struct drm_rect dest = { > + .x1 = state->crtc_x, > + .y1 = state->crtc_y, > + .x2 = state->crtc_x + state->crtc_w, > + .y2 = state->crtc_y + state->crtc_h, > + }; > + > + if (state->fb) { > + int ret; > + > + ret = drm_rect_calc_hscale(&src, &dest, > + DRM_PLANE_HELPER_NO_SCALING, > + DRM_PLANE_HELPER_NO_SCALING); > + if (ret < 0) > + return ret; > + > + ret = drm_rect_calc_vscale(&src, &dest, > + DRM_PLANE_HELPER_NO_SCALING, > + DRM_PLANE_HELPER_NO_SCALING); > + if (ret < 0) > + return ret; > + } drm_plane_helper_check_state gives you the above in less code. > + > + return 0; > +} > + > +static void meson_plane_atomic_update(struct drm_plane *plane, > + struct drm_plane_state *old_state) > +{ > + struct meson_plane *meson_plane = to_meson_plane(plane); > + > + /* > + * Update Coordinates > + * Update Formats > + * Update Buffer > + * Enable Plane > + */ > + meson_viu_update_osd1(meson_plane->priv, plane); > + meson_canvas_update_osd1_buffer(meson_plane->priv, plane); > +} > + > +static void meson_plane_atomic_disable(struct drm_plane *plane, > + struct drm_plane_state *old_state) > +{ > + struct meson_plane *meson_plane = to_meson_plane(plane); > + > + meson_vpp_disable_osd1(meson_plane->priv); > +} > + > +static const struct drm_plane_helper_funcs meson_plane_helper_funcs = { > + .atomic_check = meson_plane_atomic_check, > + .atomic_disable = meson_plane_atomic_disable, > + .atomic_update = meson_plane_atomic_update, > +}; > + > +static const struct drm_plane_funcs meson_plane_funcs = { > + .update_plane = drm_atomic_helper_update_plane, > + .disable_plane = drm_atomic_helper_disable_plane, > + .destroy = drm_plane_cleanup, > + .reset = drm_atomic_helper_plane_reset, > + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, > + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, > +}; > + > +static const uint32_t supported_drm_formats[] = { > + DRM_FORMAT_ARGB8888, > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_RGB888, > + DRM_FORMAT_RGB565, > +}; > + > +int meson_plane_create(struct meson_drm *priv) > +{ > + struct meson_plane *meson_plane; > + struct drm_plane *plane; > + > + meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane), > + GFP_KERNEL); > + if (!meson_plane) > + return -ENOMEM; > + > + meson_plane->priv = priv; > + plane = &meson_plane->base; > + > + drm_universal_plane_init(priv->drm, plane, 0xFF, > + &meson_plane_funcs, > + supported_drm_formats, > + ARRAY_SIZE(supported_drm_formats), > + DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane"); > + > + drm_plane_helper_add(plane, &meson_plane_helper_funcs); > + > + priv->primary_plane = plane; > + > + return 0; > +} > diff --git a/drivers/gpu/drm/meson/meson_plane.h b/drivers/gpu/drm/meson/meson_plane.h > new file mode 100644 > index 0000000..babb9e1 > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_plane.h > @@ -0,0 +1,32 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * Copyright (C) 2014 Endless Mobile > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + * > + * Written by: > + * Jasper St. Pierre <jstpierre@xxxxxxxxxxx> > + */ > + > +#ifndef __MESON_PLANE_H > +#define __MESON_PLANE_H > + > +#include "meson_drv.h" > + > +int meson_plane_create(struct meson_drm *priv); > + > +#endif /* __MESON_PLANE_H */ > diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h > new file mode 100644 > index 0000000..6adf9c1 > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_registers.h > @@ -0,0 +1,1395 @@ > +/* > + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + */ > + > +#ifndef __MESON_REGISTERS_H > +#define __MESON_REGISTERS_H > + > +/* Shift all registers by 2 */ > +#define _REG(reg) ((reg) << 2) > + > +#define writel_bits_relaxed(mask, val, addr) \ > + writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr) > + > +/* vpp2 */ > +#define VPP2_DUMMY_DATA 0x1900 > +#define VPP2_LINE_IN_LENGTH 0x1901 > +#define VPP2_PIC_IN_HEIGHT 0x1902 > +#define VPP2_SCALE_COEF_IDX 0x1903 > +#define VPP2_SCALE_COEF 0x1904 > +#define VPP2_VSC_REGION12_STARTP 0x1905 > +#define VPP2_VSC_REGION34_STARTP 0x1906 > +#define VPP2_VSC_REGION4_ENDP 0x1907 > +#define VPP2_VSC_START_PHASE_STEP 0x1908 > +#define VPP2_VSC_REGION0_PHASE_SLOPE 0x1909 > +#define VPP2_VSC_REGION1_PHASE_SLOPE 0x190a > +#define VPP2_VSC_REGION3_PHASE_SLOPE 0x190b > +#define VPP2_VSC_REGION4_PHASE_SLOPE 0x190c > +#define VPP2_VSC_PHASE_CTRL 0x190d > +#define VPP2_VSC_INI_PHASE 0x190e > +#define VPP2_HSC_REGION12_STARTP 0x1910 > +#define VPP2_HSC_REGION34_STARTP 0x1911 > +#define VPP2_HSC_REGION4_ENDP 0x1912 > +#define VPP2_HSC_START_PHASE_STEP 0x1913 > +#define VPP2_HSC_REGION0_PHASE_SLOPE 0x1914 > +#define VPP2_HSC_REGION1_PHASE_SLOPE 0x1915 > +#define VPP2_HSC_REGION3_PHASE_SLOPE 0x1916 > +#define VPP2_HSC_REGION4_PHASE_SLOPE 0x1917 > +#define VPP2_HSC_PHASE_CTRL 0x1918 > +#define VPP2_SC_MISC 0x1919 > +#define VPP2_PREBLEND_VD1_H_START_END 0x191a > +#define VPP2_PREBLEND_VD1_V_START_END 0x191b > +#define VPP2_POSTBLEND_VD1_H_START_END 0x191c > +#define VPP2_POSTBLEND_VD1_V_START_END 0x191d > +#define VPP2_PREBLEND_H_SIZE 0x1920 > +#define VPP2_POSTBLEND_H_SIZE 0x1921 > +#define VPP2_HOLD_LINES 0x1922 > +#define VPP2_BLEND_ONECOLOR_CTRL 0x1923 > +#define VPP2_PREBLEND_CURRENT_XY 0x1924 > +#define VPP2_POSTBLEND_CURRENT_XY 0x1925 > +#define VPP2_MISC 0x1926 > +#define VPP2_OFIFO_SIZE 0x1927 > +#define VPP2_FIFO_STATUS 0x1928 > +#define VPP2_SMOKE_CTRL 0x1929 > +#define VPP2_SMOKE1_VAL 0x192a > +#define VPP2_SMOKE2_VAL 0x192b > +#define VPP2_SMOKE1_H_START_END 0x192d > +#define VPP2_SMOKE1_V_START_END 0x192e > +#define VPP2_SMOKE2_H_START_END 0x192f > +#define VPP2_SMOKE2_V_START_END 0x1930 > +#define VPP2_SCO_FIFO_CTRL 0x1933 > +#define VPP2_HSC_PHASE_CTRL1 0x1934 > +#define VPP2_HSC_INI_PAT_CTRL 0x1935 > +#define VPP2_VADJ_CTRL 0x1940 > +#define VPP2_VADJ1_Y 0x1941 > +#define VPP2_VADJ1_MA_MB 0x1942 > +#define VPP2_VADJ1_MC_MD 0x1943 > +#define VPP2_VADJ2_Y 0x1944 > +#define VPP2_VADJ2_MA_MB 0x1945 > +#define VPP2_VADJ2_MC_MD 0x1946 > +#define VPP2_MATRIX_PROBE_COLOR 0x195c > +#define VPP2_MATRIX_HL_COLOR 0x195d > +#define VPP2_MATRIX_PROBE_POS 0x195e > +#define VPP2_MATRIX_CTRL 0x195f > +#define VPP2_MATRIX_COEF00_01 0x1960 > +#define VPP2_MATRIX_COEF02_10 0x1961 > +#define VPP2_MATRIX_COEF11_12 0x1962 > +#define VPP2_MATRIX_COEF20_21 0x1963 > +#define VPP2_MATRIX_COEF22 0x1964 > +#define VPP2_MATRIX_OFFSET0_1 0x1965 > +#define VPP2_MATRIX_OFFSET2 0x1966 > +#define VPP2_MATRIX_PRE_OFFSET0_1 0x1967 > +#define VPP2_MATRIX_PRE_OFFSET2 0x1968 > +#define VPP2_DUMMY_DATA1 0x1969 > +#define VPP2_GAINOFF_CTRL0 0x196a > +#define VPP2_GAINOFF_CTRL1 0x196b > +#define VPP2_GAINOFF_CTRL2 0x196c > +#define VPP2_GAINOFF_CTRL3 0x196d > +#define VPP2_GAINOFF_CTRL4 0x196e > +#define VPP2_CHROMA_ADDR_PORT 0x1970 > +#define VPP2_CHROMA_DATA_PORT 0x1971 > +#define VPP2_GCLK_CTRL0 0x1972 > +#define VPP2_GCLK_CTRL1 0x1973 > +#define VPP2_SC_GCLK_CTRL 0x1974 > +#define VPP2_MISC1 0x1976 > +#define VPP2_DNLP_CTRL_00 0x1981 > +#define VPP2_DNLP_CTRL_01 0x1982 > +#define VPP2_DNLP_CTRL_02 0x1983 > +#define VPP2_DNLP_CTRL_03 0x1984 > +#define VPP2_DNLP_CTRL_04 0x1985 > +#define VPP2_DNLP_CTRL_05 0x1986 > +#define VPP2_DNLP_CTRL_06 0x1987 > +#define VPP2_DNLP_CTRL_07 0x1988 > +#define VPP2_DNLP_CTRL_08 0x1989 > +#define VPP2_DNLP_CTRL_09 0x198a > +#define VPP2_DNLP_CTRL_10 0x198b > +#define VPP2_DNLP_CTRL_11 0x198c > +#define VPP2_DNLP_CTRL_12 0x198d > +#define VPP2_DNLP_CTRL_13 0x198e > +#define VPP2_DNLP_CTRL_14 0x198f > +#define VPP2_DNLP_CTRL_15 0x1990 > +#define VPP2_VE_ENABLE_CTRL 0x19a1 > +#define VPP2_VE_DEMO_LEFT_TOP_SCREEN_WIDTH 0x19a2 > +#define VPP2_VE_DEMO_CENTER_BAR 0x19a3 > +#define VPP2_VE_H_V_SIZE 0x19a4 > +#define VPP2_VDO_MEAS_CTRL 0x19a8 > +#define VPP2_VDO_MEAS_VS_COUNT_HI 0x19a9 > +#define VPP2_VDO_MEAS_VS_COUNT_LO 0x19aa > +#define VPP2_OSD_VSC_PHASE_STEP 0x19c0 > +#define VPP2_OSD_VSC_INI_PHASE 0x19c1 > +#define VPP2_OSD_VSC_CTRL0 0x19c2 > +#define VPP2_OSD_HSC_PHASE_STEP 0x19c3 > +#define VPP2_OSD_HSC_INI_PHASE 0x19c4 > +#define VPP2_OSD_HSC_CTRL0 0x19c5 > +#define VPP2_OSD_HSC_INI_PAT_CTRL 0x19c6 > +#define VPP2_OSD_SC_DUMMY_DATA 0x19c7 > +#define VPP2_OSD_SC_CTRL0 0x19c8 > +#define VPP2_OSD_SCI_WH_M1 0x19c9 > +#define VPP2_OSD_SCO_H_START_END 0x19ca > +#define VPP2_OSD_SCO_V_START_END 0x19cb > +#define VPP2_OSD_SCALE_COEF_IDX 0x19cc > +#define VPP2_OSD_SCALE_COEF 0x19cd > +#define VPP2_INT_LINE_NUM 0x19ce > + > +/* viu */ > +#define VIU_ADDR_START 0x1a00 > +#define VIU_ADDR_END 0x1aff > +#define VIU_SW_RESET 0x1a01 > +#define VIU_MISC_CTRL0 0x1a06 > +#define VIU_MISC_CTRL1 0x1a07 > +#define D2D3_INTF_LENGTH 0x1a08 > +#define D2D3_INTF_CTRL0 0x1a09 > +#define VIU_OSD1_CTRL_STAT 0x1a10 > +#define VIU_OSD1_CTRL_STAT2 0x1a2d > +#define VIU_OSD1_COLOR_ADDR 0x1a11 > +#define VIU_OSD1_COLOR 0x1a12 > +#define VIU_OSD1_TCOLOR_AG0 0x1a17 > +#define VIU_OSD1_TCOLOR_AG1 0x1a18 > +#define VIU_OSD1_TCOLOR_AG2 0x1a19 > +#define VIU_OSD1_TCOLOR_AG3 0x1a1a > +#define VIU_OSD1_BLK0_CFG_W0 0x1a1b > +#define VIU_OSD1_BLK1_CFG_W0 0x1a1f > +#define VIU_OSD1_BLK2_CFG_W0 0x1a23 > +#define VIU_OSD1_BLK3_CFG_W0 0x1a27 > +#define VIU_OSD1_BLK0_CFG_W1 0x1a1c > +#define VIU_OSD1_BLK1_CFG_W1 0x1a20 > +#define VIU_OSD1_BLK2_CFG_W1 0x1a24 > +#define VIU_OSD1_BLK3_CFG_W1 0x1a28 > +#define VIU_OSD1_BLK0_CFG_W2 0x1a1d > +#define VIU_OSD1_BLK1_CFG_W2 0x1a21 > +#define VIU_OSD1_BLK2_CFG_W2 0x1a25 > +#define VIU_OSD1_BLK3_CFG_W2 0x1a29 > +#define VIU_OSD1_BLK0_CFG_W3 0x1a1e > +#define VIU_OSD1_BLK1_CFG_W3 0x1a22 > +#define VIU_OSD1_BLK2_CFG_W3 0x1a26 > +#define VIU_OSD1_BLK3_CFG_W3 0x1a2a > +#define VIU_OSD1_BLK0_CFG_W4 0x1a13 > +#define VIU_OSD1_BLK1_CFG_W4 0x1a14 > +#define VIU_OSD1_BLK2_CFG_W4 0x1a15 > +#define VIU_OSD1_BLK3_CFG_W4 0x1a16 > +#define VIU_OSD1_FIFO_CTRL_STAT 0x1a2b > +#define VIU_OSD1_TEST_RDDATA 0x1a2c > +#define VIU_OSD1_PROT_CTRL 0x1a2e > +#define VIU_OSD2_CTRL_STAT 0x1a30 > +#define VIU_OSD2_CTRL_STAT2 0x1a4d > +#define VIU_OSD2_COLOR_ADDR 0x1a31 > +#define VIU_OSD2_COLOR 0x1a32 > +#define VIU_OSD2_HL1_H_START_END 0x1a33 > +#define VIU_OSD2_HL1_V_START_END 0x1a34 > +#define VIU_OSD2_HL2_H_START_END 0x1a35 > +#define VIU_OSD2_HL2_V_START_END 0x1a36 > +#define VIU_OSD2_TCOLOR_AG0 0x1a37 > +#define VIU_OSD2_TCOLOR_AG1 0x1a38 > +#define VIU_OSD2_TCOLOR_AG2 0x1a39 > +#define VIU_OSD2_TCOLOR_AG3 0x1a3a > +#define VIU_OSD2_BLK0_CFG_W0 0x1a3b > +#define VIU_OSD2_BLK1_CFG_W0 0x1a3f > +#define VIU_OSD2_BLK2_CFG_W0 0x1a43 > +#define VIU_OSD2_BLK3_CFG_W0 0x1a47 > +#define VIU_OSD2_BLK0_CFG_W1 0x1a3c > +#define VIU_OSD2_BLK1_CFG_W1 0x1a40 > +#define VIU_OSD2_BLK2_CFG_W1 0x1a44 > +#define VIU_OSD2_BLK3_CFG_W1 0x1a48 > +#define VIU_OSD2_BLK0_CFG_W2 0x1a3d > +#define VIU_OSD2_BLK1_CFG_W2 0x1a41 > +#define VIU_OSD2_BLK2_CFG_W2 0x1a45 > +#define VIU_OSD2_BLK3_CFG_W2 0x1a49 > +#define VIU_OSD2_BLK0_CFG_W3 0x1a3e > +#define VIU_OSD2_BLK1_CFG_W3 0x1a42 > +#define VIU_OSD2_BLK2_CFG_W3 0x1a46 > +#define VIU_OSD2_BLK3_CFG_W3 0x1a4a > +#define VIU_OSD2_BLK0_CFG_W4 0x1a64 > +#define VIU_OSD2_BLK1_CFG_W4 0x1a65 > +#define VIU_OSD2_BLK2_CFG_W4 0x1a66 > +#define VIU_OSD2_BLK3_CFG_W4 0x1a67 > +#define VIU_OSD2_FIFO_CTRL_STAT 0x1a4b > +#define VIU_OSD2_TEST_RDDATA 0x1a4c > +#define VIU_OSD2_PROT_CTRL 0x1a4e > + > +#define VD1_IF0_GEN_REG 0x1a50 > +#define VD1_IF0_CANVAS0 0x1a51 > +#define VD1_IF0_CANVAS1 0x1a52 > +#define VD1_IF0_LUMA_X0 0x1a53 > +#define VD1_IF0_LUMA_Y0 0x1a54 > +#define VD1_IF0_CHROMA_X0 0x1a55 > +#define VD1_IF0_CHROMA_Y0 0x1a56 > +#define VD1_IF0_LUMA_X1 0x1a57 > +#define VD1_IF0_LUMA_Y1 0x1a58 > +#define VD1_IF0_CHROMA_X1 0x1a59 > +#define VD1_IF0_CHROMA_Y1 0x1a5a > +#define VD1_IF0_RPT_LOOP 0x1a5b > +#define VD1_IF0_LUMA0_RPT_PAT 0x1a5c > +#define VD1_IF0_CHROMA0_RPT_PAT 0x1a5d > +#define VD1_IF0_LUMA1_RPT_PAT 0x1a5e > +#define VD1_IF0_CHROMA1_RPT_PAT 0x1a5f > +#define VD1_IF0_LUMA_PSEL 0x1a60 > +#define VD1_IF0_CHROMA_PSEL 0x1a61 > +#define VD1_IF0_DUMMY_PIXEL 0x1a62 > +#define VD1_IF0_LUMA_FIFO_SIZE 0x1a63 > +#define VD1_IF0_RANGE_MAP_Y 0x1a6a > +#define VD1_IF0_RANGE_MAP_CB 0x1a6b > +#define VD1_IF0_RANGE_MAP_CR 0x1a6c > +#define VD1_IF0_GEN_REG2 0x1a6d > +#define VD1_IF0_PROT_CNTL 0x1a6e > +#define VIU_VD1_FMT_CTRL 0x1a68 > +#define VIU_VD1_FMT_W 0x1a69 > +#define VD2_IF0_GEN_REG 0x1a70 > +#define VD2_IF0_CANVAS0 0x1a71 > +#define VD2_IF0_CANVAS1 0x1a72 > +#define VD2_IF0_LUMA_X0 0x1a73 > +#define VD2_IF0_LUMA_Y0 0x1a74 > +#define VD2_IF0_CHROMA_X0 0x1a75 > +#define VD2_IF0_CHROMA_Y0 0x1a76 > +#define VD2_IF0_LUMA_X1 0x1a77 > +#define VD2_IF0_LUMA_Y1 0x1a78 > +#define VD2_IF0_CHROMA_X1 0x1a79 > +#define VD2_IF0_CHROMA_Y1 0x1a7a > +#define VD2_IF0_RPT_LOOP 0x1a7b > +#define VD2_IF0_LUMA0_RPT_PAT 0x1a7c > +#define VD2_IF0_CHROMA0_RPT_PAT 0x1a7d > +#define VD2_IF0_LUMA1_RPT_PAT 0x1a7e > +#define VD2_IF0_CHROMA1_RPT_PAT 0x1a7f > +#define VD2_IF0_LUMA_PSEL 0x1a80 > +#define VD2_IF0_CHROMA_PSEL 0x1a81 > +#define VD2_IF0_DUMMY_PIXEL 0x1a82 > +#define VD2_IF0_LUMA_FIFO_SIZE 0x1a83 > +#define VD2_IF0_RANGE_MAP_Y 0x1a8a > +#define VD2_IF0_RANGE_MAP_CB 0x1a8b > +#define VD2_IF0_RANGE_MAP_CR 0x1a8c > +#define VD2_IF0_GEN_REG2 0x1a8d > +#define VD2_IF0_PROT_CNTL 0x1a8e > +#define VIU_VD2_FMT_CTRL 0x1a88 > +#define VIU_VD2_FMT_W 0x1a89 > + > +/* VIU Matrix Registers */ > +#define VIU_OSD1_MATRIX_CTRL 0x1a90 > +#define VIU_OSD1_MATRIX_COEF00_01 0x1a91 > +#define VIU_OSD1_MATRIX_COEF02_10 0x1a92 > +#define VIU_OSD1_MATRIX_COEF11_12 0x1a93 > +#define VIU_OSD1_MATRIX_COEF20_21 0x1a94 > +#define VIU_OSD1_MATRIX_COLMOD_COEF42 0x1a95 > +#define VIU_OSD1_MATRIX_OFFSET0_1 0x1a96 > +#define VIU_OSD1_MATRIX_OFFSET2 0x1a97 > +#define VIU_OSD1_MATRIX_PRE_OFFSET0_1 0x1a98 > +#define VIU_OSD1_MATRIX_PRE_OFFSET2 0x1a99 > +#define VIU_OSD1_MATRIX_COEF22_30 0x1a9d > +#define VIU_OSD1_MATRIX_COEF31_32 0x1a9e > +#define VIU_OSD1_MATRIX_COEF40_41 0x1a9f > +#define VIU_OSD1_EOTF_CTL 0x1ad4 > +#define VIU_OSD1_EOTF_COEF00_01 0x1ad5 > +#define VIU_OSD1_EOTF_COEF02_10 0x1ad6 > +#define VIU_OSD1_EOTF_COEF11_12 0x1ad7 > +#define VIU_OSD1_EOTF_COEF20_21 0x1ad8 > +#define VIU_OSD1_EOTF_COEF22_RS 0x1ad9 > +#define VIU_OSD1_EOTF_LUT_ADDR_PORT 0x1ada > +#define VIU_OSD1_EOTF_LUT_DATA_PORT 0x1adb > +#define VIU_OSD1_OETF_CTL 0x1adc > +#define VIU_OSD1_OETF_LUT_ADDR_PORT 0x1add > +#define VIU_OSD1_OETF_LUT_DATA_PORT 0x1ade > + > +/* vpp */ > +#define VPP_DUMMY_DATA 0x1d00 > +#define VPP_LINE_IN_LENGTH 0x1d01 > +#define VPP_PIC_IN_HEIGHT 0x1d02 > +#define VPP_SCALE_COEF_IDX 0x1d03 > +#define VPP_SCALE_COEF 0x1d04 > +#define VPP_VSC_REGION12_STARTP 0x1d05 > +#define VPP_VSC_REGION34_STARTP 0x1d06 > +#define VPP_VSC_REGION4_ENDP 0x1d07 > +#define VPP_VSC_START_PHASE_STEP 0x1d08 > +#define VPP_VSC_REGION0_PHASE_SLOPE 0x1d09 > +#define VPP_VSC_REGION1_PHASE_SLOPE 0x1d0a > +#define VPP_VSC_REGION3_PHASE_SLOPE 0x1d0b > +#define VPP_VSC_REGION4_PHASE_SLOPE 0x1d0c > +#define VPP_VSC_PHASE_CTRL 0x1d0d > +#define VPP_VSC_INI_PHASE 0x1d0e > +#define VPP_HSC_REGION12_STARTP 0x1d10 > +#define VPP_HSC_REGION34_STARTP 0x1d11 > +#define VPP_HSC_REGION4_ENDP 0x1d12 > +#define VPP_HSC_START_PHASE_STEP 0x1d13 > +#define VPP_HSC_REGION0_PHASE_SLOPE 0x1d14 > +#define VPP_HSC_REGION1_PHASE_SLOPE 0x1d15 > +#define VPP_HSC_REGION3_PHASE_SLOPE 0x1d16 > +#define VPP_HSC_REGION4_PHASE_SLOPE 0x1d17 > +#define VPP_HSC_PHASE_CTRL 0x1d18 > +#define VPP_SC_MISC 0x1d19 > +#define VPP_PREBLEND_VD1_H_START_END 0x1d1a > +#define VPP_PREBLEND_VD1_V_START_END 0x1d1b > +#define VPP_POSTBLEND_VD1_H_START_END 0x1d1c > +#define VPP_POSTBLEND_VD1_V_START_END 0x1d1d > +#define VPP_BLEND_VD2_H_START_END 0x1d1e > +#define VPP_BLEND_VD2_V_START_END 0x1d1f > +#define VPP_PREBLEND_H_SIZE 0x1d20 > +#define VPP_POSTBLEND_H_SIZE 0x1d21 > +#define VPP_HOLD_LINES 0x1d22 > +#define VPP_BLEND_ONECOLOR_CTRL 0x1d23 > +#define VPP_PREBLEND_CURRENT_XY 0x1d24 > +#define VPP_POSTBLEND_CURRENT_XY 0x1d25 > +#define VPP_MISC 0x1d26 > +#define VPP_PREBLEND_ENABLE BIT(6) > +#define VPP_POSTBLEND_ENABLE BIT(7) > +#define VPP_OSD2_ALPHA_PREMULT BIT(8) > +#define VPP_OSD1_ALPHA_PREMULT BIT(9) > +#define VPP_VD1_POSTBLEND BIT(10) > +#define VPP_VD2_POSTBLEND BIT(11) > +#define VPP_OSD1_POSTBLEND BIT(12) > +#define VPP_OSD2_POSTBLEND BIT(13) > +#define VPP_VD1_PREBLEND BIT(14) > +#define VPP_VD2_PREBLEND BIT(15) > +#define VPP_OSD1_PREBLEND BIT(16) > +#define VPP_OSD2_PREBLEND BIT(17) > +#define VPP_OFIFO_SIZE 0x1d27 > +#define VPP_FIFO_STATUS 0x1d28 > +#define VPP_SMOKE_CTRL 0x1d29 > +#define VPP_SMOKE1_VAL 0x1d2a > +#define VPP_SMOKE2_VAL 0x1d2b > +#define VPP_SMOKE3_VAL 0x1d2c > +#define VPP_SMOKE1_H_START_END 0x1d2d > +#define VPP_SMOKE1_V_START_END 0x1d2e > +#define VPP_SMOKE2_H_START_END 0x1d2f > +#define VPP_SMOKE2_V_START_END 0x1d30 > +#define VPP_SMOKE3_H_START_END 0x1d31 > +#define VPP_SMOKE3_V_START_END 0x1d32 > +#define VPP_SCO_FIFO_CTRL 0x1d33 > +#define VPP_HSC_PHASE_CTRL1 0x1d34 > +#define VPP_HSC_INI_PAT_CTRL 0x1d35 > +#define VPP_VADJ_CTRL 0x1d40 > +#define VPP_VADJ1_Y 0x1d41 > +#define VPP_VADJ1_MA_MB 0x1d42 > +#define VPP_VADJ1_MC_MD 0x1d43 > +#define VPP_VADJ2_Y 0x1d44 > +#define VPP_VADJ2_MA_MB 0x1d45 > +#define VPP_VADJ2_MC_MD 0x1d46 > +#define VPP_HSHARP_CTRL 0x1d50 > +#define VPP_HSHARP_LUMA_THRESH01 0x1d51 > +#define VPP_HSHARP_LUMA_THRESH23 0x1d52 > +#define VPP_HSHARP_CHROMA_THRESH01 0x1d53 > +#define VPP_HSHARP_CHROMA_THRESH23 0x1d54 > +#define VPP_HSHARP_LUMA_GAIN 0x1d55 > +#define VPP_HSHARP_CHROMA_GAIN 0x1d56 > +#define VPP_MATRIX_PROBE_COLOR 0x1d5c > +#define VPP_MATRIX_HL_COLOR 0x1d5d > +#define VPP_MATRIX_PROBE_POS 0x1d5e > +#define VPP_MATRIX_CTRL 0x1d5f > +#define VPP_MATRIX_COEF00_01 0x1d60 > +#define VPP_MATRIX_COEF02_10 0x1d61 > +#define VPP_MATRIX_COEF11_12 0x1d62 > +#define VPP_MATRIX_COEF20_21 0x1d63 > +#define VPP_MATRIX_COEF22 0x1d64 > +#define VPP_MATRIX_OFFSET0_1 0x1d65 > +#define VPP_MATRIX_OFFSET2 0x1d66 > +#define VPP_MATRIX_PRE_OFFSET0_1 0x1d67 > +#define VPP_MATRIX_PRE_OFFSET2 0x1d68 > +#define VPP_DUMMY_DATA1 0x1d69 > +#define VPP_GAINOFF_CTRL0 0x1d6a > +#define VPP_GAINOFF_CTRL1 0x1d6b > +#define VPP_GAINOFF_CTRL2 0x1d6c > +#define VPP_GAINOFF_CTRL3 0x1d6d > +#define VPP_GAINOFF_CTRL4 0x1d6e > +#define VPP_CHROMA_ADDR_PORT 0x1d70 > +#define VPP_CHROMA_DATA_PORT 0x1d71 > +#define VPP_GCLK_CTRL0 0x1d72 > +#define VPP_GCLK_CTRL1 0x1d73 > +#define VPP_SC_GCLK_CTRL 0x1d74 > +#define VPP_MISC1 0x1d76 > +#define VPP_BLACKEXT_CTRL 0x1d80 > +#define VPP_DNLP_CTRL_00 0x1d81 > +#define VPP_DNLP_CTRL_01 0x1d82 > +#define VPP_DNLP_CTRL_02 0x1d83 > +#define VPP_DNLP_CTRL_03 0x1d84 > +#define VPP_DNLP_CTRL_04 0x1d85 > +#define VPP_DNLP_CTRL_05 0x1d86 > +#define VPP_DNLP_CTRL_06 0x1d87 > +#define VPP_DNLP_CTRL_07 0x1d88 > +#define VPP_DNLP_CTRL_08 0x1d89 > +#define VPP_DNLP_CTRL_09 0x1d8a > +#define VPP_DNLP_CTRL_10 0x1d8b > +#define VPP_DNLP_CTRL_11 0x1d8c > +#define VPP_DNLP_CTRL_12 0x1d8d > +#define VPP_DNLP_CTRL_13 0x1d8e > +#define VPP_DNLP_CTRL_14 0x1d8f > +#define VPP_DNLP_CTRL_15 0x1d90 > +#define VPP_PEAKING_HGAIN 0x1d91 > +#define VPP_PEAKING_VGAIN 0x1d92 > +#define VPP_PEAKING_NLP_1 0x1d93 > +#define VPP_DOLBY_CTRL 0x1d93 > +#define VPP_PEAKING_NLP_2 0x1d94 > +#define VPP_PEAKING_NLP_3 0x1d95 > +#define VPP_PEAKING_NLP_4 0x1d96 > +#define VPP_PEAKING_NLP_5 0x1d97 > +#define VPP_SHARP_LIMIT 0x1d98 > +#define VPP_VLTI_CTRL 0x1d99 > +#define VPP_HLTI_CTRL 0x1d9a > +#define VPP_CTI_CTRL 0x1d9b > +#define VPP_BLUE_STRETCH_1 0x1d9c > +#define VPP_BLUE_STRETCH_2 0x1d9d > +#define VPP_BLUE_STRETCH_3 0x1d9e > +#define VPP_CCORING_CTRL 0x1da0 > +#define VPP_VE_ENABLE_CTRL 0x1da1 > +#define VPP_VE_DEMO_LEFT_TOP_SCREEN_WIDTH 0x1da2 > +#define VPP_VE_DEMO_CENTER_BAR 0x1da3 > +#define VPP_VE_H_V_SIZE 0x1da4 > +#define VPP_VDO_MEAS_CTRL 0x1da8 > +#define VPP_VDO_MEAS_VS_COUNT_HI 0x1da9 > +#define VPP_VDO_MEAS_VS_COUNT_LO 0x1daa > +#define VPP_INPUT_CTRL 0x1dab > +#define VPP_CTI_CTRL2 0x1dac > +#define VPP_PEAKING_SAT_THD1 0x1dad > +#define VPP_PEAKING_SAT_THD2 0x1dae > +#define VPP_PEAKING_SAT_THD3 0x1daf > +#define VPP_PEAKING_SAT_THD4 0x1db0 > +#define VPP_PEAKING_SAT_THD5 0x1db1 > +#define VPP_PEAKING_SAT_THD6 0x1db2 > +#define VPP_PEAKING_SAT_THD7 0x1db3 > +#define VPP_PEAKING_SAT_THD8 0x1db4 > +#define VPP_PEAKING_SAT_THD9 0x1db5 > +#define VPP_PEAKING_GAIN_ADD1 0x1db6 > +#define VPP_PEAKING_GAIN_ADD2 0x1db7 > +#define VPP_PEAKING_DNLP 0x1db8 > +#define VPP_SHARP_DEMO_WIN_CTRL1 0x1db9 > +#define VPP_SHARP_DEMO_WIN_CTRL2 0x1dba > +#define VPP_FRONT_HLTI_CTRL 0x1dbb > +#define VPP_FRONT_CTI_CTRL 0x1dbc > +#define VPP_FRONT_CTI_CTRL2 0x1dbd > +#define VPP_OSD_VSC_PHASE_STEP 0x1dc0 > +#define VPP_OSD_VSC_INI_PHASE 0x1dc1 > +#define VPP_OSD_VSC_CTRL0 0x1dc2 > +#define VPP_OSD_HSC_PHASE_STEP 0x1dc3 > +#define VPP_OSD_HSC_INI_PHASE 0x1dc4 > +#define VPP_OSD_HSC_CTRL0 0x1dc5 > +#define VPP_OSD_HSC_INI_PAT_CTRL 0x1dc6 > +#define VPP_OSD_SC_DUMMY_DATA 0x1dc7 > +#define VPP_OSD_SC_CTRL0 0x1dc8 > +#define VPP_OSD_SCI_WH_M1 0x1dc9 > +#define VPP_OSD_SCO_H_START_END 0x1dca > +#define VPP_OSD_SCO_V_START_END 0x1dcb > +#define VPP_OSD_SCALE_COEF_IDX 0x1dcc > +#define VPP_OSD_SCALE_COEF 0x1dcd > +#define VPP_INT_LINE_NUM 0x1dce > + > +/* viu2 */ > +#define VIU2_ADDR_START 0x1e00 > +#define VIU2_ADDR_END 0x1eff > +#define VIU2_SW_RESET 0x1e01 > +#define VIU2_OSD1_CTRL_STAT 0x1e10 > +#define VIU2_OSD1_CTRL_STAT2 0x1e2d > +#define VIU2_OSD1_COLOR_ADDR 0x1e11 > +#define VIU2_OSD1_COLOR 0x1e12 > +#define VIU2_OSD1_TCOLOR_AG0 0x1e17 > +#define VIU2_OSD1_TCOLOR_AG1 0x1e18 > +#define VIU2_OSD1_TCOLOR_AG2 0x1e19 > +#define VIU2_OSD1_TCOLOR_AG3 0x1e1a > +#define VIU2_OSD1_BLK0_CFG_W0 0x1e1b > +#define VIU2_OSD1_BLK1_CFG_W0 0x1e1f > +#define VIU2_OSD1_BLK2_CFG_W0 0x1e23 > +#define VIU2_OSD1_BLK3_CFG_W0 0x1e27 > +#define VIU2_OSD1_BLK0_CFG_W1 0x1e1c > +#define VIU2_OSD1_BLK1_CFG_W1 0x1e20 > +#define VIU2_OSD1_BLK2_CFG_W1 0x1e24 > +#define VIU2_OSD1_BLK3_CFG_W1 0x1e28 > +#define VIU2_OSD1_BLK0_CFG_W2 0x1e1d > +#define VIU2_OSD1_BLK1_CFG_W2 0x1e21 > +#define VIU2_OSD1_BLK2_CFG_W2 0x1e25 > +#define VIU2_OSD1_BLK3_CFG_W2 0x1e29 > +#define VIU2_OSD1_BLK0_CFG_W3 0x1e1e > +#define VIU2_OSD1_BLK1_CFG_W3 0x1e22 > +#define VIU2_OSD1_BLK2_CFG_W3 0x1e26 > +#define VIU2_OSD1_BLK3_CFG_W3 0x1e2a > +#define VIU2_OSD1_BLK0_CFG_W4 0x1e13 > +#define VIU2_OSD1_BLK1_CFG_W4 0x1e14 > +#define VIU2_OSD1_BLK2_CFG_W4 0x1e15 > +#define VIU2_OSD1_BLK3_CFG_W4 0x1e16 > +#define VIU2_OSD1_FIFO_CTRL_STAT 0x1e2b > +#define VIU2_OSD1_TEST_RDDATA 0x1e2c > +#define VIU2_OSD1_PROT_CTRL 0x1e2e > +#define VIU2_OSD2_CTRL_STAT 0x1e30 > +#define VIU2_OSD2_CTRL_STAT2 0x1e4d > +#define VIU2_OSD2_COLOR_ADDR 0x1e31 > +#define VIU2_OSD2_COLOR 0x1e32 > +#define VIU2_OSD2_HL1_H_START_END 0x1e33 > +#define VIU2_OSD2_HL1_V_START_END 0x1e34 > +#define VIU2_OSD2_HL2_H_START_END 0x1e35 > +#define VIU2_OSD2_HL2_V_START_END 0x1e36 > +#define VIU2_OSD2_TCOLOR_AG0 0x1e37 > +#define VIU2_OSD2_TCOLOR_AG1 0x1e38 > +#define VIU2_OSD2_TCOLOR_AG2 0x1e39 > +#define VIU2_OSD2_TCOLOR_AG3 0x1e3a > +#define VIU2_OSD2_BLK0_CFG_W0 0x1e3b > +#define VIU2_OSD2_BLK1_CFG_W0 0x1e3f > +#define VIU2_OSD2_BLK2_CFG_W0 0x1e43 > +#define VIU2_OSD2_BLK3_CFG_W0 0x1e47 > +#define VIU2_OSD2_BLK0_CFG_W1 0x1e3c > +#define VIU2_OSD2_BLK1_CFG_W1 0x1e40 > +#define VIU2_OSD2_BLK2_CFG_W1 0x1e44 > +#define VIU2_OSD2_BLK3_CFG_W1 0x1e48 > +#define VIU2_OSD2_BLK0_CFG_W2 0x1e3d > +#define VIU2_OSD2_BLK1_CFG_W2 0x1e41 > +#define VIU2_OSD2_BLK2_CFG_W2 0x1e45 > +#define VIU2_OSD2_BLK3_CFG_W2 0x1e49 > +#define VIU2_OSD2_BLK0_CFG_W3 0x1e3e > +#define VIU2_OSD2_BLK1_CFG_W3 0x1e42 > +#define VIU2_OSD2_BLK2_CFG_W3 0x1e46 > +#define VIU2_OSD2_BLK3_CFG_W3 0x1e4a > +#define VIU2_OSD2_BLK0_CFG_W4 0x1e64 > +#define VIU2_OSD2_BLK1_CFG_W4 0x1e65 > +#define VIU2_OSD2_BLK2_CFG_W4 0x1e66 > +#define VIU2_OSD2_BLK3_CFG_W4 0x1e67 > +#define VIU2_OSD2_FIFO_CTRL_STAT 0x1e4b > +#define VIU2_OSD2_TEST_RDDATA 0x1e4c > +#define VIU2_OSD2_PROT_CTRL 0x1e4e > +#define VIU2_VD1_IF0_GEN_REG 0x1e50 > +#define VIU2_VD1_IF0_CANVAS0 0x1e51 > +#define VIU2_VD1_IF0_CANVAS1 0x1e52 > +#define VIU2_VD1_IF0_LUMA_X0 0x1e53 > +#define VIU2_VD1_IF0_LUMA_Y0 0x1e54 > +#define VIU2_VD1_IF0_CHROMA_X0 0x1e55 > +#define VIU2_VD1_IF0_CHROMA_Y0 0x1e56 > +#define VIU2_VD1_IF0_LUMA_X1 0x1e57 > +#define VIU2_VD1_IF0_LUMA_Y1 0x1e58 > +#define VIU2_VD1_IF0_CHROMA_X1 0x1e59 > +#define VIU2_VD1_IF0_CHROMA_Y1 0x1e5a > +#define VIU2_VD1_IF0_RPT_LOOP 0x1e5b > +#define VIU2_VD1_IF0_LUMA0_RPT_PAT 0x1e5c > +#define VIU2_VD1_IF0_CHROMA0_RPT_PAT 0x1e5d > +#define VIU2_VD1_IF0_LUMA1_RPT_PAT 0x1e5e > +#define VIU2_VD1_IF0_CHROMA1_RPT_PAT 0x1e5f > +#define VIU2_VD1_IF0_LUMA_PSEL 0x1e60 > +#define VIU2_VD1_IF0_CHROMA_PSEL 0x1e61 > +#define VIU2_VD1_IF0_DUMMY_PIXEL 0x1e62 > +#define VIU2_VD1_IF0_LUMA_FIFO_SIZE 0x1e63 > +#define VIU2_VD1_IF0_RANGE_MAP_Y 0x1e6a > +#define VIU2_VD1_IF0_RANGE_MAP_CB 0x1e6b > +#define VIU2_VD1_IF0_RANGE_MAP_CR 0x1e6c > +#define VIU2_VD1_IF0_GEN_REG2 0x1e6d > +#define VIU2_VD1_IF0_PROT_CNTL 0x1e6e > +#define VIU2_VD1_FMT_CTRL 0x1e68 > +#define VIU2_VD1_FMT_W 0x1e69 > + > +/* encode */ > +#define ENCP_VFIFO2VD_CTL 0x1b58 > +#define ENCP_VFIFO2VD_PIXEL_START 0x1b59 > +#define ENCP_VFIFO2VD_PIXEL_END 0x1b5a > +#define ENCP_VFIFO2VD_LINE_TOP_START 0x1b5b > +#define ENCP_VFIFO2VD_LINE_TOP_END 0x1b5c > +#define ENCP_VFIFO2VD_LINE_BOT_START 0x1b5d > +#define ENCP_VFIFO2VD_LINE_BOT_END 0x1b5e > +#define VENC_SYNC_ROUTE 0x1b60 > +#define VENC_VIDEO_EXSRC 0x1b61 > +#define VENC_DVI_SETTING 0x1b62 > +#define VENC_C656_CTRL 0x1b63 > +#define VENC_UPSAMPLE_CTRL0 0x1b64 > +#define VENC_UPSAMPLE_CTRL1 0x1b65 > +#define VENC_UPSAMPLE_CTRL2 0x1b66 > +#define TCON_INVERT_CTL 0x1b67 > +#define VENC_VIDEO_PROG_MODE 0x1b68 > +#define VENC_ENCI_LINE 0x1b69 > +#define VENC_ENCI_PIXEL 0x1b6a > +#define VENC_ENCP_LINE 0x1b6b > +#define VENC_ENCP_PIXEL 0x1b6c > +#define VENC_STATA 0x1b6d > +#define VENC_INTCTRL 0x1b6e > +#define VENC_INTFLAG 0x1b6f > +#define VENC_VIDEO_TST_EN 0x1b70 > +#define VENC_VIDEO_TST_MDSEL 0x1b71 > +#define VENC_VIDEO_TST_Y 0x1b72 > +#define VENC_VIDEO_TST_CB 0x1b73 > +#define VENC_VIDEO_TST_CR 0x1b74 > +#define VENC_VIDEO_TST_CLRBAR_STRT 0x1b75 > +#define VENC_VIDEO_TST_CLRBAR_WIDTH 0x1b76 > +#define VENC_VIDEO_TST_VDCNT_STSET 0x1b77 > +#define VENC_VDAC_DACSEL0 0x1b78 > +#define VENC_VDAC_DACSEL1 0x1b79 > +#define VENC_VDAC_DACSEL2 0x1b7a > +#define VENC_VDAC_DACSEL3 0x1b7b > +#define VENC_VDAC_DACSEL4 0x1b7c > +#define VENC_VDAC_DACSEL5 0x1b7d > +#define VENC_VDAC_SETTING 0x1b7e > +#define VENC_VDAC_TST_VAL 0x1b7f > +#define VENC_VDAC_DAC0_GAINCTRL 0x1bf0 > +#define VENC_VDAC_DAC0_OFFSET 0x1bf1 > +#define VENC_VDAC_DAC1_GAINCTRL 0x1bf2 > +#define VENC_VDAC_DAC1_OFFSET 0x1bf3 > +#define VENC_VDAC_DAC2_GAINCTRL 0x1bf4 > +#define VENC_VDAC_DAC2_OFFSET 0x1bf5 > +#define VENC_VDAC_DAC3_GAINCTRL 0x1bf6 > +#define VENC_VDAC_DAC3_OFFSET 0x1bf7 > +#define VENC_VDAC_DAC4_GAINCTRL 0x1bf8 > +#define VENC_VDAC_DAC4_OFFSET 0x1bf9 > +#define VENC_VDAC_DAC5_GAINCTRL 0x1bfa > +#define VENC_VDAC_DAC5_OFFSET 0x1bfb > +#define VENC_VDAC_FIFO_CTRL 0x1bfc > +#define ENCL_TCON_INVERT_CTL 0x1bfd > +#define ENCP_VIDEO_EN 0x1b80 > +#define ENCP_VIDEO_SYNC_MODE 0x1b81 > +#define ENCP_MACV_EN 0x1b82 > +#define ENCP_VIDEO_Y_SCL 0x1b83 > +#define ENCP_VIDEO_PB_SCL 0x1b84 > +#define ENCP_VIDEO_PR_SCL 0x1b85 > +#define ENCP_VIDEO_SYNC_SCL 0x1b86 > +#define ENCP_VIDEO_MACV_SCL 0x1b87 > +#define ENCP_VIDEO_Y_OFFST 0x1b88 > +#define ENCP_VIDEO_PB_OFFST 0x1b89 > +#define ENCP_VIDEO_PR_OFFST 0x1b8a > +#define ENCP_VIDEO_SYNC_OFFST 0x1b8b > +#define ENCP_VIDEO_MACV_OFFST 0x1b8c > +#define ENCP_VIDEO_MODE 0x1b8d > +#define ENCP_VIDEO_MODE_ADV 0x1b8e > +#define ENCP_DBG_PX_RST 0x1b90 > +#define ENCP_DBG_LN_RST 0x1b91 > +#define ENCP_DBG_PX_INT 0x1b92 > +#define ENCP_DBG_LN_INT 0x1b93 > +#define ENCP_VIDEO_YFP1_HTIME 0x1b94 > +#define ENCP_VIDEO_YFP2_HTIME 0x1b95 > +#define ENCP_VIDEO_YC_DLY 0x1b96 > +#define ENCP_VIDEO_MAX_PXCNT 0x1b97 > +#define ENCP_VIDEO_HSPULS_BEGIN 0x1b98 > +#define ENCP_VIDEO_HSPULS_END 0x1b99 > +#define ENCP_VIDEO_HSPULS_SWITCH 0x1b9a > +#define ENCP_VIDEO_VSPULS_BEGIN 0x1b9b > +#define ENCP_VIDEO_VSPULS_END 0x1b9c > +#define ENCP_VIDEO_VSPULS_BLINE 0x1b9d > +#define ENCP_VIDEO_VSPULS_ELINE 0x1b9e > +#define ENCP_VIDEO_EQPULS_BEGIN 0x1b9f > +#define ENCP_VIDEO_EQPULS_END 0x1ba0 > +#define ENCP_VIDEO_EQPULS_BLINE 0x1ba1 > +#define ENCP_VIDEO_EQPULS_ELINE 0x1ba2 > +#define ENCP_VIDEO_HAVON_END 0x1ba3 > +#define ENCP_VIDEO_HAVON_BEGIN 0x1ba4 > +#define ENCP_VIDEO_VAVON_ELINE 0x1baf > +#define ENCP_VIDEO_VAVON_BLINE 0x1ba6 > +#define ENCP_VIDEO_HSO_BEGIN 0x1ba7 > +#define ENCP_VIDEO_HSO_END 0x1ba8 > +#define ENCP_VIDEO_VSO_BEGIN 0x1ba9 > +#define ENCP_VIDEO_VSO_END 0x1baa > +#define ENCP_VIDEO_VSO_BLINE 0x1bab > +#define ENCP_VIDEO_VSO_ELINE 0x1bac > +#define ENCP_VIDEO_SYNC_WAVE_CURVE 0x1bad > +#define ENCP_VIDEO_MAX_LNCNT 0x1bae > +#define ENCP_VIDEO_SY_VAL 0x1bb0 > +#define ENCP_VIDEO_SY2_VAL 0x1bb1 > +#define ENCP_VIDEO_BLANKY_VAL 0x1bb2 > +#define ENCP_VIDEO_BLANKPB_VAL 0x1bb3 > +#define ENCP_VIDEO_BLANKPR_VAL 0x1bb4 > +#define ENCP_VIDEO_HOFFST 0x1bb5 > +#define ENCP_VIDEO_VOFFST 0x1bb6 > +#define ENCP_VIDEO_RGB_CTRL 0x1bb7 > +#define ENCP_VIDEO_FILT_CTRL 0x1bb8 > +#define ENCP_VIDEO_OFLD_VPEQ_OFST 0x1bb9 > +#define ENCP_VIDEO_OFLD_VOAV_OFST 0x1bba > +#define ENCP_VIDEO_MATRIX_CB 0x1bbb > +#define ENCP_VIDEO_MATRIX_CR 0x1bbc > +#define ENCP_VIDEO_RGBIN_CTRL 0x1bbd > +#define ENCP_MACV_BLANKY_VAL 0x1bc0 > +#define ENCP_MACV_MAXY_VAL 0x1bc1 > +#define ENCP_MACV_1ST_PSSYNC_STRT 0x1bc2 > +#define ENCP_MACV_PSSYNC_STRT 0x1bc3 > +#define ENCP_MACV_AGC_STRT 0x1bc4 > +#define ENCP_MACV_AGC_END 0x1bc5 > +#define ENCP_MACV_WAVE_END 0x1bc6 > +#define ENCP_MACV_STRTLINE 0x1bc7 > +#define ENCP_MACV_ENDLINE 0x1bc8 > +#define ENCP_MACV_TS_CNT_MAX_L 0x1bc9 > +#define ENCP_MACV_TS_CNT_MAX_H 0x1bca > +#define ENCP_MACV_TIME_DOWN 0x1bcb > +#define ENCP_MACV_TIME_LO 0x1bcc > +#define ENCP_MACV_TIME_UP 0x1bcd > +#define ENCP_MACV_TIME_RST 0x1bce > +#define ENCP_VBI_CTRL 0x1bd0 > +#define ENCP_VBI_SETTING 0x1bd1 > +#define ENCP_VBI_BEGIN 0x1bd2 > +#define ENCP_VBI_WIDTH 0x1bd3 > +#define ENCP_VBI_HVAL 0x1bd4 > +#define ENCP_VBI_DATA0 0x1bd5 > +#define ENCP_VBI_DATA1 0x1bd6 > +#define C656_HS_ST 0x1be0 > +#define C656_HS_ED 0x1be1 > +#define C656_VS_LNST_E 0x1be2 > +#define C656_VS_LNST_O 0x1be3 > +#define C656_VS_LNED_E 0x1be4 > +#define C656_VS_LNED_O 0x1be5 > +#define C656_FS_LNST 0x1be6 > +#define C656_FS_LNED 0x1be7 > +#define ENCI_VIDEO_MODE 0x1b00 > +#define ENCI_VIDEO_MODE_ADV 0x1b01 > +#define ENCI_VIDEO_FSC_ADJ 0x1b02 > +#define ENCI_VIDEO_BRIGHT 0x1b03 > +#define ENCI_VIDEO_CONT 0x1b04 > +#define ENCI_VIDEO_SAT 0x1b05 > +#define ENCI_VIDEO_HUE 0x1b06 > +#define ENCI_VIDEO_SCH 0x1b07 > +#define ENCI_SYNC_MODE 0x1b08 > +#define ENCI_SYNC_CTRL 0x1b09 > +#define ENCI_SYNC_HSO_BEGIN 0x1b0a > +#define ENCI_SYNC_HSO_END 0x1b0b > +#define ENCI_SYNC_VSO_EVN 0x1b0c > +#define ENCI_SYNC_VSO_ODD 0x1b0d > +#define ENCI_SYNC_VSO_EVNLN 0x1b0e > +#define ENCI_SYNC_VSO_ODDLN 0x1b0f > +#define ENCI_SYNC_HOFFST 0x1b10 > +#define ENCI_SYNC_VOFFST 0x1b11 > +#define ENCI_SYNC_ADJ 0x1b12 > +#define ENCI_RGB_SETTING 0x1b13 > +#define ENCI_DE_H_BEGIN 0x1b16 > +#define ENCI_DE_H_END 0x1b17 > +#define ENCI_DE_V_BEGIN_EVEN 0x1b18 > +#define ENCI_DE_V_END_EVEN 0x1b19 > +#define ENCI_DE_V_BEGIN_ODD 0x1b1a > +#define ENCI_DE_V_END_ODD 0x1b1b > +#define ENCI_VBI_SETTING 0x1b20 > +#define ENCI_VBI_CCDT_EVN 0x1b21 > +#define ENCI_VBI_CCDT_ODD 0x1b22 > +#define ENCI_VBI_CC525_LN 0x1b23 > +#define ENCI_VBI_CC625_LN 0x1b24 > +#define ENCI_VBI_WSSDT 0x1b25 > +#define ENCI_VBI_WSS_LN 0x1b26 > +#define ENCI_VBI_CGMSDT_L 0x1b27 > +#define ENCI_VBI_CGMSDT_H 0x1b28 > +#define ENCI_VBI_CGMS_LN 0x1b29 > +#define ENCI_VBI_TTX_HTIME 0x1b2a > +#define ENCI_VBI_TTX_LN 0x1b2b > +#define ENCI_VBI_TTXDT0 0x1b2c > +#define ENCI_VBI_TTXDT1 0x1b2d > +#define ENCI_VBI_TTXDT2 0x1b2e > +#define ENCI_VBI_TTXDT3 0x1b2f > +#define ENCI_MACV_N0 0x1b30 > +#define ENCI_MACV_N1 0x1b31 > +#define ENCI_MACV_N2 0x1b32 > +#define ENCI_MACV_N3 0x1b33 > +#define ENCI_MACV_N4 0x1b34 > +#define ENCI_MACV_N5 0x1b35 > +#define ENCI_MACV_N6 0x1b36 > +#define ENCI_MACV_N7 0x1b37 > +#define ENCI_MACV_N8 0x1b38 > +#define ENCI_MACV_N9 0x1b39 > +#define ENCI_MACV_N10 0x1b3a > +#define ENCI_MACV_N11 0x1b3b > +#define ENCI_MACV_N12 0x1b3c > +#define ENCI_MACV_N13 0x1b3d > +#define ENCI_MACV_N14 0x1b3e > +#define ENCI_MACV_N15 0x1b3f > +#define ENCI_MACV_N16 0x1b40 > +#define ENCI_MACV_N17 0x1b41 > +#define ENCI_MACV_N18 0x1b42 > +#define ENCI_MACV_N19 0x1b43 > +#define ENCI_MACV_N20 0x1b44 > +#define ENCI_MACV_N21 0x1b45 > +#define ENCI_MACV_N22 0x1b46 > +#define ENCI_DBG_PX_RST 0x1b48 > +#define ENCI_DBG_FLDLN_RST 0x1b49 > +#define ENCI_DBG_PX_INT 0x1b4a > +#define ENCI_DBG_FLDLN_INT 0x1b4b > +#define ENCI_DBG_MAXPX 0x1b4c > +#define ENCI_DBG_MAXLN 0x1b4d > +#define ENCI_MACV_MAX_AMP 0x1b50 > +#define ENCI_MACV_PULSE_LO 0x1b51 > +#define ENCI_MACV_PULSE_HI 0x1b52 > +#define ENCI_MACV_BKP_MAX 0x1b53 > +#define ENCI_CFILT_CTRL 0x1b54 > +#define ENCI_CFILT7 0x1b55 > +#define ENCI_YC_DELAY 0x1b56 > +#define ENCI_VIDEO_EN 0x1b57 > +#define ENCI_DVI_HSO_BEGIN 0x1c00 > +#define ENCI_DVI_HSO_END 0x1c01 > +#define ENCI_DVI_VSO_BLINE_EVN 0x1c02 > +#define ENCI_DVI_VSO_BLINE_ODD 0x1c03 > +#define ENCI_DVI_VSO_ELINE_EVN 0x1c04 > +#define ENCI_DVI_VSO_ELINE_ODD 0x1c05 > +#define ENCI_DVI_VSO_BEGIN_EVN 0x1c06 > +#define ENCI_DVI_VSO_BEGIN_ODD 0x1c07 > +#define ENCI_DVI_VSO_END_EVN 0x1c08 > +#define ENCI_DVI_VSO_END_ODD 0x1c09 > +#define ENCI_CFILT_CTRL2 0x1c0a > +#define ENCI_DACSEL_0 0x1c0b > +#define ENCI_DACSEL_1 0x1c0c > +#define ENCP_DACSEL_0 0x1c0d > +#define ENCP_DACSEL_1 0x1c0e > +#define ENCP_MAX_LINE_SWITCH_POINT 0x1c0f > +#define ENCI_TST_EN 0x1c10 > +#define ENCI_TST_MDSEL 0x1c11 > +#define ENCI_TST_Y 0x1c12 > +#define ENCI_TST_CB 0x1c13 > +#define ENCI_TST_CR 0x1c14 > +#define ENCI_TST_CLRBAR_STRT 0x1c15 > +#define ENCI_TST_CLRBAR_WIDTH 0x1c16 > +#define ENCI_TST_VDCNT_STSET 0x1c17 > +#define ENCI_VFIFO2VD_CTL 0x1c18 > +#define ENCI_VFIFO2VD_PIXEL_START 0x1c19 > +#define ENCI_VFIFO2VD_PIXEL_END 0x1c1a > +#define ENCI_VFIFO2VD_LINE_TOP_START 0x1c1b > +#define ENCI_VFIFO2VD_LINE_TOP_END 0x1c1c > +#define ENCI_VFIFO2VD_LINE_BOT_START 0x1c1d > +#define ENCI_VFIFO2VD_LINE_BOT_END 0x1c1e > +#define ENCI_VFIFO2VD_CTL2 0x1c1f > +#define ENCT_VFIFO2VD_CTL 0x1c20 > +#define ENCT_VFIFO2VD_PIXEL_START 0x1c21 > +#define ENCT_VFIFO2VD_PIXEL_END 0x1c22 > +#define ENCT_VFIFO2VD_LINE_TOP_START 0x1c23 > +#define ENCT_VFIFO2VD_LINE_TOP_END 0x1c24 > +#define ENCT_VFIFO2VD_LINE_BOT_START 0x1c25 > +#define ENCT_VFIFO2VD_LINE_BOT_END 0x1c26 > +#define ENCT_VFIFO2VD_CTL2 0x1c27 > +#define ENCT_TST_EN 0x1c28 > +#define ENCT_TST_MDSEL 0x1c29 > +#define ENCT_TST_Y 0x1c2a > +#define ENCT_TST_CB 0x1c2b > +#define ENCT_TST_CR 0x1c2c > +#define ENCT_TST_CLRBAR_STRT 0x1c2d > +#define ENCT_TST_CLRBAR_WIDTH 0x1c2e > +#define ENCT_TST_VDCNT_STSET 0x1c2f > +#define ENCP_DVI_HSO_BEGIN 0x1c30 > +#define ENCP_DVI_HSO_END 0x1c31 > +#define ENCP_DVI_VSO_BLINE_EVN 0x1c32 > +#define ENCP_DVI_VSO_BLINE_ODD 0x1c33 > +#define ENCP_DVI_VSO_ELINE_EVN 0x1c34 > +#define ENCP_DVI_VSO_ELINE_ODD 0x1c35 > +#define ENCP_DVI_VSO_BEGIN_EVN 0x1c36 > +#define ENCP_DVI_VSO_BEGIN_ODD 0x1c37 > +#define ENCP_DVI_VSO_END_EVN 0x1c38 > +#define ENCP_DVI_VSO_END_ODD 0x1c39 > +#define ENCP_DE_H_BEGIN 0x1c3a > +#define ENCP_DE_H_END 0x1c3b > +#define ENCP_DE_V_BEGIN_EVEN 0x1c3c > +#define ENCP_DE_V_END_EVEN 0x1c3d > +#define ENCP_DE_V_BEGIN_ODD 0x1c3e > +#define ENCP_DE_V_END_ODD 0x1c3f > +#define ENCI_SYNC_LINE_LENGTH 0x1c40 > +#define ENCI_SYNC_PIXEL_EN 0x1c41 > +#define ENCI_SYNC_TO_LINE_EN 0x1c42 > +#define ENCI_SYNC_TO_PIXEL 0x1c43 > +#define ENCP_SYNC_LINE_LENGTH 0x1c44 > +#define ENCP_SYNC_PIXEL_EN 0x1c45 > +#define ENCP_SYNC_TO_LINE_EN 0x1c46 > +#define ENCP_SYNC_TO_PIXEL 0x1c47 > +#define ENCT_SYNC_LINE_LENGTH 0x1c48 > +#define ENCT_SYNC_PIXEL_EN 0x1c49 > +#define ENCT_SYNC_TO_LINE_EN 0x1c4a > +#define ENCT_SYNC_TO_PIXEL 0x1c4b > +#define ENCL_SYNC_LINE_LENGTH 0x1c4c > +#define ENCL_SYNC_PIXEL_EN 0x1c4d > +#define ENCL_SYNC_TO_LINE_EN 0x1c4e > +#define ENCL_SYNC_TO_PIXEL 0x1c4f > +#define ENCP_VFIFO2VD_CTL2 0x1c50 > +#define VENC_DVI_SETTING_MORE 0x1c51 > +#define VENC_VDAC_DAC4_FILT_CTRL0 0x1c54 > +#define VENC_VDAC_DAC4_FILT_CTRL1 0x1c55 > +#define VENC_VDAC_DAC5_FILT_CTRL0 0x1c56 > +#define VENC_VDAC_DAC5_FILT_CTRL1 0x1c57 > +#define VENC_VDAC_DAC0_FILT_CTRL0 0x1c58 > +#define VENC_VDAC_DAC0_FILT_CTRL1 0x1c59 > +#define VENC_VDAC_DAC1_FILT_CTRL0 0x1c5a > +#define VENC_VDAC_DAC1_FILT_CTRL1 0x1c5b > +#define VENC_VDAC_DAC2_FILT_CTRL0 0x1c5c > +#define VENC_VDAC_DAC2_FILT_CTRL1 0x1c5d > +#define VENC_VDAC_DAC3_FILT_CTRL0 0x1c5e > +#define VENC_VDAC_DAC3_FILT_CTRL1 0x1c5f > +#define ENCT_VIDEO_EN 0x1c60 > +#define ENCT_VIDEO_Y_SCL 0x1c61 > +#define ENCT_VIDEO_PB_SCL 0x1c62 > +#define ENCT_VIDEO_PR_SCL 0x1c63 > +#define ENCT_VIDEO_Y_OFFST 0x1c64 > +#define ENCT_VIDEO_PB_OFFST 0x1c65 > +#define ENCT_VIDEO_PR_OFFST 0x1c66 > +#define ENCT_VIDEO_MODE 0x1c67 > +#define ENCT_VIDEO_MODE_ADV 0x1c68 > +#define ENCT_DBG_PX_RST 0x1c69 > +#define ENCT_DBG_LN_RST 0x1c6a > +#define ENCT_DBG_PX_INT 0x1c6b > +#define ENCT_DBG_LN_INT 0x1c6c > +#define ENCT_VIDEO_YFP1_HTIME 0x1c6d > +#define ENCT_VIDEO_YFP2_HTIME 0x1c6e > +#define ENCT_VIDEO_YC_DLY 0x1c6f > +#define ENCT_VIDEO_MAX_PXCNT 0x1c70 > +#define ENCT_VIDEO_HAVON_END 0x1c71 > +#define ENCT_VIDEO_HAVON_BEGIN 0x1c72 > +#define ENCT_VIDEO_VAVON_ELINE 0x1c73 > +#define ENCT_VIDEO_VAVON_BLINE 0x1c74 > +#define ENCT_VIDEO_HSO_BEGIN 0x1c75 > +#define ENCT_VIDEO_HSO_END 0x1c76 > +#define ENCT_VIDEO_VSO_BEGIN 0x1c77 > +#define ENCT_VIDEO_VSO_END 0x1c78 > +#define ENCT_VIDEO_VSO_BLINE 0x1c79 > +#define ENCT_VIDEO_VSO_ELINE 0x1c7a > +#define ENCT_VIDEO_MAX_LNCNT 0x1c7b > +#define ENCT_VIDEO_BLANKY_VAL 0x1c7c > +#define ENCT_VIDEO_BLANKPB_VAL 0x1c7d > +#define ENCT_VIDEO_BLANKPR_VAL 0x1c7e > +#define ENCT_VIDEO_HOFFST 0x1c7f > +#define ENCT_VIDEO_VOFFST 0x1c80 > +#define ENCT_VIDEO_RGB_CTRL 0x1c81 > +#define ENCT_VIDEO_FILT_CTRL 0x1c82 > +#define ENCT_VIDEO_OFLD_VPEQ_OFST 0x1c83 > +#define ENCT_VIDEO_OFLD_VOAV_OFST 0x1c84 > +#define ENCT_VIDEO_MATRIX_CB 0x1c85 > +#define ENCT_VIDEO_MATRIX_CR 0x1c86 > +#define ENCT_VIDEO_RGBIN_CTRL 0x1c87 > +#define ENCT_MAX_LINE_SWITCH_POINT 0x1c88 > +#define ENCT_DACSEL_0 0x1c89 > +#define ENCT_DACSEL_1 0x1c8a > +#define ENCL_VFIFO2VD_CTL 0x1c90 > +#define ENCL_VFIFO2VD_PIXEL_START 0x1c91 > +#define ENCL_VFIFO2VD_PIXEL_END 0x1c92 > +#define ENCL_VFIFO2VD_LINE_TOP_START 0x1c93 > +#define ENCL_VFIFO2VD_LINE_TOP_END 0x1c94 > +#define ENCL_VFIFO2VD_LINE_BOT_START 0x1c95 > +#define ENCL_VFIFO2VD_LINE_BOT_END 0x1c96 > +#define ENCL_VFIFO2VD_CTL2 0x1c97 > +#define ENCL_TST_EN 0x1c98 > +#define ENCL_TST_MDSEL 0x1c99 > +#define ENCL_TST_Y 0x1c9a > +#define ENCL_TST_CB 0x1c9b > +#define ENCL_TST_CR 0x1c9c > +#define ENCL_TST_CLRBAR_STRT 0x1c9d > +#define ENCL_TST_CLRBAR_WIDTH 0x1c9e > +#define ENCL_TST_VDCNT_STSET 0x1c9f > +#define ENCL_VIDEO_EN 0x1ca0 > +#define ENCL_VIDEO_Y_SCL 0x1ca1 > +#define ENCL_VIDEO_PB_SCL 0x1ca2 > +#define ENCL_VIDEO_PR_SCL 0x1ca3 > +#define ENCL_VIDEO_Y_OFFST 0x1ca4 > +#define ENCL_VIDEO_PB_OFFST 0x1ca5 > +#define ENCL_VIDEO_PR_OFFST 0x1ca6 > +#define ENCL_VIDEO_MODE 0x1ca7 > +#define ENCL_VIDEO_MODE_ADV 0x1ca8 > +#define ENCL_DBG_PX_RST 0x1ca9 > +#define ENCL_DBG_LN_RST 0x1caa > +#define ENCL_DBG_PX_INT 0x1cab > +#define ENCL_DBG_LN_INT 0x1cac > +#define ENCL_VIDEO_YFP1_HTIME 0x1cad > +#define ENCL_VIDEO_YFP2_HTIME 0x1cae > +#define ENCL_VIDEO_YC_DLY 0x1caf > +#define ENCL_VIDEO_MAX_PXCNT 0x1cb0 > +#define ENCL_VIDEO_HAVON_END 0x1cb1 > +#define ENCL_VIDEO_HAVON_BEGIN 0x1cb2 > +#define ENCL_VIDEO_VAVON_ELINE 0x1cb3 > +#define ENCL_VIDEO_VAVON_BLINE 0x1cb4 > +#define ENCL_VIDEO_HSO_BEGIN 0x1cb5 > +#define ENCL_VIDEO_HSO_END 0x1cb6 > +#define ENCL_VIDEO_VSO_BEGIN 0x1cb7 > +#define ENCL_VIDEO_VSO_END 0x1cb8 > +#define ENCL_VIDEO_VSO_BLINE 0x1cb9 > +#define ENCL_VIDEO_VSO_ELINE 0x1cba > +#define ENCL_VIDEO_MAX_LNCNT 0x1cbb > +#define ENCL_VIDEO_BLANKY_VAL 0x1cbc > +#define ENCL_VIDEO_BLANKPB_VAL 0x1cbd > +#define ENCL_VIDEO_BLANKPR_VAL 0x1cbe > +#define ENCL_VIDEO_HOFFST 0x1cbf > +#define ENCL_VIDEO_VOFFST 0x1cc0 > +#define ENCL_VIDEO_RGB_CTRL 0x1cc1 > +#define ENCL_VIDEO_FILT_CTRL 0x1cc2 > +#define ENCL_VIDEO_OFLD_VPEQ_OFST 0x1cc3 > +#define ENCL_VIDEO_OFLD_VOAV_OFST 0x1cc4 > +#define ENCL_VIDEO_MATRIX_CB 0x1cc5 > +#define ENCL_VIDEO_MATRIX_CR 0x1cc6 > +#define ENCL_VIDEO_RGBIN_CTRL 0x1cc7 > +#define ENCL_MAX_LINE_SWITCH_POINT 0x1cc8 > +#define ENCL_DACSEL_0 0x1cc9 > +#define ENCL_DACSEL_1 0x1cca > +#define RDMA_AHB_START_ADDR_MAN 0x1100 > +#define RDMA_AHB_END_ADDR_MAN 0x1101 > +#define RDMA_AHB_START_ADDR_1 0x1102 > +#define RDMA_AHB_END_ADDR_1 0x1103 > +#define RDMA_AHB_START_ADDR_2 0x1104 > +#define RDMA_AHB_END_ADDR_2 0x1105 > +#define RDMA_AHB_START_ADDR_3 0x1106 > +#define RDMA_AHB_END_ADDR_3 0x1107 > +#define RDMA_AHB_START_ADDR_4 0x1108 > +#define RDMA_AHB_END_ADDR_4 0x1109 > +#define RDMA_AHB_START_ADDR_5 0x110a > +#define RDMA_AHB_END_ADDR_5 0x110b > +#define RDMA_AHB_START_ADDR_6 0x110c > +#define RDMA_AHB_END_ADDR_6 0x110d > +#define RDMA_AHB_START_ADDR_7 0x110e > +#define RDMA_AHB_END_ADDR_7 0x110f > +#define RDMA_ACCESS_AUTO 0x1110 > +#define RDMA_ACCESS_AUTO2 0x1111 > +#define RDMA_ACCESS_AUTO3 0x1112 > +#define RDMA_ACCESS_MAN 0x1113 > +#define RDMA_CTRL 0x1114 > +#define RDMA_STATUS 0x1115 > +#define RDMA_STATUS2 0x1116 > +#define RDMA_STATUS3 0x1117 > +#define L_GAMMA_CNTL_PORT 0x1400 > +#define L_GAMMA_DATA_PORT 0x1401 > +#define L_GAMMA_ADDR_PORT 0x1402 > +#define L_GAMMA_VCOM_HSWITCH_ADDR 0x1403 > +#define L_RGB_BASE_ADDR 0x1405 > +#define L_RGB_COEFF_ADDR 0x1406 > +#define L_POL_CNTL_ADDR 0x1407 > +#define L_DITH_CNTL_ADDR 0x1408 > +#define L_GAMMA_PROBE_CTRL 0x1409 > +#define L_GAMMA_PROBE_COLOR_L 0x140a > +#define L_GAMMA_PROBE_COLOR_H 0x140b > +#define L_GAMMA_PROBE_HL_COLOR 0x140c > +#define L_GAMMA_PROBE_POS_X 0x140d > +#define L_GAMMA_PROBE_POS_Y 0x140e > +#define L_STH1_HS_ADDR 0x1410 > +#define L_STH1_HE_ADDR 0x1411 > +#define L_STH1_VS_ADDR 0x1412 > +#define L_STH1_VE_ADDR 0x1413 > +#define L_STH2_HS_ADDR 0x1414 > +#define L_STH2_HE_ADDR 0x1415 > +#define L_STH2_VS_ADDR 0x1416 > +#define L_STH2_VE_ADDR 0x1417 > +#define L_OEH_HS_ADDR 0x1418 > +#define L_OEH_HE_ADDR 0x1419 > +#define L_OEH_VS_ADDR 0x141a > +#define L_OEH_VE_ADDR 0x141b > +#define L_VCOM_HSWITCH_ADDR 0x141c > +#define L_VCOM_VS_ADDR 0x141d > +#define L_VCOM_VE_ADDR 0x141e > +#define L_CPV1_HS_ADDR 0x141f > +#define L_CPV1_HE_ADDR 0x1420 > +#define L_CPV1_VS_ADDR 0x1421 > +#define L_CPV1_VE_ADDR 0x1422 > +#define L_CPV2_HS_ADDR 0x1423 > +#define L_CPV2_HE_ADDR 0x1424 > +#define L_CPV2_VS_ADDR 0x1425 > +#define L_CPV2_VE_ADDR 0x1426 > +#define L_STV1_HS_ADDR 0x1427 > +#define L_STV1_HE_ADDR 0x1428 > +#define L_STV1_VS_ADDR 0x1429 > +#define L_STV1_VE_ADDR 0x142a > +#define L_STV2_HS_ADDR 0x142b > +#define L_STV2_HE_ADDR 0x142c > +#define L_STV2_VS_ADDR 0x142d > +#define L_STV2_VE_ADDR 0x142e > +#define L_OEV1_HS_ADDR 0x142f > +#define L_OEV1_HE_ADDR 0x1430 > +#define L_OEV1_VS_ADDR 0x1431 > +#define L_OEV1_VE_ADDR 0x1432 > +#define L_OEV2_HS_ADDR 0x1433 > +#define L_OEV2_HE_ADDR 0x1434 > +#define L_OEV2_VS_ADDR 0x1435 > +#define L_OEV2_VE_ADDR 0x1436 > +#define L_OEV3_HS_ADDR 0x1437 > +#define L_OEV3_HE_ADDR 0x1438 > +#define L_OEV3_VS_ADDR 0x1439 > +#define L_OEV3_VE_ADDR 0x143a > +#define L_LCD_PWR_ADDR 0x143b > +#define L_LCD_PWM0_LO_ADDR 0x143c > +#define L_LCD_PWM0_HI_ADDR 0x143d > +#define L_LCD_PWM1_LO_ADDR 0x143e > +#define L_LCD_PWM1_HI_ADDR 0x143f > +#define L_INV_CNT_ADDR 0x1440 > +#define L_TCON_MISC_SEL_ADDR 0x1441 > +#define L_DUAL_PORT_CNTL_ADDR 0x1442 > +#define MLVDS_CLK_CTL1_HI 0x1443 > +#define MLVDS_CLK_CTL1_LO 0x1444 > +#define L_TCON_DOUBLE_CTL 0x1449 > +#define L_TCON_PATTERN_HI 0x144a > +#define L_TCON_PATTERN_LO 0x144b > +#define LDIM_BL_ADDR_PORT 0x144e > +#define LDIM_BL_DATA_PORT 0x144f > +#define L_DE_HS_ADDR 0x1451 > +#define L_DE_HE_ADDR 0x1452 > +#define L_DE_VS_ADDR 0x1453 > +#define L_DE_VE_ADDR 0x1454 > +#define L_HSYNC_HS_ADDR 0x1455 > +#define L_HSYNC_HE_ADDR 0x1456 > +#define L_HSYNC_VS_ADDR 0x1457 > +#define L_HSYNC_VE_ADDR 0x1458 > +#define L_VSYNC_HS_ADDR 0x1459 > +#define L_VSYNC_HE_ADDR 0x145a > +#define L_VSYNC_VS_ADDR 0x145b > +#define L_VSYNC_VE_ADDR 0x145c > +#define L_LCD_MCU_CTL 0x145d > +#define DUAL_MLVDS_CTL 0x1460 > +#define DUAL_MLVDS_LINE_START 0x1461 > +#define DUAL_MLVDS_LINE_END 0x1462 > +#define DUAL_MLVDS_PIXEL_W_START_L 0x1463 > +#define DUAL_MLVDS_PIXEL_W_END_L 0x1464 > +#define DUAL_MLVDS_PIXEL_W_START_R 0x1465 > +#define DUAL_MLVDS_PIXEL_W_END_R 0x1466 > +#define DUAL_MLVDS_PIXEL_R_START_L 0x1467 > +#define DUAL_MLVDS_PIXEL_R_CNT_L 0x1468 > +#define DUAL_MLVDS_PIXEL_R_START_R 0x1469 > +#define DUAL_MLVDS_PIXEL_R_CNT_R 0x146a > +#define V_INVERSION_PIXEL 0x1470 > +#define V_INVERSION_LINE 0x1471 > +#define V_INVERSION_CONTROL 0x1472 > +#define MLVDS2_CONTROL 0x1474 > +#define MLVDS2_CONFIG_HI 0x1475 > +#define MLVDS2_CONFIG_LO 0x1476 > +#define MLVDS2_DUAL_GATE_WR_START 0x1477 > +#define MLVDS2_DUAL_GATE_WR_END 0x1478 > +#define MLVDS2_DUAL_GATE_RD_START 0x1479 > +#define MLVDS2_DUAL_GATE_RD_END 0x147a > +#define MLVDS2_SECOND_RESET_CTL 0x147b > +#define MLVDS2_DUAL_GATE_CTL_HI 0x147c > +#define MLVDS2_DUAL_GATE_CTL_LO 0x147d > +#define MLVDS2_RESET_CONFIG_HI 0x147e > +#define MLVDS2_RESET_CONFIG_LO 0x147f > +#define GAMMA_CNTL_PORT 0x1480 > +#define GAMMA_DATA_PORT 0x1481 > +#define GAMMA_ADDR_PORT 0x1482 > +#define GAMMA_VCOM_HSWITCH_ADDR 0x1483 > +#define RGB_BASE_ADDR 0x1485 > +#define RGB_COEFF_ADDR 0x1486 > +#define POL_CNTL_ADDR 0x1487 > +#define DITH_CNTL_ADDR 0x1488 > +#define GAMMA_PROBE_CTRL 0x1489 > +#define GAMMA_PROBE_COLOR_L 0x148a > +#define GAMMA_PROBE_COLOR_H 0x148b > +#define GAMMA_PROBE_HL_COLOR 0x148c > +#define GAMMA_PROBE_POS_X 0x148d > +#define GAMMA_PROBE_POS_Y 0x148e > +#define STH1_HS_ADDR 0x1490 > +#define STH1_HE_ADDR 0x1491 > +#define STH1_VS_ADDR 0x1492 > +#define STH1_VE_ADDR 0x1493 > +#define STH2_HS_ADDR 0x1494 > +#define STH2_HE_ADDR 0x1495 > +#define STH2_VS_ADDR 0x1496 > +#define STH2_VE_ADDR 0x1497 > +#define OEH_HS_ADDR 0x1498 > +#define OEH_HE_ADDR 0x1499 > +#define OEH_VS_ADDR 0x149a > +#define OEH_VE_ADDR 0x149b > +#define VCOM_HSWITCH_ADDR 0x149c > +#define VCOM_VS_ADDR 0x149d > +#define VCOM_VE_ADDR 0x149e > +#define CPV1_HS_ADDR 0x149f > +#define CPV1_HE_ADDR 0x14a0 > +#define CPV1_VS_ADDR 0x14a1 > +#define CPV1_VE_ADDR 0x14a2 > +#define CPV2_HS_ADDR 0x14a3 > +#define CPV2_HE_ADDR 0x14a4 > +#define CPV2_VS_ADDR 0x14a5 > +#define CPV2_VE_ADDR 0x14a6 > +#define STV1_HS_ADDR 0x14a7 > +#define STV1_HE_ADDR 0x14a8 > +#define STV1_VS_ADDR 0x14a9 > +#define STV1_VE_ADDR 0x14aa > +#define STV2_HS_ADDR 0x14ab > +#define STV2_HE_ADDR 0x14ac > +#define STV2_VS_ADDR 0x14ad > +#define STV2_VE_ADDR 0x14ae > +#define OEV1_HS_ADDR 0x14af > +#define OEV1_HE_ADDR 0x14b0 > +#define OEV1_VS_ADDR 0x14b1 > +#define OEV1_VE_ADDR 0x14b2 > +#define OEV2_HS_ADDR 0x14b3 > +#define OEV2_HE_ADDR 0x14b4 > +#define OEV2_VS_ADDR 0x14b5 > +#define OEV2_VE_ADDR 0x14b6 > +#define OEV3_HS_ADDR 0x14b7 > +#define OEV3_HE_ADDR 0x14b8 > +#define OEV3_VS_ADDR 0x14b9 > +#define OEV3_VE_ADDR 0x14ba > +#define LCD_PWR_ADDR 0x14bb > +#define LCD_PWM0_LO_ADDR 0x14bc > +#define LCD_PWM0_HI_ADDR 0x14bd > +#define LCD_PWM1_LO_ADDR 0x14be > +#define LCD_PWM1_HI_ADDR 0x14bf > +#define INV_CNT_ADDR 0x14c0 > +#define TCON_MISC_SEL_ADDR 0x14c1 > +#define DUAL_PORT_CNTL_ADDR 0x14c2 > +#define MLVDS_CONTROL 0x14c3 > +#define MLVDS_RESET_PATTERN_HI 0x14c4 > +#define MLVDS_RESET_PATTERN_LO 0x14c5 > +#define MLVDS_RESET_PATTERN_EXT 0x14c6 > +#define MLVDS_CONFIG_HI 0x14c7 > +#define MLVDS_CONFIG_LO 0x14c8 > +#define TCON_DOUBLE_CTL 0x14c9 > +#define TCON_PATTERN_HI 0x14ca > +#define TCON_PATTERN_LO 0x14cb > +#define TCON_CONTROL_HI 0x14cc > +#define TCON_CONTROL_LO 0x14cd > +#define LVDS_BLANK_DATA_HI 0x14ce > +#define LVDS_BLANK_DATA_LO 0x14cf > +#define LVDS_PACK_CNTL_ADDR 0x14d0 > +#define DE_HS_ADDR 0x14d1 > +#define DE_HE_ADDR 0x14d2 > +#define DE_VS_ADDR 0x14d3 > +#define DE_VE_ADDR 0x14d4 > +#define HSYNC_HS_ADDR 0x14d5 > +#define HSYNC_HE_ADDR 0x14d6 > +#define HSYNC_VS_ADDR 0x14d7 > +#define HSYNC_VE_ADDR 0x14d8 > +#define VSYNC_HS_ADDR 0x14d9 > +#define VSYNC_HE_ADDR 0x14da > +#define VSYNC_VS_ADDR 0x14db > +#define VSYNC_VE_ADDR 0x14dc > +#define LCD_MCU_CTL 0x14dd > +#define LCD_MCU_DATA_0 0x14de > +#define LCD_MCU_DATA_1 0x14df > +#define LVDS_GEN_CNTL 0x14e0 > +#define LVDS_PHY_CNTL0 0x14e1 > +#define LVDS_PHY_CNTL1 0x14e2 > +#define LVDS_PHY_CNTL2 0x14e3 > +#define LVDS_PHY_CNTL3 0x14e4 > +#define LVDS_PHY_CNTL4 0x14e5 > +#define LVDS_PHY_CNTL5 0x14e6 > +#define LVDS_SRG_TEST 0x14e8 > +#define LVDS_BIST_MUX0 0x14e9 > +#define LVDS_BIST_MUX1 0x14ea > +#define LVDS_BIST_FIXED0 0x14eb > +#define LVDS_BIST_FIXED1 0x14ec > +#define LVDS_BIST_CNTL0 0x14ed > +#define LVDS_CLKB_CLKA 0x14ee > +#define LVDS_PHY_CLK_CNTL 0x14ef > +#define LVDS_SER_EN 0x14f0 > +#define LVDS_PHY_CNTL6 0x14f1 > +#define LVDS_PHY_CNTL7 0x14f2 > +#define LVDS_PHY_CNTL8 0x14f3 > +#define MLVDS_CLK_CTL0_HI 0x14f4 > +#define MLVDS_CLK_CTL0_LO 0x14f5 > +#define MLVDS_DUAL_GATE_WR_START 0x14f6 > +#define MLVDS_DUAL_GATE_WR_END 0x14f7 > +#define MLVDS_DUAL_GATE_RD_START 0x14f8 > +#define MLVDS_DUAL_GATE_RD_END 0x14f9 > +#define MLVDS_SECOND_RESET_CTL 0x14fa > +#define MLVDS_DUAL_GATE_CTL_HI 0x14fb > +#define MLVDS_DUAL_GATE_CTL_LO 0x14fc > +#define MLVDS_RESET_CONFIG_HI 0x14fd > +#define MLVDS_RESET_CONFIG_LO 0x14fe > +#define VPU_OSD1_MMC_CTRL 0x2701 > +#define VPU_OSD2_MMC_CTRL 0x2702 > +#define VPU_VD1_MMC_CTRL 0x2703 > +#define VPU_VD2_MMC_CTRL 0x2704 > +#define VPU_DI_IF1_MMC_CTRL 0x2705 > +#define VPU_DI_MEM_MMC_CTRL 0x2706 > +#define VPU_DI_INP_MMC_CTRL 0x2707 > +#define VPU_DI_MTNRD_MMC_CTRL 0x2708 > +#define VPU_DI_CHAN2_MMC_CTRL 0x2709 > +#define VPU_DI_MTNWR_MMC_CTRL 0x270a > +#define VPU_DI_NRWR_MMC_CTRL 0x270b > +#define VPU_DI_DIWR_MMC_CTRL 0x270c > +#define VPU_VDIN0_MMC_CTRL 0x270d > +#define VPU_VDIN1_MMC_CTRL 0x270e > +#define VPU_BT656_MMC_CTRL 0x270f > +#define VPU_TVD3D_MMC_CTRL 0x2710 > +#define VPU_TVDVBI_MMC_CTRL 0x2711 > +#define VPU_TVDVBI_VSLATCH_ADDR 0x2712 > +#define VPU_TVDVBI_WRRSP_ADDR 0x2713 > +#define VPU_VDIN_PRE_ARB_CTRL 0x2714 > +#define VPU_VDISP_PRE_ARB_CTRL 0x2715 > +#define VPU_VPUARB2_PRE_ARB_CTRL 0x2716 > +#define VPU_OSD3_MMC_CTRL 0x2717 > +#define VPU_OSD4_MMC_CTRL 0x2718 > +#define VPU_VD3_MMC_CTRL 0x2719 > +#define VPU_VIU_VENC_MUX_CTRL 0x271a > +#define VIU1_SEL_VENC_MASK 0x3 > +#define VIU1_SEL_VENC_ENCL 0 > +#define VIU1_SEL_VENC_ENCI 1 > +#define VIU1_SEL_VENC_ENCP 2 > +#define VIU1_SEL_VENC_ENCT 3 > +#define VIU2_SEL_VENC_MASK 0xc > +#define VIU2_SEL_VENC_ENCL 0 > +#define VIU2_SEL_VENC_ENCI (1 << 2) > +#define VIU2_SEL_VENC_ENCP (2 << 2) > +#define VIU2_SEL_VENC_ENCT (3 << 2) > +#define VPU_HDMI_SETTING 0x271b > +#define ENCI_INFO_READ 0x271c > +#define ENCP_INFO_READ 0x271d > +#define ENCT_INFO_READ 0x271e > +#define ENCL_INFO_READ 0x271f > +#define VPU_SW_RESET 0x2720 > +#define VPU_D2D3_MMC_CTRL 0x2721 > +#define VPU_CONT_MMC_CTRL 0x2722 > +#define VPU_CLK_GATE 0x2723 > +#define VPU_RDMA_MMC_CTRL 0x2724 > +#define VPU_MEM_PD_REG0 0x2725 > +#define VPU_MEM_PD_REG1 0x2726 > +#define VPU_HDMI_DATA_OVR 0x2727 > +#define VPU_PROT1_MMC_CTRL 0x2728 > +#define VPU_PROT2_MMC_CTRL 0x2729 > +#define VPU_PROT3_MMC_CTRL 0x272a > +#define VPU_ARB4_V1_MMC_CTRL 0x272b > +#define VPU_ARB4_V2_MMC_CTRL 0x272c > +#define VPU_VPU_PWM_V0 0x2730 > +#define VPU_VPU_PWM_V1 0x2731 > +#define VPU_VPU_PWM_V2 0x2732 > +#define VPU_VPU_PWM_V3 0x2733 > +#define VPU_VPU_PWM_H0 0x2734 > +#define VPU_VPU_PWM_H1 0x2735 > +#define VPU_VPU_PWM_H2 0x2736 > +#define VPU_VPU_PWM_H3 0x2737 > +#define VPU_MISC_CTRL 0x2740 > +#define VPU_ISP_GCLK_CTRL0 0x2741 > +#define VPU_ISP_GCLK_CTRL1 0x2742 > +#define VPU_VDIN_ASYNC_HOLD_CTRL 0x2743 > +#define VPU_VDISP_ASYNC_HOLD_CTRL 0x2744 > +#define VPU_VPUARB2_ASYNC_HOLD_CTRL 0x2745 > + > +#define VPU_PROT1_CLK_GATE 0x2750 > +#define VPU_PROT1_GEN_CNTL 0x2751 > +#define VPU_PROT1_X_START_END 0x2752 > +#define VPU_PROT1_Y_START_END 0x2753 > +#define VPU_PROT1_Y_LEN_STEP 0x2754 > +#define VPU_PROT1_RPT_LOOP 0x2755 > +#define VPU_PROT1_RPT_PAT 0x2756 > +#define VPU_PROT1_DDR 0x2757 > +#define VPU_PROT1_RBUF_ROOM 0x2758 > +#define VPU_PROT1_STAT_0 0x2759 > +#define VPU_PROT1_STAT_1 0x275a > +#define VPU_PROT1_STAT_2 0x275b > +#define VPU_PROT1_REQ_ONOFF 0x275c > +#define VPU_PROT2_CLK_GATE 0x2760 > +#define VPU_PROT2_GEN_CNTL 0x2761 > +#define VPU_PROT2_X_START_END 0x2762 > +#define VPU_PROT2_Y_START_END 0x2763 > +#define VPU_PROT2_Y_LEN_STEP 0x2764 > +#define VPU_PROT2_RPT_LOOP 0x2765 > +#define VPU_PROT2_RPT_PAT 0x2766 > +#define VPU_PROT2_DDR 0x2767 > +#define VPU_PROT2_RBUF_ROOM 0x2768 > +#define VPU_PROT2_STAT_0 0x2769 > +#define VPU_PROT2_STAT_1 0x276a > +#define VPU_PROT2_STAT_2 0x276b > +#define VPU_PROT2_REQ_ONOFF 0x276c > +#define VPU_PROT3_CLK_GATE 0x2770 > +#define VPU_PROT3_GEN_CNTL 0x2771 > +#define VPU_PROT3_X_START_END 0x2772 > +#define VPU_PROT3_Y_START_END 0x2773 > +#define VPU_PROT3_Y_LEN_STEP 0x2774 > +#define VPU_PROT3_RPT_LOOP 0x2775 > +#define VPU_PROT3_RPT_PAT 0x2776 > +#define VPU_PROT3_DDR 0x2777 > +#define VPU_PROT3_RBUF_ROOM 0x2778 > +#define VPU_PROT3_STAT_0 0x2779 > +#define VPU_PROT3_STAT_1 0x277a > +#define VPU_PROT3_STAT_2 0x277b > +#define VPU_PROT3_REQ_ONOFF 0x277c > + > +/* osd super scale */ > +#define OSDSR_HV_SIZEIN 0x3130 > +#define OSDSR_CTRL_MODE 0x3131 > +#define OSDSR_ABIC_HCOEF 0x3132 > +#define OSDSR_YBIC_HCOEF 0x3133 > +#define OSDSR_CBIC_HCOEF 0x3134 > +#define OSDSR_ABIC_VCOEF 0x3135 > +#define OSDSR_YBIC_VCOEF 0x3136 > +#define OSDSR_CBIC_VCOEF 0x3137 > +#define OSDSR_VAR_PARA 0x3138 > +#define OSDSR_CONST_PARA 0x3139 > +#define OSDSR_RKE_EXTWIN 0x313a > +#define OSDSR_UK_GRAD2DDIAG_TH_RATE 0x313b > +#define OSDSR_UK_GRAD2DDIAG_LIMIT 0x313c > +#define OSDSR_UK_GRAD2DADJA_TH_RATE 0x313d > +#define OSDSR_UK_GRAD2DADJA_LIMIT 0x313e > +#define OSDSR_UK_BST_GAIN 0x313f > +#define OSDSR_HVBLEND_TH 0x3140 > +#define OSDSR_DEMO_WIND_TB 0x3141 > +#define OSDSR_DEMO_WIND_LR 0x3142 > +#define OSDSR_INT_BLANK_NUM 0x3143 > +#define OSDSR_FRM_END_STAT 0x3144 > +#define OSDSR_ABIC_HCOEF0 0x3145 > +#define OSDSR_YBIC_HCOEF0 0x3146 > +#define OSDSR_CBIC_HCOEF0 0x3147 > +#define OSDSR_ABIC_VCOEF0 0x3148 > +#define OSDSR_YBIC_VCOEF0 0x3149 > +#define OSDSR_CBIC_VCOEF0 0x314a > + > +#endif /* __MESON_REGISTERS_H */ > diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c > new file mode 100644 > index 0000000..c8c575d > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_vclk.c > @@ -0,0 +1,169 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <drm/drmP.h> > +#include "meson_drv.h" > +#include "meson_vclk.h" > + > +/* > + * VCLK is the "Pixel Clock" frequency generator from a dedicated PLL. > + * We handle the following encodings : > + * - CVBS 27MHz generator via the VCLK2 to the VENCI and VDAC blocks > + * > + * What is missing : > + * - HDMI Pixel Clocks generation > + */ > + > +/* HHI Registers */ > +#define HHI_VID_PLL_CLK_DIV 0x1a0 /* 0x68 offset in data sheet */ > +#define VID_PLL_EN BIT(19) > +#define VID_PLL_BYPASS BIT(18) > +#define VID_PLL_PRESET BIT(15) > +#define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */ > +#define VCLK2_DIV_MASK 0xff > +#define VCLK2_DIV_EN BIT(16) > +#define VCLK2_DIV_RESET BIT(17) > +#define CTS_VDAC_SEL_MASK (0xf << 28) > +#define CTS_VDAC_SEL_SHIFT 28 > +#define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */ > +#define VCLK2_EN BIT(19) > +#define VCLK2_SEL_MASK (0x7 << 16) > +#define VCLK2_SEL_SHIFT 16 > +#define VCLK2_SOFT_RESET BIT(15) > +#define VCLK2_DIV1_EN BIT(0) > +#define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */ > +#define CTS_ENCI_SEL_MASK (0xf << 28) > +#define CTS_ENCI_SEL_SHIFT 28 > +#define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */ > +#define CTS_ENCI_EN BIT(0) > +#define CTS_VDAC_EN BIT(4) > + > +#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ > +#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ > + > +#define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ > +#define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */ > +#define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in data sheet */ > +#define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in data sheet */ > +#define HHI_HDMI_PLL_CNTL5 0x330 /* 0xcc offset in data sheet */ > +#define HHI_HDMI_PLL_CNTL6 0x334 /* 0xcd offset in data sheet */ > + > +#define HDMI_PLL_RESET BIT(28) > +#define HDMI_PLL_LOCK BIT(31) > + > +/* > + * Setup VCLK2 for 27MHz, and enable clocks for ENCI and VDAC > + * > + * TOFIX: Refactor into table to also handle HDMI frequency and paths > + */ > +static void meson_venci_cvbs_clock_config(struct meson_drm *priv) > +{ > + unsigned int val; > + > + /* Setup PLL to output 1.485GHz */ > + if (of_machine_is_compatible("amlogic,meson-gxbb")) { > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d); > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00404e00); > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4800023d); > + } else if (of_machine_is_compatible("amlogic,meson-gxm") || > + of_machine_is_compatible("amlogic,meson-gxl")) { > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b); > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300); > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0xa6212844); > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c4d000c); > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); > + regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); > + > + /* Reset PLL */ > + regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, > + HDMI_PLL_RESET, HDMI_PLL_RESET); > + regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, > + HDMI_PLL_RESET, 0); > + } > + > + /* Poll for lock bit */ > + regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val, > + (val & HDMI_PLL_LOCK), 10, 0); > + > + /* Disable VCLK2 */ > + regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0); > + > + /* Disable vid_pll output clock */ > + regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0); > + regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0); > + /* Enable vid_pll bypass to HDMI pll */ > + regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, > + VID_PLL_BYPASS, VID_PLL_BYPASS); > + /* Enable the vid_pll output clock */ > + regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, > + VID_PLL_EN, VID_PLL_EN); > + > + /* Setup the VCLK2 divider value to achieve 27MHz */ > + regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, > + VCLK2_DIV_MASK, (55 - 1)); > + > + /* select vid_pll for vclk2 */ > + regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, > + VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT)); > + /* enable vclk2 gate */ > + regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN); > + > + /* select vclk_div1 for enci */ > + regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, > + CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT)); > + /* select vclk_div1 for vdac */ > + regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, > + CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT)); > + > + /* release vclk2_div_reset and enable vclk2_div */ > + regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, > + VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN); > + > + /* enable vclk2_div1 gate */ > + regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, > + VCLK2_DIV1_EN, VCLK2_DIV1_EN); > + > + /* reset vclk2 */ > + regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, > + VCLK2_SOFT_RESET, VCLK2_SOFT_RESET); > + regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, > + VCLK2_SOFT_RESET, 0); > + > + /* enable enci_clk */ > + regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2, > + CTS_ENCI_EN, CTS_ENCI_EN); > + /* enable vdac_clk */ > + regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2, > + CTS_VDAC_EN, CTS_VDAC_EN); > +} > + > +void meson_vclk_setup(struct meson_drm *priv, unsigned int target, > + unsigned int freq) > +{ > + if (target == MESON_VCLK_TARGET_CVBS && freq == MESON_VCLK_CVBS) > + meson_venci_cvbs_clock_config(priv); > +} > diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h > new file mode 100644 > index 0000000..444d6a4 > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_vclk.h > @@ -0,0 +1,36 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + */ > + > +/* Video Clock */ > + > +#ifndef __MESON_VCLK_H > +#define __MESON_VCLK_H > + > +enum { > + MESON_VCLK_TARGET_CVBS = 0, > +}; > + > +/* 27MHz is the CVBS Pixel Clock */ > +#define MESON_VCLK_CVBS 27000 > + > +void meson_vclk_setup(struct meson_drm *priv, unsigned int target, > + unsigned int freq); > + > +#endif /* __MESON_VCLK_H */ > diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c > new file mode 100644 > index 0000000..c2a08df > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_venc.c > @@ -0,0 +1,286 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <drm/drmP.h> > +#include "meson_drv.h" > +#include "meson_venc.h" > +#include "meson_vpp.h" > +#include "meson_vclk.h" > +#include "meson_registers.h" > + > +/* > + * VENC Handle the pixels encoding to the output formats. > + * We handle the following encodings : > + * - CVBS Encoding via the ENCI encoder and VDAC digital to analog converter > + * > + * What is missing : > + * - TMDS/HDMI Encoding via ENCI_DIV and ENCP > + * - Setup of more clock rates for HDMI modes > + * - LCD Panel encoding via ENCL > + * - TV Panel encoding via ENCT > + */ > + > +/* HHI Registers */ > +#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ > +#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ > + > +struct meson_cvbs_enci_mode meson_cvbs_enci_pal = { > + .mode_tag = MESON_VENC_MODE_CVBS_PAL, > + .hso_begin = 3, > + .hso_end = 129, > + .vso_even = 3, > + .vso_odd = 260, > + .macv_max_amp = 7, > + .video_prog_mode = 0xff, > + .video_mode = 0x13, > + .sch_adjust = 0x28, > + .yc_delay = 0x343, > + .pixel_start = 251, > + .pixel_end = 1691, > + .top_field_line_start = 22, > + .top_field_line_end = 310, > + .bottom_field_line_start = 23, > + .bottom_field_line_end = 311, > + .video_saturation = 9, > + .video_contrast = 0, > + .video_brightness = 0, > + .video_hue = 0, > + .analog_sync_adj = 0x8080, > +}; > + > +struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = { > + .mode_tag = MESON_VENC_MODE_CVBS_NTSC, > + .hso_begin = 5, > + .hso_end = 129, > + .vso_even = 3, > + .vso_odd = 260, > + .macv_max_amp = 0xb, > + .video_prog_mode = 0xf0, > + .video_mode = 0x8, > + .sch_adjust = 0x20, > + .yc_delay = 0x333, > + .pixel_start = 227, > + .pixel_end = 1667, > + .top_field_line_start = 18, > + .top_field_line_end = 258, > + .bottom_field_line_start = 19, > + .bottom_field_line_end = 259, > + .video_saturation = 18, > + .video_contrast = 3, > + .video_brightness = 0, > + .video_hue = 0, > + .analog_sync_adj = 0x9c00, > +}; > + > +void meson_venci_cvbs_mode_set(struct meson_drm *priv, > + struct meson_cvbs_enci_mode *mode) > +{ > + if (mode->mode_tag == priv->venc.current_mode) > + return; > + > + /* CVBS Filter settings */ > + writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL)); > + writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2)); > + > + /* Digital Video Select : Interlace, clk27 clk, external */ > + writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING)); > + > + /* Reset Video Mode */ > + writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE)); > + writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); > + > + /* Horizontal sync signal output */ > + writel_relaxed(mode->hso_begin, > + priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN)); > + writel_relaxed(mode->hso_end, > + priv->io_base + _REG(ENCI_SYNC_HSO_END)); > + > + /* Vertical Sync lines */ > + writel_relaxed(mode->vso_even, > + priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN)); > + writel_relaxed(mode->vso_odd, > + priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN)); > + > + /* Macrovision max amplitude change */ > + writel_relaxed(0x8100 + mode->macv_max_amp, > + priv->io_base + _REG(ENCI_MACV_MAX_AMP)); > + > + /* Video mode */ > + writel_relaxed(mode->video_prog_mode, > + priv->io_base + _REG(VENC_VIDEO_PROG_MODE)); > + writel_relaxed(mode->video_mode, > + priv->io_base + _REG(ENCI_VIDEO_MODE)); > + > + /* Advanced Video Mode : > + * Demux shifting 0x2 > + * Blank line end at line17/22 > + * High bandwidth Luma Filter > + * Low bandwidth Chroma Filter > + * Bypass luma low pass filter > + * No macrovision on CSYNC > + */ > + writel_relaxed(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); > + > + writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH)); > + > + /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */ > + writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE)); > + > + /* 0x3 Y, C, and Component Y delay */ > + writel_relaxed(mode->yc_delay, priv->io_base + _REG(ENCI_YC_DELAY)); > + > + /* Timings */ > + writel_relaxed(mode->pixel_start, > + priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START)); > + writel_relaxed(mode->pixel_end, > + priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END)); > + > + writel_relaxed(mode->top_field_line_start, > + priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START)); > + writel_relaxed(mode->top_field_line_end, > + priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END)); > + > + writel_relaxed(mode->bottom_field_line_start, > + priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START)); > + writel_relaxed(mode->bottom_field_line_end, > + priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END)); > + > + /* Internal Venc, Internal VIU Sync, Internal Vencoder */ > + writel_relaxed(0, priv->io_base + _REG(VENC_SYNC_ROUTE)); > + > + /* UNreset Interlaced TV Encoder */ > + writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST)); > + > + /* Enable Vfifo2vd, Y_Cb_Y_Cr select */ > + writel_relaxed(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); > + > + /* Power UP Dacs */ > + writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_SETTING)); > + > + /* Video Upsampling */ > + writel_relaxed(0x0061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL0)); > + writel_relaxed(0x4061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL1)); > + writel_relaxed(0x5061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL2)); > + > + /* Select Interlace Y DACs */ > + writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL0)); > + writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL1)); > + writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL2)); > + writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL3)); > + writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL4)); > + writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL5)); > + > + /* Select ENCI for VIU */ > + meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI); > + > + /* Enable ENCI FIFO */ > + writel_relaxed(0x2000, priv->io_base + _REG(VENC_VDAC_FIFO_CTRL)); > + > + /* Select ENCI DACs 0, 1, 4, and 5 */ > + writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_0)); > + writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_1)); > + > + /* Interlace video enable */ > + writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); > + > + /* Configure Video Saturation / Contrast / Brightness / Hue */ > + writel_relaxed(mode->video_saturation, > + priv->io_base + _REG(ENCI_VIDEO_SAT)); > + writel_relaxed(mode->video_contrast, > + priv->io_base + _REG(ENCI_VIDEO_CONT)); > + writel_relaxed(mode->video_brightness, > + priv->io_base + _REG(ENCI_VIDEO_BRIGHT)); > + writel_relaxed(mode->video_hue, > + priv->io_base + _REG(ENCI_VIDEO_HUE)); > + > + /* Enable DAC0 Filter */ > + writel_relaxed(0x1, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0)); > + writel_relaxed(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1)); > + > + /* 0 in Macrovision register 0 */ > + writel_relaxed(0, priv->io_base + _REG(ENCI_MACV_N0)); > + > + /* Analog Synchronization and color burst value adjust */ > + writel_relaxed(mode->analog_sync_adj, > + priv->io_base + _REG(ENCI_SYNC_ADJ)); > + > + /* Setup 27MHz vclk2 for ENCI and VDAC */ > + meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, MESON_VCLK_CVBS); > + > + priv->venc.current_mode = mode->mode_tag; > +} > + > +void meson_venci_cvbs_enable(struct meson_drm *priv) > +{ > + /* VDAC0 source is not from ATV */ > + writel_bits_relaxed(BIT(5), 0, priv->io_base + _REG(VENC_VDAC_DACSEL0)); > + > + if (of_machine_is_compatible("amlogic,meson-gxbb")) > + regmap_write(priv->hhi, HHI_VDAC_CNTL0, 1); > + else if (of_machine_is_compatible("amlogic,meson-gxm") || > + of_machine_is_compatible("amlogic,meson-gxl")) > + regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0xf0001); > + > + regmap_write(priv->hhi, HHI_VDAC_CNTL1, 0); > + > + priv->venc.cvbs_enabled = true; > +} > + > +void meson_venci_cvbs_disable(struct meson_drm *priv) > +{ > + regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0); > + regmap_write(priv->hhi, HHI_VDAC_CNTL1, 0); > + > + priv->venc.cvbs_enabled = false; > +} > + > +/* Returns the current ENCI field polarity */ > +unsigned int meson_venci_get_field(struct meson_drm *priv) > +{ > + return readl_relaxed(priv->io_base + _REG(ENCI_INFO_READ)) & BIT(29); > +} > + > +void meson_venc_enable_vsync(struct meson_drm *priv) > +{ > + writel_relaxed(2, priv->io_base + _REG(VENC_INTCTRL)); > +} > + > +void meson_venc_disable_vsync(struct meson_drm *priv) > +{ > + writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL)); > +} > + > +void meson_venc_init(struct meson_drm *priv) > +{ > + /* Disable all encoders */ > + writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); > + writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); > + writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN)); > + > + /* Disable VSync IRQ */ > + meson_venc_disable_vsync(priv); > + > + meson_venci_cvbs_disable(priv); > + > + priv->venc.current_mode = MESON_VENC_MODE_NONE; > +} > diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h > new file mode 100644 > index 0000000..75a101b > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_venc.h > @@ -0,0 +1,77 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + */ > + > +/* > + * Video Encoders > + * - ENCI : Interlace Video Encoder > + * - ENCI_DVI : Interlace Video Encoder for DVI/HDMI > + * - ENCP : Progressive Video Encoder > + */ > + > +#ifndef __MESON_VENC_H > +#define __MESON_VENC_H > + > +enum { > + MESON_VENC_MODE_NONE = 0, > + MESON_VENC_MODE_CVBS_PAL, > + MESON_VENC_MODE_CVBS_NTSC, > +}; > + > +struct meson_cvbs_enci_mode { > + unsigned int mode_tag; > + unsigned int hso_begin; /* HSO begin position */ > + unsigned int hso_end; /* HSO end position */ > + unsigned int vso_even; /* VSO even line */ > + unsigned int vso_odd; /* VSO odd line */ > + unsigned int macv_max_amp; /* Macrovision max amplitude */ > + unsigned int video_prog_mode; > + unsigned int video_mode; > + unsigned int sch_adjust; > + unsigned int yc_delay; > + unsigned int pixel_start; > + unsigned int pixel_end; > + unsigned int top_field_line_start; > + unsigned int top_field_line_end; > + unsigned int bottom_field_line_start; > + unsigned int bottom_field_line_end; > + unsigned int video_saturation; > + unsigned int video_contrast; > + unsigned int video_brightness; > + unsigned int video_hue; > + unsigned int analog_sync_adj; > +}; > + > +/* CVBS Timings and Parameters */ > +extern struct meson_cvbs_enci_mode meson_cvbs_enci_pal; > +extern struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc; > + > +void meson_venci_cvbs_mode_set(struct meson_drm *priv, > + struct meson_cvbs_enci_mode *mode); > +void meson_venci_cvbs_enable(struct meson_drm *priv); > +void meson_venci_cvbs_disable(struct meson_drm *priv); > + > +unsigned int meson_venci_get_field(struct meson_drm *priv); > + > +void meson_venc_enable_vsync(struct meson_drm *priv); > +void meson_venc_disable_vsync(struct meson_drm *priv); > + > +void meson_venc_init(struct meson_drm *priv); > + > +#endif /* __MESON_VENC_H */ > diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c > new file mode 100644 > index 0000000..66f251fb > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_viu.c > @@ -0,0 +1,497 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. > + * Copyright (C) 2014 Endless Mobile > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <drm/drmP.h> > +#include "meson_drv.h" > +#include "meson_viu.h" > +#include "meson_vpp.h" > +#include "meson_venc.h" > +#include "meson_canvas.h" > +#include "meson_registers.h" > + > +/* > + * VIU Handles the Pixel scanout and the basic Colorspace conversions > + * We handle the following features : > + * - OSD1 RGB565/RGB888/xRGB8888 scanout > + * - RGB conversion to x/cb/cr > + * - Progressive or Interlace buffer scanout > + * - OSD1 Commit on Vsync > + * - HDR OSD matrix for GXL/GXM > + * > + * What is missing : > + * - BGR888/xBGR8888/BGRx8888/BGRx8888 modes > + * - YUV4:2:2 Y0CbY1Cr scanout > + * - Conversion to YUV 4:4:4 from 4:2:2 input > + * - Colorkey Alpha matching > + * - Big endian scanout > + * - X/Y reverse scanout > + * - Global alpha setup > + * - OSD2 support, would need interlace switching on vsync > + * - OSD1 full scaling to support TV overscan > + */ > + > +/* OSDx_BLKx_CFG */ > +#define OSD_CANVAS_SEL 16 > + > +#define OSD_ENDIANNESS_LE BIT(15) > +#define OSD_ENDIANNESS_BE (0) > + > +#define OSD_BLK_MODE_422 (0x03 << 8) > +#define OSD_BLK_MODE_16 (0x04 << 8) > +#define OSD_BLK_MODE_32 (0x05 << 8) > +#define OSD_BLK_MODE_24 (0x07 << 8) > + > +#define OSD_OUTPUT_COLOR_RGB BIT(7) > +#define OSD_OUTPUT_COLOR_YUV (0) > + > +#define OSD_COLOR_MATRIX_32_RGBA (0x00 << 2) > +#define OSD_COLOR_MATRIX_32_ARGB (0x01 << 2) > +#define OSD_COLOR_MATRIX_32_ABGR (0x02 << 2) > +#define OSD_COLOR_MATRIX_32_BGRA (0x03 << 2) > + > +#define OSD_COLOR_MATRIX_24_RGB (0x00 << 2) > + > +#define OSD_COLOR_MATRIX_16_RGB655 (0x00 << 2) > +#define OSD_COLOR_MATRIX_16_RGB565 (0x04 << 2) > + > +#define OSD_INTERLACE_ENABLED BIT(1) > +#define OSD_INTERLACE_ODD BIT(0) > +#define OSD_INTERLACE_EVEN (0) > + > +/* OSDx_CTRL_STAT */ > +#define OSD_ENABLE BIT(21) > +#define OSD_BLK0_ENABLE BIT(0) > + > +#define OSD_GLOBAL_ALPHA_SHIFT 12 > + > +/* OSDx_CTRL_STAT2 */ > +#define OSD_REPLACE_EN BIT(14) > +#define OSD_REPLACE_SHIFT 6 > + > +/* Takes a fixed 16.16 number and converts it to integer. */ > +static inline int64_t fixed16_to_int(int64_t value) > +{ > + return value >> 16; > +} > + > +void meson_viu_update_osd1(struct meson_drm *priv, struct drm_plane *plane) > +{ > + struct drm_plane_state *state = plane->state; > + struct drm_framebuffer *fb = state->fb; > + struct drm_rect src = { > + .x1 = (state->src_x), > + .y1 = (state->src_y), > + .x2 = (state->src_x + state->src_w), > + .y2 = (state->src_y + state->src_h), > + }; > + struct drm_rect dest = { > + .x1 = state->crtc_x, > + .y1 = state->crtc_y, > + .x2 = state->crtc_x + state->crtc_w, > + .y2 = state->crtc_y + state->crtc_h, > + }; > + unsigned long flags; > + > + spin_lock_irqsave(&priv->drm->event_lock, flags); > + > + /* Enable OSD and BLK0, set max global alpha */ > + priv->viu.osd1_ctrl_stat = OSD_ENABLE | > + (0xFF << OSD_GLOBAL_ALPHA_SHIFT) | > + OSD_BLK0_ENABLE; > + > + /* Set up BLK0 to point to the right canvas */ > + priv->viu.osd1_blk0_cfg[0] = ((MESON_CANVAS_ID_OSD1 << OSD_CANVAS_SEL) | > + OSD_ENDIANNESS_LE); > + > + /* On GXBB, Use the old non-HDR RGB2YUV converter */ > + if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) > + priv->viu.osd1_blk0_cfg[0] |= OSD_OUTPUT_COLOR_RGB; > + > + switch (fb->pixel_format) { > + case DRM_FORMAT_XRGB8888: > + /* For XRGB, replace the pixel's alpha by 0xFF */ > + writel_bits_relaxed(OSD_REPLACE_EN, OSD_REPLACE_EN, > + priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); > + priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_32 | > + OSD_COLOR_MATRIX_32_ARGB; > + break; > + case DRM_FORMAT_ARGB8888: > + /* For ARGB, use the pixel's alpha */ > + writel_bits_relaxed(OSD_REPLACE_EN, 0, > + priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); > + priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_32 | > + OSD_COLOR_MATRIX_32_ARGB; > + break; > + case DRM_FORMAT_RGB888: > + priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_24 | > + OSD_COLOR_MATRIX_24_RGB; > + break; > + case DRM_FORMAT_RGB565: > + priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_16 | > + OSD_COLOR_MATRIX_16_RGB565; > + break; > + }; > + > + if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) { > + priv->viu.osd1_interlace = true; > + > + dest.y1 /= 2; > + dest.y2 /= 2; > + } else { > + priv->viu.osd1_interlace = true; > + meson_vpp_disable_interlace_vscaler_osd1(priv); > + } > + > + /* > + * The format of these registers is (x2 << 16 | x1), > + * where x2 is exclusive. > + * e.g. +30x1920 would be (1919 << 16) | 30 > + */ > + priv->viu.osd1_blk0_cfg[1] = ((fixed16_to_int(src.x2) - 1) << 16) | > + fixed16_to_int(src.x1); > + priv->viu.osd1_blk0_cfg[2] = ((fixed16_to_int(src.y2) - 1) << 16) | > + fixed16_to_int(src.y1); > + priv->viu.osd1_blk0_cfg[3] = ((dest.x2 - 1) << 16) | dest.x1; > + priv->viu.osd1_blk0_cfg[4] = ((dest.y2 - 1) << 16) | dest.y1; > + > + spin_unlock_irqrestore(&priv->drm->event_lock, flags); > +} > + > +void meson_viu_sync_osd1(struct meson_drm *priv) > +{ > + /* Update the OSD registers */ > + if (priv->viu.osd1_enabled && priv->viu.osd1_commit) { > + writel_relaxed(priv->viu.osd1_ctrl_stat, > + priv->io_base + _REG(VIU_OSD1_CTRL_STAT)); > + writel_relaxed(priv->viu.osd1_blk0_cfg[0], > + priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W0)); > + writel_relaxed(priv->viu.osd1_blk0_cfg[1], > + priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W1)); > + writel_relaxed(priv->viu.osd1_blk0_cfg[2], > + priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W2)); > + writel_relaxed(priv->viu.osd1_blk0_cfg[3], > + priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W3)); > + writel_relaxed(priv->viu.osd1_blk0_cfg[4], > + priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W4)); > + > + if (priv->viu.osd1_interlace) { > + struct drm_plane *plane = priv->primary_plane; > + struct drm_plane_state *state = plane->state; > + struct drm_rect dest = { > + .x1 = state->crtc_x, > + .y1 = state->crtc_y, > + .x2 = state->crtc_x + state->crtc_w, > + .y2 = state->crtc_y + state->crtc_h, > + }; > + > + meson_vpp_setup_interlace_vscaler_osd1(priv, &dest); > + } > + > + meson_vpp_enable_osd1(priv); > + > + priv->viu.osd1_commit = false; > + } > +} Again I'd remove the indirection and for these put them into your plane implementation directly. > + > + > +/* OSD csc defines */ > + > +enum viu_matrix_sel_e { > + VIU_MATRIX_OSD_EOTF = 0, > + VIU_MATRIX_OSD, > +}; > + > +enum viu_lut_sel_e { > + VIU_LUT_OSD_EOTF = 0, > + VIU_LUT_OSD_OETF, > +}; > + > +#define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2)) > +#define MATRIX_5X3_COEF_SIZE 24 > + > +#define EOTF_COEFF_NORM(a) ((int)((((a) * 4096.0) + 1) / 2)) > +#define EOTF_COEFF_SIZE 10 > +#define EOTF_COEFF_RIGHTSHIFT 1 > + > +static int RGB709_to_YUV709l_coeff[MATRIX_5X3_COEF_SIZE] = { > + 0, 0, 0, /* pre offset */ > + COEFF_NORM(0.181873), COEFF_NORM(0.611831), COEFF_NORM(0.061765), > + COEFF_NORM(-0.100251), COEFF_NORM(-0.337249), COEFF_NORM(0.437500), > + COEFF_NORM(0.437500), COEFF_NORM(-0.397384), COEFF_NORM(-0.040116), > + 0, 0, 0, /* 10'/11'/12' */ > + 0, 0, 0, /* 20'/21'/22' */ > + 64, 512, 512, /* offset */ > + 0, 0, 0 /* mode, right_shift, clip_en */ > +}; > + > +/* eotf matrix: bypass */ > +static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = { > + EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), > + EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), > + EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), > + EOTF_COEFF_RIGHTSHIFT /* right shift */ > +}; > + > +void meson_viu_set_osd_matrix(struct meson_drm *priv, > + enum viu_matrix_sel_e m_select, > + int *m, bool csc_on) > +{ > + if (m_select == VIU_MATRIX_OSD) { > + /* osd matrix, VIU_MATRIX_0 */ > + writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff), > + priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET0_1)); > + writel(m[2] & 0xfff, > + priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET2)); > + writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff), > + priv->io_base + _REG(VIU_OSD1_MATRIX_COEF00_01)); > + writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff), > + priv->io_base + _REG(VIU_OSD1_MATRIX_COEF02_10)); > + writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff), > + priv->io_base + _REG(VIU_OSD1_MATRIX_COEF11_12)); > + writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff), > + priv->io_base + _REG(VIU_OSD1_MATRIX_COEF20_21)); > + > + if (m[21]) { > + writel(((m[11] & 0x1fff) << 16) | (m[12] & 0x1fff), > + priv->io_base + > + _REG(VIU_OSD1_MATRIX_COEF22_30)); > + writel(((m[13] & 0x1fff) << 16) | (m[14] & 0x1fff), > + priv->io_base + > + _REG(VIU_OSD1_MATRIX_COEF31_32)); > + writel(((m[15] & 0x1fff) << 16) | (m[16] & 0x1fff), > + priv->io_base + > + _REG(VIU_OSD1_MATRIX_COEF40_41)); > + writel(m[17] & 0x1fff, priv->io_base + > + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42)); > + } else > + writel((m[11] & 0x1fff) << 16, priv->io_base + > + _REG(VIU_OSD1_MATRIX_COEF22_30)); > + > + writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff), > + priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET0_1)); > + writel(m[20] & 0xfff, > + priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET2)); > + > + writel_bits_relaxed(3 << 30, m[21] << 30, > + priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42)); > + writel_bits_relaxed(7 << 16, m[22] << 16, > + priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42)); > + > + /* 23 reserved for clipping control */ > + writel_bits_relaxed(BIT(0), csc_on ? BIT(0) : 0, > + priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL)); > + writel_bits_relaxed(BIT(1), 0, > + priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL)); > + } else if (m_select == VIU_MATRIX_OSD_EOTF) { > + int i; > + > + /* osd eotf matrix, VIU_MATRIX_OSD_EOTF */ > + for (i = 0; i < 5; i++) > + writel(((m[i * 2] & 0x1fff) << 16) | > + (m[i * 2 + 1] & 0x1fff), priv->io_base + > + _REG(VIU_OSD1_EOTF_CTL + i + 1)); > + > + writel_bits_relaxed(BIT(30), csc_on ? BIT(30) : 0, > + priv->io_base + _REG(VIU_OSD1_EOTF_CTL)); > + writel_bits_relaxed(BIT(31), csc_on ? BIT(31) : 0, > + priv->io_base + _REG(VIU_OSD1_EOTF_CTL)); > + } > +} > + > +#define OSD_EOTF_LUT_SIZE 33 > +#define OSD_OETF_LUT_SIZE 41 > + > +void meson_viu_set_osd_lut(struct meson_drm *priv, enum viu_lut_sel_e lut_sel, > + unsigned int *r_map, unsigned int *g_map, > + unsigned int *b_map, > + bool csc_on) > +{ > + unsigned int addr_port; > + unsigned int data_port; > + unsigned int ctrl_port; > + int i; > + > + if (lut_sel == VIU_LUT_OSD_EOTF) { > + addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT; > + data_port = VIU_OSD1_EOTF_LUT_DATA_PORT; > + ctrl_port = VIU_OSD1_EOTF_CTL; > + } else if (lut_sel == VIU_LUT_OSD_OETF) { > + addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT; > + data_port = VIU_OSD1_OETF_LUT_DATA_PORT; > + ctrl_port = VIU_OSD1_OETF_CTL; > + } else > + return; > + > + if (lut_sel == VIU_LUT_OSD_OETF) { > + writel(0, priv->io_base + _REG(addr_port)); > + > + for (i = 0; i < 20; i++) > + writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16), > + priv->io_base + _REG(data_port)); > + > + writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16), > + priv->io_base + _REG(data_port)); > + > + for (i = 0; i < 20; i++) > + writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16), > + priv->io_base + _REG(data_port)); > + > + for (i = 0; i < 20; i++) > + writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16), > + priv->io_base + _REG(data_port)); > + > + writel(b_map[OSD_OETF_LUT_SIZE - 1], > + priv->io_base + _REG(data_port)); > + > + if (csc_on) > + writel_bits_relaxed(0x7 << 29, 7 << 29, > + priv->io_base + _REG(ctrl_port)); > + else > + writel_bits_relaxed(0x7 << 29, 0, > + priv->io_base + _REG(ctrl_port)); > + } else if (lut_sel == VIU_LUT_OSD_EOTF) { > + writel(0, priv->io_base + _REG(addr_port)); > + > + for (i = 0; i < 20; i++) > + writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16), > + priv->io_base + _REG(data_port)); > + > + writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16), > + priv->io_base + _REG(data_port)); > + > + for (i = 0; i < 20; i++) > + writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16), > + priv->io_base + _REG(data_port)); > + > + for (i = 0; i < 20; i++) > + writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16), > + priv->io_base + _REG(data_port)); > + > + writel(b_map[OSD_EOTF_LUT_SIZE - 1], > + priv->io_base + _REG(data_port)); > + > + if (csc_on) > + writel_bits_relaxed(7 << 27, 7 << 27, > + priv->io_base + _REG(ctrl_port)); > + else > + writel_bits_relaxed(7 << 27, 0, > + priv->io_base + _REG(ctrl_port)); > + > + writel_bits_relaxed(BIT(31), BIT(31), > + priv->io_base + _REG(ctrl_port)); > + } > +} > + > +/* eotf lut: linear */ > +static unsigned int eotf_33_linear_mapping[OSD_EOTF_LUT_SIZE] = { > + 0x0000, 0x0200, 0x0400, 0x0600, > + 0x0800, 0x0a00, 0x0c00, 0x0e00, > + 0x1000, 0x1200, 0x1400, 0x1600, > + 0x1800, 0x1a00, 0x1c00, 0x1e00, > + 0x2000, 0x2200, 0x2400, 0x2600, > + 0x2800, 0x2a00, 0x2c00, 0x2e00, > + 0x3000, 0x3200, 0x3400, 0x3600, > + 0x3800, 0x3a00, 0x3c00, 0x3e00, > + 0x4000 > +}; > + > +/* osd oetf lut: linear */ > +static unsigned int oetf_41_linear_mapping[OSD_OETF_LUT_SIZE] = { > + 0, 0, 0, 0, > + 0, 32, 64, 96, > + 128, 160, 196, 224, > + 256, 288, 320, 352, > + 384, 416, 448, 480, > + 512, 544, 576, 608, > + 640, 672, 704, 736, > + 768, 800, 832, 864, > + 896, 928, 960, 992, > + 1023, 1023, 1023, 1023, > + 1023 > +}; Might be fun to expose this using the color manager stuff, see drm_crtc_enable_color_mgmt(). > + > +static void meson_viu_load_matrix(struct meson_drm *priv) > +{ > + /* eotf lut bypass */ > + meson_viu_set_osd_lut(priv, VIU_LUT_OSD_EOTF, > + eotf_33_linear_mapping, /* R */ > + eotf_33_linear_mapping, /* G */ > + eotf_33_linear_mapping, /* B */ > + false); > + > + /* eotf matrix bypass */ > + meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD_EOTF, > + eotf_bypass_coeff, > + false); > + > + /* oetf lut bypass */ > + meson_viu_set_osd_lut(priv, VIU_LUT_OSD_OETF, > + oetf_41_linear_mapping, /* R */ > + oetf_41_linear_mapping, /* G */ > + oetf_41_linear_mapping, /* B */ > + false); > + > + /* osd matrix RGB709 to YUV709 limit */ > + meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD, > + RGB709_to_YUV709l_coeff, > + true); > +} > + > +void meson_viu_init(struct meson_drm *priv) > +{ > + uint32_t reg; > + > + /* Disable OSDs */ > + writel_bits_relaxed(BIT(0) | BIT(21), 0, > + priv->io_base + _REG(VIU_OSD1_CTRL_STAT)); > + writel_bits_relaxed(BIT(0) | BIT(21), 0, > + priv->io_base + _REG(VIU_OSD2_CTRL_STAT)); > + > + /* On GXL/GXM, Use the 10bit HDR conversion matrix */ > + if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || > + meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) > + meson_viu_load_matrix(priv); > + > + /* Initialize OSD1 fifo control register */ > + reg = BIT(0) | /* Urgent DDR request priority */ > + (4 << 5) | /* hold_fifo_lines */ > + (3 << 10) | /* burst length 64 */ > + (32 << 12) | /* fifo_depth_val: 32*8=256 */ > + (2 << 22) | /* 4 words in 1 burst */ > + (2 << 24); > + writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); > + writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT)); > + > + /* Set OSD alpha replace value */ > + writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, > + 0xff << OSD_REPLACE_SHIFT, > + priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); > + writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, > + 0xff << OSD_REPLACE_SHIFT, > + priv->io_base + _REG(VIU_OSD2_CTRL_STAT2)); > + > + priv->viu.osd1_enabled = false; > + priv->viu.osd1_commit = false; > + priv->viu.osd1_interlace = false; > +} > diff --git a/drivers/gpu/drm/meson/meson_viu.h b/drivers/gpu/drm/meson/meson_viu.h > new file mode 100644 > index 0000000..c7a7fb5 > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_viu.h > @@ -0,0 +1,37 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + */ > + > +/* Video Input Unit */ > + > +#ifndef __MESON_VIU_H > +#define __MESON_VIU_H > + > +/* Update OSD1 Coordinates */ > +void meson_viu_update_osd1(struct meson_drm *priv, struct drm_plane *plane); > + > +/* Commit OSD1 changes */ > +void meson_viu_commit_osd1(struct meson_drm *priv); > + > +/* Synchronize Field Change for OSD1 */ > +void meson_viu_sync_osd1(struct meson_drm *priv); > + > +void meson_viu_init(struct meson_drm *priv); > + > +#endif /* __MESON_VIU_H */ > diff --git a/drivers/gpu/drm/meson/meson_vpp.c b/drivers/gpu/drm/meson/meson_vpp.c > new file mode 100644 > index 0000000..ea390d0 > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_vpp.c > @@ -0,0 +1,189 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. > + * Copyright (C) 2014 Endless Mobile > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <drm/drmP.h> > +#include "meson_drv.h" > +#include "meson_vpp.h" > +#include "meson_registers.h" > + > +/* > + * VPP Handles all the Post Processing after the Scanout from the VIU > + * We handle the following post processings : > + * - Postblend : Blends the OSD1 only > + * We exclude OSD2, VS1, VS1 and Preblend output > + * - Vertical OSD Scaler for OSD1 only, we disable vertical scaler and > + * use it only for interlace scanout > + * - Intermediate FIFO with default Amlogic values > + * > + * What is missing : > + * - Preblend for video overlay pre-scaling > + * - OSD2 support for cursor framebuffer > + * - Video pre-scaling before postblend > + * - Full Vertical/Horizontal OSD scaling to support TV overscan > + * - HDR conversion > + */ > + > +void meson_vpp_enable_osd1(struct meson_drm *priv) > +{ > + writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND, > + priv->io_base + _REG(VPP_MISC)); > +} > + > +void meson_vpp_disable_osd1(struct meson_drm *priv) > +{ > + writel_bits_relaxed(VPP_OSD1_POSTBLEND, 0, > + priv->io_base + _REG(VPP_MISC)); > +} > + > +void meson_vpp_enable_postblend(struct meson_drm *priv, unsigned int width) > +{ > + writel(width, priv->io_base + _REG(VPP_POSTBLEND_H_SIZE)); > + > + writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE, > + priv->io_base + _REG(VPP_MISC)); > +} > + > +void meson_vpp_disable_postblend(struct meson_drm *priv) > +{ > + writel_bits_relaxed(VPP_POSTBLEND_ENABLE, 0, > + priv->io_base + _REG(VPP_MISC)); > +} > + > +void meson_vpp_setup_mux(struct meson_drm *priv, unsigned int mux) > +{ > + writel(mux, priv->io_base + _REG(VPU_VIU_VENC_MUX_CTRL)); > +} > + > +/* > + * When the output is interlaced, the OSD must switch between > + * each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0 > + * at each vsync. > + * But the vertical scaler can provide such funtionnality if > + * is configured for 2:1 scaling with interlace options enabled. > + */ > +void meson_vpp_setup_interlace_vscaler_osd1(struct meson_drm *priv, > + struct drm_rect *input) > +{ > + writel_relaxed(BIT(3) /* Enable scaler */ | > + BIT(2), /* Select OSD1 */ > + priv->io_base + _REG(VPP_OSD_SC_CTRL0)); > + > + writel_relaxed(((drm_rect_width(input) - 1) << 16) | > + (drm_rect_height(input) - 1), > + priv->io_base + _REG(VPP_OSD_SCI_WH_M1)); > + /* 2:1 scaling */ > + writel_relaxed(((input->x1) << 16) | (input->x2), > + priv->io_base + _REG(VPP_OSD_SCO_H_START_END)); > + writel_relaxed(((input->y1 >> 1) << 16) | (input->y2 >> 1), > + priv->io_base + _REG(VPP_OSD_SCO_V_START_END)); > + > + /* 2:1 scaling values */ > + writel_relaxed(BIT(16), priv->io_base + _REG(VPP_OSD_VSC_INI_PHASE)); > + writel_relaxed(BIT(25), priv->io_base + _REG(VPP_OSD_VSC_PHASE_STEP)); > + > + writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0)); > + > + writel_relaxed((4 << 0) /* osd_vsc_bank_length */ | > + (4 << 3) /* osd_vsc_top_ini_rcv_num0 */ | > + (1 << 8) /* osd_vsc_top_rpt_p0_num0 */ | > + (6 << 11) /* osd_vsc_bot_ini_rcv_num0 */ | > + (2 << 16) /* osd_vsc_bot_rpt_p0_num0 */ | > + BIT(23) /* osd_prog_interlace */ | > + BIT(24), /* Enable vertical scaler */ > + priv->io_base + _REG(VPP_OSD_VSC_CTRL0)); > +} > + > +void meson_vpp_disable_interlace_vscaler_osd1(struct meson_drm *priv) > +{ > + writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0)); > + writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0)); > + writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0)); > +} > + > +static unsigned int vpp_filter_coefs_4point_bspline[] = { > + 0x15561500, 0x14561600, 0x13561700, 0x12561800, > + 0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00, > + 0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200, > + 0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700, > + 0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01, > + 0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201, > + 0x05473301, 0x05463401, 0x04453601, 0x04433702, > + 0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02, > + 0x033d3d03 > +}; > + > +static void meson_vpp_write_scaling_filter_coefs(struct meson_drm *priv, > + const unsigned int *coefs, > + bool is_horizontal) > +{ > + int i; > + > + writel_relaxed(is_horizontal ? BIT(8) : 0, > + priv->io_base + _REG(VPP_OSD_SCALE_COEF_IDX)); > + for (i = 0; i < 33; i++) > + writel_relaxed(coefs[i], > + priv->io_base + _REG(VPP_OSD_SCALE_COEF)); > +} > + > +void meson_vpp_init(struct meson_drm *priv) > +{ > + /* set dummy data default YUV black */ > + if (meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) > + writel_relaxed(0x108080, priv->io_base + _REG(VPP_DUMMY_DATA1)); > + else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu")) { > + writel_bits_relaxed(0xff << 16, 0xff << 16, > + priv->io_base + _REG(VIU_MISC_CTRL1)); > + writel_relaxed(0x20000, priv->io_base + _REG(VPP_DOLBY_CTRL)); > + writel_relaxed(0x1020080, > + priv->io_base + _REG(VPP_DUMMY_DATA1)); > + } > + > + /* Initialize vpu fifo control registers */ > + writel_relaxed(readl_relaxed(priv->io_base + _REG(VPP_OFIFO_SIZE)) | > + 0x77f, priv->io_base + _REG(VPP_OFIFO_SIZE)); > + writel_relaxed(0x08080808, priv->io_base + _REG(VPP_HOLD_LINES)); > + > + /* Turn off preblend */ > + writel_bits_relaxed(VPP_PREBLEND_ENABLE, 0, > + priv->io_base + _REG(VPP_MISC)); > + > + /* Turn off POSTBLEND */ > + meson_vpp_disable_postblend(priv); > + > + /* Force all planes off */ > + writel_bits_relaxed(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND | > + VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND, 0, > + priv->io_base + _REG(VPP_MISC)); > + > + /* Disable Scalers */ > + writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0)); > + writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0)); > + writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0)); > + > + /* Write in the proper filter coefficients. */ > + meson_vpp_write_scaling_filter_coefs(priv, > + vpp_filter_coefs_4point_bspline, false); > + meson_vpp_write_scaling_filter_coefs(priv, > + vpp_filter_coefs_4point_bspline, true); > +} > diff --git a/drivers/gpu/drm/meson/meson_vpp.h b/drivers/gpu/drm/meson/meson_vpp.h > new file mode 100644 > index 0000000..98bb85e > --- /dev/null > +++ b/drivers/gpu/drm/meson/meson_vpp.h > @@ -0,0 +1,43 @@ > +/* > + * Copyright (C) 2016 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > + * 02111-1307, USA. > + */ > + > +/* Video Post Process */ > + > +#ifndef __MESON_VPP_H > +#define __MESON_VPP_H > + > +void meson_vpp_enable_osd1(struct meson_drm *priv); > +void meson_vpp_disable_osd1(struct meson_drm *priv); > + > +void meson_vpp_enable_postblend(struct meson_drm *priv, unsigned int width); > +void meson_vpp_disable_postblend(struct meson_drm *priv); > + > +/* Mux VIU/VPP to ENCI */ > +#define MESON_VIU_VPP_MUX_ENCI 0x5 > + > +void meson_vpp_setup_mux(struct meson_drm *priv, unsigned int mux); > + > +void meson_vpp_setup_interlace_vscaler_osd1(struct meson_drm *priv, > + struct drm_rect *input); > +void meson_vpp_disable_interlace_vscaler_osd1(struct meson_drm *priv); > + > +void meson_vpp_init(struct meson_drm *priv); > + > +#endif /* __MESON_VPP_H */ > -- > 1.9.1 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel