aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Armstrong <narmstrong@baylibre.com>2016-11-10 09:29:37 -0500
committerNeil Armstrong <narmstrong@baylibre.com>2016-12-01 04:07:20 -0500
commitbbbe775ec5b5dace43a35886da9924837da09ddd (patch)
tree3b16dad9cc1b67dc2da301ffa16e847d4931d162
parentbc33b0ca11e3df467777a4fa7639ba488c9d4911 (diff)
drm: Add support for Amlogic Meson Graphic Controller
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 Post Processing -------------------------- The Video Post Processing is in charge of 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. Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
-rw-r--r--drivers/gpu/drm/Kconfig2
-rw-r--r--drivers/gpu/drm/Makefile1
-rw-r--r--drivers/gpu/drm/meson/Kconfig9
-rw-r--r--drivers/gpu/drm/meson/Makefile4
-rw-r--r--drivers/gpu/drm/meson/meson_canvas.c68
-rw-r--r--drivers/gpu/drm/meson/meson_canvas.h42
-rw-r--r--drivers/gpu/drm/meson/meson_crtc.c208
-rw-r--r--drivers/gpu/drm/meson/meson_crtc.h32
-rw-r--r--drivers/gpu/drm/meson/meson_drv.c343
-rw-r--r--drivers/gpu/drm/meson/meson_drv.h59
-rw-r--r--drivers/gpu/drm/meson/meson_plane.c230
-rw-r--r--drivers/gpu/drm/meson/meson_plane.h30
-rw-r--r--drivers/gpu/drm/meson/meson_registers.h1395
-rw-r--r--drivers/gpu/drm/meson/meson_vclk.c167
-rw-r--r--drivers/gpu/drm/meson/meson_vclk.h34
-rw-r--r--drivers/gpu/drm/meson/meson_venc.c254
-rw-r--r--drivers/gpu/drm/meson/meson_venc.h72
-rw-r--r--drivers/gpu/drm/meson/meson_venc_cvbs.c293
-rw-r--r--drivers/gpu/drm/meson/meson_venc_cvbs.h41
-rw-r--r--drivers/gpu/drm/meson/meson_viu.c331
-rw-r--r--drivers/gpu/drm/meson/meson_viu.h64
-rw-r--r--drivers/gpu/drm/meson/meson_vpp.c162
-rw-r--r--drivers/gpu/drm/meson/meson_vpp.h35
23 files changed, 3876 insertions, 0 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 483059a22b1b..344ced6483f2 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -223,6 +223,8 @@ source "drivers/gpu/drm/hisilicon/Kconfig"
223 223
224source "drivers/gpu/drm/mediatek/Kconfig" 224source "drivers/gpu/drm/mediatek/Kconfig"
225 225
226source "drivers/gpu/drm/meson/Kconfig"
227
226# Keep legacy drivers last 228# Keep legacy drivers last
227 229
228menuconfig DRM_LEGACY 230menuconfig DRM_LEGACY
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 25c720454017..47e7c45b1fc0 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -79,6 +79,7 @@ obj-$(CONFIG_DRM_TEGRA) += tegra/
79obj-$(CONFIG_DRM_STI) += sti/ 79obj-$(CONFIG_DRM_STI) += sti/
80obj-$(CONFIG_DRM_IMX) += imx/ 80obj-$(CONFIG_DRM_IMX) += imx/
81obj-$(CONFIG_DRM_MEDIATEK) += mediatek/ 81obj-$(CONFIG_DRM_MEDIATEK) += mediatek/
82obj-$(CONFIG_DRM_MESON) += meson/
82obj-y += i2c/ 83obj-y += i2c/
83obj-y += panel/ 84obj-y += panel/
84obj-y += bridge/ 85obj-y += bridge/
diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
new file mode 100644
index 000000000000..99719afcc77f
--- /dev/null
+++ b/drivers/gpu/drm/meson/Kconfig
@@ -0,0 +1,9 @@
1config DRM_MESON
2 tristate "DRM Support for Amlogic Meson Display Controller"
3 depends on DRM && OF && (ARM || ARM64)
4 depends on ARCH_MESON || COMPILE_TEST
5 select DRM_KMS_HELPER
6 select DRM_KMS_CMA_HELPER
7 select DRM_GEM_CMA_HELPER
8 select VIDEOMODE_HELPERS
9 select REGMAP_MMIO
diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
new file mode 100644
index 000000000000..2591978b8aad
--- /dev/null
+++ b/drivers/gpu/drm/meson/Makefile
@@ -0,0 +1,4 @@
1meson-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o
2meson-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o
3
4obj-$(CONFIG_DRM_MESON) += meson.o
diff --git a/drivers/gpu/drm/meson/meson_canvas.c b/drivers/gpu/drm/meson/meson_canvas.c
new file mode 100644
index 000000000000..4109e36c297f
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_canvas.c
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5 * Copyright (C) 2014 Endless Mobile
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include "meson_drv.h"
24#include "meson_canvas.h"
25#include "meson_registers.h"
26
27/*
28 * CANVAS is a memory zone where physical memory frames information
29 * are stored for the VIU to scanout.
30 */
31
32/* DMC Registers */
33#define DMC_CAV_LUT_DATAL 0x48 /* 0x12 offset in data sheet */
34#define CANVAS_WIDTH_LBIT 29
35#define CANVAS_WIDTH_LWID 3
36#define DMC_CAV_LUT_DATAH 0x4c /* 0x13 offset in data sheet */
37#define CANVAS_WIDTH_HBIT 0
38#define CANVAS_HEIGHT_BIT 9
39#define CANVAS_BLKMODE_BIT 24
40#define DMC_CAV_LUT_ADDR 0x50 /* 0x14 offset in data sheet */
41#define CANVAS_LUT_WR_EN (0x2 << 8)
42#define CANVAS_LUT_RD_EN (0x1 << 8)
43
44void meson_canvas_setup(struct meson_drm *priv,
45 uint32_t canvas_index, uint32_t addr,
46 uint32_t stride, uint32_t height,
47 unsigned int wrap,
48 unsigned int blkmode)
49{
50 unsigned int val;
51
52 regmap_write(priv->dmc, DMC_CAV_LUT_DATAL,
53 (((addr + 7) >> 3)) |
54 (((stride + 7) >> 3) << CANVAS_WIDTH_LBIT));
55
56 regmap_write(priv->dmc, DMC_CAV_LUT_DATAH,
57 ((((stride + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
58 CANVAS_WIDTH_HBIT) |
59 (height << CANVAS_HEIGHT_BIT) |
60 (wrap << 22) |
61 (blkmode << CANVAS_BLKMODE_BIT));
62
63 regmap_write(priv->dmc, DMC_CAV_LUT_ADDR,
64 CANVAS_LUT_WR_EN | canvas_index);
65
66 /* Force a read-back to make sure everything is flushed. */
67 regmap_read(priv->dmc, DMC_CAV_LUT_DATAH, &val);
68}
diff --git a/drivers/gpu/drm/meson/meson_canvas.h b/drivers/gpu/drm/meson/meson_canvas.h
new file mode 100644
index 000000000000..af1759da4b27
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_canvas.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2014 Endless Mobile
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20/* Canvas LUT Memory */
21
22#ifndef __MESON_CANVAS_H
23#define __MESON_CANVAS_H
24
25#define MESON_CANVAS_ID_OSD1 0x4e
26
27/* Canvas configuration. */
28#define MESON_CANVAS_WRAP_NONE 0x00
29#define MESON_CANVAS_WRAP_X 0x01
30#define MESON_CANVAS_WRAP_Y 0x02
31
32#define MESON_CANVAS_BLKMODE_LINEAR 0x00
33#define MESON_CANVAS_BLKMODE_32x32 0x01
34#define MESON_CANVAS_BLKMODE_64x64 0x02
35
36void meson_canvas_setup(struct meson_drm *priv,
37 uint32_t canvas_index, uint32_t addr,
38 uint32_t stride, uint32_t height,
39 unsigned int wrap,
40 unsigned int blkmode);
41
42#endif /* __MESON_CANVAS_H */
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
new file mode 100644
index 000000000000..749770e5c65f
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -0,0 +1,208 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5 * Copyright (C) 2014 Endless Mobile
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 * Written by:
21 * Jasper St. Pierre <jstpierre@mecheye.net>
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/mutex.h>
27#include <linux/platform_device.h>
28#include <drm/drmP.h>
29#include <drm/drm_atomic.h>
30#include <drm/drm_atomic_helper.h>
31#include <drm/drm_flip_work.h>
32#include <drm/drm_crtc_helper.h>
33
34#include "meson_crtc.h"
35#include "meson_plane.h"
36#include "meson_vpp.h"
37#include "meson_viu.h"
38#include "meson_registers.h"
39
40/* CRTC definition */
41
42struct meson_crtc {
43 struct drm_crtc base;
44 struct drm_pending_vblank_event *event;
45 struct meson_drm *priv;
46};
47#define to_meson_crtc(x) container_of(x, struct meson_crtc, base)
48
49/* CRTC */
50
51static const struct drm_crtc_funcs meson_crtc_funcs = {
52 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
53 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
54 .destroy = drm_crtc_cleanup,
55 .page_flip = drm_atomic_helper_page_flip,
56 .reset = drm_atomic_helper_crtc_reset,
57 .set_config = drm_atomic_helper_set_config,
58};
59
60static void meson_crtc_enable(struct drm_crtc *crtc)
61{
62 struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
63 struct drm_plane *plane = meson_crtc->priv->primary_plane;
64 struct meson_drm *priv = meson_crtc->priv;
65
66 /* Enable VPP Postblend */
67 writel(plane->state->crtc_w,
68 priv->io_base + _REG(VPP_POSTBLEND_H_SIZE));
69
70 writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE,
71 priv->io_base + _REG(VPP_MISC));
72
73 priv->viu.osd1_enabled = true;
74}
75
76static void meson_crtc_disable(struct drm_crtc *crtc)
77{
78 struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
79 struct meson_drm *priv = meson_crtc->priv;
80
81 priv->viu.osd1_enabled = false;
82
83 /* Disable VPP Postblend */
84 writel_bits_relaxed(VPP_POSTBLEND_ENABLE, 0,
85 priv->io_base + _REG(VPP_MISC));
86
87 if (crtc->state->event && !crtc->state->active) {
88 spin_lock_irq(&crtc->dev->event_lock);
89 drm_crtc_send_vblank_event(crtc, crtc->state->event);
90 spin_unlock_irq(&crtc->dev->event_lock);
91
92 crtc->state->event = NULL;
93 }
94}
95
96static void meson_crtc_atomic_begin(struct drm_crtc *crtc,
97 struct drm_crtc_state *state)
98{
99 struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
100 unsigned long flags;
101
102 if (crtc->state->event) {
103 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
104
105 spin_lock_irqsave(&crtc->dev->event_lock, flags);
106 meson_crtc->event = crtc->state->event;
107 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
108 crtc->state->event = NULL;
109 }
110}
111
112static void meson_crtc_atomic_flush(struct drm_crtc *crtc,
113 struct drm_crtc_state *old_crtc_state)
114{
115 struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
116 struct meson_drm *priv = meson_crtc->priv;
117
118 if (priv->viu.osd1_enabled)
119 priv->viu.osd1_commit = true;
120}
121
122static const struct drm_crtc_helper_funcs meson_crtc_helper_funcs = {
123 .enable = meson_crtc_enable,
124 .disable = meson_crtc_disable,
125 .atomic_begin = meson_crtc_atomic_begin,
126 .atomic_flush = meson_crtc_atomic_flush,
127};
128
129void meson_crtc_irq(struct meson_drm *priv)
130{
131 struct meson_crtc *meson_crtc = to_meson_crtc(priv->crtc);
132 unsigned long flags;
133
134 /* Update the OSD registers */
135 if (priv->viu.osd1_enabled && priv->viu.osd1_commit) {
136 writel_relaxed(priv->viu.osd1_ctrl_stat,
137 priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
138 writel_relaxed(priv->viu.osd1_blk0_cfg[0],
139 priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W0));
140 writel_relaxed(priv->viu.osd1_blk0_cfg[1],
141 priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W1));
142 writel_relaxed(priv->viu.osd1_blk0_cfg[2],
143 priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W2));
144 writel_relaxed(priv->viu.osd1_blk0_cfg[3],
145 priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W3));
146 writel_relaxed(priv->viu.osd1_blk0_cfg[4],
147 priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W4));
148
149 /* If output is interlace, make use of the Scaler */
150 if (priv->viu.osd1_interlace) {
151 struct drm_plane *plane = priv->primary_plane;
152 struct drm_plane_state *state = plane->state;
153 struct drm_rect dest = {
154 .x1 = state->crtc_x,
155 .y1 = state->crtc_y,
156 .x2 = state->crtc_x + state->crtc_w,
157 .y2 = state->crtc_y + state->crtc_h,
158 };
159
160 meson_vpp_setup_interlace_vscaler_osd1(priv, &dest);
161 } else
162 meson_vpp_disable_interlace_vscaler_osd1(priv);
163
164 /* Enable OSD1 */
165 writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
166 priv->io_base + _REG(VPP_MISC));
167
168 priv->viu.osd1_commit = false;
169 }
170
171 drm_crtc_handle_vblank(priv->crtc);
172
173 spin_lock_irqsave(&priv->drm->event_lock, flags);
174 if (meson_crtc->event) {
175 drm_crtc_send_vblank_event(priv->crtc, meson_crtc->event);
176 drm_crtc_vblank_put(priv->crtc);
177 meson_crtc->event = NULL;
178 }
179 spin_unlock_irqrestore(&priv->drm->event_lock, flags);
180}
181
182int meson_crtc_create(struct meson_drm *priv)
183{
184 struct meson_crtc *meson_crtc;
185 struct drm_crtc *crtc;
186 int ret;
187
188 meson_crtc = devm_kzalloc(priv->drm->dev, sizeof(*meson_crtc),
189 GFP_KERNEL);
190 if (!meson_crtc)
191 return -ENOMEM;
192
193 meson_crtc->priv = priv;
194 crtc = &meson_crtc->base;
195 ret = drm_crtc_init_with_planes(priv->drm, crtc,
196 priv->primary_plane, NULL,
197 &meson_crtc_funcs, "meson_crtc");
198 if (ret) {
199 dev_err(priv->drm->dev, "Failed to init CRTC\n");
200 return ret;
201 }
202
203 drm_crtc_helper_add(crtc, &meson_crtc_helper_funcs);
204
205 priv->crtc = crtc;
206
207 return 0;
208}
diff --git a/drivers/gpu/drm/meson/meson_crtc.h b/drivers/gpu/drm/meson/meson_crtc.h
new file mode 100644
index 000000000000..b62b9e51764d
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_crtc.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2014 Endless Mobile
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 *
19 * Written by:
20 * Jasper St. Pierre <jstpierre@mecheye.net>
21 */
22
23#ifndef __MESON_CRTC_H
24#define __MESON_CRTC_H
25
26#include "meson_drv.h"
27
28int meson_crtc_create(struct meson_drm *priv);
29
30void meson_crtc_irq(struct meson_drm *priv);
31
32#endif /* __MESON_CRTC_H */
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
new file mode 100644
index 000000000000..ff1f6019b97b
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -0,0 +1,343 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2014 Endless Mobile
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 *
19 * Written by:
20 * Jasper St. Pierre <jstpierre@mecheye.net>
21 */
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/mutex.h>
26#include <linux/platform_device.h>
27#include <linux/of_graph.h>
28
29#include <drm/drmP.h>
30#include <drm/drm_atomic.h>
31#include <drm/drm_atomic_helper.h>
32#include <drm/drm_flip_work.h>
33#include <drm/drm_crtc_helper.h>
34#include <drm/drm_plane_helper.h>
35#include <drm/drm_gem_cma_helper.h>
36#include <drm/drm_fb_cma_helper.h>
37#include <drm/drm_rect.h>
38#include <drm/drm_fb_helper.h>
39
40#include "meson_drv.h"
41#include "meson_plane.h"
42#include "meson_crtc.h"
43#include "meson_venc_cvbs.h"
44
45#include "meson_vpp.h"
46#include "meson_viu.h"
47#include "meson_venc.h"
48#include "meson_canvas.h"
49#include "meson_registers.h"
50
51#define DRIVER_NAME "meson"
52#define DRIVER_DESC "Amlogic Meson DRM driver"
53
54/*
55 * Video Processing Unit
56 *
57 * VPU Handles the Global Video Processing, it includes management of the
58 * clocks gates, blocks reset lines and power domains.
59 *
60 * What is missing :
61 * - Full reset of entire video processing HW blocks
62 * - Scaling and setup of the VPU clock
63 * - Bus clock gates
64 * - Powering up video processing HW blocks
65 * - Powering Up HDMI controller and PHY
66 */
67
68static void meson_fb_output_poll_changed(struct drm_device *dev)
69{
70 struct meson_drm *priv = dev->dev_private;
71
72 drm_fbdev_cma_hotplug_event(priv->fbdev);
73}
74
75static const struct drm_mode_config_funcs meson_mode_config_funcs = {
76 .output_poll_changed = meson_fb_output_poll_changed,
77 .atomic_check = drm_atomic_helper_check,
78 .atomic_commit = drm_atomic_helper_commit,
79 .fb_create = drm_fb_cma_create,
80};
81
82static int meson_enable_vblank(struct drm_device *dev, unsigned int crtc)
83{
84 struct meson_drm *priv = dev->dev_private;
85
86 meson_venc_enable_vsync(priv);
87
88 return 0;
89}
90
91static void meson_disable_vblank(struct drm_device *dev, unsigned int crtc)
92{
93 struct meson_drm *priv = dev->dev_private;
94
95 meson_venc_disable_vsync(priv);
96}
97
98static irqreturn_t meson_irq(int irq, void *arg)
99{
100 struct drm_device *dev = arg;
101 struct meson_drm *priv = dev->dev_private;
102
103 (void)readl_relaxed(priv->io_base + _REG(VENC_INTFLAG));
104
105 meson_crtc_irq(priv);
106
107 return IRQ_HANDLED;
108}
109
110static const struct file_operations fops = {
111 .owner = THIS_MODULE,
112 .open = drm_open,
113 .release = drm_release,
114 .unlocked_ioctl = drm_ioctl,
115#ifdef CONFIG_COMPAT
116 .compat_ioctl = drm_compat_ioctl,
117#endif
118 .poll = drm_poll,
119 .read = drm_read,
120 .llseek = no_llseek,
121 .mmap = drm_gem_cma_mmap,
122};
123
124static struct drm_driver meson_driver = {
125 .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM |
126 DRIVER_MODESET | DRIVER_PRIME |
127 DRIVER_ATOMIC,
128
129 /* Vblank */
130 .enable_vblank = meson_enable_vblank,
131 .disable_vblank = meson_disable_vblank,
132 .get_vblank_counter = drm_vblank_no_hw_counter,
133
134 /* IRQ */
135 .irq_handler = meson_irq,
136
137 /* PRIME Ops */
138 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
139 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
140 .gem_prime_import = drm_gem_prime_import,
141 .gem_prime_export = drm_gem_prime_export,
142 .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
143 .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
144 .gem_prime_vmap = drm_gem_cma_prime_vmap,
145 .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
146 .gem_prime_mmap = drm_gem_cma_prime_mmap,
147
148 /* GEM Ops */
149 .dumb_create = drm_gem_cma_dumb_create,
150 .dumb_destroy = drm_gem_dumb_destroy,
151 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
152 .gem_free_object_unlocked = drm_gem_cma_free_object,
153 .gem_vm_ops = &drm_gem_cma_vm_ops,
154
155 /* Misc */
156 .fops = &fops,
157 .name = DRIVER_NAME,
158 .desc = DRIVER_DESC,
159 .date = "20161109",
160 .major = 1,
161 .minor = 0,
162};
163
164static bool meson_vpu_has_available_connectors(struct device *dev)
165{
166 struct device_node *ep, *remote;
167
168 /* Parses each endpoint and check if remote exists */
169 for_each_endpoint_of_node(dev->of_node, ep) {
170 /* If the endpoint node exists, consider it enabled */
171 remote = of_graph_get_remote_port(ep);
172 if (remote)
173 return true;
174 }
175
176 return false;
177}
178
179static struct regmap_config meson_regmap_config = {
180 .reg_bits = 32,
181 .val_bits = 32,
182 .reg_stride = 4,
183 .max_register = 0x1000,
184};
185
186static int meson_drv_probe(struct platform_device *pdev)
187{
188 struct device *dev = &pdev->dev;
189 struct meson_drm *priv;
190 struct drm_device *drm;
191 struct resource *res;
192 void __iomem *regs;
193 int ret;
194
195 /* Checks if an output connector is available */
196 if (!meson_vpu_has_available_connectors(dev)) {
197 dev_err(dev, "No output connector available\n");
198 return -ENODEV;
199 }
200
201 drm = drm_dev_alloc(&meson_driver, dev);
202 if (IS_ERR(drm))
203 return PTR_ERR(drm);
204
205 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
206 if (!priv) {
207 ret = -ENOMEM;
208 goto free_drm;
209 }
210 drm->dev_private = priv;
211 priv->drm = drm;
212 priv->dev = dev;
213
214 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu");
215 regs = devm_ioremap_resource(dev, res);
216 if (IS_ERR(regs))
217 return PTR_ERR(regs);
218
219 priv->io_base = regs;
220
221 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi");
222 /* Simply ioremap since it may be a shared register zone */
223 regs = devm_ioremap(dev, res->start, resource_size(res));
224 if (!regs)
225 return -EADDRNOTAVAIL;
226
227 priv->hhi = devm_regmap_init_mmio(dev, regs,
228 &meson_regmap_config);
229 if (IS_ERR(priv->hhi)) {
230 dev_err(&pdev->dev, "Couldn't create the HHI regmap\n");
231 return PTR_ERR(priv->hhi);
232 }
233
234 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc");
235 /* Simply ioremap since it may be a shared register zone */
236 regs = devm_ioremap(dev, res->start, resource_size(res));
237 if (!regs)
238 return -EADDRNOTAVAIL;
239
240 priv->dmc = devm_regmap_init_mmio(dev, regs,
241 &meson_regmap_config);
242 if (IS_ERR(priv->dmc)) {
243 dev_err(&pdev->dev, "Couldn't create the DMC regmap\n");
244 return PTR_ERR(priv->dmc);
245 }
246
247 priv->vsync_irq = platform_get_irq(pdev, 0);
248
249 drm_vblank_init(drm, 1);
250 drm_mode_config_init(drm);
251
252 /* Encoder Initialization */
253
254 ret = meson_venc_cvbs_create(priv);
255 if (ret)
256 goto free_drm;
257
258 /* Hardware Initialization */
259
260 meson_venc_init(priv);
261 meson_vpp_init(priv);
262 meson_viu_init(priv);
263
264 ret = meson_plane_create(priv);
265 if (ret)
266 goto free_drm;
267
268 ret = meson_crtc_create(priv);
269 if (ret)
270 goto free_drm;
271
272 ret = drm_irq_install(drm, priv->vsync_irq);
273 if (ret)
274 goto free_drm;
275
276 drm_mode_config_reset(drm);
277 drm->mode_config.max_width = 8192;
278 drm->mode_config.max_height = 8192;
279 drm->mode_config.funcs = &meson_mode_config_funcs;
280
281 priv->fbdev = drm_fbdev_cma_init(drm, 32,
282 drm->mode_config.num_crtc,
283 drm->mode_config.num_connector);
284 if (IS_ERR(priv->fbdev)) {
285 ret = PTR_ERR(priv->fbdev);
286 goto free_drm;
287 }
288
289 drm_kms_helper_poll_init(drm);
290
291 platform_set_drvdata(pdev, priv);
292
293 ret = drm_dev_register(drm, 0);
294 if (ret)
295 goto free_drm;
296
297 return 0;
298
299free_drm:
300 drm_dev_unref(drm);
301
302 return ret;
303}
304
305static int meson_drv_remove(struct platform_device *pdev)
306{
307 struct drm_device *drm = dev_get_drvdata(&pdev->dev);
308 struct meson_drm *priv = drm->dev_private;
309
310 drm_dev_unregister(drm);
311 drm_kms_helper_poll_fini(drm);
312 drm_fbdev_cma_fini(priv->fbdev);
313 drm_mode_config_cleanup(drm);
314 drm_vblank_cleanup(drm);
315 drm_dev_unref(drm);
316
317 return 0;
318}
319
320static const struct of_device_id dt_match[] = {
321 { .compatible = "amlogic,meson-gxbb-vpu" },
322 { .compatible = "amlogic,meson-gxl-vpu" },
323 { .compatible = "amlogic,meson-gxm-vpu" },
324 {}
325};
326MODULE_DEVICE_TABLE(of, dt_match);
327
328static struct platform_driver meson_drm_platform_driver = {
329 .probe = meson_drv_probe,
330 .remove = meson_drv_remove,
331 .driver = {
332 .owner = THIS_MODULE,
333 .name = DRIVER_NAME,
334 .of_match_table = dt_match,
335 },
336};
337
338module_platform_driver(meson_drm_platform_driver);
339
340MODULE_AUTHOR("Jasper St. Pierre <jstpierre@mecheye.net>");
341MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
342MODULE_DESCRIPTION(DRIVER_DESC);
343MODULE_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 000000000000..6195327c51ca
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_drv.h
@@ -0,0 +1,59 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __MESON_DRV_H
20#define __MESON_DRV_H
21
22#include <linux/platform_device.h>
23#include <linux/regmap.h>
24#include <linux/of.h>
25#include <drm/drmP.h>
26
27struct meson_drm {
28 struct device *dev;
29 void __iomem *io_base;
30 struct regmap *hhi;
31 struct regmap *dmc;
32 int vsync_irq;
33
34 struct drm_device *drm;
35 struct drm_crtc *crtc;
36 struct drm_fbdev_cma *fbdev;
37 struct drm_plane *primary_plane;
38
39 /* Components Data */
40 struct {
41 bool osd1_enabled;
42 bool osd1_interlace;
43 bool osd1_commit;
44 uint32_t osd1_ctrl_stat;
45 uint32_t osd1_blk0_cfg[5];
46 } viu;
47
48 struct {
49 unsigned int current_mode;
50 } venc;
51};
52
53static inline int meson_vpu_is_compatible(struct meson_drm *priv,
54 const char *compat)
55{
56 return of_device_is_compatible(priv->dev->of_node, compat);
57}
58
59#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 000000000000..4942ca090b46
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -0,0 +1,230 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5 * Copyright (C) 2014 Endless Mobile
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 * Written by:
21 * Jasper St. Pierre <jstpierre@mecheye.net>
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/mutex.h>
27#include <linux/platform_device.h>
28#include <drm/drmP.h>
29#include <drm/drm_atomic.h>
30#include <drm/drm_atomic_helper.h>
31#include <drm/drm_plane_helper.h>
32#include <drm/drm_gem_cma_helper.h>
33#include <drm/drm_fb_cma_helper.h>
34#include <drm/drm_rect.h>
35
36#include "meson_plane.h"
37#include "meson_vpp.h"
38#include "meson_viu.h"
39#include "meson_canvas.h"
40#include "meson_registers.h"
41
42struct meson_plane {
43 struct drm_plane base;
44 struct meson_drm *priv;
45};
46#define to_meson_plane(x) container_of(x, struct meson_plane, base)
47
48static int meson_plane_atomic_check(struct drm_plane *plane,
49 struct drm_plane_state *state)
50{
51 struct drm_crtc_state *crtc_state;
52 struct drm_rect clip = { 0, };
53
54 crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
55 if (IS_ERR(crtc_state))
56 return PTR_ERR(crtc_state);
57
58 clip.x2 = crtc_state->mode.hdisplay;
59 clip.y2 = crtc_state->mode.vdisplay;
60
61 return drm_plane_helper_check_state(state, &clip,
62 DRM_PLANE_HELPER_NO_SCALING,
63 DRM_PLANE_HELPER_NO_SCALING,
64 true, true);
65}
66
67/* Takes a fixed 16.16 number and converts it to integer. */
68static inline int64_t fixed16_to_int(int64_t value)
69{
70 return value >> 16;
71}
72
73static void meson_plane_atomic_update(struct drm_plane *plane,
74 struct drm_plane_state *old_state)
75{
76 struct meson_plane *meson_plane = to_meson_plane(plane);
77 struct drm_plane_state *state = plane->state;
78 struct drm_framebuffer *fb = state->fb;
79 struct meson_drm *priv = meson_plane->priv;
80 struct drm_gem_cma_object *gem;
81 struct drm_rect src = {
82 .x1 = (state->src_x),
83 .y1 = (state->src_y),
84 .x2 = (state->src_x + state->src_w),
85 .y2 = (state->src_y + state->src_h),
86 };
87 struct drm_rect dest = {
88 .x1 = state->crtc_x,
89 .y1 = state->crtc_y,
90 .x2 = state->crtc_x + state->crtc_w,
91 .y2 = state->crtc_y + state->crtc_h,
92 };
93 unsigned long flags;
94
95 /*
96 * Update Coordinates
97 * Update Formats
98 * Update Buffer
99 * Enable Plane
100 */
101 spin_lock_irqsave(&priv->drm->event_lock, flags);
102
103 /* Enable OSD and BLK0, set max global alpha */
104 priv->viu.osd1_ctrl_stat = OSD_ENABLE |
105 (0xFF << OSD_GLOBAL_ALPHA_SHIFT) |
106 OSD_BLK0_ENABLE;
107
108 /* Set up BLK0 to point to the right canvas */
109 priv->viu.osd1_blk0_cfg[0] = ((MESON_CANVAS_ID_OSD1 << OSD_CANVAS_SEL) |
110 OSD_ENDIANNESS_LE);
111
112 /* On GXBB, Use the old non-HDR RGB2YUV converter */
113 if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
114 priv->viu.osd1_blk0_cfg[0] |= OSD_OUTPUT_COLOR_RGB;
115
116 switch (fb->pixel_format) {
117 case DRM_FORMAT_XRGB8888:
118 /* For XRGB, replace the pixel's alpha by 0xFF */
119 writel_bits_relaxed(OSD_REPLACE_EN, OSD_REPLACE_EN,
120 priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
121 priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_32 |
122 OSD_COLOR_MATRIX_32_ARGB;
123 break;
124 case DRM_FORMAT_ARGB8888:
125 /* For ARGB, use the pixel's alpha */
126 writel_bits_relaxed(OSD_REPLACE_EN, 0,
127 priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
128 priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_32 |
129 OSD_COLOR_MATRIX_32_ARGB;
130 break;
131 case DRM_FORMAT_RGB888:
132 priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_24 |
133 OSD_COLOR_MATRIX_24_RGB;
134 break;
135 case DRM_FORMAT_RGB565:
136 priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_16 |
137 OSD_COLOR_MATRIX_16_RGB565;
138 break;
139 };
140
141 if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
142 priv->viu.osd1_interlace = true;
143
144 dest.y1 /= 2;
145 dest.y2 /= 2;
146 } else
147 priv->viu.osd1_interlace = false;
148
149 /*
150 * The format of these registers is (x2 << 16 | x1),
151 * where x2 is exclusive.
152 * e.g. +30x1920 would be (1919 << 16) | 30
153 */
154 priv->viu.osd1_blk0_cfg[1] = ((fixed16_to_int(src.x2) - 1) << 16) |
155 fixed16_to_int(src.x1);
156 priv->viu.osd1_blk0_cfg[2] = ((fixed16_to_int(src.y2) - 1) << 16) |
157 fixed16_to_int(src.y1);
158 priv->viu.osd1_blk0_cfg[3] = ((dest.x2 - 1) << 16) | dest.x1;
159 priv->viu.osd1_blk0_cfg[4] = ((dest.y2 - 1) << 16) | dest.y1;
160
161 /* Update Canvas with buffer address */
162 gem = drm_fb_cma_get_gem_obj(fb, 0);
163
164 meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1,
165 gem->paddr, fb->pitches[0],
166 fb->height, MESON_CANVAS_WRAP_NONE,
167 MESON_CANVAS_BLKMODE_LINEAR);
168
169 spin_unlock_irqrestore(&priv->drm->event_lock, flags);
170}
171
172static void meson_plane_atomic_disable(struct drm_plane *plane,
173 struct drm_plane_state *old_state)
174{
175 struct meson_plane *meson_plane = to_meson_plane(plane);
176 struct meson_drm *priv = meson_plane->priv;
177
178 /* Disable OSD1 */
179 writel_bits_relaxed(VPP_OSD1_POSTBLEND, 0,
180 priv->io_base + _REG(VPP_MISC));
181
182}
183
184static const struct drm_plane_helper_funcs meson_plane_helper_funcs = {
185 .atomic_check = meson_plane_atomic_check,
186 .atomic_disable = meson_plane_atomic_disable,
187 .atomic_update = meson_plane_atomic_update,
188};
189
190static const struct drm_plane_funcs meson_plane_funcs = {
191 .update_plane = drm_atomic_helper_update_plane,
192 .disable_plane = drm_atomic_helper_disable_plane,
193 .destroy = drm_plane_cleanup,
194 .reset = drm_atomic_helper_plane_reset,
195 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
196 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
197};
198
199static const uint32_t supported_drm_formats[] = {
200 DRM_FORMAT_ARGB8888,
201 DRM_FORMAT_XRGB8888,
202 DRM_FORMAT_RGB888,
203 DRM_FORMAT_RGB565,
204};
205
206int meson_plane_create(struct meson_drm *priv)
207{
208 struct meson_plane *meson_plane;
209 struct drm_plane *plane;
210
211 meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane),
212 GFP_KERNEL);
213 if (!meson_plane)
214 return -ENOMEM;
215
216 meson_plane->priv = priv;
217 plane = &meson_plane->base;
218
219 drm_universal_plane_init(priv->drm, plane, 0xFF,
220 &meson_plane_funcs,
221 supported_drm_formats,
222 ARRAY_SIZE(supported_drm_formats),
223 DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");
224
225 drm_plane_helper_add(plane, &meson_plane_helper_funcs);
226
227 priv->primary_plane = plane;
228
229 return 0;
230}
diff --git a/drivers/gpu/drm/meson/meson_plane.h b/drivers/gpu/drm/meson/meson_plane.h
new file mode 100644
index 000000000000..e26b8b0aa1fa
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_plane.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2014 Endless Mobile
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 *
19 * Written by:
20 * Jasper St. Pierre <jstpierre@mecheye.net>
21 */
22
23#ifndef __MESON_PLANE_H
24#define __MESON_PLANE_H
25
26#include "meson_drv.h"
27
28int meson_plane_create(struct meson_drm *priv);
29
30#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 000000000000..6adf9c13fafa
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -0,0 +1,1395 @@
1/*
2 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 */
15
16#ifndef __MESON_REGISTERS_H
17#define __MESON_REGISTERS_H
18
19/* Shift all registers by 2 */
20#define _REG(reg) ((reg) << 2)
21
22#define writel_bits_relaxed(mask, val, addr) \
23 writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr)
24
25/* vpp2 */
26#define VPP2_DUMMY_DATA 0x1900
27#define VPP2_LINE_IN_LENGTH 0x1901
28#define VPP2_PIC_IN_HEIGHT 0x1902
29#define VPP2_SCALE_COEF_IDX 0x1903
30#define VPP2_SCALE_COEF 0x1904
31#define VPP2_VSC_REGION12_STARTP 0x1905
32#define VPP2_VSC_REGION34_STARTP 0x1906
33#define VPP2_VSC_REGION4_ENDP 0x1907
34#define VPP2_VSC_START_PHASE_STEP 0x1908
35#define VPP2_VSC_REGION0_PHASE_SLOPE 0x1909
36#define VPP2_VSC_REGION1_PHASE_SLOPE 0x190a
37#define VPP2_VSC_REGION3_PHASE_SLOPE 0x190b
38#define VPP2_VSC_REGION4_PHASE_SLOPE 0x190c
39#define VPP2_VSC_PHASE_CTRL 0x190d
40#define VPP2_VSC_INI_PHASE 0x190e
41#define VPP2_HSC_REGION12_STARTP 0x1910
42#define VPP2_HSC_REGION34_STARTP 0x1911
43#define VPP2_HSC_REGION4_ENDP 0x1912
44#define VPP2_HSC_START_PHASE_STEP 0x1913
45#define VPP2_HSC_REGION0_PHASE_SLOPE 0x1914
46#define VPP2_HSC_REGION1_PHASE_SLOPE 0x1915
47#define VPP2_HSC_REGION3_PHASE_SLOPE 0x1916
48#define VPP2_HSC_REGION4_PHASE_SLOPE 0x1917
49#define VPP2_HSC_PHASE_CTRL 0x1918
50#define VPP2_SC_MISC 0x1919
51#define VPP2_PREBLEND_VD1_H_START_END 0x191a
52#define VPP2_PREBLEND_VD1_V_START_END 0x191b
53#define VPP2_POSTBLEND_VD1_H_START_END 0x191c
54#define VPP2_POSTBLEND_VD1_V_START_END 0x191d
55#define VPP2_PREBLEND_H_SIZE 0x1920
56#define VPP2_POSTBLEND_H_SIZE 0x1921
57#define VPP2_HOLD_LINES 0x1922
58#define VPP2_BLEND_ONECOLOR_CTRL 0x1923
59#define VPP2_PREBLEND_CURRENT_XY 0x1924
60#define VPP2_POSTBLEND_CURRENT_XY 0x1925
61#define VPP2_MISC 0x1926
62#define VPP2_OFIFO_SIZE 0x1927
63#define VPP2_FIFO_STATUS 0x1928
64#define VPP2_SMOKE_CTRL 0x1929
65#define VPP2_SMOKE1_VAL 0x192a
66#define VPP2_SMOKE2_VAL 0x192b
67#define VPP2_SMOKE1_H_START_END 0x192d
68#define VPP2_SMOKE1_V_START_END 0x192e
69#define VPP2_SMOKE2_H_START_END 0x192f
70#define VPP2_SMOKE2_V_START_END 0x1930
71#define VPP2_SCO_FIFO_CTRL 0x1933
72#define VPP2_HSC_PHASE_CTRL1 0x1934
73#define VPP2_HSC_INI_PAT_CTRL 0x1935
74#define VPP2_VADJ_CTRL 0x1940
75#define VPP2_VADJ1_Y 0x1941
76#define VPP2_VADJ1_MA_MB 0x1942
77#define VPP2_VADJ1_MC_MD 0x1943
78#define VPP2_VADJ2_Y 0x1944
79#define VPP2_VADJ2_MA_MB 0x1945
80#define VPP2_VADJ2_MC_MD 0x1946
81#define VPP2_MATRIX_PROBE_COLOR 0x195c
82#define VPP2_MATRIX_HL_COLOR 0x195d
83#define VPP2_MATRIX_PROBE_POS 0x195e
84#define VPP2_MATRIX_CTRL 0x195f
85#define VPP2_MATRIX_COEF00_01 0x1960
86#define VPP2_MATRIX_COEF02_10 0x1961
87#define VPP2_MATRIX_COEF11_12 0x1962
88#define VPP2_MATRIX_COEF20_21 0x1963
89#define VPP2_MATRIX_COEF22 0x1964
90#define VPP2_MATRIX_OFFSET0_1 0x1965
91#define VPP2_MATRIX_OFFSET2 0x1966
92#define VPP2_MATRIX_PRE_OFFSET0_1 0x1967
93#define VPP2_MATRIX_PRE_OFFSET2 0x1968
94#define VPP2_DUMMY_DATA1 0x1969
95#define VPP2_GAINOFF_CTRL0 0x196a
96#define VPP2_GAINOFF_CTRL1 0x196b
97#define VPP2_GAINOFF_CTRL2 0x196c
98#define VPP2_GAINOFF_CTRL3 0x196d
99#define VPP2_GAINOFF_CTRL4 0x196e
100#define VPP2_CHROMA_ADDR_PORT 0x1970
101#define VPP2_CHROMA_DATA_PORT 0x1971
102#define VPP2_GCLK_CTRL0 0x1972
103#define VPP2_GCLK_CTRL1 0x1973
104#define VPP2_SC_GCLK_CTRL 0x1974
105#define VPP2_MISC1 0x1976
106#define VPP2_DNLP_CTRL_00 0x1981
107#define VPP2_DNLP_CTRL_01 0x1982
108#define VPP2_DNLP_CTRL_02 0x1983
109#define VPP2_DNLP_CTRL_03 0x1984
110#define VPP2_DNLP_CTRL_04 0x1985
111#define VPP2_DNLP_CTRL_05 0x1986
112#define VPP2_DNLP_CTRL_06 0x1987
113#define VPP2_DNLP_CTRL_07 0x1988
114#define VPP2_DNLP_CTRL_08 0x1989
115#define VPP2_DNLP_CTRL_09 0x198a
116#define VPP2_DNLP_CTRL_10 0x198b
117#define VPP2_DNLP_CTRL_11 0x198c
118#define VPP2_DNLP_CTRL_12 0x198d
119#define VPP2_DNLP_CTRL_13 0x198e
120#define VPP2_DNLP_CTRL_14 0x198f
121#define VPP2_DNLP_CTRL_15 0x1990
122#define VPP2_VE_ENABLE_CTRL 0x19a1
123#define VPP2_VE_DEMO_LEFT_TOP_SCREEN_WIDTH 0x19a2
124#define VPP2_VE_DEMO_CENTER_BAR 0x19a3
125#define VPP2_VE_H_V_SIZE 0x19a4
126#define VPP2_VDO_MEAS_CTRL 0x19a8
127#define VPP2_VDO_MEAS_VS_COUNT_HI 0x19a9
128#define VPP2_VDO_MEAS_VS_COUNT_LO 0x19aa
129#define VPP2_OSD_VSC_PHASE_STEP 0x19c0
130#define VPP2_OSD_VSC_INI_PHASE 0x19c1
131#define VPP2_OSD_VSC_CTRL0 0x19c2
132#define VPP2_OSD_HSC_PHASE_STEP 0x19c3
133#define VPP2_OSD_HSC_INI_PHASE 0x19c4
134#define VPP2_OSD_HSC_CTRL0 0x19c5
135#define VPP2_OSD_HSC_INI_PAT_CTRL 0x19c6
136#define VPP2_OSD_SC_DUMMY_DATA 0x19c7
137#define VPP2_OSD_SC_CTRL0 0x19c8
138#define VPP2_OSD_SCI_WH_M1 0x19c9
139#define VPP2_OSD_SCO_H_START_END 0x19ca
140#define VPP2_OSD_SCO_V_START_END 0x19cb
141#define VPP2_OSD_SCALE_COEF_IDX 0x19cc
142#define VPP2_OSD_SCALE_COEF 0x19cd
143#define VPP2_INT_LINE_NUM 0x19ce
144
145/* viu */
146#define VIU_ADDR_START 0x1a00
147#define VIU_ADDR_END 0x1aff
148#define VIU_SW_RESET 0x1a01
149#define VIU_MISC_CTRL0 0x1a06
150#define VIU_MISC_CTRL1 0x1a07
151#define D2D3_INTF_LENGTH 0x1a08
152#define D2D3_INTF_CTRL0 0x1a09
153#define VIU_OSD1_CTRL_STAT 0x1a10
154#define VIU_OSD1_CTRL_STAT2 0x1a2d
155#define VIU_OSD1_COLOR_ADDR 0x1a11
156#define VIU_OSD1_COLOR 0x1a12
157#define VIU_OSD1_TCOLOR_AG0 0x1a17
158#define VIU_OSD1_TCOLOR_AG1 0x1a18
159#define VIU_OSD1_TCOLOR_AG2 0x1a19
160#define VIU_OSD1_TCOLOR_AG3 0x1a1a
161#define VIU_OSD1_BLK0_CFG_W0 0x1a1b
162#define VIU_OSD1_BLK1_CFG_W0 0x1a1f
163#define VIU_OSD1_BLK2_CFG_W0 0x1a23
164#define VIU_OSD1_BLK3_CFG_W0 0x1a27
165#define VIU_OSD1_BLK0_CFG_W1 0x1a1c
166#define VIU_OSD1_BLK1_CFG_W1 0x1a20
167#define VIU_OSD1_BLK2_CFG_W1 0x1a24
168#define VIU_OSD1_BLK3_CFG_W1 0x1a28
169#define VIU_OSD1_BLK0_CFG_W2 0x1a1d
170#define VIU_OSD1_BLK1_CFG_W2 0x1a21
171#define VIU_OSD1_BLK2_CFG_W2 0x1a25
172#define VIU_OSD1_BLK3_CFG_W2 0x1a29
173#define VIU_OSD1_BLK0_CFG_W3 0x1a1e
174#define VIU_OSD1_BLK1_CFG_W3 0x1a22
175#define VIU_OSD1_BLK2_CFG_W3 0x1a26
176#define VIU_OSD1_BLK3_CFG_W3 0x1a2a
177#define VIU_OSD1_BLK0_CFG_W4 0x1a13
178#define VIU_OSD1_BLK1_CFG_W4 0x1a14
179#define VIU_OSD1_BLK2_CFG_W4 0x1a15
180#define VIU_OSD1_BLK3_CFG_W4 0x1a16
181#define VIU_OSD1_FIFO_CTRL_STAT 0x1a2b
182#define VIU_OSD1_TEST_RDDATA 0x1a2c
183#define VIU_OSD1_PROT_CTRL 0x1a2e
184#define VIU_OSD2_CTRL_STAT 0x1a30
185#define VIU_OSD2_CTRL_STAT2 0x1a4d
186#define VIU_OSD2_COLOR_ADDR 0x1a31
187#define VIU_OSD2_COLOR 0x1a32
188#define VIU_OSD2_HL1_H_START_END 0x1a33
189#define VIU_OSD2_HL1_V_START_END 0x1a34
190#define VIU_OSD2_HL2_H_START_END 0x1a35
191#define VIU_OSD2_HL2_V_START_END 0x1a36
192#define VIU_OSD2_TCOLOR_AG0 0x1a37
193#define VIU_OSD2_TCOLOR_AG1 0x1a38
194#define VIU_OSD2_TCOLOR_AG2 0x1a39
195#define VIU_OSD2_TCOLOR_AG3 0x1a3a
196#define VIU_OSD2_BLK0_CFG_W0 0x1a3b
197#define VIU_OSD2_BLK1_CFG_W0 0x1a3f
198#define VIU_OSD2_BLK2_CFG_W0 0x1a43
199#define VIU_OSD2_BLK3_CFG_W0 0x1a47
200#define VIU_OSD2_BLK0_CFG_W1 0x1a3c
201#define VIU_OSD2_BLK1_CFG_W1 0x1a40
202#define VIU_OSD2_BLK2_CFG_W1 0x1a44
203#define VIU_OSD2_BLK3_CFG_W1 0x1a48
204#define VIU_OSD2_BLK0_CFG_W2 0x1a3d
205#define VIU_OSD2_BLK1_CFG_W2 0x1a41
206#define VIU_OSD2_BLK2_CFG_W2 0x1a45
207#define VIU_OSD2_BLK3_CFG_W2 0x1a49
208#define VIU_OSD2_BLK0_CFG_W3 0x1a3e
209#define VIU_OSD2_BLK1_CFG_W3 0x1a42
210#define VIU_OSD2_BLK2_CFG_W3 0x1a46
211#define VIU_OSD2_BLK3_CFG_W3 0x1a4a
212#define VIU_OSD2_BLK0_CFG_W4 0x1a64
213#define VIU_OSD2_BLK1_CFG_W4 0x1a65
214#define VIU_OSD2_BLK2_CFG_W4 0x1a66
215#define VIU_OSD2_BLK3_CFG_W4 0x1a67
216#define VIU_OSD2_FIFO_CTRL_STAT 0x1a4b
217#define VIU_OSD2_TEST_RDDATA 0x1a4c
218#define VIU_OSD2_PROT_CTRL 0x1a4e
219
220#define VD1_IF0_GEN_REG 0x1a50
221#define VD1_IF0_CANVAS0 0x1a51
222#define VD1_IF0_CANVAS1 0x1a52
223#define VD1_IF0_LUMA_X0 0x1a53
224#define VD1_IF0_LUMA_Y0 0x1a54
225#define VD1_IF0_CHROMA_X0 0x1a55
226#define VD1_IF0_CHROMA_Y0 0x1a56
227#define VD1_IF0_LUMA_X1 0x1a57
228#define VD1_IF0_LUMA_Y1 0x1a58
229#define VD1_IF0_CHROMA_X1 0x1a59
230#define VD1_IF0_CHROMA_Y1 0x1a5a
231#define VD1_IF0_RPT_LOOP 0x1a5b
232#define VD1_IF0_LUMA0_RPT_PAT 0x1a5c
233#define VD1_IF0_CHROMA0_RPT_PAT 0x1a5d
234#define VD1_IF0_LUMA1_RPT_PAT 0x1a5e
235#define VD1_IF0_CHROMA1_RPT_PAT 0x1a5f
236#define VD1_IF0_LUMA_PSEL 0x1a60
237#define VD1_IF0_CHROMA_PSEL 0x1a61
238#define VD1_IF0_DUMMY_PIXEL 0x1a62
239#define VD1_IF0_LUMA_FIFO_SIZE 0x1a63
240#define VD1_IF0_RANGE_MAP_Y 0x1a6a
241#define VD1_IF0_RANGE_MAP_CB 0x1a6b
242#define VD1_IF0_RANGE_MAP_CR 0x1a6c
243#define VD1_IF0_GEN_REG2 0x1a6d
244#define VD1_IF0_PROT_CNTL 0x1a6e
245#define VIU_VD1_FMT_CTRL 0x1a68
246#define VIU_VD1_FMT_W 0x1a69
247#define VD2_IF0_GEN_REG 0x1a70
248#define VD2_IF0_CANVAS0 0x1a71
249#define VD2_IF0_CANVAS1 0x1a72
250#define VD2_IF0_LUMA_X0 0x1a73
251#define VD2_IF0_LUMA_Y0 0x1a74
252#define VD2_IF0_CHROMA_X0 0x1a75
253#define VD2_IF0_CHROMA_Y0 0x1a76
254#define VD2_IF0_LUMA_X1 0x1a77
255#define VD2_IF0_LUMA_Y1 0x1a78
256#define VD2_IF0_CHROMA_X1 0x1a79
257#define VD2_IF0_CHROMA_Y1 0x1a7a
258#define VD2_IF0_RPT_LOOP 0x1a7b
259#define VD2_IF0_LUMA0_RPT_PAT 0x1a7c
260#define VD2_IF0_CHROMA0_RPT_PAT 0x1a7d
261#define VD2_IF0_LUMA1_RPT_PAT 0x1a7e
262#define VD2_IF0_CHROMA1_RPT_PAT 0x1a7f
263#define VD2_IF0_LUMA_PSEL 0x1a80
264#define VD2_IF0_CHROMA_PSEL 0x1a81
265#define VD2_IF0_DUMMY_PIXEL 0x1a82
266#define VD2_IF0_LUMA_FIFO_SIZE 0x1a83
267#define VD2_IF0_RANGE_MAP_Y 0x1a8a
268#define VD2_IF0_RANGE_MAP_CB 0x1a8b
269#define VD2_IF0_RANGE_MAP_CR 0x1a8c
270#define VD2_IF0_GEN_REG2 0x1a8d
271#define VD2_IF0_PROT_CNTL 0x1a8e
272#define VIU_VD2_FMT_CTRL 0x1a88
273#define VIU_VD2_FMT_W 0x1a89
274
275/* VIU Matrix Registers */
276#define VIU_OSD1_MATRIX_CTRL 0x1a90
277#define VIU_OSD1_MATRIX_COEF00_01 0x1a91
278#define VIU_OSD1_MATRIX_COEF02_10 0x1a92
279#define VIU_OSD1_MATRIX_COEF11_12 0x1a93
280#define VIU_OSD1_MATRIX_COEF20_21 0x1a94
281#define VIU_OSD1_MATRIX_COLMOD_COEF42 0x1a95
282#define VIU_OSD1_MATRIX_OFFSET0_1 0x1a96
283#define VIU_OSD1_MATRIX_OFFSET2 0x1a97
284#define VIU_OSD1_MATRIX_PRE_OFFSET0_1 0x1a98
285#define VIU_OSD1_MATRIX_PRE_OFFSET2 0x1a99
286#define VIU_OSD1_MATRIX_COEF22_30 0x1a9d
287#define VIU_OSD1_MATRIX_COEF31_32 0x1a9e
288#define VIU_OSD1_MATRIX_COEF40_41 0x1a9f
289#define VIU_OSD1_EOTF_CTL 0x1ad4
290#define VIU_OSD1_EOTF_COEF00_01 0x1ad5
291#define VIU_OSD1_EOTF_COEF02_10 0x1ad6
292#define VIU_OSD1_EOTF_COEF11_12 0x1ad7
293#define VIU_OSD1_EOTF_COEF20_21 0x1ad8
294#define VIU_OSD1_EOTF_COEF22_RS 0x1ad9
295#define VIU_OSD1_EOTF_LUT_ADDR_PORT 0x1ada
296#define VIU_OSD1_EOTF_LUT_DATA_PORT 0x1adb
297#define VIU_OSD1_OETF_CTL 0x1adc
298#define VIU_OSD1_OETF_LUT_ADDR_PORT 0x1add
299#define VIU_OSD1_OETF_LUT_DATA_PORT 0x1ade
300
301/* vpp */
302#define VPP_DUMMY_DATA 0x1d00
303#define VPP_LINE_IN_LENGTH 0x1d01
304#define VPP_PIC_IN_HEIGHT 0x1d02
305#define VPP_SCALE_COEF_IDX 0x1d03
306#define VPP_SCALE_COEF 0x1d04
307#define VPP_VSC_REGION12_STARTP 0x1d05
308#define VPP_VSC_REGION34_STARTP 0x1d06
309#define VPP_VSC_REGION4_ENDP 0x1d07
310#define VPP_VSC_START_PHASE_STEP 0x1d08
311#define VPP_VSC_REGION0_PHASE_SLOPE 0x1d09
312#define VPP_VSC_REGION1_PHASE_SLOPE 0x1d0a
313#define VPP_VSC_REGION3_PHASE_SLOPE 0x1d0b
314#define VPP_VSC_REGION4_PHASE_SLOPE 0x1d0c
315#define VPP_VSC_PHASE_CTRL 0x1d0d
316#define VPP_VSC_INI_PHASE 0x1d0e
317#define VPP_HSC_REGION12_STARTP 0x1d10
318#define VPP_HSC_REGION34_STARTP 0x1d11
319#define VPP_HSC_REGION4_ENDP 0x1d12
320#define VPP_HSC_START_PHASE_STEP 0x1d13
321#define VPP_HSC_REGION0_PHASE_SLOPE 0x1d14
322#define VPP_HSC_REGION1_PHASE_SLOPE 0x1d15
323#define VPP_HSC_REGION3_PHASE_SLOPE 0x1d16
324#define VPP_HSC_REGION4_PHASE_SLOPE 0x1d17
325#define VPP_HSC_PHASE_CTRL 0x1d18
326#define VPP_SC_MISC 0x1d19
327#define VPP_PREBLEND_VD1_H_START_END 0x1d1a
328#define VPP_PREBLEND_VD1_V_START_END 0x1d1b
329#define VPP_POSTBLEND_VD1_H_START_END 0x1d1c
330#define VPP_POSTBLEND_VD1_V_START_END 0x1d1d
331#define VPP_BLEND_VD2_H_START_END 0x1d1e
332#define VPP_BLEND_VD2_V_START_END 0x1d1f
333#define VPP_PREBLEND_H_SIZE 0x1d20
334#define VPP_POSTBLEND_H_SIZE 0x1d21
335#define VPP_HOLD_LINES 0x1d22
336#define VPP_BLEND_ONECOLOR_CTRL 0x1d23
337#define VPP_PREBLEND_CURRENT_XY 0x1d24
338#define VPP_POSTBLEND_CURRENT_XY 0x1d25
339#define VPP_MISC 0x1d26
340#define VPP_PREBLEND_ENABLE BIT(6)
341#define VPP_POSTBLEND_ENABLE BIT(7)
342#define VPP_OSD2_ALPHA_PREMULT BIT(8)
343#define VPP_OSD1_ALPHA_PREMULT BIT(9)
344#define VPP_VD1_POSTBLEND BIT(10)
345#define VPP_VD2_POSTBLEND BIT(11)
346#define VPP_OSD1_POSTBLEND BIT(12)
347#define VPP_OSD2_POSTBLEND BIT(13)
348#define VPP_VD1_PREBLEND BIT(14)
349#define VPP_VD2_PREBLEND BIT(15)
350#define VPP_OSD1_PREBLEND BIT(16)
351#define VPP_OSD2_PREBLEND BIT(17)
352#define VPP_OFIFO_SIZE 0x1d27
353#define VPP_FIFO_STATUS 0x1d28
354#define VPP_SMOKE_CTRL 0x1d29
355#define VPP_SMOKE1_VAL 0x1d2a
356#define VPP_SMOKE2_VAL 0x1d2b
357#define VPP_SMOKE3_VAL 0x1d2c
358#define VPP_SMOKE1_H_START_END 0x1d2d
359#define VPP_SMOKE1_V_START_END 0x1d2e
360#define VPP_SMOKE2_H_START_END 0x1d2f
361#define VPP_SMOKE2_V_START_END 0x1d30
362#define VPP_SMOKE3_H_START_END 0x1d31
363#define VPP_SMOKE3_V_START_END 0x1d32
364#define VPP_SCO_FIFO_CTRL 0x1d33
365#define VPP_HSC_PHASE_CTRL1 0x1d34
366#define VPP_HSC_INI_PAT_CTRL 0x1d35
367#define VPP_VADJ_CTRL 0x1d40
368#define VPP_VADJ1_Y 0x1d41
369#define VPP_VADJ1_MA_MB 0x1d42
370#define VPP_VADJ1_MC_MD 0x1d43
371#define VPP_VADJ2_Y 0x1d44
372#define VPP_VADJ2_MA_MB 0x1d45
373#define VPP_VADJ2_MC_MD 0x1d46
374#define VPP_HSHARP_CTRL 0x1d50
375#define VPP_HSHARP_LUMA_THRESH01 0x1d51
376#define VPP_HSHARP_LUMA_THRESH23 0x1d52
377#define VPP_HSHARP_CHROMA_THRESH01 0x1d53
378#define VPP_HSHARP_CHROMA_THRESH23 0x1d54
379#define VPP_HSHARP_LUMA_GAIN 0x1d55
380#define VPP_HSHARP_CHROMA_GAIN 0x1d56
381#define VPP_MATRIX_PROBE_COLOR 0x1d5c
382#define VPP_MATRIX_HL_COLOR 0x1d5d
383#define VPP_MATRIX_PROBE_POS 0x1d5e
384#define VPP_MATRIX_CTRL 0x1d5f
385#define VPP_MATRIX_COEF00_01 0x1d60
386#define VPP_MATRIX_COEF02_10 0x1d61
387#define VPP_MATRIX_COEF11_12 0x1d62
388#define VPP_MATRIX_COEF20_21 0x1d63
389#define VPP_MATRIX_COEF22 0x1d64
390#define VPP_MATRIX_OFFSET0_1 0x1d65
391#define VPP_MATRIX_OFFSET2 0x1d66
392#define VPP_MATRIX_PRE_OFFSET0_1 0x1d67
393#define VPP_MATRIX_PRE_OFFSET2 0x1d68
394#define VPP_DUMMY_DATA1 0x1d69
395#define VPP_GAINOFF_CTRL0 0x1d6a
396#define VPP_GAINOFF_CTRL1 0x1d6b
397#define VPP_GAINOFF_CTRL2 0x1d6c
398#define VPP_GAINOFF_CTRL3 0x1d6d
399#define VPP_GAINOFF_CTRL4 0x1d6e
400#define VPP_CHROMA_ADDR_PORT 0x1d70
401#define VPP_CHROMA_DATA_PORT 0x1d71
402#define VPP_GCLK_CTRL0 0x1d72
403#define VPP_GCLK_CTRL1 0x1d73
404#define VPP_SC_GCLK_CTRL 0x1d74
405#define VPP_MISC1 0x1d76
406#define VPP_BLACKEXT_CTRL 0x1d80
407#define VPP_DNLP_CTRL_00 0x1d81
408#define VPP_DNLP_CTRL_01 0x1d82
409#define VPP_DNLP_CTRL_02 0x1d83
410#define VPP_DNLP_CTRL_03 0x1d84
411#define VPP_DNLP_CTRL_04 0x1d85
412#define VPP_DNLP_CTRL_05 0x1d86
413#define VPP_DNLP_CTRL_06 0x1d87
414#define VPP_DNLP_CTRL_07 0x1d88
415#define VPP_DNLP_CTRL_08 0x1d89
416#define VPP_DNLP_CTRL_09 0x1d8a
417#define VPP_DNLP_CTRL_10 0x1d8b
418#define VPP_DNLP_CTRL_11 0x1d8c
419#define VPP_DNLP_CTRL_12 0x1d8d
420#define VPP_DNLP_CTRL_13 0x1d8e
421#define VPP_DNLP_CTRL_14 0x1d8f
422#define VPP_DNLP_CTRL_15 0x1d90
423#define VPP_PEAKING_HGAIN 0x1d91
424#define VPP_PEAKING_VGAIN 0x1d92
425#define VPP_PEAKING_NLP_1 0x1d93
426#define VPP_DOLBY_CTRL 0x1d93
427#define VPP_PEAKING_NLP_2 0x1d94
428#define VPP_PEAKING_NLP_3 0x1d95
429#define VPP_PEAKING_NLP_4 0x1d96
430#define VPP_PEAKING_NLP_5 0x1d97
431#define VPP_SHARP_LIMIT 0x1d98
432#define VPP_VLTI_CTRL 0x1d99
433#define VPP_HLTI_CTRL 0x1d9a
434#define VPP_CTI_CTRL 0x1d9b
435#define VPP_BLUE_STRETCH_1 0x1d9c
436#define VPP_BLUE_STRETCH_2 0x1d9d
437#define VPP_BLUE_STRETCH_3 0x1d9e
438#define VPP_CCORING_CTRL 0x1da0
439#define VPP_VE_ENABLE_CTRL 0x1da1
440#define VPP_VE_DEMO_LEFT_TOP_SCREEN_WIDTH 0x1da2
441#define VPP_VE_DEMO_CENTER_BAR 0x1da3
442#define VPP_VE_H_V_SIZE 0x1da4
443#define VPP_VDO_MEAS_CTRL 0x1da8
444#define VPP_VDO_MEAS_VS_COUNT_HI 0x1da9
445#define VPP_VDO_MEAS_VS_COUNT_LO 0x1daa
446#define VPP_INPUT_CTRL 0x1dab
447#define VPP_CTI_CTRL2 0x1dac
448#define VPP_PEAKING_SAT_THD1 0x1dad
449#define VPP_PEAKING_SAT_THD2 0x1dae
450#define VPP_PEAKING_SAT_THD3 0x1daf
451#define VPP_PEAKING_SAT_THD4 0x1db0
452#define VPP_PEAKING_SAT_THD5 0x1db1
453#define VPP_PEAKING_SAT_THD6 0x1db2
454#define VPP_PEAKING_SAT_THD7 0x1db3
455#define VPP_PEAKING_SAT_THD8 0x1db4
456#define VPP_PEAKING_SAT_THD9 0x1db5
457#define VPP_PEAKING_GAIN_ADD1 0x1db6
458#define VPP_PEAKING_GAIN_ADD2 0x1db7
459#define VPP_PEAKING_DNLP 0x1db8
460#define VPP_SHARP_DEMO_WIN_CTRL1 0x1db9
461#define VPP_SHARP_DEMO_WIN_CTRL2 0x1dba
462#define VPP_FRONT_HLTI_CTRL 0x1dbb
463#define VPP_FRONT_CTI_CTRL 0x1dbc
464#define VPP_FRONT_CTI_CTRL2 0x1dbd
465#define VPP_OSD_VSC_PHASE_STEP 0x1dc0
466#define VPP_OSD_VSC_INI_PHASE 0x1dc1
467#define VPP_OSD_VSC_CTRL0 0x1dc2
468#define VPP_OSD_HSC_PHASE_STEP 0x1dc3
469#define VPP_OSD_HSC_INI_PHASE 0x1dc4
470#define VPP_OSD_HSC_CTRL0 0x1dc5
471#define VPP_OSD_HSC_INI_PAT_CTRL 0x1dc6
472#define VPP_OSD_SC_DUMMY_DATA 0x1dc7
473#define VPP_OSD_SC_CTRL0 0x1dc8
474#define VPP_OSD_SCI_WH_M1 0x1dc9
475#define VPP_OSD_SCO_H_START_END 0x1dca
476#define VPP_OSD_SCO_V_START_END 0x1dcb
477#define VPP_OSD_SCALE_COEF_IDX 0x1dcc
478#define VPP_OSD_SCALE_COEF 0x1dcd
479#define VPP_INT_LINE_NUM 0x1dce
480
481/* viu2 */
482#define VIU2_ADDR_START 0x1e00
483#define VIU2_ADDR_END 0x1eff
484#define VIU2_SW_RESET 0x1e01
485#define VIU2_OSD1_CTRL_STAT 0x1e10
486#define VIU2_OSD1_CTRL_STAT2 0x1e2d
487#define VIU2_OSD1_COLOR_ADDR 0x1e11
488#define VIU2_OSD1_COLOR 0x1e12
489#define VIU2_OSD1_TCOLOR_AG0 0x1e17
490#define VIU2_OSD1_TCOLOR_AG1 0x1e18
491#define VIU2_OSD1_TCOLOR_AG2 0x1e19
492#define VIU2_OSD1_TCOLOR_AG3 0x1e1a
493#define VIU2_OSD1_BLK0_CFG_W0 0x1e1b
494#define VIU2_OSD1_BLK1_CFG_W0 0x1e1f
495#define VIU2_OSD1_BLK2_CFG_W0 0x1e23
496#define VIU2_OSD1_BLK3_CFG_W0 0x1e27
497#define VIU2_OSD1_BLK0_CFG_W1 0x1e1c
498#define VIU2_OSD1_BLK1_CFG_W1 0x1e20
499#define VIU2_OSD1_BLK2_CFG_W1 0x1e24
500#define VIU2_OSD1_BLK3_CFG_W1 0x1e28
501#define VIU2_OSD1_BLK0_CFG_W2 0x1e1d
502#define VIU2_OSD1_BLK1_CFG_W2 0x1e21
503#define VIU2_OSD1_BLK2_CFG_W2 0x1e25
504#define VIU2_OSD1_BLK3_CFG_W2 0x1e29
505#define VIU2_OSD1_BLK0_CFG_W3 0x1e1e
506#define VIU2_OSD1_BLK1_CFG_W3 0x1e22
507#define VIU2_OSD1_BLK2_CFG_W3 0x1e26
508#define VIU2_OSD1_BLK3_CFG_W3 0x1e2a
509#define VIU2_OSD1_BLK0_CFG_W4 0x1e13
510#define VIU2_OSD1_BLK1_CFG_W4 0x1e14
511#define VIU2_OSD1_BLK2_CFG_W4 0x1e15
512#define VIU2_OSD1_BLK3_CFG_W4 0x1e16
513#define VIU2_OSD1_FIFO_CTRL_STAT 0x1e2b
514#define VIU2_OSD1_TEST_RDDATA 0x1e2c
515#define VIU2_OSD1_PROT_CTRL 0x1e2e
516#define VIU2_OSD2_CTRL_STAT 0x1e30
517#define VIU2_OSD2_CTRL_STAT2 0x1e4d
518#define VIU2_OSD2_COLOR_ADDR 0x1e31
519#define VIU2_OSD2_COLOR 0x1e32
520#define VIU2_OSD2_HL1_H_START_END 0x1e33
521#define VIU2_OSD2_HL1_V_START_END 0x1e34
522#define VIU2_OSD2_HL2_H_START_END 0x1e35
523#define VIU2_OSD2_HL2_V_START_END 0x1e36
524#define VIU2_OSD2_TCOLOR_AG0 0x1e37
525#define VIU2_OSD2_TCOLOR_AG1 0x1e38
526#define VIU2_OSD2_TCOLOR_AG2 0x1e39
527#define VIU2_OSD2_TCOLOR_AG3 0x1e3a
528#define VIU2_OSD2_BLK0_CFG_W0 0x1e3b
529#define VIU2_OSD2_BLK1_CFG_W0 0x1e3f
530#define VIU2_OSD2_BLK2_CFG_W0 0x1e43
531#define VIU2_OSD2_BLK3_CFG_W0 0x1e47
532#define VIU2_OSD2_BLK0_CFG_W1 0x1e3c
533#define VIU2_OSD2_BLK1_CFG_W1 0x1e40
534#define VIU2_OSD2_BLK2_CFG_W1 0x1e44
535#define VIU2_OSD2_BLK3_CFG_W1 0x1e48
536#define VIU2_OSD2_BLK0_CFG_W2 0x1e3d
537#define VIU2_OSD2_BLK1_CFG_W2 0x1e41
538#define VIU2_OSD2_BLK2_CFG_W2 0x1e45
539#define VIU2_OSD2_BLK3_CFG_W2 0x1e49
540#define VIU2_OSD2_BLK0_CFG_W3 0x1e3e
541#define VIU2_OSD2_BLK1_CFG_W3 0x1e42
542#define VIU2_OSD2_BLK2_CFG_W3 0x1e46
543#define VIU2_OSD2_BLK3_CFG_W3 0x1e4a
544#define VIU2_OSD2_BLK0_CFG_W4 0x1e64
545#define VIU2_OSD2_BLK1_CFG_W4 0x1e65
546#define VIU2_OSD2_BLK2_CFG_W4 0x1e66
547#define VIU2_OSD2_BLK3_CFG_W4 0x1e67
548#define VIU2_OSD2_FIFO_CTRL_STAT 0x1e4b
549#define VIU2_OSD2_TEST_RDDATA 0x1e4c
550#define VIU2_OSD2_PROT_CTRL 0x1e4e
551#define VIU2_VD1_IF0_GEN_REG 0x1e50
552#define VIU2_VD1_IF0_CANVAS0 0x1e51
553#define VIU2_VD1_IF0_CANVAS1 0x1e52
554#define VIU2_VD1_IF0_LUMA_X0 0x1e53
555#define VIU2_VD1_IF0_LUMA_Y0 0x1e54
556#define VIU2_VD1_IF0_CHROMA_X0 0x1e55
557#define VIU2_VD1_IF0_CHROMA_Y0 0x1e56
558#define VIU2_VD1_IF0_LUMA_X1 0x1e57
559#define VIU2_VD1_IF0_LUMA_Y1 0x1e58
560#define VIU2_VD1_IF0_CHROMA_X1 0x1e59
561#define VIU2_VD1_IF0_CHROMA_Y1 0x1e5a
562#define VIU2_VD1_IF0_RPT_LOOP 0x1e5b
563#define VIU2_VD1_IF0_LUMA0_RPT_PAT 0x1e5c
564#define VIU2_VD1_IF0_CHROMA0_RPT_PAT 0x1e5d
565#define VIU2_VD1_IF0_LUMA1_RPT_PAT 0x1e5e
566#define VIU2_VD1_IF0_CHROMA1_RPT_PAT 0x1e5f
567#define VIU2_VD1_IF0_LUMA_PSEL 0x1e60
568#define VIU2_VD1_IF0_CHROMA_PSEL 0x1e61
569#define VIU2_VD1_IF0_DUMMY_PIXEL 0x1e62
570#define VIU2_VD1_IF0_LUMA_FIFO_SIZE 0x1e63
571#define VIU2_VD1_IF0_RANGE_MAP_Y 0x1e6a
572#define VIU2_VD1_IF0_RANGE_MAP_CB 0x1e6b
573#define VIU2_VD1_IF0_RANGE_MAP_CR 0x1e6c
574#define VIU2_VD1_IF0_GEN_REG2 0x1e6d
575#define VIU2_VD1_IF0_PROT_CNTL 0x1e6e
576#define VIU2_VD1_FMT_CTRL 0x1e68
577#define VIU2_VD1_FMT_W 0x1e69
578
579/* encode */
580#define ENCP_VFIFO2VD_CTL 0x1b58
581#define ENCP_VFIFO2VD_PIXEL_START 0x1b59
582#define ENCP_VFIFO2VD_PIXEL_END 0x1b5a
583#define ENCP_VFIFO2VD_LINE_TOP_START 0x1b5b
584#define ENCP_VFIFO2VD_LINE_TOP_END 0x1b5c
585#define ENCP_VFIFO2VD_LINE_BOT_START 0x1b5d
586#define ENCP_VFIFO2VD_LINE_BOT_END 0x1b5e
587#define VENC_SYNC_ROUTE 0x1b60
588#define VENC_VIDEO_EXSRC 0x1b61
589#define VENC_DVI_SETTING 0x1b62
590#define VENC_C656_CTRL 0x1b63
591#define VENC_UPSAMPLE_CTRL0 0x1b64
592#define VENC_UPSAMPLE_CTRL1 0x1b65
593#define VENC_UPSAMPLE_CTRL2 0x1b66
594#define TCON_INVERT_CTL 0x1b67
595#define VENC_VIDEO_PROG_MODE 0x1b68
596#define VENC_ENCI_LINE 0x1b69
597#define VENC_ENCI_PIXEL 0x1b6a
598#define VENC_ENCP_LINE 0x1b6b
599#define VENC_ENCP_PIXEL 0x1b6c
600#define VENC_STATA 0x1b6d
601#define VENC_INTCTRL 0x1b6e
602#define VENC_INTFLAG 0x1b6f
603#define VENC_VIDEO_TST_EN 0x1b70
604#define VENC_VIDEO_TST_MDSEL 0x1b71
605#define VENC_VIDEO_TST_Y 0x1b72
606#define VENC_VIDEO_TST_CB 0x1b73
607#define VENC_VIDEO_TST_CR 0x1b74
608#define VENC_VIDEO_TST_CLRBAR_STRT 0x1b75
609#define VENC_VIDEO_TST_CLRBAR_WIDTH 0x1b76
610#define VENC_VIDEO_TST_VDCNT_STSET 0x1b77
611#define VENC_VDAC_DACSEL0 0x1b78
612#define VENC_VDAC_DACSEL1 0x1b79
613#define VENC_VDAC_DACSEL2 0x1b7a
614#define VENC_VDAC_DACSEL3 0x1b7b
615#define VENC_VDAC_DACSEL4 0x1b7c
616#define VENC_VDAC_DACSEL5 0x1b7d
617#define VENC_VDAC_SETTING 0x1b7e
618#define VENC_VDAC_TST_VAL 0x1b7f
619#define VENC_VDAC_DAC0_GAINCTRL 0x1bf0
620#define VENC_VDAC_DAC0_OFFSET 0x1bf1
621#define VENC_VDAC_DAC1_GAINCTRL 0x1bf2
622#define VENC_VDAC_DAC1_OFFSET 0x1bf3
623#define VENC_VDAC_DAC2_GAINCTRL 0x1bf4
624#define VENC_VDAC_DAC2_OFFSET 0x1bf5
625#define VENC_VDAC_DAC3_GAINCTRL 0x1bf6
626#define VENC_VDAC_DAC3_OFFSET 0x1bf7
627#define VENC_VDAC_DAC4_GAINCTRL 0x1bf8
628#define VENC_VDAC_DAC4_OFFSET 0x1bf9
629#define VENC_VDAC_DAC5_GAINCTRL 0x1bfa
630#define VENC_VDAC_DAC5_OFFSET 0x1bfb
631#define VENC_VDAC_FIFO_CTRL 0x1bfc
632#define ENCL_TCON_INVERT_CTL 0x1bfd
633#define ENCP_VIDEO_EN 0x1b80
634#define ENCP_VIDEO_SYNC_MODE 0x1b81
635#define ENCP_MACV_EN 0x1b82
636#define ENCP_VIDEO_Y_SCL 0x1b83
637#define ENCP_VIDEO_PB_SCL 0x1b84
638#define ENCP_VIDEO_PR_SCL 0x1b85
639#define ENCP_VIDEO_SYNC_SCL 0x1b86
640#define ENCP_VIDEO_MACV_SCL 0x1b87
641#define ENCP_VIDEO_Y_OFFST 0x1b88
642#define ENCP_VIDEO_PB_OFFST 0x1b89
643#define ENCP_VIDEO_PR_OFFST 0x1b8a
644#define ENCP_VIDEO_SYNC_OFFST 0x1b8b
645#define ENCP_VIDEO_MACV_OFFST 0x1b8c
646#define ENCP_VIDEO_MODE 0x1b8d
647#define ENCP_VIDEO_MODE_ADV 0x1b8e
648#define ENCP_DBG_PX_RST 0x1b90
649#define ENCP_DBG_LN_RST 0x1b91
650#define ENCP_DBG_PX_INT 0x1b92
651#define ENCP_DBG_LN_INT 0x1b93
652#define ENCP_VIDEO_YFP1_HTIME 0x1b94
653#define ENCP_VIDEO_YFP2_HTIME 0x1b95
654#define ENCP_VIDEO_YC_DLY 0x1b96
655#define ENCP_VIDEO_MAX_PXCNT 0x1b97
656#define ENCP_VIDEO_HSPULS_BEGIN 0x1b98
657#define ENCP_VIDEO_HSPULS_END 0x1b99
658#define ENCP_VIDEO_HSPULS_SWITCH 0x1b9a
659#define ENCP_VIDEO_VSPULS_BEGIN 0x1b9b
660#define ENCP_VIDEO_VSPULS_END 0x1b9c
661#define ENCP_VIDEO_VSPULS_BLINE 0x1b9d
662#define ENCP_VIDEO_VSPULS_ELINE 0x1b9e
663#define ENCP_VIDEO_EQPULS_BEGIN 0x1b9f
664#define ENCP_VIDEO_EQPULS_END 0x1ba0
665#define ENCP_VIDEO_EQPULS_BLINE 0x1ba1
666#define ENCP_VIDEO_EQPULS_ELINE 0x1ba2
667#define ENCP_VIDEO_HAVON_END 0x1ba3
668#define ENCP_VIDEO_HAVON_BEGIN 0x1ba4
669#define ENCP_VIDEO_VAVON_ELINE 0x1baf
670#define ENCP_VIDEO_VAVON_BLINE 0x1ba6
671#define ENCP_VIDEO_HSO_BEGIN 0x1ba7
672#define ENCP_VIDEO_HSO_END 0x1ba8
673#define ENCP_VIDEO_VSO_BEGIN 0x1ba9
674#define ENCP_VIDEO_VSO_END 0x1baa
675#define ENCP_VIDEO_VSO_BLINE 0x1bab
676#define ENCP_VIDEO_VSO_ELINE 0x1bac
677#define ENCP_VIDEO_SYNC_WAVE_CURVE 0x1bad
678#define ENCP_VIDEO_MAX_LNCNT 0x1bae
679#define ENCP_VIDEO_SY_VAL 0x1bb0
680#define ENCP_VIDEO_SY2_VAL 0x1bb1
681#define ENCP_VIDEO_BLANKY_VAL 0x1bb2
682#define ENCP_VIDEO_BLANKPB_VAL 0x1bb3
683#define ENCP_VIDEO_BLANKPR_VAL 0x1bb4
684#define ENCP_VIDEO_HOFFST 0x1bb5
685#define ENCP_VIDEO_VOFFST 0x1bb6
686#define ENCP_VIDEO_RGB_CTRL 0x1bb7
687#define ENCP_VIDEO_FILT_CTRL 0x1bb8
688#define ENCP_VIDEO_OFLD_VPEQ_OFST 0x1bb9
689#define ENCP_VIDEO_OFLD_VOAV_OFST 0x1bba
690#define ENCP_VIDEO_MATRIX_CB 0x1bbb
691#define ENCP_VIDEO_MATRIX_CR 0x1bbc
692#define ENCP_VIDEO_RGBIN_CTRL 0x1bbd
693#define ENCP_MACV_BLANKY_VAL 0x1bc0
694#define ENCP_MACV_MAXY_VAL 0x1bc1
695#define ENCP_MACV_1ST_PSSYNC_STRT 0x1bc2
696#define ENCP_MACV_PSSYNC_STRT 0x1bc3
697#define ENCP_MACV_AGC_STRT 0x1bc4
698#define ENCP_MACV_AGC_END 0x1bc5
699#define ENCP_MACV_WAVE_END 0x1bc6
700#define ENCP_MACV_STRTLINE 0x1bc7
701#define ENCP_MACV_ENDLINE 0x1bc8
702#define ENCP_MACV_TS_CNT_MAX_L 0x1bc9
703#define ENCP_MACV_TS_CNT_MAX_H 0x1bca
704#define ENCP_MACV_TIME_DOWN 0x1bcb
705#define ENCP_MACV_TIME_LO 0x1bcc
706#define ENCP_MACV_TIME_UP 0x1bcd
707#define ENCP_MACV_TIME_RST 0x1bce
708#define ENCP_VBI_CTRL 0x1bd0
709#define ENCP_VBI_SETTING 0x1bd1
710#define ENCP_VBI_BEGIN 0x1bd2
711#define ENCP_VBI_WIDTH 0x1bd3
712#define ENCP_VBI_HVAL 0x1bd4
713#define ENCP_VBI_DATA0 0x1bd5
714#define ENCP_VBI_DATA1 0x1bd6
715#define C656_HS_ST 0x1be0
716#define C656_HS_ED 0x1be1
717#define C656_VS_LNST_E 0x1be2
718#define C656_VS_LNST_O 0x1be3
719#define C656_VS_LNED_E 0x1be4
720#define C656_VS_LNED_O 0x1be5
721#define C656_FS_LNST 0x1be6
722#define C656_FS_LNED 0x1be7
723#define ENCI_VIDEO_MODE 0x1b00
724#define ENCI_VIDEO_MODE_ADV 0x1b01
725#define ENCI_VIDEO_FSC_ADJ 0x1b02
726#define ENCI_VIDEO_BRIGHT 0x1b03
727#define ENCI_VIDEO_CONT 0x1b04
728#define ENCI_VIDEO_SAT 0x1b05
729#define ENCI_VIDEO_HUE 0x1b06
730#define ENCI_VIDEO_SCH 0x1b07
731#define ENCI_SYNC_MODE 0x1b08
732#define ENCI_SYNC_CTRL 0x1b09
733#define ENCI_SYNC_HSO_BEGIN 0x1b0a
734#define ENCI_SYNC_HSO_END 0x1b0b
735#define ENCI_SYNC_VSO_EVN 0x1b0c
736#define ENCI_SYNC_VSO_ODD 0x1b0d
737#define ENCI_SYNC_VSO_EVNLN 0x1b0e
738#define ENCI_SYNC_VSO_ODDLN 0x1b0f
739#define ENCI_SYNC_HOFFST 0x1b10
740#define ENCI_SYNC_VOFFST 0x1b11
741#define ENCI_SYNC_ADJ 0x1b12
742#define ENCI_RGB_SETTING 0x1b13
743#define ENCI_DE_H_BEGIN 0x1b16
744#define ENCI_DE_H_END 0x1b17
745#define ENCI_DE_V_BEGIN_EVEN 0x1b18
746#define ENCI_DE_V_END_EVEN 0x1b19
747#define ENCI_DE_V_BEGIN_ODD 0x1b1a
748#define ENCI_DE_V_END_ODD 0x1b1b
749#define ENCI_VBI_SETTING 0x1b20
750#define ENCI_VBI_CCDT_EVN 0x1b21
751#define ENCI_VBI_CCDT_ODD 0x1b22
752#define ENCI_VBI_CC525_LN 0x1b23
753#define ENCI_VBI_CC625_LN 0x1b24
754#define ENCI_VBI_WSSDT 0x1b25
755#define ENCI_VBI_WSS_LN 0x1b26
756#define ENCI_VBI_CGMSDT_L 0x1b27
757#define ENCI_VBI_CGMSDT_H 0x1b28
758#define ENCI_VBI_CGMS_LN 0x1b29
759#define ENCI_VBI_TTX_HTIME 0x1b2a
760#define ENCI_VBI_TTX_LN 0x1b2b
761#define ENCI_VBI_TTXDT0 0x1b2c
762#define ENCI_VBI_TTXDT1 0x1b2d
763#define ENCI_VBI_TTXDT2 0x1b2e
764#define ENCI_VBI_TTXDT3 0x1b2f
765#define ENCI_MACV_N0 0x1b30
766#define ENCI_MACV_N1 0x1b31
767#define ENCI_MACV_N2 0x1b32
768#define ENCI_MACV_N3 0x1b33
769#define ENCI_MACV_N4 0x1b34
770#define ENCI_MACV_N5 0x1b35
771#define ENCI_MACV_N6 0x1b36
772#define ENCI_MACV_N7 0x1b37
773#define ENCI_MACV_N8 0x1b38
774#define ENCI_MACV_N9 0x1b39
775#define ENCI_MACV_N10 0x1b3a
776#define ENCI_MACV_N11 0x1b3b
777#define ENCI_MACV_N12 0x1b3c
778#define ENCI_MACV_N13 0x1b3d
779#define ENCI_MACV_N14 0x1b3e
780#define ENCI_MACV_N15 0x1b3f
781#define ENCI_MACV_N16 0x1b40
782#define ENCI_MACV_N17 0x1b41
783#define ENCI_MACV_N18 0x1b42
784#define ENCI_MACV_N19 0x1b43
785#define ENCI_MACV_N20 0x1b44
786#define ENCI_MACV_N21 0x1b45
787#define ENCI_MACV_N22 0x1b46
788#define ENCI_DBG_PX_RST 0x1b48
789#define ENCI_DBG_FLDLN_RST 0x1b49
790#define ENCI_DBG_PX_INT 0x1b4a
791#define ENCI_DBG_FLDLN_INT 0x1b4b
792#define ENCI_DBG_MAXPX 0x1b4c
793#define ENCI_DBG_MAXLN 0x1b4d
794#define ENCI_MACV_MAX_AMP 0x1b50
795#define ENCI_MACV_PULSE_LO 0x1b51
796#define ENCI_MACV_PULSE_HI 0x1b52
797#define ENCI_MACV_BKP_MAX 0x1b53
798#define ENCI_CFILT_CTRL 0x1b54
799#define ENCI_CFILT7 0x1b55
800#define ENCI_YC_DELAY 0x1b56
801#define ENCI_VIDEO_EN 0x1b57
802#define ENCI_DVI_HSO_BEGIN 0x1c00
803#define ENCI_DVI_HSO_END 0x1c01
804#define ENCI_DVI_VSO_BLINE_EVN 0x1c02
805#define ENCI_DVI_VSO_BLINE_ODD 0x1c03
806#define ENCI_DVI_VSO_ELINE_EVN 0x1c04
807#define ENCI_DVI_VSO_ELINE_ODD 0x1c05
808#define ENCI_DVI_VSO_BEGIN_EVN 0x1c06
809#define ENCI_DVI_VSO_BEGIN_ODD 0x1c07
810#define ENCI_DVI_VSO_END_EVN 0x1c08
811#define ENCI_DVI_VSO_END_ODD 0x1c09
812#define ENCI_CFILT_CTRL2 0x1c0a
813#define ENCI_DACSEL_0 0x1c0b
814#define ENCI_DACSEL_1 0x1c0c
815#define ENCP_DACSEL_0 0x1c0d
816#define ENCP_DACSEL_1 0x1c0e
817#define ENCP_MAX_LINE_SWITCH_POINT 0x1c0f
818#define ENCI_TST_EN 0x1c10
819#define ENCI_TST_MDSEL 0x1c11
820#define ENCI_TST_Y 0x1c12
821#define ENCI_TST_CB 0x1c13
822#define ENCI_TST_CR 0x1c14
823#define ENCI_TST_CLRBAR_STRT 0x1c15
824#define ENCI_TST_CLRBAR_WIDTH 0x1c16
825#define ENCI_TST_VDCNT_STSET 0x1c17
826#define ENCI_VFIFO2VD_CTL 0x1c18
827#define ENCI_VFIFO2VD_PIXEL_START 0x1c19
828#define ENCI_VFIFO2VD_PIXEL_END 0x1c1a
829#define ENCI_VFIFO2VD_LINE_TOP_START 0x1c1b
830#define ENCI_VFIFO2VD_LINE_TOP_END 0x1c1c
831#define ENCI_VFIFO2VD_LINE_BOT_START 0x1c1d
832#define ENCI_VFIFO2VD_LINE_BOT_END 0x1c1e
833#define ENCI_VFIFO2VD_CTL2 0x1c1f
834#define ENCT_VFIFO2VD_CTL 0x1c20
835#define ENCT_VFIFO2VD_PIXEL_START 0x1c21
836#define ENCT_VFIFO2VD_PIXEL_END 0x1c22
837#define ENCT_VFIFO2VD_LINE_TOP_START 0x1c23
838#define ENCT_VFIFO2VD_LINE_TOP_END 0x1c24
839#define ENCT_VFIFO2VD_LINE_BOT_START 0x1c25
840#define ENCT_VFIFO2VD_LINE_BOT_END 0x1c26
841#define ENCT_VFIFO2VD_CTL2 0x1c27
842#define ENCT_TST_EN 0x1c28
843#define ENCT_TST_MDSEL 0x1c29
844#define ENCT_TST_Y 0x1c2a
845#define ENCT_TST_CB 0x1c2b
846#define ENCT_TST_CR 0x1c2c
847#define ENCT_TST_CLRBAR_STRT 0x1c2d
848#define ENCT_TST_CLRBAR_WIDTH 0x1c2e
849#define ENCT_TST_VDCNT_STSET 0x1c2f
850#define ENCP_DVI_HSO_BEGIN 0x1c30
851#define ENCP_DVI_HSO_END 0x1c31
852#define ENCP_DVI_VSO_BLINE_EVN 0x1c32
853#define ENCP_DVI_VSO_BLINE_ODD 0x1c33
854#define ENCP_DVI_VSO_ELINE_EVN 0x1c34
855#define ENCP_DVI_VSO_ELINE_ODD 0x1c35
856#define ENCP_DVI_VSO_BEGIN_EVN 0x1c36
857#define ENCP_DVI_VSO_BEGIN_ODD 0x1c37
858#define ENCP_DVI_VSO_END_EVN 0x1c38
859#define ENCP_DVI_VSO_END_ODD 0x1c39
860#define ENCP_DE_H_BEGIN 0x1c3a
861#define ENCP_DE_H_END 0x1c3b
862#define ENCP_DE_V_BEGIN_EVEN 0x1c3c
863#define ENCP_DE_V_END_EVEN 0x1c3d
864#define ENCP_DE_V_BEGIN_ODD 0x1c3e
865#define ENCP_DE_V_END_ODD 0x1c3f
866#define ENCI_SYNC_LINE_LENGTH 0x1c40
867#define ENCI_SYNC_PIXEL_EN 0x1c41
868#define ENCI_SYNC_TO_LINE_EN 0x1c42
869#define ENCI_SYNC_TO_PIXEL 0x1c43
870#define ENCP_SYNC_LINE_LENGTH 0x1c44
871#define ENCP_SYNC_PIXEL_EN 0x1c45
872#define ENCP_SYNC_TO_LINE_EN 0x1c46
873#define ENCP_SYNC_TO_PIXEL 0x1c47
874#define ENCT_SYNC_LINE_LENGTH 0x1c48
875#define ENCT_SYNC_PIXEL_EN 0x1c49
876#define ENCT_SYNC_TO_LINE_EN 0x1c4a
877#define ENCT_SYNC_TO_PIXEL 0x1c4b
878#define ENCL_SYNC_LINE_LENGTH 0x1c4c
879#define ENCL_SYNC_PIXEL_EN 0x1c4d
880#define ENCL_SYNC_TO_LINE_EN 0x1c4e
881#define ENCL_SYNC_TO_PIXEL 0x1c4f
882#define ENCP_VFIFO2VD_CTL2 0x1c50
883#define VENC_DVI_SETTING_MORE 0x1c51
884#define VENC_VDAC_DAC4_FILT_CTRL0 0x1c54
885#define VENC_VDAC_DAC4_FILT_CTRL1 0x1c55
886#define VENC_VDAC_DAC5_FILT_CTRL0 0x1c56
887#define VENC_VDAC_DAC5_FILT_CTRL1 0x1c57
888#define VENC_VDAC_DAC0_FILT_CTRL0 0x1c58
889#define VENC_VDAC_DAC0_FILT_CTRL1 0x1c59
890#define VENC_VDAC_DAC1_FILT_CTRL0 0x1c5a
891#define VENC_VDAC_DAC1_FILT_CTRL1 0x1c5b
892#define VENC_VDAC_DAC2_FILT_CTRL0 0x1c5c
893#define VENC_VDAC_DAC2_FILT_CTRL1 0x1c5d
894#define VENC_VDAC_DAC3_FILT_CTRL0 0x1c5e
895#define VENC_VDAC_DAC3_FILT_CTRL1 0x1c5f
896#define ENCT_VIDEO_EN 0x1c60
897#define ENCT_VIDEO_Y_SCL 0x1c61
898#define ENCT_VIDEO_PB_SCL 0x1c62
899#define ENCT_VIDEO_PR_SCL 0x1c63
900#define ENCT_VIDEO_Y_OFFST 0x1c64
901#define ENCT_VIDEO_PB_OFFST 0x1c65
902#define ENCT_VIDEO_PR_OFFST 0x1c66
903#define ENCT_VIDEO_MODE 0x1c67
904#define ENCT_VIDEO_MODE_ADV 0x1c68
905#define ENCT_DBG_PX_RST 0x1c69
906#define ENCT_DBG_LN_RST 0x1c6a
907#define ENCT_DBG_PX_INT 0x1c6b
908#define ENCT_DBG_LN_INT 0x1c6c
909#define ENCT_VIDEO_YFP1_HTIME 0x1c6d
910#define ENCT_VIDEO_YFP2_HTIME 0x1c6e
911#define ENCT_VIDEO_YC_DLY 0x1c6f
912#define ENCT_VIDEO_MAX_PXCNT 0x1c70
913#define ENCT_VIDEO_HAVON_END 0x1c71
914#define ENCT_VIDEO_HAVON_BEGIN 0x1c72
915#define ENCT_VIDEO_VAVON_ELINE 0x1c73
916#define ENCT_VIDEO_VAVON_BLINE 0x1c74
917#define ENCT_VIDEO_HSO_BEGIN 0x1c75
918#define ENCT_VIDEO_HSO_END 0x1c76
919#define ENCT_VIDEO_VSO_BEGIN 0x1c77
920#define ENCT_VIDEO_VSO_END 0x1c78
921#define ENCT_VIDEO_VSO_BLINE 0x1c79
922#define ENCT_VIDEO_VSO_ELINE 0x1c7a
923#define ENCT_VIDEO_MAX_LNCNT 0x1c7b
924#define ENCT_VIDEO_BLANKY_VAL 0x1c7c
925#define ENCT_VIDEO_BLANKPB_VAL 0x1c7d
926#define ENCT_VIDEO_BLANKPR_VAL 0x1c7e
927#define ENCT_VIDEO_HOFFST 0x1c7f
928#define ENCT_VIDEO_VOFFST 0x1c80
929#define ENCT_VIDEO_RGB_CTRL 0x1c81
930#define ENCT_VIDEO_FILT_CTRL 0x1c82
931#define ENCT_VIDEO_OFLD_VPEQ_OFST 0x1c83
932#define ENCT_VIDEO_OFLD_VOAV_OFST 0x1c84
933#define ENCT_VIDEO_MATRIX_CB 0x1c85
934#define ENCT_VIDEO_MATRIX_CR 0x1c86
935#define ENCT_VIDEO_RGBIN_CTRL 0x1c87
936#define ENCT_MAX_LINE_SWITCH_POINT 0x1c88
937#define ENCT_DACSEL_0 0x1c89
938#define ENCT_DACSEL_1 0x1c8a
939#define ENCL_VFIFO2VD_CTL 0x1c90
940#define ENCL_VFIFO2VD_PIXEL_START 0x1c91
941#define ENCL_VFIFO2VD_PIXEL_END 0x1c92
942#define ENCL_VFIFO2VD_LINE_TOP_START 0x1c93
943#define ENCL_VFIFO2VD_LINE_TOP_END 0x1c94
944#define ENCL_VFIFO2VD_LINE_BOT_START 0x1c95
945#define ENCL_VFIFO2VD_LINE_BOT_END 0x1c96
946#define ENCL_VFIFO2VD_CTL2 0x1c97
947#define ENCL_TST_EN 0x1c98
948#define ENCL_TST_MDSEL 0x1c99
949#define ENCL_TST_Y 0x1c9a
950#define ENCL_TST_CB 0x1c9b
951#define ENCL_TST_CR 0x1c9c
952#define ENCL_TST_CLRBAR_STRT 0x1c9d
953#define ENCL_TST_CLRBAR_WIDTH 0x1c9e
954#define ENCL_TST_VDCNT_STSET 0x1c9f
955#define ENCL_VIDEO_EN 0x1ca0
956#define ENCL_VIDEO_Y_SCL 0x1ca1
957#define ENCL_VIDEO_PB_SCL 0x1ca2
958#define ENCL_VIDEO_PR_SCL 0x1ca3
959#define ENCL_VIDEO_Y_OFFST 0x1ca4
960#define ENCL_VIDEO_PB_OFFST 0x1ca5
961#define ENCL_VIDEO_PR_OFFST 0x1ca6
962#define ENCL_VIDEO_MODE 0x1ca7
963#define ENCL_VIDEO_MODE_ADV 0x1ca8
964#define ENCL_DBG_PX_RST 0x1ca9
965#define ENCL_DBG_LN_RST 0x1caa
966#define ENCL_DBG_PX_INT 0x1cab
967#define ENCL_DBG_LN_INT 0x1cac
968#define ENCL_VIDEO_YFP1_HTIME 0x1cad
969#define ENCL_VIDEO_YFP2_HTIME 0x1cae
970#define ENCL_VIDEO_YC_DLY 0x1caf
971#define ENCL_VIDEO_MAX_PXCNT 0x1cb0
972#define ENCL_VIDEO_HAVON_END 0x1cb1
973#define ENCL_VIDEO_HAVON_BEGIN 0x1cb2
974#define ENCL_VIDEO_VAVON_ELINE 0x1cb3
975#define ENCL_VIDEO_VAVON_BLINE 0x1cb4
976#define ENCL_VIDEO_HSO_BEGIN 0x1cb5
977#define ENCL_VIDEO_HSO_END 0x1cb6
978#define ENCL_VIDEO_VSO_BEGIN 0x1cb7
979#define ENCL_VIDEO_VSO_END 0x1cb8
980#define ENCL_VIDEO_VSO_BLINE 0x1cb9
981#define ENCL_VIDEO_VSO_ELINE 0x1cba
982#define ENCL_VIDEO_MAX_LNCNT 0x1cbb
983#define ENCL_VIDEO_BLANKY_VAL 0x1cbc
984#define ENCL_VIDEO_BLANKPB_VAL 0x1cbd
985#define ENCL_VIDEO_BLANKPR_VAL 0x1cbe
986#define ENCL_VIDEO_HOFFST 0x1cbf
987#define ENCL_VIDEO_VOFFST 0x1cc0
988#define ENCL_VIDEO_RGB_CTRL 0x1cc1
989#define ENCL_VIDEO_FILT_CTRL 0x1cc2
990#define ENCL_VIDEO_OFLD_VPEQ_OFST 0x1cc3
991#define ENCL_VIDEO_OFLD_VOAV_OFST 0x1cc4
992#define ENCL_VIDEO_MATRIX_CB 0x1cc5
993#define ENCL_VIDEO_MATRIX_CR 0x1cc6
994#define ENCL_VIDEO_RGBIN_CTRL 0x1cc7
995#define ENCL_MAX_LINE_SWITCH_POINT 0x1cc8
996#define ENCL_DACSEL_0 0x1cc9
997#define ENCL_DACSEL_1 0x1cca
998#define RDMA_AHB_START_ADDR_MAN 0x1100
999#define RDMA_AHB_END_ADDR_MAN 0x1101
1000#define RDMA_AHB_START_ADDR_1 0x1102
1001#define RDMA_AHB_END_ADDR_1 0x1103
1002#define RDMA_AHB_START_ADDR_2 0x1104
1003#define RDMA_AHB_END_ADDR_2 0x1105
1004#define RDMA_AHB_START_ADDR_3 0x1106
1005#define RDMA_AHB_END_ADDR_3 0x1107
1006#define RDMA_AHB_START_ADDR_4 0x1108
1007#define RDMA_AHB_END_ADDR_4 0x1109
1008#define RDMA_AHB_START_ADDR_5 0x110a
1009#define RDMA_AHB_END_ADDR_5 0x110b
1010#define RDMA_AHB_START_ADDR_6 0x110c
1011#define RDMA_AHB_END_ADDR_6 0x110d
1012#define RDMA_AHB_START_ADDR_7 0x110e
1013#define RDMA_AHB_END_ADDR_7 0x110f
1014#define RDMA_ACCESS_AUTO 0x1110
1015#define RDMA_ACCESS_AUTO2 0x1111
1016#define RDMA_ACCESS_AUTO3 0x1112
1017#define RDMA_ACCESS_MAN 0x1113
1018#define RDMA_CTRL 0x1114
1019#define RDMA_STATUS 0x1115
1020#define RDMA_STATUS2 0x1116
1021#define RDMA_STATUS3 0x1117
1022#define L_GAMMA_CNTL_PORT 0x1400
1023#define L_GAMMA_DATA_PORT 0x1401
1024#define L_GAMMA_ADDR_PORT 0x1402
1025#define L_GAMMA_VCOM_HSWITCH_ADDR 0x1403
1026#define L_RGB_BASE_ADDR 0x1405
1027#define L_RGB_COEFF_ADDR 0x1406
1028#define L_POL_CNTL_ADDR 0x1407
1029#define L_DITH_CNTL_ADDR 0x1408
1030#define L_GAMMA_PROBE_CTRL 0x1409
1031#define L_GAMMA_PROBE_COLOR_L 0x140a
1032#define L_GAMMA_PROBE_COLOR_H 0x140b
1033#define L_GAMMA_PROBE_HL_COLOR 0x140c
1034#define L_GAMMA_PROBE_POS_X 0x140d
1035#define L_GAMMA_PROBE_POS_Y 0x140e
1036#define L_STH1_HS_ADDR 0x1410
1037#define L_STH1_HE_ADDR 0x1411
1038#define L_STH1_VS_ADDR 0x1412
1039#define L_STH1_VE_ADDR 0x1413
1040#define L_STH2_HS_ADDR 0x1414
1041#define L_STH2_HE_ADDR 0x1415
1042#define L_STH2_VS_ADDR 0x1416
1043#define L_STH2_VE_ADDR 0x1417
1044#define L_OEH_HS_ADDR 0x1418
1045#define L_OEH_HE_ADDR 0x1419
1046#define L_OEH_VS_ADDR 0x141a
1047#define L_OEH_VE_ADDR 0x141b
1048#define L_VCOM_HSWITCH_ADDR 0x141c
1049#define L_VCOM_VS_ADDR 0x141d
1050#define L_VCOM_VE_ADDR 0x141e
1051#define L_CPV1_HS_ADDR 0x141f
1052#define L_CPV1_HE_ADDR 0x1420
1053#define L_CPV1_VS_ADDR 0x1421
1054#define L_CPV1_VE_ADDR 0x1422
1055#define L_CPV2_HS_ADDR 0x1423
1056#define L_CPV2_HE_ADDR 0x1424
1057#define L_CPV2_VS_ADDR 0x1425
1058#define L_CPV2_VE_ADDR 0x1426
1059#define L_STV1_HS_ADDR 0x1427
1060#define L_STV1_HE_ADDR 0x1428
1061#define L_STV1_VS_ADDR 0x1429
1062#define L_STV1_VE_ADDR 0x142a
1063#define L_STV2_HS_ADDR 0x142b
1064#define L_STV2_HE_ADDR 0x142c
1065#define L_STV2_VS_ADDR 0x142d
1066#define L_STV2_VE_ADDR 0x142e
1067#define L_OEV1_HS_ADDR 0x142f
1068#define L_OEV1_HE_ADDR 0x1430
1069#define L_OEV1_VS_ADDR 0x1431
1070#define L_OEV1_VE_ADDR 0x1432
1071#define L_OEV2_HS_ADDR 0x1433
1072#define L_OEV2_HE_ADDR 0x1434
1073#define L_OEV2_VS_ADDR 0x1435
1074#define L_OEV2_VE_ADDR 0x1436
1075#define L_OEV3_HS_ADDR 0x1437
1076#define L_OEV3_HE_ADDR 0x1438
1077#define L_OEV3_VS_ADDR 0x1439
1078#define L_OEV3_VE_ADDR 0x143a
1079#define L_LCD_PWR_ADDR 0x143b
1080#define L_LCD_PWM0_LO_ADDR 0x143c
1081#define L_LCD_PWM0_HI_ADDR 0x143d
1082#define L_LCD_PWM1_LO_ADDR 0x143e
1083#define L_LCD_PWM1_HI_ADDR 0x143f
1084#define L_INV_CNT_ADDR 0x1440
1085#define L_TCON_MISC_SEL_ADDR 0x1441
1086#define L_DUAL_PORT_CNTL_ADDR 0x1442
1087#define MLVDS_CLK_CTL1_HI 0x1443
1088#define MLVDS_CLK_CTL1_LO 0x1444
1089#define L_TCON_DOUBLE_CTL 0x1449
1090#define L_TCON_PATTERN_HI 0x144a
1091#define L_TCON_PATTERN_LO 0x144b
1092#define LDIM_BL_ADDR_PORT 0x144e
1093#define LDIM_BL_DATA_PORT 0x144f
1094#define L_DE_HS_ADDR 0x1451
1095#define L_DE_HE_ADDR 0x1452
1096#define L_DE_VS_ADDR 0x1453
1097#define L_DE_VE_ADDR 0x1454
1098#define L_HSYNC_HS_ADDR 0x1455
1099#define L_HSYNC_HE_ADDR 0x1456
1100#define L_HSYNC_VS_ADDR 0x1457
1101#define L_HSYNC_VE_ADDR 0x1458
1102#define L_VSYNC_HS_ADDR 0x1459
1103#define L_VSYNC_HE_ADDR 0x145a
1104#define L_VSYNC_VS_ADDR 0x145b
1105#define L_VSYNC_VE_ADDR 0x145c
1106#define L_LCD_MCU_CTL 0x145d
1107#define DUAL_MLVDS_CTL 0x1460
1108#define DUAL_MLVDS_LINE_START 0x1461
1109#define DUAL_MLVDS_LINE_END 0x1462
1110#define DUAL_MLVDS_PIXEL_W_START_L 0x1463
1111#define DUAL_MLVDS_PIXEL_W_END_L 0x1464
1112#define DUAL_MLVDS_PIXEL_W_START_R 0x1465
1113#define DUAL_MLVDS_PIXEL_W_END_R 0x1466
1114#define DUAL_MLVDS_PIXEL_R_START_L 0x1467
1115#define DUAL_MLVDS_PIXEL_R_CNT_L 0x1468
1116#define DUAL_MLVDS_PIXEL_R_START_R 0x1469
1117#define DUAL_MLVDS_PIXEL_R_CNT_R 0x146a
1118#define V_INVERSION_PIXEL 0x1470
1119#define V_INVERSION_LINE 0x1471
1120#define V_INVERSION_CONTROL 0x1472
1121#define MLVDS2_CONTROL 0x1474
1122#define MLVDS2_CONFIG_HI 0x1475
1123#define MLVDS2_CONFIG_LO 0x1476
1124#define MLVDS2_DUAL_GATE_WR_START 0x1477
1125#define MLVDS2_DUAL_GATE_WR_END 0x1478
1126#define MLVDS2_DUAL_GATE_RD_START 0x1479
1127#define MLVDS2_DUAL_GATE_RD_END 0x147a
1128#define MLVDS2_SECOND_RESET_CTL 0x147b
1129#define MLVDS2_DUAL_GATE_CTL_HI 0x147c
1130#define MLVDS2_DUAL_GATE_CTL_LO 0x147d
1131#define MLVDS2_RESET_CONFIG_HI 0x147e
1132#define MLVDS2_RESET_CONFIG_LO 0x147f
1133#define GAMMA_CNTL_PORT 0x1480
1134#define GAMMA_DATA_PORT 0x1481
1135#define GAMMA_ADDR_PORT 0x1482
1136#define GAMMA_VCOM_HSWITCH_ADDR 0x1483
1137#define RGB_BASE_ADDR 0x1485
1138#define RGB_COEFF_ADDR 0x1486
1139#define POL_CNTL_ADDR 0x1487
1140#define DITH_CNTL_ADDR 0x1488
1141#define GAMMA_PROBE_CTRL 0x1489
1142#define GAMMA_PROBE_COLOR_L 0x148a
1143#define GAMMA_PROBE_COLOR_H 0x148b
1144#define GAMMA_PROBE_HL_COLOR 0x148c
1145#define GAMMA_PROBE_POS_X 0x148d
1146#define GAMMA_PROBE_POS_Y 0x148e
1147#define STH1_HS_ADDR 0x1490
1148#define STH1_HE_ADDR 0x1491
1149#define STH1_VS_ADDR 0x1492
1150#define STH1_VE_ADDR 0x1493
1151#define STH2_HS_ADDR 0x1494
1152#define STH2_HE_ADDR 0x1495
1153#define STH2_VS_ADDR 0x1496
1154#define STH2_VE_ADDR 0x1497
1155#define OEH_HS_ADDR 0x1498
1156#define OEH_HE_ADDR 0x1499
1157#define OEH_VS_ADDR 0x149a
1158#define OEH_VE_ADDR 0x149b
1159#define VCOM_HSWITCH_ADDR 0x149c
1160#define VCOM_VS_ADDR 0x149d
1161#define VCOM_VE_ADDR 0x149e
1162#define CPV1_HS_ADDR 0x149f
1163#define CPV1_HE_ADDR 0x14a0
1164#define CPV1_VS_ADDR 0x14a1
1165#define CPV1_VE_ADDR 0x14a2
1166#define CPV2_HS_ADDR 0x14a3
1167#define CPV2_HE_ADDR 0x14a4
1168#define CPV2_VS_ADDR 0x14a5
1169#define CPV2_VE_ADDR 0x14a6
1170#define STV1_HS_ADDR 0x14a7
1171#define STV1_HE_ADDR 0x14a8
1172#define STV1_VS_ADDR 0x14a9
1173#define STV1_VE_ADDR 0x14aa
1174#define STV2_HS_ADDR 0x14ab
1175#define STV2_HE_ADDR 0x14ac
1176#define STV2_VS_ADDR 0x14ad
1177#define STV2_VE_ADDR 0x14ae
1178#define OEV1_HS_ADDR 0x14af
1179#define OEV1_HE_ADDR 0x14b0
1180#define OEV1_VS_ADDR 0x14b1
1181#define OEV1_VE_ADDR 0x14b2
1182#define OEV2_HS_ADDR 0x14b3
1183#define OEV2_HE_ADDR 0x14b4
1184#define OEV2_VS_ADDR 0x14b5
1185#define OEV2_VE_ADDR 0x14b6
1186#define OEV3_HS_ADDR 0x14b7
1187#define OEV3_HE_ADDR 0x14b8
1188#define OEV3_VS_ADDR 0x14b9
1189#define OEV3_VE_ADDR 0x14ba
1190#define LCD_PWR_ADDR 0x14bb
1191#define LCD_PWM0_LO_ADDR 0x14bc
1192#define LCD_PWM0_HI_ADDR 0x14bd
1193#define LCD_PWM1_LO_ADDR 0x14be
1194#define LCD_PWM1_HI_ADDR 0x14bf
1195#define INV_CNT_ADDR 0x14c0
1196#define TCON_MISC_SEL_ADDR 0x14c1
1197#define DUAL_PORT_CNTL_ADDR 0x14c2
1198#define MLVDS_CONTROL 0x14c3
1199#define MLVDS_RESET_PATTERN_HI 0x14c4
1200#define MLVDS_RESET_PATTERN_LO 0x14c5
1201#define MLVDS_RESET_PATTERN_EXT 0x14c6
1202#define MLVDS_CONFIG_HI 0x14c7
1203#define MLVDS_CONFIG_LO 0x14c8
1204#define TCON_DOUBLE_CTL 0x14c9
1205#define TCON_PATTERN_HI 0x14ca
1206#define TCON_PATTERN_LO 0x14cb
1207#define TCON_CONTROL_HI 0x14cc
1208#define TCON_CONTROL_LO 0x14cd
1209#define LVDS_BLANK_DATA_HI 0x14ce
1210#define LVDS_BLANK_DATA_LO 0x14cf
1211#define LVDS_PACK_CNTL_ADDR 0x14d0
1212#define DE_HS_ADDR 0x14d1
1213#define DE_HE_ADDR 0x14d2
1214#define DE_VS_ADDR 0x14d3
1215#define DE_VE_ADDR 0x14d4
1216#define HSYNC_HS_ADDR 0x14d5
1217#define HSYNC_HE_ADDR 0x14d6
1218#define HSYNC_VS_ADDR 0x14d7
1219#define HSYNC_VE_ADDR 0x14d8
1220#define VSYNC_HS_ADDR 0x14d9
1221#define VSYNC_HE_ADDR 0x14da
1222#define VSYNC_VS_ADDR 0x14db
1223#define VSYNC_VE_ADDR 0x14dc
1224#define LCD_MCU_CTL 0x14dd
1225#define LCD_MCU_DATA_0 0x14de
1226#define LCD_MCU_DATA_1 0x14df
1227#define LVDS_GEN_CNTL 0x14e0
1228#define LVDS_PHY_CNTL0 0x14e1
1229#define LVDS_PHY_CNTL1 0x14e2
1230#define LVDS_PHY_CNTL2 0x14e3
1231#define LVDS_PHY_CNTL3 0x14e4
1232#define LVDS_PHY_CNTL4 0x14e5
1233#define LVDS_PHY_CNTL5 0x14e6
1234#define LVDS_SRG_TEST 0x14e8
1235#define LVDS_BIST_MUX0 0x14e9
1236#define LVDS_BIST_MUX1 0x14ea
1237#define LVDS_BIST_FIXED0 0x14eb
1238#define LVDS_BIST_FIXED1 0x14ec
1239#define LVDS_BIST_CNTL0 0x14ed
1240#define LVDS_CLKB_CLKA 0x14ee
1241#define LVDS_PHY_CLK_CNTL 0x14ef
1242#define LVDS_SER_EN 0x14f0
1243#define LVDS_PHY_CNTL6 0x14f1
1244#define LVDS_PHY_CNTL7 0x14f2
1245#define LVDS_PHY_CNTL8 0x14f3
1246#define MLVDS_CLK_CTL0_HI 0x14f4
1247#define MLVDS_CLK_CTL0_LO 0x14f5
1248#define MLVDS_DUAL_GATE_WR_START 0x14f6
1249#define MLVDS_DUAL_GATE_WR_END 0x14f7
1250#define MLVDS_DUAL_GATE_RD_START 0x14f8
1251#define MLVDS_DUAL_GATE_RD_END 0x14f9
1252#define MLVDS_SECOND_RESET_CTL 0x14fa
1253#define MLVDS_DUAL_GATE_CTL_HI 0x14fb
1254#define MLVDS_DUAL_GATE_CTL_LO 0x14fc
1255#define MLVDS_RESET_CONFIG_HI 0x14fd
1256#define MLVDS_RESET_CONFIG_LO 0x14fe
1257#define VPU_OSD1_MMC_CTRL 0x2701
1258#define VPU_OSD2_MMC_CTRL 0x2702
1259#define VPU_VD1_MMC_CTRL 0x2703
1260#define VPU_VD2_MMC_CTRL 0x2704
1261#define VPU_DI_IF1_MMC_CTRL 0x2705
1262#define VPU_DI_MEM_MMC_CTRL 0x2706
1263#define VPU_DI_INP_MMC_CTRL 0x2707
1264#define VPU_DI_MTNRD_MMC_CTRL 0x2708
1265#define VPU_DI_CHAN2_MMC_CTRL 0x2709
1266#define VPU_DI_MTNWR_MMC_CTRL 0x270a
1267#define VPU_DI_NRWR_MMC_CTRL 0x270b
1268#define VPU_DI_DIWR_MMC_CTRL 0x270c
1269#define VPU_VDIN0_MMC_CTRL 0x270d
1270#define VPU_VDIN1_MMC_CTRL 0x270e
1271#define VPU_BT656_MMC_CTRL 0x270f
1272#define VPU_TVD3D_MMC_CTRL 0x2710
1273#define VPU_TVDVBI_MMC_CTRL 0x2711
1274#define VPU_TVDVBI_VSLATCH_ADDR 0x2712
1275#define VPU_TVDVBI_WRRSP_ADDR 0x2713
1276#define VPU_VDIN_PRE_ARB_CTRL 0x2714
1277#define VPU_VDISP_PRE_ARB_CTRL 0x2715
1278#define VPU_VPUARB2_PRE_ARB_CTRL 0x2716
1279#define VPU_OSD3_MMC_CTRL 0x2717
1280#define VPU_OSD4_MMC_CTRL 0x2718
1281#define VPU_VD3_MMC_CTRL 0x2719
1282#define VPU_VIU_VENC_MUX_CTRL 0x271a
1283#define VIU1_SEL_VENC_MASK 0x3
1284#define VIU1_SEL_VENC_ENCL 0
1285#define VIU1_SEL_VENC_ENCI 1
1286#define VIU1_SEL_VENC_ENCP 2
1287#define VIU1_SEL_VENC_ENCT 3
1288#define VIU2_SEL_VENC_MASK 0xc
1289#define VIU2_SEL_VENC_ENCL 0
1290#define VIU2_SEL_VENC_ENCI (1 << 2)
1291#define VIU2_SEL_VENC_ENCP (2 << 2)
1292#define VIU2_SEL_VENC_ENCT (3 << 2)
1293#define VPU_HDMI_SETTING 0x271b
1294#define ENCI_INFO_READ 0x271c
1295#define ENCP_INFO_READ 0x271d
1296#define ENCT_INFO_READ 0x271e
1297#define ENCL_INFO_READ 0x271f
1298#define VPU_SW_RESET 0x2720
1299#define VPU_D2D3_MMC_CTRL 0x2721
1300#define VPU_CONT_MMC_CTRL 0x2722
1301#define VPU_CLK_GATE 0x2723
1302#define VPU_RDMA_MMC_CTRL 0x2724
1303#define VPU_MEM_PD_REG0 0x2725
1304#define VPU_MEM_PD_REG1 0x2726
1305#define VPU_HDMI_DATA_OVR 0x2727
1306#define VPU_PROT1_MMC_CTRL 0x2728
1307#define VPU_PROT2_MMC_CTRL 0x2729
1308#define VPU_PROT3_MMC_CTRL 0x272a
1309#define VPU_ARB4_V1_MMC_CTRL 0x272b
1310#define VPU_ARB4_V2_MMC_CTRL 0x272c
1311#define VPU_VPU_PWM_V0 0x2730
1312#define VPU_VPU_PWM_V1 0x2731
1313#define VPU_VPU_PWM_V2 0x2732
1314#define VPU_VPU_PWM_V3 0x2733
1315#define VPU_VPU_PWM_H0 0x2734
1316#define VPU_VPU_PWM_H1 0x2735
1317#define VPU_VPU_PWM_H2 0x2736
1318#define VPU_VPU_PWM_H3 0x2737
1319#define VPU_MISC_CTRL 0x2740
1320#define VPU_ISP_GCLK_CTRL0 0x2741
1321#define VPU_ISP_GCLK_CTRL1 0x2742
1322#define VPU_VDIN_ASYNC_HOLD_CTRL 0x2743
1323#define VPU_VDISP_ASYNC_HOLD_CTRL 0x2744
1324#define VPU_VPUARB2_ASYNC_HOLD_CTRL 0x2745
1325
1326#define VPU_PROT1_CLK_GATE 0x2750
1327#define VPU_PROT1_GEN_CNTL 0x2751
1328#define VPU_PROT1_X_START_END 0x2752
1329#define VPU_PROT1_Y_START_END 0x2753
1330#define VPU_PROT1_Y_LEN_STEP 0x2754
1331#define VPU_PROT1_RPT_LOOP 0x2755
1332#define VPU_PROT1_RPT_PAT 0x2756
1333#define VPU_PROT1_DDR 0x2757
1334#define VPU_PROT1_RBUF_ROOM 0x2758
1335#define VPU_PROT1_STAT_0 0x2759
1336#define VPU_PROT1_STAT_1 0x275a
1337#define VPU_PROT1_STAT_2 0x275b
1338#define VPU_PROT1_REQ_ONOFF 0x275c
1339#define VPU_PROT2_CLK_GATE 0x2760
1340#define VPU_PROT2_GEN_CNTL 0x2761
1341#define VPU_PROT2_X_START_END 0x2762
1342#define VPU_PROT2_Y_START_END 0x2763
1343#define VPU_PROT2_Y_LEN_STEP 0x2764
1344#define VPU_PROT2_RPT_LOOP 0x2765
1345#define VPU_PROT2_RPT_PAT 0x2766
1346#define VPU_PROT2_DDR 0x2767
1347#define VPU_PROT2_RBUF_ROOM 0x2768
1348#define VPU_PROT2_STAT_0 0x2769
1349#define VPU_PROT2_STAT_1 0x276a
1350#define VPU_PROT2_STAT_2 0x276b
1351#define VPU_PROT2_REQ_ONOFF 0x276c
1352#define VPU_PROT3_CLK_GATE 0x2770
1353#define VPU_PROT3_GEN_CNTL 0x2771
1354#define VPU_PROT3_X_START_END 0x2772
1355#define VPU_PROT3_Y_START_END 0x2773
1356#define VPU_PROT3_Y_LEN_STEP 0x2774
1357#define VPU_PROT3_RPT_LOOP 0x2775
1358#define VPU_PROT3_RPT_PAT 0x2776
1359#define VPU_PROT3_DDR 0x2777
1360#define VPU_PROT3_RBUF_ROOM 0x2778
1361#define VPU_PROT3_STAT_0 0x2779
1362#define VPU_PROT3_STAT_1 0x277a
1363#define VPU_PROT3_STAT_2 0x277b
1364#define VPU_PROT3_REQ_ONOFF 0x277c
1365
1366/* osd super scale */
1367#define OSDSR_HV_SIZEIN 0x3130
1368#define OSDSR_CTRL_MODE 0x3131
1369#define OSDSR_ABIC_HCOEF 0x3132
1370#define OSDSR_YBIC_HCOEF 0x3133
1371#define OSDSR_CBIC_HCOEF 0x3134
1372#define OSDSR_ABIC_VCOEF 0x3135
1373#define OSDSR_YBIC_VCOEF 0x3136
1374#define OSDSR_CBIC_VCOEF 0x3137
1375#define OSDSR_VAR_PARA 0x3138
1376#define OSDSR_CONST_PARA 0x3139
1377#define OSDSR_RKE_EXTWIN 0x313a
1378#define OSDSR_UK_GRAD2DDIAG_TH_RATE 0x313b
1379#define OSDSR_UK_GRAD2DDIAG_LIMIT 0x313c
1380#define OSDSR_UK_GRAD2DADJA_TH_RATE 0x313d
1381#define OSDSR_UK_GRAD2DADJA_LIMIT 0x313e
1382#define OSDSR_UK_BST_GAIN 0x313f
1383#define OSDSR_HVBLEND_TH 0x3140
1384#define OSDSR_DEMO_WIND_TB 0x3141
1385#define OSDSR_DEMO_WIND_LR 0x3142
1386#define OSDSR_INT_BLANK_NUM 0x3143
1387#define OSDSR_FRM_END_STAT 0x3144
1388#define OSDSR_ABIC_HCOEF0 0x3145
1389#define OSDSR_YBIC_HCOEF0 0x3146
1390#define OSDSR_CBIC_HCOEF0 0x3147
1391#define OSDSR_ABIC_VCOEF0 0x3148
1392#define OSDSR_YBIC_VCOEF0 0x3149
1393#define OSDSR_CBIC_VCOEF0 0x314a
1394
1395#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 000000000000..252cfd4b19b1
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -0,0 +1,167 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <drm/drmP.h>
23#include "meson_drv.h"
24#include "meson_vclk.h"
25
26/*
27 * VCLK is the "Pixel Clock" frequency generator from a dedicated PLL.
28 * We handle the following encodings :
29 * - CVBS 27MHz generator via the VCLK2 to the VENCI and VDAC blocks
30 *
31 * What is missing :
32 * - HDMI Pixel Clocks generation
33 */
34
35/* HHI Registers */
36#define HHI_VID_PLL_CLK_DIV 0x1a0 /* 0x68 offset in data sheet */
37#define VID_PLL_EN BIT(19)
38#define VID_PLL_BYPASS BIT(18)
39#define VID_PLL_PRESET BIT(15)
40#define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */
41#define VCLK2_DIV_MASK 0xff
42#define VCLK2_DIV_EN BIT(16)
43#define VCLK2_DIV_RESET BIT(17)
44#define CTS_VDAC_SEL_MASK (0xf << 28)
45#define CTS_VDAC_SEL_SHIFT 28
46#define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */
47#define VCLK2_EN BIT(19)
48#define VCLK2_SEL_MASK (0x7 << 16)
49#define VCLK2_SEL_SHIFT 16
50#define VCLK2_SOFT_RESET BIT(15)
51#define VCLK2_DIV1_EN BIT(0)
52#define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */
53#define CTS_ENCI_SEL_MASK (0xf << 28)
54#define CTS_ENCI_SEL_SHIFT 28
55#define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */
56#define CTS_ENCI_EN BIT(0)
57#define CTS_VDAC_EN BIT(4)
58
59#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
60#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
61
62#define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
63#define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */
64#define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in data sheet */
65#define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in data sheet */
66#define HHI_HDMI_PLL_CNTL5 0x330 /* 0xcc offset in data sheet */
67#define HHI_HDMI_PLL_CNTL6 0x334 /* 0xcd offset in data sheet */
68
69#define HDMI_PLL_RESET BIT(28)
70#define HDMI_PLL_LOCK BIT(31)
71
72/*
73 * Setup VCLK2 for 27MHz, and enable clocks for ENCI and VDAC
74 *
75 * TOFIX: Refactor into table to also handle HDMI frequency and paths
76 */
77static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
78{
79 unsigned int val;
80
81 /* Setup PLL to output 1.485GHz */
82 if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
83 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d);
84 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00404e00);
85 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
86 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
87 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
88 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
89 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4800023d);
90 } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
91 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
92 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b);
93 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300);
94 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0xa6212844);
95 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c4d000c);
96 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
97 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
98
99 /* Reset PLL */
100 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
101 HDMI_PLL_RESET, HDMI_PLL_RESET);
102 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
103 HDMI_PLL_RESET, 0);
104 }
105
106 /* Poll for lock bit */
107 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
108 (val & HDMI_PLL_LOCK), 10, 0);
109
110 /* Disable VCLK2 */
111 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
112
113 /* Disable vid_pll output clock */
114 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0);
115 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0);
116 /* Enable vid_pll bypass to HDMI pll */
117 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
118 VID_PLL_BYPASS, VID_PLL_BYPASS);
119 /* Enable the vid_pll output clock */
120 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
121 VID_PLL_EN, VID_PLL_EN);
122
123 /* Setup the VCLK2 divider value to achieve 27MHz */
124 regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
125 VCLK2_DIV_MASK, (55 - 1));
126
127 /* select vid_pll for vclk2 */
128 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
129 VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT));
130 /* enable vclk2 gate */
131 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
132
133 /* select vclk_div1 for enci */
134 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
135 CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT));
136 /* select vclk_div1 for vdac */
137 regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
138 CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT));
139
140 /* release vclk2_div_reset and enable vclk2_div */
141 regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
142 VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
143
144 /* enable vclk2_div1 gate */
145 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
146 VCLK2_DIV1_EN, VCLK2_DIV1_EN);
147
148 /* reset vclk2 */
149 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
150 VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
151 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
152 VCLK2_SOFT_RESET, 0);
153
154 /* enable enci_clk */
155 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
156 CTS_ENCI_EN, CTS_ENCI_EN);
157 /* enable vdac_clk */
158 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
159 CTS_VDAC_EN, CTS_VDAC_EN);
160}
161
162void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
163 unsigned int freq)
164{
165 if (target == MESON_VCLK_TARGET_CVBS && freq == MESON_VCLK_CVBS)
166 meson_venci_cvbs_clock_config(priv);
167}
diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h
new file mode 100644
index 000000000000..ec62735996de
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_vclk.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* Video Clock */
20
21#ifndef __MESON_VCLK_H
22#define __MESON_VCLK_H
23
24enum {
25 MESON_VCLK_TARGET_CVBS = 0,
26};
27
28/* 27MHz is the CVBS Pixel Clock */
29#define MESON_VCLK_CVBS 27000
30
31void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
32 unsigned int freq);
33
34#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 000000000000..d836b2274531
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -0,0 +1,254 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <drm/drmP.h>
23#include "meson_drv.h"
24#include "meson_venc.h"
25#include "meson_vpp.h"
26#include "meson_vclk.h"
27#include "meson_registers.h"
28
29/*
30 * VENC Handle the pixels encoding to the output formats.
31 * We handle the following encodings :
32 * - CVBS Encoding via the ENCI encoder and VDAC digital to analog converter
33 *
34 * What is missing :
35 * - TMDS/HDMI Encoding via ENCI_DIV and ENCP
36 * - Setup of more clock rates for HDMI modes
37 * - LCD Panel encoding via ENCL
38 * - TV Panel encoding via ENCT
39 */
40
41struct meson_cvbs_enci_mode meson_cvbs_enci_pal = {
42 .mode_tag = MESON_VENC_MODE_CVBS_PAL,
43 .hso_begin = 3,
44 .hso_end = 129,
45 .vso_even = 3,
46 .vso_odd = 260,
47 .macv_max_amp = 7,
48 .video_prog_mode = 0xff,
49 .video_mode = 0x13,
50 .sch_adjust = 0x28,
51 .yc_delay = 0x343,
52 .pixel_start = 251,
53 .pixel_end = 1691,
54 .top_field_line_start = 22,
55 .top_field_line_end = 310,
56 .bottom_field_line_start = 23,
57 .bottom_field_line_end = 311,
58 .video_saturation = 9,
59 .video_contrast = 0,
60 .video_brightness = 0,
61 .video_hue = 0,
62 .analog_sync_adj = 0x8080,
63};
64
65struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = {
66 .mode_tag = MESON_VENC_MODE_CVBS_NTSC,
67 .hso_begin = 5,
68 .hso_end = 129,
69 .vso_even = 3,
70 .vso_odd = 260,
71 .macv_max_amp = 0xb,
72 .video_prog_mode = 0xf0,
73 .video_mode = 0x8,
74 .sch_adjust = 0x20,
75 .yc_delay = 0x333,
76 .pixel_start = 227,
77 .pixel_end = 1667,
78 .top_field_line_start = 18,
79 .top_field_line_end = 258,
80 .bottom_field_line_start = 19,
81 .bottom_field_line_end = 259,
82 .video_saturation = 18,
83 .video_contrast = 3,
84 .video_brightness = 0,
85 .video_hue = 0,
86 .analog_sync_adj = 0x9c00,
87};
88
89void meson_venci_cvbs_mode_set(struct meson_drm *priv,
90 struct meson_cvbs_enci_mode *mode)
91{
92 if (mode->mode_tag == priv->venc.current_mode)
93 return;
94
95 /* CVBS Filter settings */
96 writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL));
97 writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2));
98
99 /* Digital Video Select : Interlace, clk27 clk, external */
100 writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
101
102 /* Reset Video Mode */
103 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE));
104 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
105
106 /* Horizontal sync signal output */
107 writel_relaxed(mode->hso_begin,
108 priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN));
109 writel_relaxed(mode->hso_end,
110 priv->io_base + _REG(ENCI_SYNC_HSO_END));
111
112 /* Vertical Sync lines */
113 writel_relaxed(mode->vso_even,
114 priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN));
115 writel_relaxed(mode->vso_odd,
116 priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
117
118 /* Macrovision max amplitude change */
119 writel_relaxed(0x8100 + mode->macv_max_amp,
120 priv->io_base + _REG(ENCI_MACV_MAX_AMP));
121
122 /* Video mode */
123 writel_relaxed(mode->video_prog_mode,
124 priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
125 writel_relaxed(mode->video_mode,
126 priv->io_base + _REG(ENCI_VIDEO_MODE));
127
128 /* Advanced Video Mode :
129 * Demux shifting 0x2
130 * Blank line end at line17/22
131 * High bandwidth Luma Filter
132 * Low bandwidth Chroma Filter
133 * Bypass luma low pass filter
134 * No macrovision on CSYNC
135 */
136 writel_relaxed(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
137
138 writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH));
139
140 /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
141 writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE));
142
143 /* 0x3 Y, C, and Component Y delay */
144 writel_relaxed(mode->yc_delay, priv->io_base + _REG(ENCI_YC_DELAY));
145
146 /* Timings */
147 writel_relaxed(mode->pixel_start,
148 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START));
149 writel_relaxed(mode->pixel_end,
150 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END));
151
152 writel_relaxed(mode->top_field_line_start,
153 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START));
154 writel_relaxed(mode->top_field_line_end,
155 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END));
156
157 writel_relaxed(mode->bottom_field_line_start,
158 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START));
159 writel_relaxed(mode->bottom_field_line_end,
160 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END));
161
162 /* Internal Venc, Internal VIU Sync, Internal Vencoder */
163 writel_relaxed(0, priv->io_base + _REG(VENC_SYNC_ROUTE));
164
165 /* UNreset Interlaced TV Encoder */
166 writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
167
168 /* Enable Vfifo2vd, Y_Cb_Y_Cr select */
169 writel_relaxed(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
170
171 /* Power UP Dacs */
172 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_SETTING));
173
174 /* Video Upsampling */
175 writel_relaxed(0x0061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL0));
176 writel_relaxed(0x4061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL1));
177 writel_relaxed(0x5061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL2));
178
179 /* Select Interlace Y DACs */
180 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL0));
181 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL1));
182 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL2));
183 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL3));
184 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL4));
185 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL5));
186
187 /* Select ENCI for VIU */
188 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
189
190 /* Enable ENCI FIFO */
191 writel_relaxed(0x2000, priv->io_base + _REG(VENC_VDAC_FIFO_CTRL));
192
193 /* Select ENCI DACs 0, 1, 4, and 5 */
194 writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_0));
195 writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_1));
196
197 /* Interlace video enable */
198 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN));
199
200 /* Configure Video Saturation / Contrast / Brightness / Hue */
201 writel_relaxed(mode->video_saturation,
202 priv->io_base + _REG(ENCI_VIDEO_SAT));
203 writel_relaxed(mode->video_contrast,
204 priv->io_base + _REG(ENCI_VIDEO_CONT));
205 writel_relaxed(mode->video_brightness,
206 priv->io_base + _REG(ENCI_VIDEO_BRIGHT));
207 writel_relaxed(mode->video_hue,
208 priv->io_base + _REG(ENCI_VIDEO_HUE));
209
210 /* Enable DAC0 Filter */
211 writel_relaxed(0x1, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0));
212 writel_relaxed(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1));
213
214 /* 0 in Macrovision register 0 */
215 writel_relaxed(0, priv->io_base + _REG(ENCI_MACV_N0));
216
217 /* Analog Synchronization and color burst value adjust */
218 writel_relaxed(mode->analog_sync_adj,
219 priv->io_base + _REG(ENCI_SYNC_ADJ));
220
221 /* Setup 27MHz vclk2 for ENCI and VDAC */
222 meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, MESON_VCLK_CVBS);
223
224 priv->venc.current_mode = mode->mode_tag;
225}
226
227/* Returns the current ENCI field polarity */
228unsigned int meson_venci_get_field(struct meson_drm *priv)
229{
230 return readl_relaxed(priv->io_base + _REG(ENCI_INFO_READ)) & BIT(29);
231}
232
233void meson_venc_enable_vsync(struct meson_drm *priv)
234{
235 writel_relaxed(2, priv->io_base + _REG(VENC_INTCTRL));
236}
237
238void meson_venc_disable_vsync(struct meson_drm *priv)
239{
240 writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL));
241}
242
243void meson_venc_init(struct meson_drm *priv)
244{
245 /* Disable all encoders */
246 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
247 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
248 writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
249
250 /* Disable VSync IRQ */
251 meson_venc_disable_vsync(priv);
252
253 priv->venc.current_mode = MESON_VENC_MODE_NONE;
254}
diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h
new file mode 100644
index 000000000000..77d4a7d82c44
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_venc.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * Video Encoders
21 * - ENCI : Interlace Video Encoder
22 * - ENCI_DVI : Interlace Video Encoder for DVI/HDMI
23 * - ENCP : Progressive Video Encoder
24 */
25
26#ifndef __MESON_VENC_H
27#define __MESON_VENC_H
28
29enum {
30 MESON_VENC_MODE_NONE = 0,
31 MESON_VENC_MODE_CVBS_PAL,
32 MESON_VENC_MODE_CVBS_NTSC,
33};
34
35struct meson_cvbs_enci_mode {
36 unsigned int mode_tag;
37 unsigned int hso_begin; /* HSO begin position */
38 unsigned int hso_end; /* HSO end position */
39 unsigned int vso_even; /* VSO even line */
40 unsigned int vso_odd; /* VSO odd line */
41 unsigned int macv_max_amp; /* Macrovision max amplitude */
42 unsigned int video_prog_mode;
43 unsigned int video_mode;
44 unsigned int sch_adjust;
45 unsigned int yc_delay;
46 unsigned int pixel_start;
47 unsigned int pixel_end;
48 unsigned int top_field_line_start;
49 unsigned int top_field_line_end;
50 unsigned int bottom_field_line_start;
51 unsigned int bottom_field_line_end;
52 unsigned int video_saturation;
53 unsigned int video_contrast;
54 unsigned int video_brightness;
55 unsigned int video_hue;
56 unsigned int analog_sync_adj;
57};
58
59/* CVBS Timings and Parameters */
60extern struct meson_cvbs_enci_mode meson_cvbs_enci_pal;
61extern struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc;
62
63void meson_venci_cvbs_mode_set(struct meson_drm *priv,
64 struct meson_cvbs_enci_mode *mode);
65unsigned int meson_venci_get_field(struct meson_drm *priv);
66
67void meson_venc_enable_vsync(struct meson_drm *priv);
68void meson_venc_disable_vsync(struct meson_drm *priv);
69
70void meson_venc_init(struct meson_drm *priv);
71
72#endif /* __MESON_VENC_H */
diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_venc_cvbs.c
new file mode 100644
index 000000000000..c809c085fd78
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_venc_cvbs.c
@@ -0,0 +1,293 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5 * Copyright (C) 2014 Endless Mobile
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 * Written by:
21 * Jasper St. Pierre <jstpierre@mecheye.net>
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/of_graph.h>
27
28#include <drm/drmP.h>
29#include <drm/drm_edid.h>
30#include <drm/drm_crtc_helper.h>
31#include <drm/drm_atomic_helper.h>
32
33#include "meson_venc_cvbs.h"
34#include "meson_venc.h"
35#include "meson_registers.h"
36
37/* HHI VDAC Registers */
38#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
39#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
40
41struct meson_venc_cvbs {
42 struct drm_encoder encoder;
43 struct drm_connector connector;
44 struct meson_drm *priv;
45};
46#define encoder_to_meson_venc_cvbs(x) \
47 container_of(x, struct meson_venc_cvbs, encoder)
48
49#define connector_to_meson_venc_cvbs(x) \
50 container_of(x, struct meson_venc_cvbs, connector)
51
52/* Supported Modes */
53
54struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT] = {
55 { /* PAL */
56 .enci = &meson_cvbs_enci_pal,
57 .mode = {
58 DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
59 720, 732, 795, 864, 0, 576, 580, 586, 625, 0,
60 DRM_MODE_FLAG_INTERLACE),
61 .vrefresh = 50,
62 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
63 },
64 },
65 { /* NTSC */
66 .enci = &meson_cvbs_enci_ntsc,
67 .mode = {
68 DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
69 720, 739, 801, 858, 0, 480, 488, 494, 525, 0,
70 DRM_MODE_FLAG_INTERLACE),
71 .vrefresh = 60,
72 .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
73 },
74 },
75};
76
77/* Connector */
78
79static void meson_cvbs_connector_destroy(struct drm_connector *connector)
80{
81 drm_connector_cleanup(connector);
82}
83
84static enum drm_connector_status
85meson_cvbs_connector_detect(struct drm_connector *connector, bool force)
86{
87 /* FIXME: Add load-detect or jack-detect if possible */
88 return connector_status_connected;
89}
90
91static int meson_cvbs_connector_get_modes(struct drm_connector *connector)
92{
93 struct drm_device *dev = connector->dev;
94 struct drm_display_mode *mode;
95 int i;
96
97 for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
98 struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
99
100 mode = drm_mode_duplicate(dev, &meson_mode->mode);
101 if (!mode) {
102 DRM_ERROR("Failed to create a new display mode\n");
103 return 0;
104 }
105
106 drm_mode_probed_add(connector, mode);
107 }
108
109 return i;
110}
111
112static int meson_cvbs_connector_mode_valid(struct drm_connector *connector,
113 struct drm_display_mode *mode)
114{
115 /* Validate the modes added in get_modes */
116 return MODE_OK;
117}
118
119static const struct drm_connector_funcs meson_cvbs_connector_funcs = {
120 .dpms = drm_atomic_helper_connector_dpms,
121 .detect = meson_cvbs_connector_detect,
122 .fill_modes = drm_helper_probe_single_connector_modes,
123 .destroy = meson_cvbs_connector_destroy,
124 .reset = drm_atomic_helper_connector_reset,
125 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
126 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
127};
128
129static const
130struct drm_connector_helper_funcs meson_cvbs_connector_helper_funcs = {
131 .get_modes = meson_cvbs_connector_get_modes,
132 .mode_valid = meson_cvbs_connector_mode_valid,
133};
134
135/* Encoder */
136
137static void meson_venc_cvbs_encoder_destroy(struct drm_encoder *encoder)
138{
139 drm_encoder_cleanup(encoder);
140}
141
142static const struct drm_encoder_funcs meson_venc_cvbs_encoder_funcs = {
143 .destroy = meson_venc_cvbs_encoder_destroy,
144};
145
146static int meson_venc_cvbs_encoder_atomic_check(struct drm_encoder *encoder,
147 struct drm_crtc_state *crtc_state,
148 struct drm_connector_state *conn_state)
149{
150 int i;
151
152 for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
153 struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
154
155 if (drm_mode_equal(&crtc_state->mode, &meson_mode->mode))
156 return 0;
157 }
158
159 return -EINVAL;
160}
161
162static void meson_venc_cvbs_encoder_disable(struct drm_encoder *encoder)
163{
164 struct meson_venc_cvbs *meson_venc_cvbs =
165 encoder_to_meson_venc_cvbs(encoder);
166 struct meson_drm *priv = meson_venc_cvbs->priv;
167
168 /* Disable CVBS VDAC */
169 regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0);
170 regmap_write(priv->hhi, HHI_VDAC_CNTL1, 0);
171}
172
173static void meson_venc_cvbs_encoder_enable(struct drm_encoder *encoder)
174{
175 struct meson_venc_cvbs *meson_venc_cvbs =
176 encoder_to_meson_venc_cvbs(encoder);
177 struct meson_drm *priv = meson_venc_cvbs->priv;
178
179 /* VDAC0 source is not from ATV */
180 writel_bits_relaxed(BIT(5), 0, priv->io_base + _REG(VENC_VDAC_DACSEL0));
181
182 if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
183 regmap_write(priv->hhi, HHI_VDAC_CNTL0, 1);
184 else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
185 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
186 regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0xf0001);
187
188 regmap_write(priv->hhi, HHI_VDAC_CNTL1, 0);
189}
190
191static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder,
192 struct drm_display_mode *mode,
193 struct drm_display_mode *adjusted_mode)
194{
195 struct meson_venc_cvbs *meson_venc_cvbs =
196 encoder_to_meson_venc_cvbs(encoder);
197 int i;
198
199 for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
200 struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
201
202 if (drm_mode_equal(mode, &meson_mode->mode)) {
203 meson_venci_cvbs_mode_set(meson_venc_cvbs->priv,
204 meson_mode->enci);
205 break;
206 }
207 }
208}
209
210static const struct drm_encoder_helper_funcs
211 meson_venc_cvbs_encoder_helper_funcs = {
212 .atomic_check = meson_venc_cvbs_encoder_atomic_check,
213 .disable = meson_venc_cvbs_encoder_disable,
214 .enable = meson_venc_cvbs_encoder_enable,
215 .mode_set = meson_venc_cvbs_encoder_mode_set,
216};
217
218static bool meson_venc_cvbs_connector_is_available(struct meson_drm *priv)
219{
220 struct device_node *ep, *remote;
221
222 /* CVBS VDAC output is on the first port, first endpoint */
223 ep = of_graph_get_endpoint_by_regs(priv->dev->of_node, 0, 0);
224 if (!ep)
225 return false;
226
227
228 /* If the endpoint node exists, consider it enabled */
229 remote = of_graph_get_remote_port(ep);
230 if (remote) {
231 of_node_put(ep);
232 return true;
233 }
234
235 of_node_put(ep);
236 of_node_put(remote);
237
238 return false;
239}
240
241int meson_venc_cvbs_create(struct meson_drm *priv)
242{
243 struct drm_device *drm = priv->drm;
244 struct meson_venc_cvbs *meson_venc_cvbs;
245 struct drm_connector *connector;
246 struct drm_encoder *encoder;
247 int ret;
248
249 if (!meson_venc_cvbs_connector_is_available(priv)) {
250 dev_info(drm->dev, "CVBS Output connector not available\n");
251 return -ENODEV;
252 }
253
254 meson_venc_cvbs = devm_kzalloc(priv->dev, sizeof(*meson_venc_cvbs),
255 GFP_KERNEL);
256 if (!meson_venc_cvbs)
257 return -ENOMEM;
258
259 meson_venc_cvbs->priv = priv;
260 encoder = &meson_venc_cvbs->encoder;
261 connector = &meson_venc_cvbs->connector;
262
263 /* Connector */
264
265 drm_connector_helper_add(connector,
266 &meson_cvbs_connector_helper_funcs);
267
268 ret = drm_connector_init(drm, connector, &meson_cvbs_connector_funcs,
269 DRM_MODE_CONNECTOR_Composite);
270 if (ret) {
271 dev_err(priv->dev, "Failed to init CVBS connector\n");
272 return ret;
273 }
274
275 connector->interlace_allowed = 1;
276
277 /* Encoder */
278
279 drm_encoder_helper_add(encoder, &meson_venc_cvbs_encoder_helper_funcs);
280
281 ret = drm_encoder_init(drm, encoder, &meson_venc_cvbs_encoder_funcs,
282 DRM_MODE_ENCODER_TVDAC, "meson_venc_cvbs");
283 if (ret) {
284 dev_err(priv->dev, "Failed to init CVBS encoder\n");
285 return ret;
286 }
287
288 encoder->possible_crtcs = BIT(0);
289
290 drm_mode_connector_attach_encoder(connector, encoder);
291
292 return 0;
293}
diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.h b/drivers/gpu/drm/meson/meson_venc_cvbs.h
new file mode 100644
index 000000000000..9256ccf9d931
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_venc_cvbs.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2014 Endless Mobile
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 *
19 * Written by:
20 * Jasper St. Pierre <jstpierre@mecheye.net>
21 */
22
23#ifndef __MESON_VENC_CVBS_H
24#define __MESON_VENC_CVBS_H
25
26#include "meson_drv.h"
27#include "meson_venc.h"
28
29struct meson_cvbs_mode {
30 struct meson_cvbs_enci_mode *enci;
31 struct drm_display_mode mode;
32};
33
34#define MESON_CVBS_MODES_COUNT 2
35
36/* Modes supported by the CVBS output */
37extern struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT];
38
39int meson_venc_cvbs_create(struct meson_drm *priv);
40
41#endif /* __MESON_VENC_CVBS_H */
diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
new file mode 100644
index 000000000000..a6de8ba7af19
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -0,0 +1,331 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5 * Copyright (C) 2014 Endless Mobile
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <drm/drmP.h>
24#include "meson_drv.h"
25#include "meson_viu.h"
26#include "meson_vpp.h"
27#include "meson_venc.h"
28#include "meson_canvas.h"
29#include "meson_registers.h"
30
31/*
32 * VIU Handles the Pixel scanout and the basic Colorspace conversions
33 * We handle the following features :
34 * - OSD1 RGB565/RGB888/xRGB8888 scanout
35 * - RGB conversion to x/cb/cr
36 * - Progressive or Interlace buffer scanout
37 * - OSD1 Commit on Vsync
38 * - HDR OSD matrix for GXL/GXM
39 *
40 * What is missing :
41 * - BGR888/xBGR8888/BGRx8888/BGRx8888 modes
42 * - YUV4:2:2 Y0CbY1Cr scanout
43 * - Conversion to YUV 4:4:4 from 4:2:2 input
44 * - Colorkey Alpha matching
45 * - Big endian scanout
46 * - X/Y reverse scanout
47 * - Global alpha setup
48 * - OSD2 support, would need interlace switching on vsync
49 * - OSD1 full scaling to support TV overscan
50 */
51
52/* OSD csc defines */
53
54enum viu_matrix_sel_e {
55 VIU_MATRIX_OSD_EOTF = 0,
56 VIU_MATRIX_OSD,
57};
58
59enum viu_lut_sel_e {
60 VIU_LUT_OSD_EOTF = 0,
61 VIU_LUT_OSD_OETF,
62};
63
64#define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2))
65#define MATRIX_5X3_COEF_SIZE 24
66
67#define EOTF_COEFF_NORM(a) ((int)((((a) * 4096.0) + 1) / 2))
68#define EOTF_COEFF_SIZE 10
69#define EOTF_COEFF_RIGHTSHIFT 1
70
71static int RGB709_to_YUV709l_coeff[MATRIX_5X3_COEF_SIZE] = {
72 0, 0, 0, /* pre offset */
73 COEFF_NORM(0.181873), COEFF_NORM(0.611831), COEFF_NORM(0.061765),
74 COEFF_NORM(-0.100251), COEFF_NORM(-0.337249), COEFF_NORM(0.437500),
75 COEFF_NORM(0.437500), COEFF_NORM(-0.397384), COEFF_NORM(-0.040116),
76 0, 0, 0, /* 10'/11'/12' */
77 0, 0, 0, /* 20'/21'/22' */
78 64, 512, 512, /* offset */
79 0, 0, 0 /* mode, right_shift, clip_en */
80};
81
82/* eotf matrix: bypass */
83static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = {
84 EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0),
85 EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0),
86 EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0),
87 EOTF_COEFF_RIGHTSHIFT /* right shift */
88};
89
90void meson_viu_set_osd_matrix(struct meson_drm *priv,
91 enum viu_matrix_sel_e m_select,
92 int *m, bool csc_on)
93{
94 if (m_select == VIU_MATRIX_OSD) {
95 /* osd matrix, VIU_MATRIX_0 */
96 writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff),
97 priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET0_1));
98 writel(m[2] & 0xfff,
99 priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET2));
100 writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff),
101 priv->io_base + _REG(VIU_OSD1_MATRIX_COEF00_01));
102 writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff),
103 priv->io_base + _REG(VIU_OSD1_MATRIX_COEF02_10));
104 writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff),
105 priv->io_base + _REG(VIU_OSD1_MATRIX_COEF11_12));
106 writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff),
107 priv->io_base + _REG(VIU_OSD1_MATRIX_COEF20_21));
108
109 if (m[21]) {
110 writel(((m[11] & 0x1fff) << 16) | (m[12] & 0x1fff),
111 priv->io_base +
112 _REG(VIU_OSD1_MATRIX_COEF22_30));
113 writel(((m[13] & 0x1fff) << 16) | (m[14] & 0x1fff),
114 priv->io_base +
115 _REG(VIU_OSD1_MATRIX_COEF31_32));
116 writel(((m[15] & 0x1fff) << 16) | (m[16] & 0x1fff),
117 priv->io_base +
118 _REG(VIU_OSD1_MATRIX_COEF40_41));
119 writel(m[17] & 0x1fff, priv->io_base +
120 _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
121 } else
122 writel((m[11] & 0x1fff) << 16, priv->io_base +
123 _REG(VIU_OSD1_MATRIX_COEF22_30));
124
125 writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff),
126 priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET0_1));
127 writel(m[20] & 0xfff,
128 priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET2));
129
130 writel_bits_relaxed(3 << 30, m[21] << 30,
131 priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
132 writel_bits_relaxed(7 << 16, m[22] << 16,
133 priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
134
135 /* 23 reserved for clipping control */
136 writel_bits_relaxed(BIT(0), csc_on ? BIT(0) : 0,
137 priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
138 writel_bits_relaxed(BIT(1), 0,
139 priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
140 } else if (m_select == VIU_MATRIX_OSD_EOTF) {
141 int i;
142
143 /* osd eotf matrix, VIU_MATRIX_OSD_EOTF */
144 for (i = 0; i < 5; i++)
145 writel(((m[i * 2] & 0x1fff) << 16) |
146 (m[i * 2 + 1] & 0x1fff), priv->io_base +
147 _REG(VIU_OSD1_EOTF_CTL + i + 1));
148
149 writel_bits_relaxed(BIT(30), csc_on ? BIT(30) : 0,
150 priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
151 writel_bits_relaxed(BIT(31), csc_on ? BIT(31) : 0,
152 priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
153 }
154}
155
156#define OSD_EOTF_LUT_SIZE 33
157#define OSD_OETF_LUT_SIZE 41
158
159void meson_viu_set_osd_lut(struct meson_drm *priv, enum viu_lut_sel_e lut_sel,
160 unsigned int *r_map, unsigned int *g_map,
161 unsigned int *b_map,
162 bool csc_on)
163{
164 unsigned int addr_port;
165 unsigned int data_port;
166 unsigned int ctrl_port;
167 int i;
168
169 if (lut_sel == VIU_LUT_OSD_EOTF) {
170 addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT;
171 data_port = VIU_OSD1_EOTF_LUT_DATA_PORT;
172 ctrl_port = VIU_OSD1_EOTF_CTL;
173 } else if (lut_sel == VIU_LUT_OSD_OETF) {
174 addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT;
175 data_port = VIU_OSD1_OETF_LUT_DATA_PORT;
176 ctrl_port = VIU_OSD1_OETF_CTL;
177 } else
178 return;
179
180 if (lut_sel == VIU_LUT_OSD_OETF) {
181 writel(0, priv->io_base + _REG(addr_port));
182
183 for (i = 0; i < 20; i++)
184 writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
185 priv->io_base + _REG(data_port));
186
187 writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16),
188 priv->io_base + _REG(data_port));
189
190 for (i = 0; i < 20; i++)
191 writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
192 priv->io_base + _REG(data_port));
193
194 for (i = 0; i < 20; i++)
195 writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
196 priv->io_base + _REG(data_port));
197
198 writel(b_map[OSD_OETF_LUT_SIZE - 1],
199 priv->io_base + _REG(data_port));
200
201 if (csc_on)
202 writel_bits_relaxed(0x7 << 29, 7 << 29,
203 priv->io_base + _REG(ctrl_port));
204 else
205 writel_bits_relaxed(0x7 << 29, 0,
206 priv->io_base + _REG(ctrl_port));
207 } else if (lut_sel == VIU_LUT_OSD_EOTF) {
208 writel(0, priv->io_base + _REG(addr_port));
209
210 for (i = 0; i < 20; i++)
211 writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
212 priv->io_base + _REG(data_port));
213
214 writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16),
215 priv->io_base + _REG(data_port));
216
217 for (i = 0; i < 20; i++)
218 writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
219 priv->io_base + _REG(data_port));
220
221 for (i = 0; i < 20; i++)
222 writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
223 priv->io_base + _REG(data_port));
224
225 writel(b_map[OSD_EOTF_LUT_SIZE - 1],
226 priv->io_base + _REG(data_port));
227
228 if (csc_on)
229 writel_bits_relaxed(7 << 27, 7 << 27,
230 priv->io_base + _REG(ctrl_port));
231 else
232 writel_bits_relaxed(7 << 27, 0,
233 priv->io_base + _REG(ctrl_port));
234
235 writel_bits_relaxed(BIT(31), BIT(31),
236 priv->io_base + _REG(ctrl_port));
237 }
238}
239
240/* eotf lut: linear */
241static unsigned int eotf_33_linear_mapping[OSD_EOTF_LUT_SIZE] = {
242 0x0000, 0x0200, 0x0400, 0x0600,
243 0x0800, 0x0a00, 0x0c00, 0x0e00,
244 0x1000, 0x1200, 0x1400, 0x1600,
245 0x1800, 0x1a00, 0x1c00, 0x1e00,
246 0x2000, 0x2200, 0x2400, 0x2600,
247 0x2800, 0x2a00, 0x2c00, 0x2e00,
248 0x3000, 0x3200, 0x3400, 0x3600,
249 0x3800, 0x3a00, 0x3c00, 0x3e00,
250 0x4000
251};
252
253/* osd oetf lut: linear */
254static unsigned int oetf_41_linear_mapping[OSD_OETF_LUT_SIZE] = {
255 0, 0, 0, 0,
256 0, 32, 64, 96,
257 128, 160, 196, 224,
258 256, 288, 320, 352,
259 384, 416, 448, 480,
260 512, 544, 576, 608,
261 640, 672, 704, 736,
262 768, 800, 832, 864,
263 896, 928, 960, 992,
264 1023, 1023, 1023, 1023,
265 1023
266};
267
268static void meson_viu_load_matrix(struct meson_drm *priv)
269{
270 /* eotf lut bypass */
271 meson_viu_set_osd_lut(priv, VIU_LUT_OSD_EOTF,
272 eotf_33_linear_mapping, /* R */
273 eotf_33_linear_mapping, /* G */
274 eotf_33_linear_mapping, /* B */
275 false);
276
277 /* eotf matrix bypass */
278 meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD_EOTF,
279 eotf_bypass_coeff,
280 false);
281
282 /* oetf lut bypass */
283 meson_viu_set_osd_lut(priv, VIU_LUT_OSD_OETF,
284 oetf_41_linear_mapping, /* R */
285 oetf_41_linear_mapping, /* G */
286 oetf_41_linear_mapping, /* B */
287 false);
288
289 /* osd matrix RGB709 to YUV709 limit */
290 meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD,
291 RGB709_to_YUV709l_coeff,
292 true);
293}
294
295void meson_viu_init(struct meson_drm *priv)
296{
297 uint32_t reg;
298
299 /* Disable OSDs */
300 writel_bits_relaxed(BIT(0) | BIT(21), 0,
301 priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
302 writel_bits_relaxed(BIT(0) | BIT(21), 0,
303 priv->io_base + _REG(VIU_OSD2_CTRL_STAT));
304
305 /* On GXL/GXM, Use the 10bit HDR conversion matrix */
306 if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
307 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
308 meson_viu_load_matrix(priv);
309
310 /* Initialize OSD1 fifo control register */
311 reg = BIT(0) | /* Urgent DDR request priority */
312 (4 << 5) | /* hold_fifo_lines */
313 (3 << 10) | /* burst length 64 */
314 (32 << 12) | /* fifo_depth_val: 32*8=256 */
315 (2 << 22) | /* 4 words in 1 burst */
316 (2 << 24);
317 writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
318 writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
319
320 /* Set OSD alpha replace value */
321 writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
322 0xff << OSD_REPLACE_SHIFT,
323 priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
324 writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
325 0xff << OSD_REPLACE_SHIFT,
326 priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
327
328 priv->viu.osd1_enabled = false;
329 priv->viu.osd1_commit = false;
330 priv->viu.osd1_interlace = false;
331}
diff --git a/drivers/gpu/drm/meson/meson_viu.h b/drivers/gpu/drm/meson/meson_viu.h
new file mode 100644
index 000000000000..073b1910bd1b
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_viu.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* Video Input Unit */
20
21#ifndef __MESON_VIU_H
22#define __MESON_VIU_H
23
24/* OSDx_BLKx_CFG */
25#define OSD_CANVAS_SEL 16
26
27#define OSD_ENDIANNESS_LE BIT(15)
28#define OSD_ENDIANNESS_BE (0)
29
30#define OSD_BLK_MODE_422 (0x03 << 8)
31#define OSD_BLK_MODE_16 (0x04 << 8)
32#define OSD_BLK_MODE_32 (0x05 << 8)
33#define OSD_BLK_MODE_24 (0x07 << 8)
34
35#define OSD_OUTPUT_COLOR_RGB BIT(7)
36#define OSD_OUTPUT_COLOR_YUV (0)
37
38#define OSD_COLOR_MATRIX_32_RGBA (0x00 << 2)
39#define OSD_COLOR_MATRIX_32_ARGB (0x01 << 2)
40#define OSD_COLOR_MATRIX_32_ABGR (0x02 << 2)
41#define OSD_COLOR_MATRIX_32_BGRA (0x03 << 2)
42
43#define OSD_COLOR_MATRIX_24_RGB (0x00 << 2)
44
45#define OSD_COLOR_MATRIX_16_RGB655 (0x00 << 2)
46#define OSD_COLOR_MATRIX_16_RGB565 (0x04 << 2)
47
48#define OSD_INTERLACE_ENABLED BIT(1)
49#define OSD_INTERLACE_ODD BIT(0)
50#define OSD_INTERLACE_EVEN (0)
51
52/* OSDx_CTRL_STAT */
53#define OSD_ENABLE BIT(21)
54#define OSD_BLK0_ENABLE BIT(0)
55
56#define OSD_GLOBAL_ALPHA_SHIFT 12
57
58/* OSDx_CTRL_STAT2 */
59#define OSD_REPLACE_EN BIT(14)
60#define OSD_REPLACE_SHIFT 6
61
62void meson_viu_init(struct meson_drm *priv);
63
64#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 000000000000..671909d8672e
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_vpp.c
@@ -0,0 +1,162 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5 * Copyright (C) 2014 Endless Mobile
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <drm/drmP.h>
24#include "meson_drv.h"
25#include "meson_vpp.h"
26#include "meson_registers.h"
27
28/*
29 * VPP Handles all the Post Processing after the Scanout from the VIU
30 * We handle the following post processings :
31 * - Postblend : Blends the OSD1 only
32 * We exclude OSD2, VS1, VS1 and Preblend output
33 * - Vertical OSD Scaler for OSD1 only, we disable vertical scaler and
34 * use it only for interlace scanout
35 * - Intermediate FIFO with default Amlogic values
36 *
37 * What is missing :
38 * - Preblend for video overlay pre-scaling
39 * - OSD2 support for cursor framebuffer
40 * - Video pre-scaling before postblend
41 * - Full Vertical/Horizontal OSD scaling to support TV overscan
42 * - HDR conversion
43 */
44
45void meson_vpp_setup_mux(struct meson_drm *priv, unsigned int mux)
46{
47 writel(mux, priv->io_base + _REG(VPU_VIU_VENC_MUX_CTRL));
48}
49
50/*
51 * When the output is interlaced, the OSD must switch between
52 * each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0
53 * at each vsync.
54 * But the vertical scaler can provide such funtionnality if
55 * is configured for 2:1 scaling with interlace options enabled.
56 */
57void meson_vpp_setup_interlace_vscaler_osd1(struct meson_drm *priv,
58 struct drm_rect *input)
59{
60 writel_relaxed(BIT(3) /* Enable scaler */ |
61 BIT(2), /* Select OSD1 */
62 priv->io_base + _REG(VPP_OSD_SC_CTRL0));
63
64 writel_relaxed(((drm_rect_width(input) - 1) << 16) |
65 (drm_rect_height(input) - 1),
66 priv->io_base + _REG(VPP_OSD_SCI_WH_M1));
67 /* 2:1 scaling */
68 writel_relaxed(((input->x1) << 16) | (input->x2),
69 priv->io_base + _REG(VPP_OSD_SCO_H_START_END));
70 writel_relaxed(((input->y1 >> 1) << 16) | (input->y2 >> 1),
71 priv->io_base + _REG(VPP_OSD_SCO_V_START_END));
72
73 /* 2:1 scaling values */
74 writel_relaxed(BIT(16), priv->io_base + _REG(VPP_OSD_VSC_INI_PHASE));
75 writel_relaxed(BIT(25), priv->io_base + _REG(VPP_OSD_VSC_PHASE_STEP));
76
77 writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
78
79 writel_relaxed((4 << 0) /* osd_vsc_bank_length */ |
80 (4 << 3) /* osd_vsc_top_ini_rcv_num0 */ |
81 (1 << 8) /* osd_vsc_top_rpt_p0_num0 */ |
82 (6 << 11) /* osd_vsc_bot_ini_rcv_num0 */ |
83 (2 << 16) /* osd_vsc_bot_rpt_p0_num0 */ |
84 BIT(23) /* osd_prog_interlace */ |
85 BIT(24), /* Enable vertical scaler */
86 priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
87}
88
89void meson_vpp_disable_interlace_vscaler_osd1(struct meson_drm *priv)
90{
91 writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0));
92 writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
93 writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
94}
95
96static unsigned int vpp_filter_coefs_4point_bspline[] = {
97 0x15561500, 0x14561600, 0x13561700, 0x12561800,
98 0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00,
99 0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200,
100 0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700,
101 0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01,
102 0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201,
103 0x05473301, 0x05463401, 0x04453601, 0x04433702,
104 0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02,
105 0x033d3d03
106};
107
108static void meson_vpp_write_scaling_filter_coefs(struct meson_drm *priv,
109 const unsigned int *coefs,
110 bool is_horizontal)
111{
112 int i;
113
114 writel_relaxed(is_horizontal ? BIT(8) : 0,
115 priv->io_base + _REG(VPP_OSD_SCALE_COEF_IDX));
116 for (i = 0; i < 33; i++)
117 writel_relaxed(coefs[i],
118 priv->io_base + _REG(VPP_OSD_SCALE_COEF));
119}
120
121void meson_vpp_init(struct meson_drm *priv)
122{
123 /* set dummy data default YUV black */
124 if (meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
125 writel_relaxed(0x108080, priv->io_base + _REG(VPP_DUMMY_DATA1));
126 else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu")) {
127 writel_bits_relaxed(0xff << 16, 0xff << 16,
128 priv->io_base + _REG(VIU_MISC_CTRL1));
129 writel_relaxed(0x20000, priv->io_base + _REG(VPP_DOLBY_CTRL));
130 writel_relaxed(0x1020080,
131 priv->io_base + _REG(VPP_DUMMY_DATA1));
132 }
133
134 /* Initialize vpu fifo control registers */
135 writel_relaxed(readl_relaxed(priv->io_base + _REG(VPP_OFIFO_SIZE)) |
136 0x77f, priv->io_base + _REG(VPP_OFIFO_SIZE));
137 writel_relaxed(0x08080808, priv->io_base + _REG(VPP_HOLD_LINES));
138
139 /* Turn off preblend */
140 writel_bits_relaxed(VPP_PREBLEND_ENABLE, 0,
141 priv->io_base + _REG(VPP_MISC));
142
143 /* Turn off POSTBLEND */
144 writel_bits_relaxed(VPP_POSTBLEND_ENABLE, 0,
145 priv->io_base + _REG(VPP_MISC));
146
147 /* Force all planes off */
148 writel_bits_relaxed(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND |
149 VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND, 0,
150 priv->io_base + _REG(VPP_MISC));
151
152 /* Disable Scalers */
153 writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0));
154 writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
155 writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
156
157 /* Write in the proper filter coefficients. */
158 meson_vpp_write_scaling_filter_coefs(priv,
159 vpp_filter_coefs_4point_bspline, false);
160 meson_vpp_write_scaling_filter_coefs(priv,
161 vpp_filter_coefs_4point_bspline, true);
162}
diff --git a/drivers/gpu/drm/meson/meson_vpp.h b/drivers/gpu/drm/meson/meson_vpp.h
new file mode 100644
index 000000000000..ede3b26e0f22
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_vpp.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (C) 2016 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* Video Post Process */
20
21#ifndef __MESON_VPP_H
22#define __MESON_VPP_H
23
24/* Mux VIU/VPP to ENCI */
25#define MESON_VIU_VPP_MUX_ENCI 0x5
26
27void meson_vpp_setup_mux(struct meson_drm *priv, unsigned int mux);
28
29void meson_vpp_setup_interlace_vscaler_osd1(struct meson_drm *priv,
30 struct drm_rect *input);
31void meson_vpp_disable_interlace_vscaler_osd1(struct meson_drm *priv);
32
33void meson_vpp_init(struct meson_drm *priv);
34
35#endif /* __MESON_VPP_H */