- GXBB (S905) : "amlogic,meson-gxbb-vpu"
- GXL (S905X, S905D) : "amlogic,meson-gxl-vpu"
- GXM (S912) : "amlogic,meson-gxm-vpu"
+ - TXL (T962X, T962E) : "amlogic,meson-txl-vpu"
+ - TXLX (T962X, T962E) : "amlogic,meson-txlx-vpu"
+ - AXG (A113G, A113D) : "amlogic,meson-axg-vpu"
+ - G12A (S905D2) : "amlogic,meson-g12a-vpu"
followed by the common "amlogic,meson-gx-vpu"
- reg: base address and size of he following memory-mapped regions :
- vpu
Example:
-tv-connector {
- compatible = "composite-video-connector";
+ drm_amhdmitx: drm-amhdmitx {
+ status = "disabled";
+ compatible = "amlogic,drm-amhdmitx";
+ dev_name = "meson-amhdmitx";
+ interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
+ drm_feature = <1>;
+ ports {
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ hdmi_in_vpu: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vpu_out_hdmi>;
+ };
+ };
+ };
+ };
- port {
- tv_connector_in: endpoint {
- remote-endpoint = <&cvbs_vdac_out>;
+ drm_lcd: drm-lcd {
+ status = "disabled";
+ compatible = "amlogic,drm-lcd";
+ dev_name = "meson-lcd";
+ ports {
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ lcd_in_vpu: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vpu_out_lcd>;
+ };
+ };
};
};
-};
-
-vpu: vpu@d0100000 {
- compatible = "amlogic,meson-gxbb-vpu";
- reg = <0x0 0xd0100000 0x0 0x100000>,
- <0x0 0xc883c000 0x0 0x1000>,
- <0x0 0xc8838000 0x0 0x1000>;
- reg-names = "vpu", "hhi", "dmc";
- interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* CVBS VDAC output port */
- port@0 {
- reg = <0>;
-
- cvbs_vdac_out: endpoint {
- remote-endpoint = <&tv_connector_in>;
+
+ drm_vpu: drm-vpu@0xff900000 {
+ status = "disabled";
+ compatible = "amlogic,meson-g12a-vpu";
+ reg = <0x0 0xff900000 0x0 0x40000>,
+ <0x0 0xff63c000 0x0 0x2000>,
+ <0x0 0xff638000 0x0 0x2000>;
+ reg-names = "base", "hhi", "dmc";
+ interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
+ dma-coherent;
+ vpu_out: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vpu_out_hdmi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hdmi_in_vpu>;
+ };
+ vpu_out_lcd: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&lcd_in_vpu>;
+ };
};
};
-};
+
+ drm_subsystem: drm-subsystem {
+ status = "okay";
+ compatible = "amlogic,drm-subsystem";
+ ports = <&vpu_out>;
+ };
+
F: include/linux/amlogic/meson_drm.h
F: arch/arm64/boot/dts/amlogic/g12a_skt_buildroot.dts
F: arch/arm64/boot/dts/amlogic/mesong12a_drm.dtsi
+F: driver/amlogic/drm/am_meson_drv.c
+F: driver/amlogic/drm/am_meson_drv.h
+F: driver/amlogic/drm/am_meson_vpu.c
+F: driver/amlogic/drm/am_meson_vpu.h
AMLOGIC ADD S400EMMC DTS
M: Yue Gui <yuegui.he@amlogic.com>
}; /* end of / */
+&drm_vpu {
+ status = "okay";
+};
+
+&drm_amhdmitx {
+ status = "okay";
+};
+
+&drm_lcd {
+ status = "okay";
+};
+
&pwm_AO_cd {
status = "okay";
};
#include "mesong12a.dtsi"
#include "mesong12a_skt-panel.dtsi"
+#include "mesong12a_drm.dtsi"
/ {
model = "Amlogic";
}; /* end of / */
+&drm_vpu {
+ status = "okay";
+};
+
+&drm_amhdmitx {
+ status = "okay";
+};
+
+&drm_lcd {
+ status = "okay";
+};
+
&pwm_AO_cd {
status = "okay";
};
*/
/ {
- venc-cvbs {
- status = "okay";
- compatible = "amlogic,meson-gxbb-cvbs";
-
+ drm_amhdmitx: drm-amhdmitx {
+ status = "disabled";
+ compatible = "amlogic,drm-amhdmitx";
+ dev_name = "meson-amhdmitx";
+ interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
+ drm_feature = <1>;
ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- enc_cvbs_in: port@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
-
- venc_cvbs_in_vpu: endpoint@0 {
- reg = <0>;
- remote-endpoint = <&vpu_out_venc_cvbs>;
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ hdmi_in_vpu: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vpu_out_hdmi>;
};
};
};
};
- amhdmitx: amhdmitx {
- compatible = "amlogic, drm_amhdmitx";
- dev_name = "amhdmitx";
- drm_feature = <1>;
+ drm_lcd: drm-lcd {
+ status = "disabled";
+ compatible = "amlogic,drm-lcd";
+ dev_name = "meson-lcd";
+ ports {
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ lcd_in_vpu: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vpu_out_lcd>;
+ };
+ };
+ };
};
- drm_vpu@d0100000 {
- status = "okay";
+ drm_vpu: drm-vpu@0xff900000 {
+ status = "disabled";
compatible = "amlogic,meson-gxbb-vpu";
reg = <0x0 0xd0100000 0x0 0x100000>,
<0x0 0xc883c000 0x0 0x1000>,
reg-names = "base", "hhi", "dmc";
interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
dma-coherent;
- ports {
+ vpu_out: port {
#address-cells = <1>;
#size-cells = <0>;
- vpu_out: port@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
-
- vpu_out_venc_cvbs: endpoint@0 {
- reg = <0>;
- remote-endpoint = <&venc_cvbs_in_vpu>;
- };
- };
+ vpu_out_hdmi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hdmi_in_vpu>;
+ };
+ vpu_out_lcd: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&lcd_in_vpu>;
+ };
};
};
+
+ drm_subsystem: drm-subsystem {
+ status = "okay";
+ compatible = "amlogic,drm-subsystem";
+ ports = <&vpu_out>;
+ };
+};
+
+&drm_vpu {
+ status = "okay";
+};
+
+&drm_amhdmitx {
+ status = "okay";
};
&gpu{
#size-cells = <0>;
reg = <0>;
- venc_cvbs_in_vpu: endpoint@0 {
- reg = <0>;
- remote-endpoint = <&vpu_out_venc_cvbs>;
- };
+ //venc_cvbs_in_vpu: endpoint@0 {
+ // reg = <0>;
+ // remote-endpoint = <&vpu_out_venc_cvbs>;
+ //};
};
};
};
- amhdmitx: amhdmitx {
- compatible = "amlogic, drm_amhdmitx";
- dev_name = "amhdmitx";
+ drm_amhdmitx: drm-amhdmitx {
+ status = "disabled";
+ compatible = "amlogic,drm-amhdmitx";
+ dev_name = "meson-amhdmitx";
+ interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
drm_feature = <1>;
+ ports {
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ hdmi_in_vpu: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vpu_out_hdmi>;
+ };
+ };
+ };
};
- drm_vpu:drm@0xff900000 {
- status = "okay";
- compatible = "amlogic,meson-g12a";
+ drm_lcd: drm-lcd {
+ status = "disabled";
+ compatible = "amlogic,drm-lcd";
+ dev_name = "meson-lcd";
+ ports {
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ lcd_in_vpu: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vpu_out_lcd>;
+ };
+ };
+ };
+ };
+
+ drm_vpu: drm-vpu@0xff900000 {
+ status = "disabled";
+ compatible = "amlogic,meson-g12a-vpu";
reg = <0x0 0xff900000 0x0 0x40000>,
<0x0 0xff63c000 0x0 0x2000>,
<0x0 0xff638000 0x0 0x2000>;
reg-names = "base", "hhi", "dmc";
interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
dma-coherent;
- ports {
+ vpu_out: port {
#address-cells = <1>;
#size-cells = <0>;
- vpu_out: port@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
-
- vpu_out_venc_cvbs: endpoint@0 {
- reg = <0>;
- remote-endpoint = <&venc_cvbs_in_vpu>;
- };
- };
+ vpu_out_hdmi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hdmi_in_vpu>;
+ };
+ vpu_out_lcd: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&lcd_in_vpu>;
+ };
};
};
+
+ drm_subsystem: drm-subsystem {
+ status = "okay";
+ compatible = "amlogic,drm-subsystem";
+ ports = <&vpu_out>;
+ };
};
select VIDEOMODE_HELPERS
select REGMAP_MMIO
-config DRM_MESON_BYPASS_MODE
- bool "use the drm display path, but all the implements in other drivers."
+config DRM_MESON_VPU
+ tristate "support drm vpu function for meson drm display."
default y
depends on DRM_MESON
help
- The MESON DRM want to rewrite all the display component,its a big job,
- and will meet a lot of bugs which are already handled before.
- We add bypass mode to implment drm based on amlogic existing driver,
- it should be easier and more robust.
+ add drm vpu support.
+ Choose this option if you have a aMLOGIC soc chipset.
+ This driver provides KMS.
+ This driver also provides crtcs and planes management.
+
+config DRM_MESON_HDMI
+ tristate "support drm hdmi function for meson drm display."
+ default y
+ depends on DRM_MESON
+ depends on AMLOGIC_HDMITX
+ help
+ add drm hdmi support.
+ use internal amlogic media vout hdmi driver.
+ We should confirm AMLOGIC_HDMITX is configured if
+ DRM_MESON_HDMI is selected.
config DRM_MESON_PANEL
- bool "support drm panel function for meson drm display."
+ tristate "support drm panel function for meson drm display."
default y
depends on DRM_MESON
depends on AMLOGIC_LCD
config DRM_MESON_USE_ION
bool "gem use ion to alloc/free graphic buffer."
default y
- depends on DRM_MESON && DRM_MESON_BYPASS_MODE
+ depends on DRM_MESON
help
MESON DRM use CMA HELPER to manage framebuffer.
It need reserve memory in CMA pool.
config DRM_MESON_EMULATE_FBDEV
bool "emulate framebuffer dev by drm."
default n
- depends on DRM_MESON && DRM_MESON_BYPASS_MODE && DRM_MESON_USE_ION
+ depends on DRM_MESON && DRM_MESON_USE_ION
help
Emulate framebuffer device for device which need use fbdev api.
-meson-y := meson_drv.o
-
-ifeq ($(CONFIG_DRM_MESON_BYPASS_MODE),y)
- meson-y += am_meson_plane.o am_meson_crtc.o am_meson_hdmi.o
- ccflags-y += -Idrivers/amlogic/media/osd/
-else
- meson-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o meson_plane.o meson_crtc.o meson_venc_cvbs.o
-endif
+meson_drv-y += am_meson_drv.o
+ccflags-y += -Idrivers/amlogic/media/osd/
ifeq ($(CONFIG_DRM_MESON_USE_ION),y)
- meson-y += am_meson_gem.o am_meson_fb.o
+ meson_drv-y += am_meson_gem.o am_meson_fb.o
ccflags-y += -Idrivers/staging/android/
endif
ifeq ($(CONFIG_DRM_MESON_EMULATE_FBDEV),y)
- meson-y += am_meson_fbdev.o
+ meson_drv-y += am_meson_fbdev.o
+endif
+
+ifneq ($(CONFIG_DRM_MESON_VPU),)
+ meson_vpu-y += am_meson_vpu.o
+endif
+
+ifneq ($(CONFIG_DRM_MESON_HDMI),)
+ meson_hdmi-y += am_meson_hdmi.o
endif
-ifeq ($(CONFIG_DRM_MESON_PANEL),y)
- meson-y += am_meson_lcd.o
+ifneq ($(CONFIG_DRM_MESON_PANEL),)
+ meson_lcd-y += am_meson_lcd.o
endif
-obj-$(CONFIG_DRM_MESON) += meson.o
+obj-$(CONFIG_DRM_MESON) += meson_drv.o
+obj-$(CONFIG_DRM_MESON_VPU) += meson_vpu.o
+obj-$(CONFIG_DRM_MESON_HDMI) += meson_hdmi.o
+obj-$(CONFIG_DRM_MESON_PANEL) += meson_lcd.o
+++ /dev/null
-/*
- * drivers/amlogic/drm/am_meson_crtc.c
- *
- * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#include <drm/drmP.h>
-#include <drm/drm_plane.h>
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
-
-/* Amlogic Headers */
-#include <linux/amlogic/media/vout/vout_notify.h>
-
-#include "meson_crtc.h"
-#include "osd_drm.h"
-
-static struct osd_device_data_s osd_meson_dev;
-
-#define to_am_meson_crtc(x) container_of(x, struct am_meson_crtc, base)
-
-struct am_vout_mode {
- char name[DRM_DISPLAY_MODE_LEN];
- enum vmode_e mode;
- int width, height, vrefresh;
- unsigned int flags;
-};
-
-static struct am_vout_mode am_vout_modes[] = {
- { "1080p60hz", VMODE_HDMI, 1920, 1080, 60, 0},
- { "1080p30hz", VMODE_HDMI, 1920, 1080, 30, 0},
- { "1080p50hz", VMODE_HDMI, 1920, 1080, 50, 0},
- { "1080p25hz", VMODE_HDMI, 1920, 1080, 25, 0},
- { "1080p24hz", VMODE_HDMI, 1920, 1080, 24, 0},
- { "2160p30hz", VMODE_HDMI, 3840, 2160, 30, 0},
- { "2160p60hz", VMODE_HDMI, 3840, 2160, 60, 0},
- { "2160p50hz", VMODE_HDMI, 3840, 2160, 50, 0},
- { "2160p25hz", VMODE_HDMI, 3840, 2160, 25, 0},
- { "2160p24hz", VMODE_HDMI, 3840, 2160, 24, 0},
- { "1080i60hz", VMODE_HDMI, 1920, 1080, 60, DRM_MODE_FLAG_INTERLACE},
- { "1080i50hz", VMODE_HDMI, 1920, 1080, 50, DRM_MODE_FLAG_INTERLACE},
- { "720p60hz", VMODE_HDMI, 1280, 720, 60, 0},
- { "720p50hz", VMODE_HDMI, 1280, 720, 50, 0},
- { "480p60hz", VMODE_HDMI, 720, 480, 60, 0},
- { "480i60hz", VMODE_HDMI, 720, 480, 60, DRM_MODE_FLAG_INTERLACE},
- { "576p50hz", VMODE_HDMI, 720, 576, 50, 0},
- { "576i50hz", VMODE_HDMI, 720, 576, 50, DRM_MODE_FLAG_INTERLACE},
- { "480p60hz", VMODE_HDMI, 720, 480, 60, 0},
-};
-
-char *am_meson_crtc_get_voutmode(struct drm_display_mode *mode)
-{
- int i;
-
- if (!strcmp(mode->name, "panel")) {
- return "panel";
- }
- for (i = 0; i < ARRAY_SIZE(am_vout_modes); i++) {
- if ((am_vout_modes[i].width == mode->hdisplay)
- && (am_vout_modes[i].height == mode->vdisplay)
- && (am_vout_modes[i].vrefresh == mode->vrefresh)
- && (am_vout_modes[i].flags ==
- (mode->flags&DRM_MODE_FLAG_INTERLACE)))
- return am_vout_modes[i].name;
- }
- return NULL;
-}
-
-struct am_vpp {
-};
-
-struct am_vout {
-};
-
-struct am_meson_crtc {
- struct drm_crtc base;
- struct meson_drm *priv;
-
- struct drm_pending_vblank_event *event;
-
- struct am_vpp vpp;
- struct am_vout vout;
-};
-
-void am_meson_crtc_handle_vsync(struct am_meson_crtc *amcrtc)
-{
- unsigned long flags;
- struct drm_crtc *crtc;
-
- crtc = &amcrtc->base;
- drm_crtc_handle_vblank(crtc);
-
- spin_lock_irqsave(&crtc->dev->event_lock, flags);
- if (amcrtc->event) {
- drm_crtc_send_vblank_event(crtc, amcrtc->event);
- drm_crtc_vblank_put(crtc);
- amcrtc->event = NULL;
- }
- spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
-}
-
-int am_meson_crtc_set_mode(struct drm_mode_set *set)
-{
- struct am_meson_crtc *amcrtc;
- int ret;
-
- DRM_DEBUG_DRIVER("am_crtc_set_mode\n");
- amcrtc = to_am_meson_crtc(set->crtc);
- ret = drm_atomic_helper_set_config(set);
-
- return ret;
-}
-
-static const struct drm_crtc_funcs am_meson_crtc_funcs = {
- .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
- .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
- .destroy = drm_crtc_cleanup,
- .page_flip = drm_atomic_helper_page_flip,
- .reset = drm_atomic_helper_crtc_reset,
- .set_config = am_meson_crtc_set_mode,
-};
-
-static bool am_meson_crtc_mode_fixup(struct drm_crtc *crtc,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adj_mode)
-{
- //DRM_INFO("am_meson_crtc_mode_fixup !!\n");
-
- return true;
-}
-
-void am_meson_crtc_enable(struct drm_crtc *crtc)
-{
- char *name;
- enum vmode_e mode;
- struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
-
- if (!adjusted_mode) {
- DRM_ERROR("meson_crtc_enable fail, unsupport mode:%s\n",
- adjusted_mode->name);
- return;
- }
- DRM_INFO("%s: %s\n", __func__, adjusted_mode->name);
- name = am_meson_crtc_get_voutmode(adjusted_mode);
- mode = validate_vmode(name);
- if (mode == VMODE_MAX) {
- DRM_ERROR("no matched vout mode\n");
- return;
- }
-
- set_vout_init(mode);
- update_vout_viu();
-
- return;
-}
-
-void am_meson_crtc_disable(struct drm_crtc *crtc)
-{
- DRM_INFO("%s\n", __func__);
- if (crtc->state->event && !crtc->state->active) {
- spin_lock_irq(&crtc->dev->event_lock);
- drm_crtc_send_vblank_event(crtc, crtc->state->event);
- spin_unlock_irq(&crtc->dev->event_lock);
-
- crtc->state->event = NULL;
- }
-}
-
-void am_meson_crtc_commit(struct drm_crtc *crtc)
-{
- //DRM_INFO("am_meson_crtc_commit!!\n");
-}
-
-void am_meson_crtc_atomic_begin(struct drm_crtc *crtc,
- struct drm_crtc_state *old_crtc_state)
-{
- struct am_meson_crtc *amcrtc;
- unsigned long flags;
-
- amcrtc = to_am_meson_crtc(crtc);
-
- if (crtc->state->event) {
- WARN_ON(drm_crtc_vblank_get(crtc) != 0);
-
- spin_lock_irqsave(&crtc->dev->event_lock, flags);
- amcrtc->event = crtc->state->event;
- spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
- crtc->state->event = NULL;
- }
-}
-
-void am_meson_crtc_atomic_flush(struct drm_crtc *crtc,
- struct drm_crtc_state *old_crtc_state)
-{
-}
-
-static const struct drm_crtc_helper_funcs am_crtc_helper_funcs = {
- .enable = am_meson_crtc_enable,
- .disable = am_meson_crtc_disable,
- .commit = am_meson_crtc_commit,
- .mode_fixup = am_meson_crtc_mode_fixup,
- .atomic_begin = am_meson_crtc_atomic_begin,
- .atomic_flush = am_meson_crtc_atomic_flush,
-};
-
-int meson_crtc_create(struct meson_drm *priv)
-{
- struct am_meson_crtc *amcrtc;
- struct drm_crtc *crtc;
- int ret;
-
- DRM_DEBUG("amlogic meson_crtc_create\n");
- amcrtc = devm_kzalloc(priv->drm->dev, sizeof(*amcrtc),
- GFP_KERNEL);
- if (!amcrtc)
- return -ENOMEM;
-
- amcrtc->priv = priv;
- crtc = &amcrtc->base;
- ret = drm_crtc_init_with_planes(priv->drm, crtc,
- priv->primary_plane, priv->cursor_plane,
- &am_meson_crtc_funcs, "amlogic vpu");
- if (ret) {
- dev_err(priv->drm->dev, "Failed to init CRTC\n");
- return ret;
- }
-
- drm_crtc_helper_add(crtc, &am_crtc_helper_funcs);
- osd_drm_init(&osd_meson_dev);
-
- priv->crtc = crtc;
- return 0;
-}
-
-void meson_crtc_irq(struct meson_drm *priv)
-{
- struct am_meson_crtc *amcrtc = to_am_meson_crtc(priv->crtc);
-
- osd_drm_vsync_isr_handler();
- am_meson_crtc_handle_vsync(amcrtc);
-}
-
-int meson_crtc_dts_info_set(const void *dt_match_data)
-{
- struct osd_device_data_s *osd_meson;
-
- osd_meson = (struct osd_device_data_s *)dt_match_data;
- if (osd_meson)
- memcpy(&osd_meson_dev, osd_meson,
- sizeof(struct osd_device_data_s));
- else {
- pr_err("%s data NOT match\n", __func__);
- return -1;
- }
- return 0;
-}
--- /dev/null
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (C) 2014 Endless Mobile
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Written by:
+ * Jasper St. Pierre <jstpierre@mecheye.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/component.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_flip_work.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_rect.h>
+#include <drm/drm_fb_helper.h>
+
+#include "am_meson_fbdev.h"
+#ifdef CONFIG_DRM_MESON_USE_ION
+#include "am_meson_gem.h"
+#include "am_meson_fb.h"
+#endif
+#include "am_meson_drv.h"
+
+
+#define DRIVER_NAME "meson"
+#define DRIVER_DESC "Amlogic Meson DRM driver"
+
+
+static void am_meson_fb_output_poll_changed(struct drm_device *dev)
+{
+#ifdef CONFIG_DRM_MESON_EMULATE_FBDEV
+ struct meson_drm *priv = dev->dev_private;
+
+ drm_fbdev_cma_hotplug_event(priv->fbdev);
+#endif
+}
+
+static const struct drm_mode_config_funcs meson_mode_config_funcs = {
+ .output_poll_changed = am_meson_fb_output_poll_changed,
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
+#ifdef CONFIG_DRM_MESON_USE_ION
+ .fb_create = am_meson_fb_create,
+#else
+ .fb_create = drm_fb_cma_create,
+#endif
+};
+
+int am_meson_register_crtc_funcs(struct drm_crtc *crtc,
+ const struct meson_crtc_funcs *crtc_funcs)
+{
+ int pipe = drm_crtc_index(crtc);
+ struct meson_drm *priv = crtc->dev->dev_private;
+
+ if (pipe >= MESON_MAX_CRTC)
+ return -EINVAL;
+
+ priv->crtc_funcs[pipe] = crtc_funcs;
+
+ return 0;
+}
+EXPORT_SYMBOL(am_meson_register_crtc_funcs);
+
+void am_meson_unregister_crtc_funcs(struct drm_crtc *crtc)
+{
+ int pipe = drm_crtc_index(crtc);
+ struct meson_drm *priv = crtc->dev->dev_private;
+
+ if (pipe >= MESON_MAX_CRTC)
+ return;
+
+ priv->crtc_funcs[pipe] = NULL;
+}
+EXPORT_SYMBOL(am_meson_unregister_crtc_funcs);
+
+static int am_meson_enable_vblank(struct drm_device *dev, unsigned int crtc)
+{
+ return 0;
+}
+
+static void am_meson_disable_vblank(struct drm_device *dev, unsigned int crtc)
+{
+}
+
+static void am_meson_load(struct drm_device *dev)
+{
+#if 0
+ struct meson_drm *priv = dev->dev_private;
+ struct drm_crtc *crtc = priv->crtc;
+ int pipe = drm_crtc_index(crtc);
+
+ if (priv->crtc_funcs[pipe] &&
+ priv->crtc_funcs[pipe]->loader_protect)
+ priv->crtc_funcs[pipe]->loader_protect(crtc, true);
+#endif
+}
+
+#ifdef CONFIG_DRM_MESON_USE_ION
+static const struct drm_ioctl_desc meson_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(MESON_GEM_CREATE, am_meson_gem_create_ioctl,
+ DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
+};
+#endif
+
+static const struct file_operations fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = drm_compat_ioctl,
+#endif
+ .poll = drm_poll,
+ .read = drm_read,
+ .llseek = no_llseek,
+#ifdef CONFIG_DRM_MESON_USE_ION
+ .mmap = am_meson_gem_mmap,
+#else
+ .mmap = drm_gem_cma_mmap,
+#endif
+};
+
+static struct drm_driver meson_driver = {
+ /*driver_features setting move to probe functions*/
+ .driver_features = 0,
+ /* Vblank */
+ .enable_vblank = am_meson_enable_vblank,
+ .disable_vblank = am_meson_disable_vblank,
+ .get_vblank_counter = drm_vblank_no_hw_counter,
+
+#ifdef CONFIG_DRM_MESON_USE_ION
+ /* PRIME Ops */
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+
+ .gem_prime_export = drm_gem_prime_export,
+ .gem_prime_get_sg_table = am_meson_gem_prime_get_sg_table,
+
+ .gem_prime_import = drm_gem_prime_import,
+ /*
+ * If gem_prime_import_sg_table is NULL,only buffer created
+ * by meson driver can be imported ok.
+ */
+ /*.gem_prime_import_sg_table = am_meson_gem_prime_import_sg_table,*/
+
+ .gem_prime_vmap = am_meson_gem_prime_vmap,
+ .gem_prime_vunmap = am_meson_gem_prime_vunmap,
+ .gem_prime_mmap = am_meson_gem_prime_mmap,
+
+ /* GEM Ops */
+ .dumb_create = am_meson_gem_dumb_create,
+ .dumb_destroy = am_meson_gem_dumb_destroy,
+ .dumb_map_offset = am_meson_gem_dumb_map_offset,
+ .gem_free_object_unlocked = am_meson_gem_object_free,
+ .gem_vm_ops = &drm_gem_cma_vm_ops,
+ .ioctls = meson_ioctls,
+ .num_ioctls = ARRAY_SIZE(meson_ioctls),
+#else
+ /* PRIME Ops */
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_import = drm_gem_prime_import,
+ .gem_prime_export = drm_gem_prime_export,
+ .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
+ .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+ .gem_prime_vmap = drm_gem_cma_prime_vmap,
+ .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
+ .gem_prime_mmap = drm_gem_cma_prime_mmap,
+
+ /* GEM Ops */
+ .dumb_create = drm_gem_cma_dumb_create,
+ .dumb_destroy = drm_gem_dumb_destroy,
+ .dumb_map_offset = drm_gem_cma_dumb_map_offset,
+ .gem_free_object_unlocked = drm_gem_cma_free_object,
+ .gem_vm_ops = &drm_gem_cma_vm_ops,
+#endif
+
+ /* Misc */
+ .fops = &fops,
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = "20180321",
+ .major = 1,
+ .minor = 0,
+};
+
+static int am_meson_drm_bind(struct device *dev)
+{
+ struct meson_drm *priv;
+ struct drm_device *drm;
+ int ret = 0;
+
+ meson_driver.driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM |
+ DRIVER_MODESET | DRIVER_PRIME |
+ DRIVER_ATOMIC | DRIVER_IRQ_SHARED;
+
+ drm = drm_dev_alloc(&meson_driver, dev);
+ if (!drm)
+ return -ENOMEM;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ goto err_free1;
+ }
+ drm->dev_private = priv;
+ priv->drm = drm;
+ priv->dev = dev;
+ dev_set_drvdata(dev, priv);
+
+#ifdef CONFIG_DRM_MESON_USE_ION
+ ret = am_meson_gem_create(priv);
+ if (ret)
+ goto err_free2;
+#endif
+
+ drm_mode_config_init(drm);
+
+ /* Try to bind all sub drivers. */
+ ret = component_bind_all(dev, drm);
+ if (ret)
+ goto err_gem;
+ DRM_INFO("mode_config crtc number:%d\n", drm->mode_config.num_crtc);
+
+ ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
+ if (ret)
+ goto err_unbind_all;
+
+ drm_mode_config_reset(drm);
+ drm->mode_config.max_width = 8192;
+ drm->mode_config.max_height = 8192;
+ drm->mode_config.funcs = &meson_mode_config_funcs;
+ /*
+ * enable drm irq mode.
+ * - with irq_enabled = true, we can use the vblank feature.
+ */
+ drm->irq_enabled = true;
+
+ drm_kms_helper_poll_init(drm);
+
+ am_meson_load(drm);
+
+#ifdef CONFIG_DRM_MESON_EMULATE_FBDEV
+ ret = am_meson_drm_fbdev_init(drm);
+ if (ret)
+ goto err_poll_fini;
+ drm->mode_config.allow_fb_modifiers = true;
+#endif
+
+ ret = drm_dev_register(drm, 0);
+ if (ret)
+ goto err_fbdev_fini;
+
+ return 0;
+
+
+err_fbdev_fini:
+#ifdef CONFIG_DRM_MESON_EMULATE_FBDEV
+ am_meson_drm_fbdev_fini(drm);
+err_poll_fini:
+#endif
+ drm_kms_helper_poll_fini(drm);
+ drm->irq_enabled = false;
+ drm_vblank_cleanup(drm);
+err_unbind_all:
+ component_unbind_all(dev, drm);
+err_gem:
+ drm_mode_config_cleanup(drm);
+#ifdef CONFIG_DRM_MESON_USE_ION
+ am_meson_gem_cleanup(drm->dev_private);
+err_free2:
+#endif
+ drm->dev_private = NULL;
+ dev_set_drvdata(dev, NULL);
+err_free1:
+ drm_dev_unref(drm);
+
+ return ret;
+}
+
+static void am_meson_drm_unbind(struct device *dev)
+{
+ struct drm_device *drm = dev_get_drvdata(dev);
+
+ drm_dev_unregister(drm);
+#ifdef CONFIG_DRM_MESON_EMULATE_FBDEV
+ am_meson_drm_fbdev_fini(drm);
+#endif
+ drm_kms_helper_poll_fini(drm);
+ drm->irq_enabled = false;
+ drm_vblank_cleanup(drm);
+ component_unbind_all(dev, drm);
+ drm_mode_config_cleanup(drm);
+#ifdef CONFIG_DRM_MESON_USE_ION
+ am_meson_gem_cleanup(drm->dev_private);
+#endif
+ drm->dev_private = NULL;
+ dev_set_drvdata(dev, NULL);
+ drm_dev_unref(drm);
+}
+
+static int compare_of(struct device *dev, void *data)
+{
+ struct device_node *np = data;
+
+ return dev->of_node == np;
+}
+
+static void am_meson_add_endpoints(struct device *dev,
+ struct component_match **match,
+ struct device_node *port)
+{
+ struct device_node *ep, *remote;
+
+ for_each_child_of_node(port, ep) {
+ remote = of_graph_get_remote_port_parent(ep);
+ if (!remote || !of_device_is_available(remote)) {
+ of_node_put(remote);
+ continue;
+ } else if (!of_device_is_available(remote->parent)) {
+ of_node_put(remote);
+ continue;
+ }
+ component_match_add(dev, match, compare_of, remote);
+ of_node_put(remote);
+ }
+}
+
+static const struct component_master_ops am_meson_drm_ops = {
+ .bind = am_meson_drm_bind,
+ .unbind = am_meson_drm_unbind,
+};
+
+static bool am_meson_drv_use_osd(void)
+{
+ struct device_node *node;
+ const char *str;
+ int ret;
+
+ node = of_find_node_by_path("/meson-fb");
+ if (node) {
+ ret = of_property_read_string(node, "status", &str);
+ if (ret) {
+ DRM_INFO("get 'status' failed:%d\n", ret);
+ return false;
+ }
+
+ if (strcmp(str, "okay") && strcmp(str, "ok")) {
+ DRM_INFO("device %s status is %s\n",
+ node->name, str);
+ } else {
+ DRM_INFO("device %s status is %s\n",
+ node->name, str);
+ return true;
+ }
+ }
+ return false;
+}
+
+static int am_meson_drv_probe_prune(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct meson_drm *priv;
+ struct drm_device *drm;
+ int ret;
+
+ /*driver_features reset to DRIVER_GEM | DRIVER_PRIME, for prune drm*/
+ meson_driver.driver_features = DRIVER_GEM | DRIVER_PRIME;
+
+ drm = drm_dev_alloc(&meson_driver, dev);
+ if (!drm)
+ return -ENOMEM;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ goto err_free1;
+ }
+ drm->dev_private = priv;
+ priv->drm = drm;
+ priv->dev = dev;
+
+ platform_set_drvdata(pdev, priv);
+
+#ifdef CONFIG_DRM_MESON_USE_ION
+ ret = am_meson_gem_create(priv);
+ if (ret)
+ goto err_free2;
+#endif
+
+ ret = drm_dev_register(drm, 0);
+ if (ret)
+ goto err_gem;
+
+ return 0;
+
+err_gem:
+#ifdef CONFIG_DRM_MESON_USE_ION
+ am_meson_gem_cleanup(drm->dev_private);
+err_free2:
+#endif
+ drm->dev_private = NULL;
+ platform_set_drvdata(pdev, NULL);
+err_free1:
+ drm_dev_unref(drm);
+ return ret;
+}
+
+static int am_meson_drv_remove_prune(struct platform_device *pdev)
+{
+ struct drm_device *drm = platform_get_drvdata(pdev);
+
+ drm_dev_unregister(drm);
+#ifdef CONFIG_DRM_MESON_USE_ION
+ am_meson_gem_cleanup(drm->dev_private);
+#endif
+ drm->dev_private = NULL;
+ platform_set_drvdata(pdev, NULL);
+ drm_dev_unref(drm);
+
+ return 0;
+}
+
+static int am_meson_drv_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *port;
+ struct component_match *match = NULL;
+ int i;
+
+ if (am_meson_drv_use_osd())
+ return am_meson_drv_probe_prune(pdev);
+
+ if (!np)
+ return -ENODEV;
+
+ /*
+ * Bind the crtc ports first, so that
+ * drm_of_find_possible_crtcs called from encoder .bind callbacks
+ * works as expected.
+ */
+ for (i = 0;; i++) {
+ port = of_parse_phandle(np, "ports", i);
+ if (!port)
+ break;
+
+ if (!of_device_is_available(port->parent)) {
+ of_node_put(port);
+ continue;
+ }
+
+ component_match_add(dev, &match, compare_of, port->parent);
+ of_node_put(port);
+ }
+
+ if (i == 0) {
+ dev_err(dev, "missing 'ports' property.\n");
+ return -ENODEV;
+ }
+
+ if (!match) {
+ dev_err(dev, "No available vout found for display-subsystem.\n");
+ return -ENODEV;
+ }
+
+ /*
+ * For each bound crtc, bind the encoders attached to its
+ * remote endpoint.
+ */
+ for (i = 0;; i++) {
+ port = of_parse_phandle(np, "ports", i);
+ if (!port)
+ break;
+
+ if (!of_device_is_available(port->parent)) {
+ of_node_put(port);
+ continue;
+ }
+
+ am_meson_add_endpoints(dev, &match, port);
+ of_node_put(port);
+ }
+
+ return component_master_add_with_match(dev, &am_meson_drm_ops, match);
+}
+
+static int am_meson_drv_remove(struct platform_device *pdev)
+{
+ if (am_meson_drv_use_osd())
+ return am_meson_drv_remove_prune(pdev);
+
+ component_master_del(&pdev->dev, &am_meson_drm_ops);
+ return 0;
+}
+
+static const struct of_device_id am_meson_drm_dt_match[] = {
+ { .compatible = "amlogic,drm-subsystem" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, am_meson_drm_dt_match);
+
+static struct platform_driver am_meson_drm_platform_driver = {
+ .probe = am_meson_drv_probe,
+ .remove = am_meson_drv_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME,
+ .of_match_table = am_meson_drm_dt_match,
+ },
+};
+
+module_platform_driver(am_meson_drm_platform_driver);
+
+MODULE_AUTHOR("Jasper St. Pierre <jstpierre@mecheye.net>");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_AUTHOR("MultiMedia Amlogic <multimedia-sh@amlogic.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __MESON_DRV_H
-#define __MESON_DRV_H
+#ifndef __AM_MESON_DRV_H
+#define __AM_MESON_DRV_H
#include <linux/platform_device.h>
-#include <linux/regmap.h>
#include <linux/of.h>
#include <drm/drmP.h>
#ifdef CONFIG_DRM_MESON_USE_ION
#include <ion/ion_priv.h>
#endif
-struct meson_drm {
- struct device *dev;
+#define MESON_MAX_CRTC 2
-#ifndef CONFIG_DRM_MESON_BYPASS_MODE
- void __iomem *io_base;
- struct regmap *hhi;
- struct regmap *dmc;
-#endif
+/*
+ * Amlogic drm private crtc funcs.
+ * @loader_protect: protect loader logo crtc's power
+ * @enable_vblank: enable crtc vblank irq.
+ * @disable_vblank: disable crtc vblank irq.
+ */
+struct meson_crtc_funcs {
+ int (*loader_protect)(struct drm_crtc *crtc, bool on);
+ int (*enable_vblank)(struct drm_crtc *crtc);
+ void (*disable_vblank)(struct drm_crtc *crtc);
+};
- int vsync_irq;
+struct meson_drm {
+ struct device *dev;
struct drm_device *drm;
struct drm_crtc *crtc;
+ const struct meson_crtc_funcs *crtc_funcs[MESON_MAX_CRTC];
struct drm_fbdev_cma *fbdev;
struct drm_fb_helper *fbdev_helper;
struct drm_gem_object *fbdev_bo;
struct drm_plane *primary_plane;
struct drm_plane *cursor_plane;
-#ifndef CONFIG_DRM_MESON_BYPASS_MODE
- /* Components Data */
- struct {
- bool osd1_enabled;
- bool osd1_interlace;
- bool osd1_commit;
- uint32_t osd1_ctrl_stat;
- uint32_t osd1_blk0_cfg[5];
- } viu;
-
- struct {
- unsigned int current_mode;
- } venc;
-#endif
-
#ifdef CONFIG_DRM_MESON_USE_ION
struct ion_client *gem_client;
#endif
return of_device_is_compatible(priv->dev->of_node, compat);
}
-#endif /* __MESON_DRV_H */
+extern int am_meson_register_crtc_funcs(struct drm_crtc *crtc,
+ const struct meson_crtc_funcs *crtc_funcs);
+extern void am_meson_unregister_crtc_funcs(struct drm_crtc *crtc);
+
+#endif /* __AM_MESON_DRV_H */
#include <drm/drm_fb_helper.h>
#include <drm/drm_crtc_helper.h>
-#include "meson_drv.h"
+#include "am_meson_drv.h"
#include "am_meson_gem.h"
#include "am_meson_fb.h"
#include "am_meson_fbdev.h"
#define PREFERRED_BPP 32
#define MESON_DRM_MAX_CONNECTOR 2
-static int meson_fbdev_mmap(struct fb_info *info,
+static int am_meson_fbdev_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
struct drm_fb_helper *helper = info->par;
return am_meson_gem_object_mmap(meson_gem, vma);
}
-static int meson_drm_fbdev_sync(struct fb_info *info)
+static int am_meson_drm_fbdev_sync(struct fb_info *info)
{
return 0;
}
-static int meson_drm_fbdev_ioctl(struct fb_info *info,
+static int am_meson_drm_fbdev_ioctl(struct fb_info *info,
unsigned int cmd, unsigned long arg)
{
return 0;
static struct fb_ops meson_drm_fbdev_ops = {
.owner = THIS_MODULE,
- .fb_mmap = meson_fbdev_mmap,
+ .fb_mmap = am_meson_fbdev_mmap,
.fb_fillrect = drm_fb_helper_cfb_fillrect,
.fb_copyarea = drm_fb_helper_cfb_copyarea,
.fb_imageblit = drm_fb_helper_cfb_imageblit,
.fb_blank = drm_fb_helper_blank,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_setcmap = drm_fb_helper_setcmap,
- .fb_sync = meson_drm_fbdev_sync,
- .fb_ioctl = meson_drm_fbdev_ioctl,
+ .fb_sync = am_meson_drm_fbdev_sync,
+ .fb_ioctl = am_meson_drm_fbdev_ioctl,
#ifdef CONFIG_COMPAT
- .fb_compat_ioctl = meson_drm_fbdev_ioctl,
+ .fb_compat_ioctl = am_meson_drm_fbdev_ioctl,
#endif
};
-static int meson_drm_fbdev_create(struct drm_fb_helper *helper,
+static int am_meson_drm_fbdev_create(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
struct meson_drm *private = helper->dev->dev_private;
}
static const struct drm_fb_helper_funcs meson_drm_fb_helper_funcs = {
- .fb_probe = meson_drm_fbdev_create,
+ .fb_probe = am_meson_drm_fbdev_create,
};
-int meson_drm_fbdev_init(struct drm_device *dev)
+int am_meson_drm_fbdev_init(struct drm_device *dev)
{
struct meson_drm *private = dev->dev_private;
struct drm_fb_helper *helper;
return ret;
}
-void meson_drm_fbdev_fini(struct drm_device *dev)
+void am_meson_drm_fbdev_fini(struct drm_device *dev)
{
struct meson_drm *private = dev->dev_private;
struct drm_fb_helper *helper = private->fbdev_helper;
* GNU General Public License for more details.
*/
-#ifndef _MESON_DRM_FBDEV_H
-#define _MESON_DRM_FBDEV_H
+#ifndef __AM_MESON_FBDEV_H
+#define __AM_MESON_FBDEV_H
#ifdef CONFIG_DRM_MESON_EMULATE_FBDEV
-int meson_drm_fbdev_init(struct drm_device *dev);
-void meson_drm_fbdev_fini(struct drm_device *dev);
+int am_meson_drm_fbdev_init(struct drm_device *dev);
+void am_meson_drm_fbdev_fini(struct drm_device *dev);
#endif
-#endif /* _MESON_DRM_FBDEV_H */
+#endif /* __AM_MESON_FBDEV_H */
#include <linux/meson_ion.h>
#include <ion/ion.h>
-#include "meson_drv.h"
#include "am_meson_gem.h"
#define to_am_meson_gem_obj(x) container_of(x, struct am_meson_gem_object, base)
return addr;
}
+EXPORT_SYMBOL(am_meson_gem_object_get_phyaddr);
int am_meson_gem_dumb_create(
struct drm_file *file_priv,
#include <drm/drm_gem.h>
#include <linux/amlogic/meson_drm.h>
#include <ion/ion_priv.h>
-#include "meson_drv.h"
+
+#include "am_meson_drv.h"
struct am_meson_gem_object {
struct drm_gem_object base;
struct am_meson_gem_object *obj,
struct vm_area_struct *vma);
-int am_meson_gem_object_get_phyaddr(
+extern int am_meson_gem_object_get_phyaddr(
struct meson_drm *drm,
struct am_meson_gem_object *meson_gem);
#include <drm/drm_crtc_helper.h>
#include <drm/drm_atomic_helper.h>
+#include <linux/component.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/delay.h>
return connector_status_connected;
}
if (!(hdmitx_hpd_hw_op(HPD_READ_HPD_GPIO))) {
- DRM_INFO("connector_status_connected\n");
+ DRM_INFO("connector_status_disconnected\n");
return connector_status_disconnected;
}
return IRQ_HANDLED;
}
-int am_hdmi_connector_create(struct meson_drm *priv)
+static const struct of_device_id am_meson_hdmi_dt_ids[] = {
+ { .compatible = "amlogic,drm-amhdmitx", },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, am_meson_hdmi_dt_ids);
+
+static int am_meson_hdmi_bind(struct device *dev,
+ struct device *master, void *data)
{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct drm_device *drm = data;
+ struct meson_drm *priv = drm->dev_private;
struct am_hdmi_tx *am_hdmi;
- struct platform_device *pdev;
- struct drm_device *drm = priv->drm;
struct drm_connector *connector;
struct drm_encoder *encoder;
+
int ret;
int irq;
DRM_INFO("hdmi connector init\n");
am_hdmi->priv = priv;
- pdev = to_platform_device(am_hdmi->priv->dev);
encoder = &am_hdmi->encoder;
connector = &am_hdmi->connector;
return 0;
}
-int am_hdmi_connector_cleanup(struct drm_device *dev)
+static void am_meson_hdmi_unbind(struct device *dev,
+ struct device *master, void *data)
{
am_hdmi_info.connector.funcs->destroy(&am_hdmi_info.connector);
am_hdmi_info.encoder.funcs->destroy(&am_hdmi_info.encoder);
+}
+
+static const struct component_ops am_meson_hdmi_ops = {
+ .bind = am_meson_hdmi_bind,
+ .unbind = am_meson_hdmi_unbind,
+};
+
+static int am_meson_hdmi_probe(struct platform_device *pdev)
+{
+ return component_add(&pdev->dev, &am_meson_hdmi_ops);
+}
+
+static int am_meson_hdmi_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &am_meson_hdmi_ops);
return 0;
}
+
+static struct platform_driver am_meson_hdmi_pltfm_driver = {
+ .probe = am_meson_hdmi_probe,
+ .remove = am_meson_hdmi_remove,
+ .driver = {
+ .name = "meson-amhdmitx",
+ .of_match_table = am_meson_hdmi_dt_ids,
+ },
+};
+
+module_platform_driver(am_meson_hdmi_pltfm_driver);
+
+MODULE_AUTHOR("MultiMedia Amlogic <multimedia-sh@amlogic.com>");
+MODULE_DESCRIPTION("Amlogic Meson Drm HDMI driver");
+MODULE_LICENSE("GPL");
#ifndef __AM_MESON_HDMI_H
#define __AM_MESON_HDMI_H
-#include "meson_drv.h"
+#include "am_meson_drv.h"
#define DDC_SEGMENT_ADDR 0x30
#define VIC_MAX_NUM 512
#define to_am_hdmi(x) container_of(x, struct am_hdmi_tx, x)
-int am_hdmi_connector_create(struct meson_drm *priv);
-int am_hdmi_connector_cleanup(struct drm_device *dev);
-
#define HDMITX_REG_IDX 6
#define HDMITX_SEC_REG_IDX 7
#define BASE_REG_OFFSET 24
#include <drm/drm_panel.h>
#include <drm/drm_mipi_dsi.h>
#include <video/display_timing.h>
+#include <linux/component.h>
#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
#include <linux/amlogic/media/vout/lcd/lcd_notify.h>
-#include "meson_drv.h"
#include "am_meson_lcd.h"
struct am_drm_lcd_s {
pr_info("am_drm_lcd: %s %d\n", __func__, __LINE__);
}
-int am_drm_lcd_register(struct drm_device *drm)
+static const struct of_device_id am_meson_lcd_dt_ids[] = {
+ { .compatible = "amlogic,drm-lcd", },
+ {},
+};
+
+static int am_meson_lcd_bind(struct device *dev, struct device *master,
+ void *data)
{
+ struct drm_device *drm = data;
struct drm_connector *connector;
struct drm_encoder *encoder;
int encoder_type, connector_type;
return ret;
}
-int am_drm_lcd_unregister(struct drm_device *drm)
+static void am_meson_lcd_unbind(struct device *dev, struct device *master,
+ void *data)
{
- int ret = 0;
-
if (!am_drm_lcd)
- return -ENODEV;
+ return;
if (!am_drm_lcd->lcd_drv)
- return -ENODEV;
+ return;
pr_info("am_drm_lcd: %s %d\n", __func__, __LINE__);
pr_info("am_drm_lcd: %s %d\n", __func__, __LINE__);
- return ret;
+ return;
+}
+
+static const struct component_ops am_meson_lcd_ops = {
+ .bind = am_meson_lcd_bind,
+ .unbind = am_meson_lcd_unbind,
+};
+
+static int am_meson_lcd_probe(struct platform_device *pdev)
+{
+ return component_add(&pdev->dev, &am_meson_lcd_ops);
}
+
+static int am_meson_lcd_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &am_meson_lcd_ops);
+ return 0;
+}
+
+static struct platform_driver am_meson_lcd_pltfm_driver = {
+ .probe = am_meson_lcd_probe,
+ .remove = am_meson_lcd_remove,
+ .driver = {
+ .name = "meson-lcd",
+ .of_match_table = am_meson_lcd_dt_ids,
+ },
+};
+
+module_platform_driver(am_meson_lcd_pltfm_driver);
+
+MODULE_AUTHOR("MultiMedia Amlogic <multimedia-sh@amlogic.com>");
+MODULE_DESCRIPTION("Amlogic Meson Drm LCD driver");
+MODULE_LICENSE("GPL");
#ifndef __AM_DRM_LCD_H
#define __AM_DRM_LCD_H
-#include "meson_drv.h"
-
-extern int am_drm_lcd_register(struct drm_device *drm);
-extern int am_drm_lcd_unregister(struct drm_device *drm);
+#include "am_meson_drv.h"
#endif
+++ /dev/null
-/*
- * drivers/amlogic/drm/am_meson_plane.c
- *
- * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#include <drm/drmP.h>
-#include <drm/drm_plane.h>
-#include <drm/drm_atomic.h>
-#include <drm/drm_plane_helper.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_fb_cma_helper.h>
-#include <drm/drm_gem_cma_helper.h>
-
-#include "osd.h"
-#include "osd_drm.h"
-
-#include "meson_plane.h"
-#ifdef CONFIG_DRM_MESON_USE_ION
-#include "am_meson_fb.h"
-#endif
-
-#define to_am_osd_plane(x) container_of(x, struct am_osd_plane, base)
-
-struct am_osd_plane {
- struct drm_plane base; //must be first element.
- struct meson_drm *drv; //point to struct parent.
- struct dentry *plane_debugfs_dir;
-
- u32 osd_idx;
-};
-
-static const struct drm_plane_funcs am_osd_plane_funs = {
- .update_plane = drm_atomic_helper_update_plane,
- .disable_plane = drm_atomic_helper_disable_plane,
- .destroy = drm_plane_cleanup,
- .reset = drm_atomic_helper_plane_reset,
- .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
-};
-
-int am_osd_begin_display(
- struct drm_plane *plane,
- struct drm_plane_state *new_state)
-{
- struct am_osd_plane *osd_plane = to_am_osd_plane(plane);
-
- DRM_DEBUG("%s osd %d.\n", __func__, osd_plane->osd_idx);
- return 0;
-}
-
-void am_osd_end_display(
- struct drm_plane *plane,
- struct drm_plane_state *old_state)
-{
- struct am_osd_plane *osd_plane = to_am_osd_plane(plane);
-
- DRM_DEBUG("%s osd %d.\n", __func__, osd_plane->osd_idx);
-}
-
-void am_osd_do_display(
- struct drm_plane *plane,
- struct drm_plane_state *old_state)
-{
- struct am_osd_plane *osd_plane = to_am_osd_plane(plane);
- struct drm_plane_state *state = plane->state;
- struct drm_framebuffer *fb = state->fb;
- struct meson_drm *drv = osd_plane->drv;
- struct osd_plane_map_s plane_map;
-#ifdef CONFIG_DRM_MESON_USE_ION
- struct am_meson_fb *meson_fb;
-#else
- struct drm_gem_cma_object *gem;
-#endif
- int format = DRM_FORMAT_ARGB8888;
- dma_addr_t phyaddr;
- unsigned long flags;
-
- //DRM_INFO("%s osd %d.\n", __func__, osd_plane->osd_idx);
-
- switch (fb->pixel_format) {
- case DRM_FORMAT_XRGB8888:
- /*
- *force convert to ARGB8888 format,
- *because overlay layer needs to display
- */
- format = COLOR_INDEX_32_XRGB;//COLOR_INDEX_32_ARGB;
- break;
- case DRM_FORMAT_XBGR8888:
- format = COLOR_INDEX_32_XBGR;
- break;
- case DRM_FORMAT_RGBX8888:
- format = COLOR_INDEX_32_RGBX;
- break;
- case DRM_FORMAT_BGRX8888:
- format = COLOR_INDEX_32_BGRX;
- break;
- case DRM_FORMAT_ARGB8888:
- format = COLOR_INDEX_32_ARGB;
- break;
- case DRM_FORMAT_ABGR8888:
- format = COLOR_INDEX_32_ABGR;
- break;
- case DRM_FORMAT_RGBA8888:
- format = COLOR_INDEX_32_RGBA;
- break;
- case DRM_FORMAT_BGRA8888:
- format = COLOR_INDEX_32_BGRA;
- break;
- case DRM_FORMAT_RGB888:
- format = COLOR_INDEX_24_RGB;
- break;
- case DRM_FORMAT_RGB565:
- format = COLOR_INDEX_16_565;
- break;
- case DRM_FORMAT_ARGB1555:
- format = COLOR_INDEX_16_1555_A;
- break;
- case DRM_FORMAT_ARGB4444:
- format = COLOR_INDEX_16_4444_A;
- break;
- default:
- DRM_INFO("unsupport fb->pixel_format=%x\n", fb->pixel_format);
- break;
- };
-
- spin_lock_irqsave(&drv->drm->event_lock, flags);
-
-#ifdef CONFIG_DRM_MESON_USE_ION
- meson_fb = container_of(fb, struct am_meson_fb, base);
- phyaddr = am_meson_gem_object_get_phyaddr(drv, meson_fb->bufp);
- if (meson_fb->bufp->bscatter)
- DRM_ERROR("ERROR:am_meson_plane meet a scatter framebuffer.\n");
-#else
- /* Update Canvas with buffer address */
- gem = drm_fb_cma_get_gem_obj(fb, 0);
- phyaddr = gem->paddr;
-#endif
-
- /* setup osd display parameters */
- plane_map.plane_index = osd_plane->osd_idx;
- plane_map.zorder = state->zpos;
- plane_map.phy_addr = phyaddr;
- plane_map.enable = 1;
- plane_map.format = format;
- plane_map.byte_stride = fb->pitches[0];
-
- plane_map.src_x = state->src_x;
- plane_map.src_y = state->src_y;
- plane_map.src_w = (state->src_w >> 16) & 0xffff;
- plane_map.src_h = (state->src_h >> 16) & 0xffff;
-
- plane_map.dst_x = state->crtc_x;
- plane_map.dst_y = state->crtc_y;
- plane_map.dst_w = state->crtc_w;
- plane_map.dst_h = state->crtc_h;
- #if 0
- DRM_INFO("flags:%d pixel_format:%d,zpos=%d\n",
- fb->flags, fb->pixel_format, state->zpos);
- DRM_INFO("plane index=%d, type=%d\n", plane->index, plane->type);
- #endif
- osd_drm_plane_page_flip(&plane_map);
-
- spin_unlock_irqrestore(&drv->drm->event_lock, flags);
-}
-
-int am_osd_check(struct drm_plane *plane, struct drm_plane_state *state)
-{
- struct am_osd_plane *osd_plane = to_am_osd_plane(plane);
-
- DRM_DEBUG("%s osd %d.\n", __func__, osd_plane->osd_idx);
- return 0;
-}
-
-void am_osd_blank(struct drm_plane *plane, struct drm_plane_state *old_state)
-{
- struct am_osd_plane *osd_plane = to_am_osd_plane(plane);
-
- DRM_DEBUG("%s osd %d.\n", __func__, osd_plane->osd_idx);
-}
-
-static const struct drm_plane_helper_funcs am_osd_helper_funcs = {
- .prepare_fb = am_osd_begin_display,
- .cleanup_fb = am_osd_end_display,
- .atomic_update = am_osd_do_display,
- .atomic_check = am_osd_check,
- .atomic_disable = am_osd_blank,
-};
-
-static const uint32_t supported_drm_formats[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_RGB565,
-};
-
-struct am_osd_plane *am_osd_plane_create(struct meson_drm *priv, u32 type)
-{
- struct am_osd_plane *osd_plane;
- struct drm_plane *plane;
- char *plane_name = NULL;
-
- osd_plane = devm_kzalloc(priv->drm->dev, sizeof(*osd_plane),
- GFP_KERNEL);
- if (!osd_plane)
- return 0;
-
- osd_plane->drv = priv;
- plane = &osd_plane->base;
-
- if (type == DRM_PLANE_TYPE_PRIMARY) {
- osd_plane->osd_idx = 0;
- plane_name = "osd-0";
- } else if (type == DRM_PLANE_TYPE_CURSOR) {
- osd_plane->osd_idx = 1;
- plane_name = "osd-1";
- }
-
- drm_universal_plane_init(priv->drm, plane, 0xFF,
- &am_osd_plane_funs,
- supported_drm_formats,
- ARRAY_SIZE(supported_drm_formats),
- type, plane_name);
-
- drm_plane_helper_add(plane, &am_osd_helper_funcs);
- osd_drm_debugfs_add(&(osd_plane->plane_debugfs_dir),
- plane_name, osd_plane->osd_idx);
- return osd_plane;
-}
-
-int meson_plane_create(struct meson_drm *priv)
-{
- struct am_osd_plane *plane;
-
- DRM_DEBUG("%s. enter\n", __func__);
- /*crate primary plane*/
- plane = am_osd_plane_create(priv, DRM_PLANE_TYPE_PRIMARY);
- if (plane == NULL)
- return -ENOMEM;
-
- priv->primary_plane = &(plane->base);
-
- /*crate cursor plane*/
- plane = am_osd_plane_create(priv, DRM_PLANE_TYPE_CURSOR);
- if (plane == NULL)
- return -ENOMEM;
-
- priv->cursor_plane = &(plane->base);
-
- return 0;
-}
-
--- /dev/null
+/*
+ * drivers/amlogic/drm/am_meson_vpu.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+#include <drm/drmP.h>
+#include <drm/drm_plane.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/component.h>
+#ifdef CONFIG_DRM_MESON_USE_ION
+#include <ion/ion_priv.h>
+#endif
+
+/* Amlogic Headers */
+#include <linux/amlogic/media/vout/vout_notify.h>
+
+#include "osd.h"
+#include "osd_drm.h"
+#ifdef CONFIG_DRM_MESON_USE_ION
+#include "am_meson_fb.h"
+#endif
+#include "am_meson_vpu.h"
+
+/*
+ * Video Processing Unit
+ *
+ * VPU Handles the Global Video Processing, it includes management of the
+ * clocks gates, blocks reset lines and power domains.
+ *
+ * What is missing :
+ * - Full reset of entire video processing HW blocks
+ * - Scaling and setup of the VPU clock
+ * - Bus clock gates
+ * - Powering up video processing HW blocks
+ * - Powering Up HDMI controller and PHY
+ */
+struct am_osd_plane {
+ struct drm_plane base; //must be first element.
+ struct meson_drm *drv; //point to struct parent.
+ struct dentry *plane_debugfs_dir;
+
+ u32 osd_idx;
+};
+#define to_am_osd_plane(x) container_of(x, struct am_osd_plane, base)
+
+struct am_meson_crtc {
+ struct drm_crtc base;
+ struct device *dev;
+ struct drm_device *drm_dev;
+
+ struct meson_drm *priv;
+
+ struct drm_pending_vblank_event *event;
+
+ unsigned int irq;
+
+ struct dentry *crtc_debugfs_dir;
+};
+
+#define to_am_meson_crtc(x) container_of(x, struct am_meson_crtc, base)
+
+struct am_vout_mode {
+ char name[DRM_DISPLAY_MODE_LEN];
+ enum vmode_e mode;
+ int width, height, vrefresh;
+ unsigned int flags;
+};
+
+static struct am_vout_mode am_vout_modes[] = {
+ { "1080p60hz", VMODE_HDMI, 1920, 1080, 60, 0},
+ { "1080p30hz", VMODE_HDMI, 1920, 1080, 30, 0},
+ { "1080p50hz", VMODE_HDMI, 1920, 1080, 50, 0},
+ { "1080p25hz", VMODE_HDMI, 1920, 1080, 25, 0},
+ { "1080p24hz", VMODE_HDMI, 1920, 1080, 24, 0},
+ { "2160p30hz", VMODE_HDMI, 3840, 2160, 30, 0},
+ { "2160p60hz", VMODE_HDMI, 3840, 2160, 60, 0},
+ { "2160p50hz", VMODE_HDMI, 3840, 2160, 50, 0},
+ { "2160p25hz", VMODE_HDMI, 3840, 2160, 25, 0},
+ { "2160p24hz", VMODE_HDMI, 3840, 2160, 24, 0},
+ { "1080i60hz", VMODE_HDMI, 1920, 1080, 60, DRM_MODE_FLAG_INTERLACE},
+ { "1080i50hz", VMODE_HDMI, 1920, 1080, 50, DRM_MODE_FLAG_INTERLACE},
+ { "720p60hz", VMODE_HDMI, 1280, 720, 60, 0},
+ { "720p50hz", VMODE_HDMI, 1280, 720, 50, 0},
+ { "480p60hz", VMODE_HDMI, 720, 480, 60, 0},
+ { "480i60hz", VMODE_HDMI, 720, 480, 60, DRM_MODE_FLAG_INTERLACE},
+ { "576p50hz", VMODE_HDMI, 720, 576, 50, 0},
+ { "576i50hz", VMODE_HDMI, 720, 576, 50, DRM_MODE_FLAG_INTERLACE},
+ { "480p60hz", VMODE_HDMI, 720, 480, 60, 0},
+};
+
+
+static struct osd_device_data_s osd_gxbb = {
+ .cpu_id = __MESON_CPU_MAJOR_ID_GXBB,
+ .osd_ver = OSD_NORMAL,
+ .afbc_type = NO_AFBC,
+ .osd_count = 2,
+ .has_deband = 0,
+ .has_lut = 0,
+ .has_rdma = 1,
+ .has_dolby_vision = 0,
+ .osd_fifo_len = 32,
+ .vpp_fifo_len = 0x77f,
+ .dummy_data = 0x00808000,
+ .has_viu2 = 0,
+};
+
+static struct osd_device_data_s osd_gxl = {
+ .cpu_id = __MESON_CPU_MAJOR_ID_GXL,
+ .osd_ver = OSD_NORMAL,
+ .afbc_type = NO_AFBC,
+ .osd_count = 2,
+ .has_deband = 0,
+ .has_lut = 0,
+ .has_rdma = 1,
+ .has_dolby_vision = 0,
+ .osd_fifo_len = 32,
+ .vpp_fifo_len = 0x77f,
+ .dummy_data = 0x00808000,
+ .has_viu2 = 0,
+};
+
+static struct osd_device_data_s osd_gxm = {
+ .cpu_id = __MESON_CPU_MAJOR_ID_GXM,
+ .osd_ver = OSD_NORMAL,
+ .afbc_type = MESON_AFBC,
+ .osd_count = 2,
+ .has_deband = 0,
+ .has_lut = 0,
+ .has_rdma = 1,
+ .has_dolby_vision = 0,
+ .osd_fifo_len = 32,
+ .vpp_fifo_len = 0xfff,
+ .dummy_data = 0x00202000,/* dummy data is different */
+ .has_viu2 = 0,
+};
+
+static struct osd_device_data_s osd_txl = {
+ .cpu_id = __MESON_CPU_MAJOR_ID_TXL,
+ .osd_ver = OSD_NORMAL,
+ .afbc_type = NO_AFBC,
+ .osd_count = 2,
+ .has_deband = 0,
+ .has_lut = 0,
+ .has_rdma = 1,
+ .has_dolby_vision = 0,
+ .osd_fifo_len = 64,
+ .vpp_fifo_len = 0x77f,
+ .dummy_data = 0x00808000,
+ .has_viu2 = 0,
+};
+
+static struct osd_device_data_s osd_txlx = {
+ .cpu_id = __MESON_CPU_MAJOR_ID_TXLX,
+ .osd_ver = OSD_NORMAL,
+ .afbc_type = NO_AFBC,
+ .osd_count = 2,
+ .has_deband = 1,
+ .has_lut = 1,
+ .has_rdma = 1,
+ .has_dolby_vision = 1,
+ .osd_fifo_len = 64, /* fifo len 64*8 = 512 */
+ .vpp_fifo_len = 0x77f,
+ .dummy_data = 0x00808000,
+ .has_viu2 = 0,
+};
+
+static struct osd_device_data_s osd_axg = {
+ .cpu_id = __MESON_CPU_MAJOR_ID_AXG,
+ .osd_ver = OSD_SIMPLE,
+ .afbc_type = NO_AFBC,
+ .osd_count = 1,
+ .has_deband = 1,
+ .has_lut = 1,
+ .has_rdma = 0,
+ .has_dolby_vision = 0,
+ /* use iomap its self, no rdma, no canvas, no freescale */
+ .osd_fifo_len = 64, /* fifo len 64*8 = 512 */
+ .vpp_fifo_len = 0x400,
+ .dummy_data = 0x00808000,
+ .has_viu2 = 0,
+};
+
+static struct osd_device_data_s osd_g12a = {
+ .cpu_id = __MESON_CPU_MAJOR_ID_G12A,
+ .osd_ver = OSD_HIGH_ONE,
+ .afbc_type = MALI_AFBC,
+ .osd_count = 3,
+ .has_deband = 1,
+ .has_lut = 1,
+ .has_rdma = 1,
+ .has_dolby_vision = 0,
+ .osd_fifo_len = 64, /* fifo len 64*8 = 512 */
+ .vpp_fifo_len = 0xfff,/* 2048 */
+ .dummy_data = 0x00808000,
+ .has_viu2 = 1,
+};
+
+static struct osd_device_data_s osd_meson_dev;
+
+int am_meson_crtc_dts_info_set(const void *dt_match_data)
+{
+ struct osd_device_data_s *osd_meson;
+
+ osd_meson = (struct osd_device_data_s *)dt_match_data;
+ if (osd_meson)
+ memcpy(&osd_meson_dev, osd_meson,
+ sizeof(struct osd_device_data_s));
+ else {
+ DRM_ERROR("%s data NOT match\n", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static const struct drm_plane_funcs am_osd_plane_funs = {
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = drm_plane_cleanup,
+ .reset = drm_atomic_helper_plane_reset,
+ .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+int am_osd_begin_display(
+ struct drm_plane *plane,
+ struct drm_plane_state *new_state)
+{
+ struct am_osd_plane *osd_plane = to_am_osd_plane(plane);
+
+ DRM_DEBUG("%s osd %d.\n", __func__, osd_plane->osd_idx);
+ return 0;
+}
+
+void am_osd_end_display(
+ struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct am_osd_plane *osd_plane = to_am_osd_plane(plane);
+
+ DRM_DEBUG("%s osd %d.\n", __func__, osd_plane->osd_idx);
+}
+
+void am_osd_do_display(
+ struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct am_osd_plane *osd_plane = to_am_osd_plane(plane);
+ struct drm_plane_state *state = plane->state;
+ struct drm_framebuffer *fb = state->fb;
+ struct meson_drm *drv = osd_plane->drv;
+ struct osd_plane_map_s plane_map;
+#ifdef CONFIG_DRM_MESON_USE_ION
+ struct am_meson_fb *meson_fb;
+#else
+ struct drm_gem_cma_object *gem;
+#endif
+ int format = DRM_FORMAT_ARGB8888;
+ dma_addr_t phyaddr;
+ unsigned long flags;
+
+ //DRM_INFO("%s osd %d.\n", __func__, osd_plane->osd_idx);
+
+ switch (fb->pixel_format) {
+ case DRM_FORMAT_XRGB8888:
+ /*
+ *force convert to ARGB8888 format,
+ *because overlay layer needs to display
+ */
+ format = COLOR_INDEX_32_XRGB;//COLOR_INDEX_32_ARGB;
+ break;
+ case DRM_FORMAT_XBGR8888:
+ format = COLOR_INDEX_32_XBGR;
+ break;
+ case DRM_FORMAT_RGBX8888:
+ format = COLOR_INDEX_32_RGBX;
+ break;
+ case DRM_FORMAT_BGRX8888:
+ format = COLOR_INDEX_32_BGRX;
+ break;
+ case DRM_FORMAT_ARGB8888:
+ format = COLOR_INDEX_32_ARGB;
+ break;
+ case DRM_FORMAT_ABGR8888:
+ format = COLOR_INDEX_32_ABGR;
+ break;
+ case DRM_FORMAT_RGBA8888:
+ format = COLOR_INDEX_32_RGBA;
+ break;
+ case DRM_FORMAT_BGRA8888:
+ format = COLOR_INDEX_32_BGRA;
+ break;
+ case DRM_FORMAT_RGB888:
+ format = COLOR_INDEX_24_RGB;
+ break;
+ case DRM_FORMAT_RGB565:
+ format = COLOR_INDEX_16_565;
+ break;
+ case DRM_FORMAT_ARGB1555:
+ format = COLOR_INDEX_16_1555_A;
+ break;
+ case DRM_FORMAT_ARGB4444:
+ format = COLOR_INDEX_16_4444_A;
+ break;
+ default:
+ DRM_INFO("unsupport fb->pixel_format=%x\n", fb->pixel_format);
+ break;
+ };
+
+ spin_lock_irqsave(&drv->drm->event_lock, flags);
+
+#ifdef CONFIG_DRM_MESON_USE_ION
+ meson_fb = container_of(fb, struct am_meson_fb, base);
+ phyaddr = am_meson_gem_object_get_phyaddr(drv, meson_fb->bufp);
+ if (meson_fb->bufp->bscatter)
+ DRM_ERROR("ERROR:am_meson_plane meet a scatter framebuffer.\n");
+#else
+ /* Update Canvas with buffer address */
+ gem = drm_fb_cma_get_gem_obj(fb, 0);
+ phyaddr = gem->paddr;
+#endif
+
+ /* setup osd display parameters */
+ plane_map.plane_index = osd_plane->osd_idx;
+ plane_map.zorder = state->zpos;
+ plane_map.phy_addr = phyaddr;
+ plane_map.enable = 1;
+ plane_map.format = format;
+ plane_map.byte_stride = fb->pitches[0];
+
+ plane_map.src_x = state->src_x;
+ plane_map.src_y = state->src_y;
+ plane_map.src_w = (state->src_w >> 16) & 0xffff;
+ plane_map.src_h = (state->src_h >> 16) & 0xffff;
+
+ plane_map.dst_x = state->crtc_x;
+ plane_map.dst_y = state->crtc_y;
+ plane_map.dst_w = state->crtc_w;
+ plane_map.dst_h = state->crtc_h;
+ #if 0
+ DRM_INFO("flags:%d pixel_format:%d,zpos=%d\n",
+ fb->flags, fb->pixel_format, state->zpos);
+ DRM_INFO("plane index=%d, type=%d\n", plane->index, plane->type);
+ #endif
+ osd_drm_plane_page_flip(&plane_map);
+
+ spin_unlock_irqrestore(&drv->drm->event_lock, flags);
+}
+
+int am_osd_check(struct drm_plane *plane, struct drm_plane_state *state)
+{
+ struct am_osd_plane *osd_plane = to_am_osd_plane(plane);
+
+ DRM_DEBUG("%s osd %d.\n", __func__, osd_plane->osd_idx);
+ return 0;
+}
+
+void am_osd_blank(struct drm_plane *plane, struct drm_plane_state *old_state)
+{
+ struct am_osd_plane *osd_plane = to_am_osd_plane(plane);
+
+ DRM_DEBUG("%s osd %d.\n", __func__, osd_plane->osd_idx);
+}
+
+static const struct drm_plane_helper_funcs am_osd_helper_funcs = {
+ .prepare_fb = am_osd_begin_display,
+ .cleanup_fb = am_osd_end_display,
+ .atomic_update = am_osd_do_display,
+ .atomic_check = am_osd_check,
+ .atomic_disable = am_osd_blank,
+};
+
+static const uint32_t supported_drm_formats[] = {
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_RGB565,
+};
+
+struct am_osd_plane *am_osd_plane_create(struct meson_drm *priv, u32 type)
+{
+ struct am_osd_plane *osd_plane;
+ struct drm_plane *plane;
+ char *plane_name = NULL;
+
+ osd_plane = devm_kzalloc(priv->drm->dev, sizeof(*osd_plane),
+ GFP_KERNEL);
+ if (!osd_plane)
+ return 0;
+
+ osd_plane->drv = priv;
+ plane = &osd_plane->base;
+
+ if (type == DRM_PLANE_TYPE_PRIMARY) {
+ osd_plane->osd_idx = 0;
+ plane_name = "osd-0";
+ } else if (type == DRM_PLANE_TYPE_CURSOR) {
+ osd_plane->osd_idx = 1;
+ plane_name = "osd-1";
+ }
+
+ drm_universal_plane_init(priv->drm, plane, 0xFF,
+ &am_osd_plane_funs,
+ supported_drm_formats,
+ ARRAY_SIZE(supported_drm_formats),
+ type, plane_name);
+
+ drm_plane_helper_add(plane, &am_osd_helper_funcs);
+ osd_drm_debugfs_add(&(osd_plane->plane_debugfs_dir),
+ plane_name, osd_plane->osd_idx);
+ return osd_plane;
+}
+
+int am_meson_plane_create(struct meson_drm *priv)
+{
+ struct am_osd_plane *plane;
+
+ DRM_DEBUG("%s. enter\n", __func__);
+ /*crate primary plane*/
+ plane = am_osd_plane_create(priv, DRM_PLANE_TYPE_PRIMARY);
+ if (plane == NULL)
+ return -ENOMEM;
+
+ priv->primary_plane = &(plane->base);
+
+ /*crate cursor plane*/
+ plane = am_osd_plane_create(priv, DRM_PLANE_TYPE_CURSOR);
+ if (plane == NULL)
+ return -ENOMEM;
+
+ priv->cursor_plane = &(plane->base);
+
+ return 0;
+}
+
+char *am_meson_crtc_get_voutmode(struct drm_display_mode *mode)
+{
+ int i;
+
+ if (!strcmp(mode->name, "panel"))
+ return "panel";
+
+ for (i = 0; i < ARRAY_SIZE(am_vout_modes); i++) {
+ if ((am_vout_modes[i].width == mode->hdisplay)
+ && (am_vout_modes[i].height == mode->vdisplay)
+ && (am_vout_modes[i].vrefresh == mode->vrefresh)
+ && (am_vout_modes[i].flags ==
+ (mode->flags&DRM_MODE_FLAG_INTERLACE)))
+ return am_vout_modes[i].name;
+ }
+ return NULL;
+}
+
+void am_meson_crtc_handle_vsync(struct am_meson_crtc *amcrtc)
+{
+ unsigned long flags;
+ struct drm_crtc *crtc;
+
+ crtc = &amcrtc->base;
+ drm_crtc_handle_vblank(crtc);
+
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ if (amcrtc->event) {
+ drm_crtc_send_vblank_event(crtc, amcrtc->event);
+ drm_crtc_vblank_put(crtc);
+ amcrtc->event = NULL;
+ }
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+}
+
+int am_meson_crtc_set_mode(struct drm_mode_set *set)
+{
+ struct am_meson_crtc *amcrtc;
+ int ret;
+
+ DRM_DEBUG_DRIVER("%s\n", __func__);
+ amcrtc = to_am_meson_crtc(set->crtc);
+ ret = drm_atomic_helper_set_config(set);
+
+ return ret;
+}
+
+static const struct drm_crtc_funcs am_meson_crtc_funcs = {
+ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+ .destroy = drm_crtc_cleanup,
+ .page_flip = drm_atomic_helper_page_flip,
+ .reset = drm_atomic_helper_crtc_reset,
+ .set_config = am_meson_crtc_set_mode,
+};
+
+static int am_meson_crtc_loader_protect(struct drm_crtc *crtc, bool on)
+{
+ struct am_meson_crtc *amcrtc = to_am_meson_crtc(crtc);
+
+ DRM_INFO("%s %d\n", __func__, on);
+
+ if (on) {
+ enable_irq(amcrtc->irq);
+ drm_crtc_vblank_on(crtc);
+ } else {
+ disable_irq(amcrtc->irq);
+ drm_crtc_vblank_off(crtc);
+ }
+
+ return 0;
+}
+
+static int am_meson_crtc_enable_vblank(struct drm_crtc *crtc)
+{
+ return 0;
+}
+
+static void am_meson_crtc_disable_vblank(struct drm_crtc *crtc)
+{
+}
+
+static const struct meson_crtc_funcs meson_private_crtc_funcs = {
+ .loader_protect = am_meson_crtc_loader_protect,
+ .enable_vblank = am_meson_crtc_enable_vblank,
+ .disable_vblank = am_meson_crtc_disable_vblank,
+};
+
+static bool am_meson_crtc_mode_fixup(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adj_mode)
+{
+ //DRM_INFO("%s !!\n", __func__);
+
+ return true;
+}
+
+void am_meson_crtc_enable(struct drm_crtc *crtc)
+{
+ char *name;
+ enum vmode_e mode;
+ struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
+ struct am_meson_crtc *amcrtc = to_am_meson_crtc(crtc);
+
+ DRM_INFO("%s\n", __func__);
+ if (!adjusted_mode) {
+ DRM_ERROR("meson_crtc_enable fail, unsupport mode:%s\n",
+ adjusted_mode->name);
+ return;
+ }
+ DRM_INFO("%s: %s\n", __func__, adjusted_mode->name);
+ name = am_meson_crtc_get_voutmode(adjusted_mode);
+ mode = validate_vmode(name);
+ if (mode == VMODE_MAX) {
+ DRM_ERROR("no matched vout mode\n");
+ return;
+ }
+
+ set_vout_init(mode);
+ update_vout_viu();
+
+ enable_irq(amcrtc->irq);
+}
+
+void am_meson_crtc_disable(struct drm_crtc *crtc)
+{
+ struct am_meson_crtc *amcrtc = to_am_meson_crtc(crtc);
+
+ DRM_INFO("%s\n", __func__);
+ if (crtc->state->event && !crtc->state->active) {
+ spin_lock_irq(&crtc->dev->event_lock);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ spin_unlock_irq(&crtc->dev->event_lock);
+
+ crtc->state->event = NULL;
+ }
+
+ disable_irq(amcrtc->irq);
+}
+
+void am_meson_crtc_commit(struct drm_crtc *crtc)
+{
+ //DRM_INFO("%s\n", __func__);
+}
+
+void am_meson_crtc_atomic_begin(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+ struct am_meson_crtc *amcrtc;
+ unsigned long flags;
+
+ amcrtc = to_am_meson_crtc(crtc);
+
+ if (crtc->state->event) {
+ WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ amcrtc->event = crtc->state->event;
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+ crtc->state->event = NULL;
+ }
+}
+
+void am_meson_crtc_atomic_flush(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+{
+}
+
+static const struct drm_crtc_helper_funcs am_crtc_helper_funcs = {
+ .enable = am_meson_crtc_enable,
+ .disable = am_meson_crtc_disable,
+ .commit = am_meson_crtc_commit,
+ .mode_fixup = am_meson_crtc_mode_fixup,
+ .atomic_begin = am_meson_crtc_atomic_begin,
+ .atomic_flush = am_meson_crtc_atomic_flush,
+};
+
+int am_meson_crtc_create(struct am_meson_crtc *amcrtc)
+{
+ struct meson_drm *priv = amcrtc->priv;
+ struct drm_crtc *crtc = &amcrtc->base;
+ int ret;
+
+ DRM_INFO("%s\n", __func__);
+ ret = drm_crtc_init_with_planes(priv->drm, crtc,
+ priv->primary_plane, priv->cursor_plane,
+ &am_meson_crtc_funcs, "amlogic vpu");
+ if (ret) {
+ dev_err(amcrtc->dev, "Failed to init CRTC\n");
+ return ret;
+ }
+
+ drm_crtc_helper_add(crtc, &am_crtc_helper_funcs);
+ osd_drm_init(&osd_meson_dev);
+
+ priv->crtc = crtc;
+ return 0;
+}
+
+void am_meson_crtc_irq(struct meson_drm *priv)
+{
+ struct am_meson_crtc *amcrtc = to_am_meson_crtc(priv->crtc);
+
+ osd_drm_vsync_isr_handler();
+ am_meson_crtc_handle_vsync(amcrtc);
+}
+
+static irqreturn_t am_meson_vpu_irq(int irq, void *arg)
+{
+ struct drm_device *dev = arg;
+ struct meson_drm *priv = dev->dev_private;
+
+ am_meson_crtc_irq(priv);
+
+ return IRQ_HANDLED;
+}
+
+static int am_meson_vpu_bind(struct device *dev,
+ struct device *master, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct drm_device *drm_dev = data;
+ struct meson_drm *private = drm_dev->dev_private;
+ struct am_meson_crtc *amcrtc;
+
+ int ret, irq;
+
+ /* Allocate crtc struct */
+ DRM_DEBUG("%s\n", __func__);
+ amcrtc = devm_kzalloc(dev, sizeof(*amcrtc),
+ GFP_KERNEL);
+ if (!amcrtc)
+ return -ENOMEM;
+
+ amcrtc->priv = private;
+ amcrtc->dev = dev;
+ amcrtc->drm_dev = drm_dev;
+
+ dev_set_drvdata(dev, amcrtc);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(dev, "cannot find irq for vpu\n");
+ return irq;
+ }
+ amcrtc->irq = (unsigned int)irq;
+
+ ret = devm_request_irq(dev, amcrtc->irq, am_meson_vpu_irq,
+ IRQF_SHARED, dev_name(dev), drm_dev);
+ if (ret)
+ return ret;
+ /* IRQ is initially disabled; it gets enabled in crtc_enable */
+ disable_irq(amcrtc->irq);
+
+ ret = am_meson_plane_create(private);
+ if (ret)
+ return ret;
+
+ ret = am_meson_crtc_create(amcrtc);
+ if (ret)
+ return ret;
+
+ am_meson_register_crtc_funcs(private->crtc, &meson_private_crtc_funcs);
+
+ return 0;
+}
+
+static void am_meson_vpu_unbind(struct device *dev,
+ struct device *master, void *data)
+{
+ struct drm_device *drm_dev = data;
+ struct meson_drm *private = drm_dev->dev_private;
+
+ am_meson_unregister_crtc_funcs(private->crtc);
+ osd_drm_debugfs_exit();
+}
+
+static const struct component_ops am_meson_vpu_component_ops = {
+ .bind = am_meson_vpu_bind,
+ .unbind = am_meson_vpu_unbind,
+};
+
+static const struct of_device_id am_meson_vpu_driver_dt_match[] = {
+ { .compatible = "amlogic,meson-gxbb-vpu",
+ .data = &osd_gxbb, },
+ { .compatible = "amlogic,meson-gxl-vpu",
+ .data = &osd_gxl, },
+ { .compatible = "amlogic,meson-gxm-vpu",
+ .data = &osd_gxm, },
+ { .compatible = "amlogic,meson-txl-vpu",
+ .data = &osd_txl, },
+ { .compatible = "amlogic,meson-txlx-vpu",
+ .data = &osd_txlx, },
+ { .compatible = "amlogic,meson-axg-vpu",
+ .data = &osd_axg, },
+ { .compatible = "amlogic,meson-g12a-vpu",
+ .data = &osd_g12a, },
+ {},
+};
+MODULE_DEVICE_TABLE(of, am_meson_vpu_driver_dt_match);
+
+static int am_meson_vpu_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const void *vpu_data;
+ int ret;
+
+ if (!dev->of_node) {
+ dev_err(dev, "can't find vpu devices\n");
+ return -ENODEV;
+ }
+
+ vpu_data = of_device_get_match_data(dev);
+ if (vpu_data) {
+ ret = am_meson_crtc_dts_info_set(vpu_data);
+ if (ret < 0)
+ return -ENODEV;
+ } else {
+ dev_err(dev, "%s NOT match\n", __func__);
+ return -ENODEV;
+ }
+
+ return component_add(dev, &am_meson_vpu_component_ops);
+}
+
+static int am_meson_vpu_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &am_meson_vpu_component_ops);
+
+ return 0;
+}
+
+static struct platform_driver am_meson_vpu_platform_driver = {
+ .probe = am_meson_vpu_probe,
+ .remove = am_meson_vpu_remove,
+ .driver = {
+ .name = "meson-vpu",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(am_meson_vpu_driver_dt_match),
+ },
+};
+
+module_platform_driver(am_meson_vpu_platform_driver);
+
+MODULE_AUTHOR("MultiMedia Amlogic <multimedia-sh@amlogic.com>");
+MODULE_DESCRIPTION("Amlogic Meson Drm VPU driver");
+MODULE_LICENSE("GPL");
--- /dev/null
+/*
+ * drivers/amlogic/drm/am_meson_vpu.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+#ifndef __AM_MESON_VPU_H
+#define __AM_MESON_VPU_H
+
+struct am_meson_vpu_data {
+ uint32_t version;
+};
+
+#endif /* __AM_MESON_VPU_H */
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include "meson_drv.h"
-#include "meson_canvas.h"
-#include "meson_registers.h"
-
-/*
- * CANVAS is a memory zone where physical memory frames information
- * are stored for the VIU to scanout.
- */
-
-/* DMC Registers */
-#define DMC_CAV_LUT_DATAL 0x48 /* 0x12 offset in data sheet */
-#define CANVAS_WIDTH_LBIT 29
-#define CANVAS_WIDTH_LWID 3
-#define DMC_CAV_LUT_DATAH 0x4c /* 0x13 offset in data sheet */
-#define CANVAS_WIDTH_HBIT 0
-#define CANVAS_HEIGHT_BIT 9
-#define CANVAS_BLKMODE_BIT 24
-#define DMC_CAV_LUT_ADDR 0x50 /* 0x14 offset in data sheet */
-#define CANVAS_LUT_WR_EN (0x2 << 8)
-#define CANVAS_LUT_RD_EN (0x1 << 8)
-
-void meson_canvas_setup(struct meson_drm *priv,
- uint32_t canvas_index, uint32_t addr,
- uint32_t stride, uint32_t height,
- unsigned int wrap,
- unsigned int blkmode)
-{
- unsigned int val;
-
- regmap_write(priv->dmc, DMC_CAV_LUT_DATAL,
- (((addr + 7) >> 3)) |
- (((stride + 7) >> 3) << CANVAS_WIDTH_LBIT));
-
- regmap_write(priv->dmc, DMC_CAV_LUT_DATAH,
- ((((stride + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
- CANVAS_WIDTH_HBIT) |
- (height << CANVAS_HEIGHT_BIT) |
- (wrap << 22) |
- (blkmode << CANVAS_BLKMODE_BIT));
-
- regmap_write(priv->dmc, DMC_CAV_LUT_ADDR,
- CANVAS_LUT_WR_EN | canvas_index);
-
- /* Force a read-back to make sure everything is flushed. */
- regmap_read(priv->dmc, DMC_CAV_LUT_DATAH, &val);
-}
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Canvas LUT Memory */
-
-#ifndef __MESON_CANVAS_H
-#define __MESON_CANVAS_H
-
-#define MESON_CANVAS_ID_OSD1 0x4e
-
-/* Canvas configuration. */
-#define MESON_CANVAS_WRAP_NONE 0x00
-#define MESON_CANVAS_WRAP_X 0x01
-#define MESON_CANVAS_WRAP_Y 0x02
-
-#define MESON_CANVAS_BLKMODE_LINEAR 0x00
-#define MESON_CANVAS_BLKMODE_32x32 0x01
-#define MESON_CANVAS_BLKMODE_64x64 0x02
-
-void meson_canvas_setup(struct meson_drm *priv,
- uint32_t canvas_index, uint32_t addr,
- uint32_t stride, uint32_t height,
- unsigned int wrap,
- unsigned int blkmode);
-
-#endif /* __MESON_CANVAS_H */
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Written by:
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <drm/drmP.h>
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_flip_work.h>
-#include <drm/drm_crtc_helper.h>
-
-#include "meson_crtc.h"
-#include "meson_plane.h"
-#include "meson_vpp.h"
-#include "meson_viu.h"
-#include "meson_registers.h"
-
-/* CRTC definition */
-
-struct meson_crtc {
- struct drm_crtc base;
- struct drm_pending_vblank_event *event;
- struct meson_drm *priv;
-};
-#define to_meson_crtc(x) container_of(x, struct meson_crtc, base)
-
-/* CRTC */
-
-static const struct drm_crtc_funcs meson_crtc_funcs = {
- .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
- .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
- .destroy = drm_crtc_cleanup,
- .page_flip = drm_atomic_helper_page_flip,
- .reset = drm_atomic_helper_crtc_reset,
- .set_config = drm_atomic_helper_set_config,
-};
-
-static void meson_crtc_enable(struct drm_crtc *crtc)
-{
- struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
- struct drm_plane *plane = meson_crtc->priv->primary_plane;
- struct meson_drm *priv = meson_crtc->priv;
-
- /* Enable VPP Postblend */
- writel(plane->state->crtc_w,
- priv->io_base + _REG(VPP_POSTBLEND_H_SIZE));
-
- writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE,
- priv->io_base + _REG(VPP_MISC));
-
- priv->viu.osd1_enabled = true;
-}
-
-static void meson_crtc_disable(struct drm_crtc *crtc)
-{
- struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
- struct meson_drm *priv = meson_crtc->priv;
-
- priv->viu.osd1_enabled = false;
-
- /* Disable VPP Postblend */
- writel_bits_relaxed(VPP_POSTBLEND_ENABLE, 0,
- priv->io_base + _REG(VPP_MISC));
-
- if (crtc->state->event && !crtc->state->active) {
- spin_lock_irq(&crtc->dev->event_lock);
- drm_crtc_send_vblank_event(crtc, crtc->state->event);
- spin_unlock_irq(&crtc->dev->event_lock);
-
- crtc->state->event = NULL;
- }
-}
-
-static void meson_crtc_atomic_begin(struct drm_crtc *crtc,
- struct drm_crtc_state *state)
-{
- struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
- unsigned long flags;
-
- if (crtc->state->event) {
- WARN_ON(drm_crtc_vblank_get(crtc) != 0);
-
- spin_lock_irqsave(&crtc->dev->event_lock, flags);
- meson_crtc->event = crtc->state->event;
- spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
- crtc->state->event = NULL;
- }
-}
-
-static void meson_crtc_atomic_flush(struct drm_crtc *crtc,
- struct drm_crtc_state *old_crtc_state)
-{
- struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
- struct meson_drm *priv = meson_crtc->priv;
-
- if (priv->viu.osd1_enabled)
- priv->viu.osd1_commit = true;
-}
-
-static const struct drm_crtc_helper_funcs meson_crtc_helper_funcs = {
- .enable = meson_crtc_enable,
- .disable = meson_crtc_disable,
- .atomic_begin = meson_crtc_atomic_begin,
- .atomic_flush = meson_crtc_atomic_flush,
-};
-
-void meson_crtc_irq(struct meson_drm *priv)
-{
- struct meson_crtc *meson_crtc = to_meson_crtc(priv->crtc);
- unsigned long flags;
-
- /* Update the OSD registers */
- if (priv->viu.osd1_enabled && priv->viu.osd1_commit) {
- writel_relaxed(priv->viu.osd1_ctrl_stat,
- priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
- writel_relaxed(priv->viu.osd1_blk0_cfg[0],
- priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W0));
- writel_relaxed(priv->viu.osd1_blk0_cfg[1],
- priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W1));
- writel_relaxed(priv->viu.osd1_blk0_cfg[2],
- priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W2));
- writel_relaxed(priv->viu.osd1_blk0_cfg[3],
- priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W3));
- writel_relaxed(priv->viu.osd1_blk0_cfg[4],
- priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W4));
-
- /* If output is interlace, make use of the Scaler */
- if (priv->viu.osd1_interlace) {
- struct drm_plane *plane = priv->primary_plane;
- struct drm_plane_state *state = plane->state;
- struct drm_rect dest = {
- .x1 = state->crtc_x,
- .y1 = state->crtc_y,
- .x2 = state->crtc_x + state->crtc_w,
- .y2 = state->crtc_y + state->crtc_h,
- };
-
- meson_vpp_setup_interlace_vscaler_osd1(priv, &dest);
- } else
- meson_vpp_disable_interlace_vscaler_osd1(priv);
-
- /* Enable OSD1 */
- writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
- priv->io_base + _REG(VPP_MISC));
-
- priv->viu.osd1_commit = false;
- }
-
- drm_crtc_handle_vblank(priv->crtc);
-
- spin_lock_irqsave(&priv->drm->event_lock, flags);
- if (meson_crtc->event) {
- drm_crtc_send_vblank_event(priv->crtc, meson_crtc->event);
- drm_crtc_vblank_put(priv->crtc);
- meson_crtc->event = NULL;
- }
- spin_unlock_irqrestore(&priv->drm->event_lock, flags);
-}
-
-int meson_crtc_create(struct meson_drm *priv)
-{
- struct meson_crtc *meson_crtc;
- struct drm_crtc *crtc;
- int ret;
-
- meson_crtc = devm_kzalloc(priv->drm->dev, sizeof(*meson_crtc),
- GFP_KERNEL);
- if (!meson_crtc)
- return -ENOMEM;
-
- meson_crtc->priv = priv;
- crtc = &meson_crtc->base;
- ret = drm_crtc_init_with_planes(priv->drm, crtc,
- priv->primary_plane, NULL,
- &meson_crtc_funcs, "meson_crtc");
- if (ret) {
- dev_err(priv->drm->dev, "Failed to init CRTC\n");
- return ret;
- }
-
- drm_crtc_helper_add(crtc, &meson_crtc_helper_funcs);
-
- priv->crtc = crtc;
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Written by:
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#ifndef __MESON_CRTC_H
-#define __MESON_CRTC_H
-
-#include "meson_drv.h"
-
-int meson_crtc_create(struct meson_drm *priv);
-
-void meson_crtc_irq(struct meson_drm *priv);
-
-int meson_crtc_dts_info_set(const void *dt_match_data);
-#endif /* __MESON_CRTC_H */
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Written by:
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/of_graph.h>
-
-#include <drm/drmP.h>
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_flip_work.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_plane_helper.h>
-#include <drm/drm_gem_cma_helper.h>
-#include <drm/drm_fb_cma_helper.h>
-#include <drm/drm_rect.h>
-#include <drm/drm_fb_helper.h>
-
-#include "meson_drv.h"
-#include "meson_plane.h"
-#include "meson_crtc.h"
-#include "meson_venc_cvbs.h"
-#ifdef CONFIG_DRM_MESON_BYPASS_MODE
-#include "am_meson_hdmi.h"
-#include "osd_drm.h"
-#else
-#include "meson_vpp.h"
-#include "meson_viu.h"
-#include "meson_venc.h"
-#include "meson_canvas.h"
-#include "meson_registers.h"
-#endif
-#include "am_meson_lcd.h"
-#ifdef CONFIG_DRM_MESON_USE_ION
-#include "am_meson_gem.h"
-#include "am_meson_fb.h"
-#endif
-#ifdef CONFIG_DRM_MESON_EMULATE_FBDEV
-#include "am_meson_fbdev.h"
-#endif
-
-#define DRIVER_NAME "meson"
-#define DRIVER_DESC "Amlogic Meson DRM driver"
-
-/*
- * Video Processing Unit
- *
- * VPU Handles the Global Video Processing, it includes management of the
- * clocks gates, blocks reset lines and power domains.
- *
- * What is missing :
- * - Full reset of entire video processing HW blocks
- * - Scaling and setup of the VPU clock
- * - Bus clock gates
- * - Powering up video processing HW blocks
- * - Powering Up HDMI controller and PHY
- */
-#if 1
-static struct osd_device_data_s osd_gxbb = {
- .cpu_id = __MESON_CPU_MAJOR_ID_GXBB,
- .osd_ver = OSD_NORMAL,
- .afbc_type = NO_AFBC,
- .osd_count = 2,
- .has_deband = 0,
- .has_lut = 0,
- .has_rdma = 1,
- .has_dolby_vision = 0,
- .osd_fifo_len = 32,
- .vpp_fifo_len = 0x77f,
- .dummy_data = 0x00808000,
- .has_viu2 = 0,
-};
-
-static struct osd_device_data_s osd_gxl = {
- .cpu_id = __MESON_CPU_MAJOR_ID_GXL,
- .osd_ver = OSD_NORMAL,
- .afbc_type = NO_AFBC,
- .osd_count = 2,
- .has_deband = 0,
- .has_lut = 0,
- .has_rdma = 1,
- .has_dolby_vision = 0,
- .osd_fifo_len = 32,
- .vpp_fifo_len = 0x77f,
- .dummy_data = 0x00808000,
- .has_viu2 = 0,
-};
-
-static struct osd_device_data_s osd_gxm = {
- .cpu_id = __MESON_CPU_MAJOR_ID_GXM,
- .osd_ver = OSD_NORMAL,
- .afbc_type = MESON_AFBC,
- .osd_count = 2,
- .has_deband = 0,
- .has_lut = 0,
- .has_rdma = 1,
- .has_dolby_vision = 0,
- .osd_fifo_len = 32,
- .vpp_fifo_len = 0xfff,
- .dummy_data = 0x00202000,/* dummy data is different */
- .has_viu2 = 0,
-};
-
-static struct osd_device_data_s osd_txl = {
- .cpu_id = __MESON_CPU_MAJOR_ID_TXL,
- .osd_ver = OSD_NORMAL,
- .afbc_type = NO_AFBC,
- .osd_count = 2,
- .has_deband = 0,
- .has_lut = 0,
- .has_rdma = 1,
- .has_dolby_vision = 0,
- .osd_fifo_len = 64,
- .vpp_fifo_len = 0x77f,
- .dummy_data = 0x00808000,
- .has_viu2 = 0,
-};
-
-static struct osd_device_data_s osd_txlx = {
- .cpu_id = __MESON_CPU_MAJOR_ID_TXLX,
- .osd_ver = OSD_NORMAL,
- .afbc_type = NO_AFBC,
- .osd_count = 2,
- .has_deband = 1,
- .has_lut = 1,
- .has_rdma = 1,
- .has_dolby_vision = 1,
- .osd_fifo_len = 64, /* fifo len 64*8 = 512 */
- .vpp_fifo_len = 0x77f,
- .dummy_data = 0x00808000,
- .has_viu2 = 0,
-};
-
-static struct osd_device_data_s osd_axg = {
- .cpu_id = __MESON_CPU_MAJOR_ID_AXG,
- .osd_ver = OSD_SIMPLE,
- .afbc_type = NO_AFBC,
- .osd_count = 1,
- .has_deband = 1,
- .has_lut = 1,
- .has_rdma = 0,
- .has_dolby_vision = 0,
- /* use iomap its self, no rdma, no canvas, no freescale */
- .osd_fifo_len = 64, /* fifo len 64*8 = 512 */
- .vpp_fifo_len = 0x400,
- .dummy_data = 0x00808000,
- .has_viu2 = 0,
-};
-
-static struct osd_device_data_s osd_g12a = {
- .cpu_id = __MESON_CPU_MAJOR_ID_G12A,
- .osd_ver = OSD_HIGH_ONE,
- .afbc_type = MALI_AFBC,
- .osd_count = 3,
- .has_deband = 1,
- .has_lut = 1,
- .has_rdma = 1,
- .has_dolby_vision = 0,
- .osd_fifo_len = 64, /* fifo len 64*8 = 512 */
- .vpp_fifo_len = 0xfff,/* 2048 */
- .dummy_data = 0x00808000,
- .has_viu2 = 1,
-};
-
-static const struct of_device_id meson_drm_dt_match[] = {
- {
- .compatible = "amlogic,meson-gxbb",
- .data = &osd_gxbb,
-
- },
- {
- .compatible = "amlogic,meson-gxl",
- .data = &osd_gxl,
- },
- {
- .compatible = "amlogic,meson-gxm",
- .data = &osd_gxm,
-
- },
- {
- .compatible = "amlogic,meson-txl",
- .data = &osd_txl,
- },
- {
- .compatible = "amlogic,meson-txlx",
- .data = &osd_txlx,
-
- },
- {
- .compatible = "amlogic,meson-axg",
- .data = &osd_axg,
-
- },
- {
- .compatible = "amlogic,meson-g12a",
- .data = &osd_g12a,
- },
- {},
-};
-
-#else
-static const struct of_device_id meson_drm_dt_match[] = {
- { .compatible = "amlogic,meson-gxbb-vpu" },
- { .compatible = "amlogic,meson-gxl-vpu" },
- { .compatible = "amlogic,meson-gxm-vpu" },
- {}
-};
-#endif
-
-static void meson_fb_output_poll_changed(struct drm_device *dev)
-{
-#ifdef CONFIG_DRM_MESON_EMULATE_FBDEV
- struct meson_drm *priv = dev->dev_private;
- drm_fbdev_cma_hotplug_event(priv->fbdev);
-#endif
-}
-
-static const struct drm_mode_config_funcs meson_mode_config_funcs = {
- .output_poll_changed = meson_fb_output_poll_changed,
- .atomic_check = drm_atomic_helper_check,
- .atomic_commit = drm_atomic_helper_commit,
-#ifdef CONFIG_DRM_MESON_USE_ION
- .fb_create = am_meson_fb_create,
-#else
- .fb_create = drm_fb_cma_create,
-#endif
-};
-
-static int meson_enable_vblank(struct drm_device *dev, unsigned int crtc)
-{
-#ifndef CONFIG_DRM_MESON_BYPASS_MODE
- struct meson_drm *priv = dev->dev_private;
-
- meson_venc_enable_vsync(priv);
-#endif
- return 0;
-}
-
-static void meson_disable_vblank(struct drm_device *dev, unsigned int crtc)
-{
-#ifndef CONFIG_DRM_MESON_BYPASS_MODE
- struct meson_drm *priv = dev->dev_private;
-
- meson_venc_disable_vsync(priv);
-#endif
-}
-
-static irqreturn_t meson_irq(int irq, void *arg)
-{
- struct drm_device *dev = arg;
- struct meson_drm *priv = dev->dev_private;
-
-#ifndef CONFIG_DRM_MESON_BYPASS_MODE
- (void)readl_relaxed(priv->io_base + _REG(VENC_INTFLAG));
-#endif
-
- meson_crtc_irq(priv);
-
- return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_DRM_MESON_USE_ION
-static const struct drm_ioctl_desc meson_ioctls[] = {
- DRM_IOCTL_DEF_DRV(MESON_GEM_CREATE, am_meson_gem_create_ioctl,
- DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
-};
-#endif
-
-static const struct file_operations fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .unlocked_ioctl = drm_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = drm_compat_ioctl,
-#endif
- .poll = drm_poll,
- .read = drm_read,
- .llseek = no_llseek,
-#ifdef CONFIG_DRM_MESON_USE_ION
- .mmap = am_meson_gem_mmap,
-#else
- .mmap = drm_gem_cma_mmap,
-#endif
-};
-
-static struct drm_driver meson_driver = {
- /*driver_features setting move to probe functions*/
- .driver_features = 0,
- /* Vblank */
- .enable_vblank = meson_enable_vblank,
- .disable_vblank = meson_disable_vblank,
- .get_vblank_counter = drm_vblank_no_hw_counter,
-
- /* IRQ */
- .irq_handler = meson_irq,
-
-#ifdef CONFIG_DRM_MESON_USE_ION
- /* PRIME Ops */
- .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
- .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
-
- .gem_prime_export = drm_gem_prime_export,
- .gem_prime_get_sg_table = am_meson_gem_prime_get_sg_table,
-
- .gem_prime_import = drm_gem_prime_import,
- /*
- * If gem_prime_import_sg_table is NULL,only buffer created
- * by meson driver can be imported ok.
- */
- /*.gem_prime_import_sg_table = am_meson_gem_prime_import_sg_table,*/
-
- .gem_prime_vmap = am_meson_gem_prime_vmap,
- .gem_prime_vunmap = am_meson_gem_prime_vunmap,
- .gem_prime_mmap = am_meson_gem_prime_mmap,
-
- /* GEM Ops */
- .dumb_create = am_meson_gem_dumb_create,
- .dumb_destroy = am_meson_gem_dumb_destroy,
- .dumb_map_offset = am_meson_gem_dumb_map_offset,
- .gem_free_object_unlocked = am_meson_gem_object_free,
- .gem_vm_ops = &drm_gem_cma_vm_ops,
- .ioctls = meson_ioctls,
- .num_ioctls = ARRAY_SIZE(meson_ioctls),
-#else
- /* PRIME Ops */
- .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
- .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
- .gem_prime_import = drm_gem_prime_import,
- .gem_prime_export = drm_gem_prime_export,
- .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
- .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
- .gem_prime_vmap = drm_gem_cma_prime_vmap,
- .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
- .gem_prime_mmap = drm_gem_cma_prime_mmap,
-
- /* GEM Ops */
- .dumb_create = drm_gem_cma_dumb_create,
- .dumb_destroy = drm_gem_dumb_destroy,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .gem_free_object_unlocked = drm_gem_cma_free_object,
- .gem_vm_ops = &drm_gem_cma_vm_ops,
-#endif
-
- /* Misc */
- .fops = &fops,
- .name = DRIVER_NAME,
- .desc = DRIVER_DESC,
- .date = "20161109",
- .major = 1,
- .minor = 0,
-};
-
-#ifndef CONFIG_DRM_MESON_BYPASS_MODE
-static bool meson_vpu_has_available_connectors(struct device *dev)
-{
- struct device_node *ep, *remote;
-
- /* Parses each endpoint and check if remote exists */
- for_each_endpoint_of_node(dev->of_node, ep) {
- /* If the endpoint node exists, consider it enabled */
- remote = of_graph_get_remote_port(ep);
- if (remote)
- return true;
- }
-
- return false;
-}
-
-static struct regmap_config meson_regmap_config = {
- .reg_bits = 32,
- .val_bits = 32,
- .reg_stride = 4,
- .max_register = 0x1000,
-};
-#endif
-
-static bool meson_drv_use_osd(void)
-{
- struct device_node *node;
- const char *str;
- int ret;
-
- node = of_find_node_by_path("/meson-fb");
- if (node) {
- ret = of_property_read_string(node, "status", &str);
- if (ret) {
- DRM_INFO("get 'status' failed:%d\n", ret);
- return false;
- }
-
- if (strcmp(str, "okay") && strcmp(str, "ok")) {
- DRM_INFO("device %s status is %s\n",
- node->name, str);
- } else {
- DRM_INFO("device %s status is %s\n",
- node->name, str);
- return true;
- }
- }
- return false;
-}
-
-static int meson_drv_probe_prune(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct meson_drm *priv;
- struct drm_device *drm;
- int ret;
-
- /*driver_features reset to DRIVER_GEM | DRIVER_PRIME, for prune drm*/
- meson_driver.driver_features = DRIVER_GEM | DRIVER_PRIME;
-
- drm = drm_dev_alloc(&meson_driver, dev);
- if (IS_ERR(drm))
- return PTR_ERR(drm);
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- ret = -ENOMEM;
- goto free_drm;
- }
- drm->dev_private = priv;
- priv->drm = drm;
- priv->dev = dev;
-
-#ifdef CONFIG_DRM_MESON_USE_ION
- am_meson_gem_create(priv);
-#endif
-
- platform_set_drvdata(pdev, priv);
-
- ret = drm_dev_register(drm, 0);
- if (ret)
- goto free_drm;
-
- return 0;
-
-free_drm:
- DRM_DEBUG("free-drm");
- drm_dev_unref(drm);
- return ret;
-}
-
-static int meson_drv_remove_prune(struct platform_device *pdev)
-{
- struct drm_device *drm = dev_get_drvdata(&pdev->dev);
-
- drm_dev_unregister(drm);
-#ifdef CONFIG_DRM_MESON_USE_ION
- am_meson_gem_cleanup(drm->dev_private);
-#endif
- drm_dev_unref(drm);
-
- return 0;
-}
-
-static int meson_drv_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct meson_drm *priv;
- struct drm_device *drm;
- int ret;
-#ifndef CONFIG_DRM_MESON_BYPASS_MODE
- struct resource *res;
- void __iomem *regs;
-#endif
-
- if (meson_drv_use_osd())
- return meson_drv_probe_prune(pdev);
-
- if (pdev->dev.of_node) {
- const struct of_device_id *match;
- struct device_node *of_node = pdev->dev.of_node;
-
- match = of_match_node(meson_drm_dt_match, of_node);
- if (match) {
- ret = meson_crtc_dts_info_set((match->data));
- if (ret < 0)
- return -ENODEV;
- } else {
- pr_err("%s NOT match\n", __func__);
- return -ENODEV;
- }
- }
-
-#ifndef CONFIG_DRM_MESON_BYPASS_MODE
- /* Checks if an output connector is available */
- if (!meson_vpu_has_available_connectors(dev)) {
- dev_err(dev, "No output connector available\n");
- return -ENODEV;
- }
-#endif
-
- meson_driver.driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM |
- DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_ATOMIC | DRIVER_IRQ_SHARED;
-
- drm = drm_dev_alloc(&meson_driver, dev);
- if (IS_ERR(drm))
- return PTR_ERR(drm);
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- ret = -ENOMEM;
- goto free_drm;
- }
- drm->dev_private = priv;
- priv->drm = drm;
- priv->dev = dev;
-
-#ifndef CONFIG_DRM_MESON_BYPASS_MODE
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu");
- regs = devm_ioremap_resource(dev, res);
- if (IS_ERR(regs))
- return PTR_ERR(regs);
-
- priv->io_base = regs;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi");
- /* Simply ioremap since it may be a shared register zone */
- regs = devm_ioremap(dev, res->start, resource_size(res));
- if (!regs)
- return -EADDRNOTAVAIL;
-
- priv->hhi = devm_regmap_init_mmio(dev, regs,
- &meson_regmap_config);
- if (IS_ERR(priv->hhi)) {
- dev_err(&pdev->dev, "Couldn't create the HHI regmap\n");
- return PTR_ERR(priv->hhi);
- }
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc");
- /* Simply ioremap since it may be a shared register zone */
- regs = devm_ioremap(dev, res->start, resource_size(res));
- if (!regs)
- return -EADDRNOTAVAIL;
-
- priv->dmc = devm_regmap_init_mmio(dev, regs,
- &meson_regmap_config);
- if (IS_ERR(priv->dmc)) {
- dev_err(&pdev->dev, "Couldn't create the DMC regmap\n");
- return PTR_ERR(priv->dmc);
- }
-#endif
-
-#ifdef CONFIG_DRM_MESON_USE_ION
- am_meson_gem_create(priv);
-#endif
-
- priv->vsync_irq = platform_get_irq(pdev, 0);
- drm_vblank_init(drm, 1);
- drm_mode_config_init(drm);
-
-#ifdef CONFIG_DRM_MESON_BYPASS_MODE
- am_hdmi_connector_create(priv);
-#else
- /* Encoder Initialization */
- ret = meson_venc_cvbs_create(priv);
- if (ret)
- goto free_drm;
-
- /* Hardware Initialization */
-
- meson_venc_init(priv);
- meson_vpp_init(priv);
- meson_viu_init(priv);
-#endif
- am_drm_lcd_register(drm);
-
- ret = meson_plane_create(priv);
- if (ret)
- goto free_drm;
-
- ret = meson_crtc_create(priv);
- if (ret)
- goto free_drm;
-
- ret = drm_irq_install(drm, priv->vsync_irq);
- if (ret)
- goto free_drm;
-
- drm_mode_config_reset(drm);
- drm->mode_config.max_width = 8192;
- drm->mode_config.max_height = 8192;
- drm->mode_config.funcs = &meson_mode_config_funcs;
- drm_kms_helper_poll_init(drm);
-#ifdef CONFIG_DRM_MESON_EMULATE_FBDEV
- ret = meson_drm_fbdev_init(drm);
- if (ret)
- goto free_drm;
- drm->mode_config.allow_fb_modifiers = true;
-#endif
- platform_set_drvdata(pdev, priv);
-
- ret = drm_dev_register(drm, 0);
- if (ret)
- goto free_drm;
-
- return 0;
-
-free_drm:
- DRM_DEBUG("free-drm");
- drm_dev_unref(drm);
-
- return ret;
-}
-
-static int meson_drv_remove(struct platform_device *pdev)
-{
- struct drm_device *drm = dev_get_drvdata(&pdev->dev);
-
- am_drm_lcd_unregister(drm);
-
- if (meson_drv_use_osd())
- return meson_drv_remove_prune(pdev);
-
-#ifdef CONFIG_DRM_MESON_BYPASS_MODE
- osd_drm_debugfs_exit();
- am_hdmi_connector_cleanup(drm);
-
-#endif
- drm_dev_unregister(drm);
-#ifdef CONFIG_DRM_MESON_EMULATE_FBDEV
- meson_drm_fbdev_fini(drm);
-#endif
- drm_kms_helper_poll_fini(drm);
- drm_mode_config_cleanup(drm);
- drm_vblank_cleanup(drm);
-#ifdef CONFIG_DRM_MESON_USE_ION
- am_meson_gem_cleanup(drm->dev_private);
-#endif
- drm_dev_unref(drm);
-
- return 0;
-}
-
-
-MODULE_DEVICE_TABLE(of, meson_drm_dt_match);
-
-static struct platform_driver meson_drm_platform_driver = {
- .probe = meson_drv_probe,
- .remove = meson_drv_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = DRIVER_NAME,
- .of_match_table = meson_drm_dt_match,
- },
-};
-
-module_platform_driver(meson_drm_platform_driver);
-
-MODULE_AUTHOR("Jasper St. Pierre <jstpierre@mecheye.net>");
-MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
-MODULE_AUTHOR("MultiMedia Amlogic <multimedia-sh@amlogic.com>");
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Written by:
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <drm/drmP.h>
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_plane_helper.h>
-#include <drm/drm_gem_cma_helper.h>
-#include <drm/drm_fb_cma_helper.h>
-#include <drm/drm_rect.h>
-
-#include "meson_plane.h"
-#include "meson_vpp.h"
-#include "meson_viu.h"
-#include "meson_canvas.h"
-#include "meson_registers.h"
-
-struct meson_plane {
- struct drm_plane base;
- struct meson_drm *priv;
-};
-#define to_meson_plane(x) container_of(x, struct meson_plane, base)
-
-static int meson_plane_atomic_check(struct drm_plane *plane,
- struct drm_plane_state *state)
-{
- struct drm_crtc_state *crtc_state;
- struct drm_rect clip = { 0, };
-
- if (!state->crtc)
- return 0;
-
- crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
- if (IS_ERR(crtc_state))
- return PTR_ERR(crtc_state);
-
- clip.x2 = crtc_state->mode.hdisplay;
- clip.y2 = crtc_state->mode.vdisplay;
-
- return drm_plane_helper_check_state(state, &clip,
- DRM_PLANE_HELPER_NO_SCALING,
- DRM_PLANE_HELPER_NO_SCALING,
- true, true);
-}
-
-/* Takes a fixed 16.16 number and converts it to integer. */
-static inline int64_t fixed16_to_int(int64_t value)
-{
- return value >> 16;
-}
-
-static void meson_plane_atomic_update(struct drm_plane *plane,
- struct drm_plane_state *old_state)
-{
- struct meson_plane *meson_plane = to_meson_plane(plane);
- struct drm_plane_state *state = plane->state;
- struct drm_framebuffer *fb = state->fb;
- struct meson_drm *priv = meson_plane->priv;
- struct drm_gem_cma_object *gem;
- struct drm_rect src = {
- .x1 = (state->src_x),
- .y1 = (state->src_y),
- .x2 = (state->src_x + state->src_w),
- .y2 = (state->src_y + state->src_h),
- };
- struct drm_rect dest = {
- .x1 = state->crtc_x,
- .y1 = state->crtc_y,
- .x2 = state->crtc_x + state->crtc_w,
- .y2 = state->crtc_y + state->crtc_h,
- };
- unsigned long flags;
-
- /*
- * Update Coordinates
- * Update Formats
- * Update Buffer
- * Enable Plane
- */
- spin_lock_irqsave(&priv->drm->event_lock, flags);
-
- /* Enable OSD and BLK0, set max global alpha */
- priv->viu.osd1_ctrl_stat = OSD_ENABLE |
- (0xFF << OSD_GLOBAL_ALPHA_SHIFT) |
- OSD_BLK0_ENABLE;
-
- /* Set up BLK0 to point to the right canvas */
- priv->viu.osd1_blk0_cfg[0] = ((MESON_CANVAS_ID_OSD1 << OSD_CANVAS_SEL) |
- OSD_ENDIANNESS_LE);
-
- /* On GXBB, Use the old non-HDR RGB2YUV converter */
- if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
- priv->viu.osd1_blk0_cfg[0] |= OSD_OUTPUT_COLOR_RGB;
-
- switch (fb->pixel_format) {
- case DRM_FORMAT_XRGB8888:
- /* For XRGB, replace the pixel's alpha by 0xFF */
- writel_bits_relaxed(OSD_REPLACE_EN, OSD_REPLACE_EN,
- priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
- priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_32 |
- OSD_COLOR_MATRIX_32_ARGB;
- break;
- case DRM_FORMAT_ARGB8888:
- /* For ARGB, use the pixel's alpha */
- writel_bits_relaxed(OSD_REPLACE_EN, 0,
- priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
- priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_32 |
- OSD_COLOR_MATRIX_32_ARGB;
- break;
- case DRM_FORMAT_RGB888:
- priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_24 |
- OSD_COLOR_MATRIX_24_RGB;
- break;
- case DRM_FORMAT_RGB565:
- priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_16 |
- OSD_COLOR_MATRIX_16_RGB565;
- break;
- };
-
- if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
- priv->viu.osd1_interlace = true;
-
- dest.y1 /= 2;
- dest.y2 /= 2;
- } else
- priv->viu.osd1_interlace = false;
-
- /*
- * The format of these registers is (x2 << 16 | x1),
- * where x2 is exclusive.
- * e.g. +30x1920 would be (1919 << 16) | 30
- */
- priv->viu.osd1_blk0_cfg[1] = ((fixed16_to_int(src.x2) - 1) << 16) |
- fixed16_to_int(src.x1);
- priv->viu.osd1_blk0_cfg[2] = ((fixed16_to_int(src.y2) - 1) << 16) |
- fixed16_to_int(src.y1);
- priv->viu.osd1_blk0_cfg[3] = ((dest.x2 - 1) << 16) | dest.x1;
- priv->viu.osd1_blk0_cfg[4] = ((dest.y2 - 1) << 16) | dest.y1;
-
- /* Update Canvas with buffer address */
- gem = drm_fb_cma_get_gem_obj(fb, 0);
-
- meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1,
- gem->paddr, fb->pitches[0],
- fb->height, MESON_CANVAS_WRAP_NONE,
- MESON_CANVAS_BLKMODE_LINEAR);
-
- spin_unlock_irqrestore(&priv->drm->event_lock, flags);
-}
-
-static void meson_plane_atomic_disable(struct drm_plane *plane,
- struct drm_plane_state *old_state)
-{
- struct meson_plane *meson_plane = to_meson_plane(plane);
- struct meson_drm *priv = meson_plane->priv;
-
- /* Disable OSD1 */
- writel_bits_relaxed(VPP_OSD1_POSTBLEND, 0,
- priv->io_base + _REG(VPP_MISC));
-
-}
-
-static const struct drm_plane_helper_funcs meson_plane_helper_funcs = {
- .atomic_check = meson_plane_atomic_check,
- .atomic_disable = meson_plane_atomic_disable,
- .atomic_update = meson_plane_atomic_update,
-};
-
-static const struct drm_plane_funcs meson_plane_funcs = {
- .update_plane = drm_atomic_helper_update_plane,
- .disable_plane = drm_atomic_helper_disable_plane,
- .destroy = drm_plane_cleanup,
- .reset = drm_atomic_helper_plane_reset,
- .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
-};
-
-static const uint32_t supported_drm_formats[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_RGB565,
-};
-
-int meson_plane_create(struct meson_drm *priv)
-{
- struct meson_plane *meson_plane;
- struct drm_plane *plane;
-
- meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane),
- GFP_KERNEL);
- if (!meson_plane)
- return -ENOMEM;
-
- meson_plane->priv = priv;
- plane = &meson_plane->base;
-
- drm_universal_plane_init(priv->drm, plane, 0xFF,
- &meson_plane_funcs,
- supported_drm_formats,
- ARRAY_SIZE(supported_drm_formats),
- DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");
-
- drm_plane_helper_add(plane, &meson_plane_helper_funcs);
-
- priv->primary_plane = plane;
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Written by:
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#ifndef __MESON_PLANE_H
-#define __MESON_PLANE_H
-
-#include "meson_drv.h"
-
-int meson_plane_create(struct meson_drm *priv);
-
-#endif /* __MESON_PLANE_H */
+++ /dev/null
-/*
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#ifndef __MESON_REGISTERS_H
-#define __MESON_REGISTERS_H
-
-/* Shift all registers by 2 */
-#define _REG(reg) ((reg) << 2)
-
-#define writel_bits_relaxed(mask, val, addr) \
- writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr)
-
-/* vpp2 */
-#define VPP2_MISC 0x1e26
-#define VPP2_OFIFO_SIZE 0x1e27
-#define VPP2_INT_LINE_NUM 0x1e20
-#define VPP2_OFIFO_URG_CTRL 0x1e21
-
-
-/* viu */
-#define VIU_ADDR_START 0x1a00
-#define VIU_ADDR_END 0x1aff
-#define VIU_SW_RESET 0x1a01
-#define VIU_MISC_CTRL0 0x1a06
-#define VIU_MISC_CTRL1 0x1a07
-#define D2D3_INTF_LENGTH 0x1a08
-#define D2D3_INTF_CTRL0 0x1a09
-#define VIU_OSD1_CTRL_STAT 0x1a10
-#define VIU_OSD1_CTRL_STAT2 0x1a2d
-#define VIU_OSD1_COLOR_ADDR 0x1a11
-#define VIU_OSD1_COLOR 0x1a12
-#define VIU_OSD1_TCOLOR_AG0 0x1a17
-#define VIU_OSD1_TCOLOR_AG1 0x1a18
-#define VIU_OSD1_TCOLOR_AG2 0x1a19
-#define VIU_OSD1_TCOLOR_AG3 0x1a1a
-#define VIU_OSD1_BLK0_CFG_W0 0x1a1b
-#define VIU_OSD1_BLK1_CFG_W0 0x1a1f
-#define VIU_OSD1_BLK2_CFG_W0 0x1a23
-#define VIU_OSD1_BLK3_CFG_W0 0x1a27
-#define VIU_OSD1_BLK0_CFG_W1 0x1a1c
-#define VIU_OSD1_BLK1_CFG_W1 0x1a20
-#define VIU_OSD1_BLK2_CFG_W1 0x1a24
-#define VIU_OSD1_BLK3_CFG_W1 0x1a28
-#define VIU_OSD1_BLK0_CFG_W2 0x1a1d
-#define VIU_OSD1_BLK1_CFG_W2 0x1a21
-#define VIU_OSD1_BLK2_CFG_W2 0x1a25
-#define VIU_OSD1_BLK3_CFG_W2 0x1a29
-#define VIU_OSD1_BLK0_CFG_W3 0x1a1e
-#define VIU_OSD1_BLK1_CFG_W3 0x1a22
-#define VIU_OSD1_BLK2_CFG_W3 0x1a26
-#define VIU_OSD1_BLK3_CFG_W3 0x1a2a
-#define VIU_OSD1_BLK0_CFG_W4 0x1a13
-#define VIU_OSD1_BLK1_CFG_W4 0x1a14
-#define VIU_OSD1_BLK2_CFG_W4 0x1a15
-#define VIU_OSD1_BLK3_CFG_W4 0x1a16
-#define VIU_OSD1_FIFO_CTRL_STAT 0x1a2b
-#define VIU_OSD1_TEST_RDDATA 0x1a2c
-#define VIU_OSD1_PROT_CTRL 0x1a2e
-#define VIU_OSD2_CTRL_STAT 0x1a30
-#define VIU_OSD2_CTRL_STAT2 0x1a4d
-#define VIU_OSD2_COLOR_ADDR 0x1a31
-#define VIU_OSD2_COLOR 0x1a32
-#define VIU_OSD2_HL1_H_START_END 0x1a33
-#define VIU_OSD2_HL1_V_START_END 0x1a34
-#define VIU_OSD2_HL2_H_START_END 0x1a35
-#define VIU_OSD2_HL2_V_START_END 0x1a36
-#define VIU_OSD2_TCOLOR_AG0 0x1a37
-#define VIU_OSD2_TCOLOR_AG1 0x1a38
-#define VIU_OSD2_TCOLOR_AG2 0x1a39
-#define VIU_OSD2_TCOLOR_AG3 0x1a3a
-#define VIU_OSD2_BLK0_CFG_W0 0x1a3b
-#define VIU_OSD2_BLK1_CFG_W0 0x1a3f
-#define VIU_OSD2_BLK2_CFG_W0 0x1a43
-#define VIU_OSD2_BLK3_CFG_W0 0x1a47
-#define VIU_OSD2_BLK0_CFG_W1 0x1a3c
-#define VIU_OSD2_BLK1_CFG_W1 0x1a40
-#define VIU_OSD2_BLK2_CFG_W1 0x1a44
-#define VIU_OSD2_BLK3_CFG_W1 0x1a48
-#define VIU_OSD2_BLK0_CFG_W2 0x1a3d
-#define VIU_OSD2_BLK1_CFG_W2 0x1a41
-#define VIU_OSD2_BLK2_CFG_W2 0x1a45
-#define VIU_OSD2_BLK3_CFG_W2 0x1a49
-#define VIU_OSD2_BLK0_CFG_W3 0x1a3e
-#define VIU_OSD2_BLK1_CFG_W3 0x1a42
-#define VIU_OSD2_BLK2_CFG_W3 0x1a46
-#define VIU_OSD2_BLK3_CFG_W3 0x1a4a
-#define VIU_OSD2_BLK0_CFG_W4 0x1a64
-#define VIU_OSD2_BLK1_CFG_W4 0x1a65
-#define VIU_OSD2_BLK2_CFG_W4 0x1a66
-#define VIU_OSD2_BLK3_CFG_W4 0x1a67
-#define VIU_OSD2_FIFO_CTRL_STAT 0x1a4b
-#define VIU_OSD2_TEST_RDDATA 0x1a4c
-#define VIU_OSD2_PROT_CTRL 0x1a4e
-
-#define VD1_IF0_GEN_REG 0x1a50
-#define VD1_IF0_CANVAS0 0x1a51
-#define VD1_IF0_CANVAS1 0x1a52
-#define VD1_IF0_LUMA_X0 0x1a53
-#define VD1_IF0_LUMA_Y0 0x1a54
-#define VD1_IF0_CHROMA_X0 0x1a55
-#define VD1_IF0_CHROMA_Y0 0x1a56
-#define VD1_IF0_LUMA_X1 0x1a57
-#define VD1_IF0_LUMA_Y1 0x1a58
-#define VD1_IF0_CHROMA_X1 0x1a59
-#define VD1_IF0_CHROMA_Y1 0x1a5a
-#define VD1_IF0_RPT_LOOP 0x1a5b
-#define VD1_IF0_LUMA0_RPT_PAT 0x1a5c
-#define VD1_IF0_CHROMA0_RPT_PAT 0x1a5d
-#define VD1_IF0_LUMA1_RPT_PAT 0x1a5e
-#define VD1_IF0_CHROMA1_RPT_PAT 0x1a5f
-#define VD1_IF0_LUMA_PSEL 0x1a60
-#define VD1_IF0_CHROMA_PSEL 0x1a61
-#define VD1_IF0_DUMMY_PIXEL 0x1a62
-#define VD1_IF0_LUMA_FIFO_SIZE 0x1a63
-#define VD1_IF0_RANGE_MAP_Y 0x1a6a
-#define VD1_IF0_RANGE_MAP_CB 0x1a6b
-#define VD1_IF0_RANGE_MAP_CR 0x1a6c
-#define VD1_IF0_GEN_REG2 0x1a6d
-#define VD1_IF0_PROT_CNTL 0x1a6e
-#define VIU_VD1_FMT_CTRL 0x1a68
-#define VIU_VD1_FMT_W 0x1a69
-#define VD2_IF0_GEN_REG 0x1a70
-#define VD2_IF0_CANVAS0 0x1a71
-#define VD2_IF0_CANVAS1 0x1a72
-#define VD2_IF0_LUMA_X0 0x1a73
-#define VD2_IF0_LUMA_Y0 0x1a74
-#define VD2_IF0_CHROMA_X0 0x1a75
-#define VD2_IF0_CHROMA_Y0 0x1a76
-#define VD2_IF0_LUMA_X1 0x1a77
-#define VD2_IF0_LUMA_Y1 0x1a78
-#define VD2_IF0_CHROMA_X1 0x1a79
-#define VD2_IF0_CHROMA_Y1 0x1a7a
-#define VD2_IF0_RPT_LOOP 0x1a7b
-#define VD2_IF0_LUMA0_RPT_PAT 0x1a7c
-#define VD2_IF0_CHROMA0_RPT_PAT 0x1a7d
-#define VD2_IF0_LUMA1_RPT_PAT 0x1a7e
-#define VD2_IF0_CHROMA1_RPT_PAT 0x1a7f
-#define VD2_IF0_LUMA_PSEL 0x1a80
-#define VD2_IF0_CHROMA_PSEL 0x1a81
-#define VD2_IF0_DUMMY_PIXEL 0x1a82
-#define VD2_IF0_LUMA_FIFO_SIZE 0x1a83
-#define VD2_IF0_RANGE_MAP_Y 0x1a8a
-#define VD2_IF0_RANGE_MAP_CB 0x1a8b
-#define VD2_IF0_RANGE_MAP_CR 0x1a8c
-#define VD2_IF0_GEN_REG2 0x1a8d
-#define VD2_IF0_PROT_CNTL 0x1a8e
-#define VIU_VD2_FMT_CTRL 0x1a88
-#define VIU_VD2_FMT_W 0x1a89
-
-/* VIU Matrix Registers */
-#define VIU_OSD1_MATRIX_CTRL 0x1a90
-#define VIU_OSD1_MATRIX_COEF00_01 0x1a91
-#define VIU_OSD1_MATRIX_COEF02_10 0x1a92
-#define VIU_OSD1_MATRIX_COEF11_12 0x1a93
-#define VIU_OSD1_MATRIX_COEF20_21 0x1a94
-#define VIU_OSD1_MATRIX_COLMOD_COEF42 0x1a95
-#define VIU_OSD1_MATRIX_OFFSET0_1 0x1a96
-#define VIU_OSD1_MATRIX_OFFSET2 0x1a97
-#define VIU_OSD1_MATRIX_PRE_OFFSET0_1 0x1a98
-#define VIU_OSD1_MATRIX_PRE_OFFSET2 0x1a99
-#define VIU_OSD1_MATRIX_COEF22_30 0x1a9d
-#define VIU_OSD1_MATRIX_COEF31_32 0x1a9e
-#define VIU_OSD1_MATRIX_COEF40_41 0x1a9f
-#define VIU_OSD1_EOTF_CTL 0x1ad4
-#define VIU_OSD1_EOTF_COEF00_01 0x1ad5
-#define VIU_OSD1_EOTF_COEF02_10 0x1ad6
-#define VIU_OSD1_EOTF_COEF11_12 0x1ad7
-#define VIU_OSD1_EOTF_COEF20_21 0x1ad8
-#define VIU_OSD1_EOTF_COEF22_RS 0x1ad9
-#define VIU_OSD1_EOTF_LUT_ADDR_PORT 0x1ada
-#define VIU_OSD1_EOTF_LUT_DATA_PORT 0x1adb
-#define VIU_OSD1_OETF_CTL 0x1adc
-#define VIU_OSD1_OETF_LUT_ADDR_PORT 0x1add
-#define VIU_OSD1_OETF_LUT_DATA_PORT 0x1ade
-
-/* vpp */
-#define VPP_DUMMY_DATA 0x1d00
-#define VPP_LINE_IN_LENGTH 0x1d01
-#define VPP_PIC_IN_HEIGHT 0x1d02
-#define VPP_SCALE_COEF_IDX 0x1d03
-#define VPP_SCALE_COEF 0x1d04
-#define VPP_VSC_REGION12_STARTP 0x1d05
-#define VPP_VSC_REGION34_STARTP 0x1d06
-#define VPP_VSC_REGION4_ENDP 0x1d07
-#define VPP_VSC_START_PHASE_STEP 0x1d08
-#define VPP_VSC_REGION0_PHASE_SLOPE 0x1d09
-#define VPP_VSC_REGION1_PHASE_SLOPE 0x1d0a
-#define VPP_VSC_REGION3_PHASE_SLOPE 0x1d0b
-#define VPP_VSC_REGION4_PHASE_SLOPE 0x1d0c
-#define VPP_VSC_PHASE_CTRL 0x1d0d
-#define VPP_VSC_INI_PHASE 0x1d0e
-#define VPP_HSC_REGION12_STARTP 0x1d10
-#define VPP_HSC_REGION34_STARTP 0x1d11
-#define VPP_HSC_REGION4_ENDP 0x1d12
-#define VPP_HSC_START_PHASE_STEP 0x1d13
-#define VPP_HSC_REGION0_PHASE_SLOPE 0x1d14
-#define VPP_HSC_REGION1_PHASE_SLOPE 0x1d15
-#define VPP_HSC_REGION3_PHASE_SLOPE 0x1d16
-#define VPP_HSC_REGION4_PHASE_SLOPE 0x1d17
-#define VPP_HSC_PHASE_CTRL 0x1d18
-#define VPP_SC_MISC 0x1d19
-#define VPP_PREBLEND_VD1_H_START_END 0x1d1a
-#define VPP_PREBLEND_VD1_V_START_END 0x1d1b
-#define VPP_POSTBLEND_VD1_H_START_END 0x1d1c
-#define VPP_POSTBLEND_VD1_V_START_END 0x1d1d
-#define VPP_BLEND_VD2_H_START_END 0x1d1e
-#define VPP_BLEND_VD2_V_START_END 0x1d1f
-#define VPP_PREBLEND_H_SIZE 0x1d20
-#define VPP_POSTBLEND_H_SIZE 0x1d21
-#define VPP_HOLD_LINES 0x1d22
-#define VPP_BLEND_ONECOLOR_CTRL 0x1d23
-#define VPP_PREBLEND_CURRENT_XY 0x1d24
-#define VPP_POSTBLEND_CURRENT_XY 0x1d25
-#define VPP_MISC 0x1d26
-#define VPP_PREBLEND_ENABLE BIT(6)
-#define VPP_POSTBLEND_ENABLE BIT(7)
-#define VPP_OSD2_ALPHA_PREMULT BIT(8)
-#define VPP_OSD1_ALPHA_PREMULT BIT(9)
-#define VPP_VD1_POSTBLEND BIT(10)
-#define VPP_VD2_POSTBLEND BIT(11)
-#define VPP_OSD1_POSTBLEND BIT(12)
-#define VPP_OSD2_POSTBLEND BIT(13)
-#define VPP_VD1_PREBLEND BIT(14)
-#define VPP_VD2_PREBLEND BIT(15)
-#define VPP_OSD1_PREBLEND BIT(16)
-#define VPP_OSD2_PREBLEND BIT(17)
-#define VPP_OFIFO_SIZE 0x1d27
-#define VPP_FIFO_STATUS 0x1d28
-#define VPP_SMOKE_CTRL 0x1d29
-#define VPP_SMOKE1_VAL 0x1d2a
-#define VPP_SMOKE2_VAL 0x1d2b
-#define VPP_SMOKE3_VAL 0x1d2c
-#define VPP_SMOKE1_H_START_END 0x1d2d
-#define VPP_SMOKE1_V_START_END 0x1d2e
-#define VPP_SMOKE2_H_START_END 0x1d2f
-#define VPP_SMOKE2_V_START_END 0x1d30
-#define VPP_SMOKE3_H_START_END 0x1d31
-#define VPP_SMOKE3_V_START_END 0x1d32
-#define VPP_SCO_FIFO_CTRL 0x1d33
-#define VPP_HSC_PHASE_CTRL1 0x1d34
-#define VPP_HSC_INI_PAT_CTRL 0x1d35
-#define VPP_VADJ_CTRL 0x1d40
-#define VPP_VADJ1_Y 0x1d41
-#define VPP_VADJ1_MA_MB 0x1d42
-#define VPP_VADJ1_MC_MD 0x1d43
-#define VPP_VADJ2_Y 0x1d44
-#define VPP_VADJ2_MA_MB 0x1d45
-#define VPP_VADJ2_MC_MD 0x1d46
-#define VPP_HSHARP_CTRL 0x1d50
-#define VPP_HSHARP_LUMA_THRESH01 0x1d51
-#define VPP_HSHARP_LUMA_THRESH23 0x1d52
-#define VPP_HSHARP_CHROMA_THRESH01 0x1d53
-#define VPP_HSHARP_CHROMA_THRESH23 0x1d54
-#define VPP_HSHARP_LUMA_GAIN 0x1d55
-#define VPP_HSHARP_CHROMA_GAIN 0x1d56
-#define VPP_MATRIX_PROBE_COLOR 0x1d5c
-#define VPP_MATRIX_HL_COLOR 0x1d5d
-#define VPP_MATRIX_PROBE_POS 0x1d5e
-#define VPP_MATRIX_CTRL 0x1d5f
-#define VPP_MATRIX_COEF00_01 0x1d60
-#define VPP_MATRIX_COEF02_10 0x1d61
-#define VPP_MATRIX_COEF11_12 0x1d62
-#define VPP_MATRIX_COEF20_21 0x1d63
-#define VPP_MATRIX_COEF22 0x1d64
-#define VPP_MATRIX_OFFSET0_1 0x1d65
-#define VPP_MATRIX_OFFSET2 0x1d66
-#define VPP_MATRIX_PRE_OFFSET0_1 0x1d67
-#define VPP_MATRIX_PRE_OFFSET2 0x1d68
-#define VPP_DUMMY_DATA1 0x1d69
-#define VPP_GAINOFF_CTRL0 0x1d6a
-#define VPP_GAINOFF_CTRL1 0x1d6b
-#define VPP_GAINOFF_CTRL2 0x1d6c
-#define VPP_GAINOFF_CTRL3 0x1d6d
-#define VPP_GAINOFF_CTRL4 0x1d6e
-#define VPP_CHROMA_ADDR_PORT 0x1d70
-#define VPP_CHROMA_DATA_PORT 0x1d71
-#define VPP_GCLK_CTRL0 0x1d72
-#define VPP_GCLK_CTRL1 0x1d73
-#define VPP_SC_GCLK_CTRL 0x1d74
-#define VPP_MISC1 0x1d76
-#define VPP_BLACKEXT_CTRL 0x1d80
-#define VPP_DNLP_CTRL_00 0x1d81
-#define VPP_DNLP_CTRL_01 0x1d82
-#define VPP_DNLP_CTRL_02 0x1d83
-#define VPP_DNLP_CTRL_03 0x1d84
-#define VPP_DNLP_CTRL_04 0x1d85
-#define VPP_DNLP_CTRL_05 0x1d86
-#define VPP_DNLP_CTRL_06 0x1d87
-#define VPP_DNLP_CTRL_07 0x1d88
-#define VPP_DNLP_CTRL_08 0x1d89
-#define VPP_DNLP_CTRL_09 0x1d8a
-#define VPP_DNLP_CTRL_10 0x1d8b
-#define VPP_DNLP_CTRL_11 0x1d8c
-#define VPP_DNLP_CTRL_12 0x1d8d
-#define VPP_DNLP_CTRL_13 0x1d8e
-#define VPP_DNLP_CTRL_14 0x1d8f
-#define VPP_DNLP_CTRL_15 0x1d90
-#define VPP_PEAKING_HGAIN 0x1d91
-#define VPP_PEAKING_VGAIN 0x1d92
-#define VPP_PEAKING_NLP_1 0x1d93
-#define VPP_DOLBY_CTRL 0x1d93
-#define VPP_PEAKING_NLP_2 0x1d94
-#define VPP_PEAKING_NLP_3 0x1d95
-#define VPP_PEAKING_NLP_4 0x1d96
-#define VPP_PEAKING_NLP_5 0x1d97
-#define VPP_SHARP_LIMIT 0x1d98
-#define VPP_VLTI_CTRL 0x1d99
-#define VPP_HLTI_CTRL 0x1d9a
-#define VPP_CTI_CTRL 0x1d9b
-#define VPP_BLUE_STRETCH_1 0x1d9c
-#define VPP_BLUE_STRETCH_2 0x1d9d
-#define VPP_BLUE_STRETCH_3 0x1d9e
-#define VPP_CCORING_CTRL 0x1da0
-#define VPP_VE_ENABLE_CTRL 0x1da1
-#define VPP_VE_DEMO_LEFT_TOP_SCREEN_WIDTH 0x1da2
-#define VPP_VE_DEMO_CENTER_BAR 0x1da3
-#define VPP_VE_H_V_SIZE 0x1da4
-#define VPP_VDO_MEAS_CTRL 0x1da8
-#define VPP_VDO_MEAS_VS_COUNT_HI 0x1da9
-#define VPP_VDO_MEAS_VS_COUNT_LO 0x1daa
-#define VPP_INPUT_CTRL 0x1dab
-#define VPP_CTI_CTRL2 0x1dac
-#define VPP_PEAKING_SAT_THD1 0x1dad
-#define VPP_PEAKING_SAT_THD2 0x1dae
-#define VPP_PEAKING_SAT_THD3 0x1daf
-#define VPP_PEAKING_SAT_THD4 0x1db0
-#define VPP_PEAKING_SAT_THD5 0x1db1
-#define VPP_PEAKING_SAT_THD6 0x1db2
-#define VPP_PEAKING_SAT_THD7 0x1db3
-#define VPP_PEAKING_SAT_THD8 0x1db4
-#define VPP_PEAKING_SAT_THD9 0x1db5
-#define VPP_PEAKING_GAIN_ADD1 0x1db6
-#define VPP_PEAKING_GAIN_ADD2 0x1db7
-#define VPP_PEAKING_DNLP 0x1db8
-#define VPP_SHARP_DEMO_WIN_CTRL1 0x1db9
-#define VPP_SHARP_DEMO_WIN_CTRL2 0x1dba
-#define VPP_FRONT_HLTI_CTRL 0x1dbb
-#define VPP_FRONT_CTI_CTRL 0x1dbc
-#define VPP_FRONT_CTI_CTRL2 0x1dbd
-#define VPP_OSD_VSC_PHASE_STEP 0x1dc0
-#define VPP_OSD_VSC_INI_PHASE 0x1dc1
-#define VPP_OSD_VSC_CTRL0 0x1dc2
-#define VPP_OSD_HSC_PHASE_STEP 0x1dc3
-#define VPP_OSD_HSC_INI_PHASE 0x1dc4
-#define VPP_OSD_HSC_CTRL0 0x1dc5
-#define VPP_OSD_HSC_INI_PAT_CTRL 0x1dc6
-#define VPP_OSD_SC_DUMMY_DATA 0x1dc7
-#define VPP_OSD_SC_CTRL0 0x1dc8
-#define VPP_OSD_SCI_WH_M1 0x1dc9
-#define VPP_OSD_SCO_H_START_END 0x1dca
-#define VPP_OSD_SCO_V_START_END 0x1dcb
-#define VPP_OSD_SCALE_COEF_IDX 0x1dcc
-#define VPP_OSD_SCALE_COEF 0x1dcd
-#define VPP_INT_LINE_NUM 0x1dce
-
-/* viu2 */
-#define VIU2_ADDR_START 0x1e00
-#define VIU2_ADDR_END 0x1eff
-#define VIU2_SW_RESET 0x1e01
-#define VIU2_OSD1_CTRL_STAT 0x1e10
-#define VIU2_OSD1_CTRL_STAT2 0x1e2d
-#define VIU2_OSD1_COLOR_ADDR 0x1e11
-#define VIU2_OSD1_COLOR 0x1e12
-#define VIU2_OSD1_TCOLOR_AG0 0x1e17
-#define VIU2_OSD1_TCOLOR_AG1 0x1e18
-#define VIU2_OSD1_TCOLOR_AG2 0x1e19
-#define VIU2_OSD1_TCOLOR_AG3 0x1e1a
-#define VIU2_OSD1_BLK0_CFG_W0 0x1e1b
-#define VIU2_OSD1_BLK1_CFG_W0 0x1e1f
-#define VIU2_OSD1_BLK2_CFG_W0 0x1e23
-#define VIU2_OSD1_BLK3_CFG_W0 0x1e27
-#define VIU2_OSD1_BLK0_CFG_W1 0x1e1c
-#define VIU2_OSD1_BLK1_CFG_W1 0x1e20
-#define VIU2_OSD1_BLK2_CFG_W1 0x1e24
-#define VIU2_OSD1_BLK3_CFG_W1 0x1e28
-#define VIU2_OSD1_BLK0_CFG_W2 0x1e1d
-#define VIU2_OSD1_BLK1_CFG_W2 0x1e21
-#define VIU2_OSD1_BLK2_CFG_W2 0x1e25
-#define VIU2_OSD1_BLK3_CFG_W2 0x1e29
-#define VIU2_OSD1_BLK0_CFG_W3 0x1e1e
-#define VIU2_OSD1_BLK1_CFG_W3 0x1e22
-#define VIU2_OSD1_BLK2_CFG_W3 0x1e26
-#define VIU2_OSD1_BLK3_CFG_W3 0x1e2a
-#define VIU2_OSD1_BLK0_CFG_W4 0x1e13
-#define VIU2_OSD1_BLK1_CFG_W4 0x1e14
-#define VIU2_OSD1_BLK2_CFG_W4 0x1e15
-#define VIU2_OSD1_BLK3_CFG_W4 0x1e16
-#define VIU2_OSD1_FIFO_CTRL_STAT 0x1e2b
-#define VIU2_OSD1_TEST_RDDATA 0x1e2c
-#define VIU2_OSD1_PROT_CTRL 0x1e2e
-#define VIU2_OSD2_CTRL_STAT 0x1e30
-#define VIU2_OSD2_CTRL_STAT2 0x1e4d
-#define VIU2_OSD2_COLOR_ADDR 0x1e31
-#define VIU2_OSD2_COLOR 0x1e32
-#define VIU2_OSD2_HL1_H_START_END 0x1e33
-#define VIU2_OSD2_HL1_V_START_END 0x1e34
-#define VIU2_OSD2_HL2_H_START_END 0x1e35
-#define VIU2_OSD2_HL2_V_START_END 0x1e36
-#define VIU2_OSD2_TCOLOR_AG0 0x1e37
-#define VIU2_OSD2_TCOLOR_AG1 0x1e38
-#define VIU2_OSD2_TCOLOR_AG2 0x1e39
-#define VIU2_OSD2_TCOLOR_AG3 0x1e3a
-#define VIU2_OSD2_BLK0_CFG_W0 0x1e3b
-#define VIU2_OSD2_BLK1_CFG_W0 0x1e3f
-#define VIU2_OSD2_BLK2_CFG_W0 0x1e43
-#define VIU2_OSD2_BLK3_CFG_W0 0x1e47
-#define VIU2_OSD2_BLK0_CFG_W1 0x1e3c
-#define VIU2_OSD2_BLK1_CFG_W1 0x1e40
-#define VIU2_OSD2_BLK2_CFG_W1 0x1e44
-#define VIU2_OSD2_BLK3_CFG_W1 0x1e48
-#define VIU2_OSD2_BLK0_CFG_W2 0x1e3d
-#define VIU2_OSD2_BLK1_CFG_W2 0x1e41
-#define VIU2_OSD2_BLK2_CFG_W2 0x1e45
-#define VIU2_OSD2_BLK3_CFG_W2 0x1e49
-#define VIU2_OSD2_BLK0_CFG_W3 0x1e3e
-#define VIU2_OSD2_BLK1_CFG_W3 0x1e42
-#define VIU2_OSD2_BLK2_CFG_W3 0x1e46
-#define VIU2_OSD2_BLK3_CFG_W3 0x1e4a
-#define VIU2_OSD2_BLK0_CFG_W4 0x1e64
-#define VIU2_OSD2_BLK1_CFG_W4 0x1e65
-#define VIU2_OSD2_BLK2_CFG_W4 0x1e66
-#define VIU2_OSD2_BLK3_CFG_W4 0x1e67
-#define VIU2_OSD2_FIFO_CTRL_STAT 0x1e4b
-#define VIU2_OSD2_TEST_RDDATA 0x1e4c
-#define VIU2_OSD2_PROT_CTRL 0x1e4e
-#define VIU2_VD1_IF0_GEN_REG 0x1e50
-#define VIU2_VD1_IF0_CANVAS0 0x1e51
-#define VIU2_VD1_IF0_CANVAS1 0x1e52
-#define VIU2_VD1_IF0_LUMA_X0 0x1e53
-#define VIU2_VD1_IF0_LUMA_Y0 0x1e54
-#define VIU2_VD1_IF0_CHROMA_X0 0x1e55
-#define VIU2_VD1_IF0_CHROMA_Y0 0x1e56
-#define VIU2_VD1_IF0_LUMA_X1 0x1e57
-#define VIU2_VD1_IF0_LUMA_Y1 0x1e58
-#define VIU2_VD1_IF0_CHROMA_X1 0x1e59
-#define VIU2_VD1_IF0_CHROMA_Y1 0x1e5a
-#define VIU2_VD1_IF0_RPT_LOOP 0x1e5b
-#define VIU2_VD1_IF0_LUMA0_RPT_PAT 0x1e5c
-#define VIU2_VD1_IF0_CHROMA0_RPT_PAT 0x1e5d
-#define VIU2_VD1_IF0_LUMA1_RPT_PAT 0x1e5e
-#define VIU2_VD1_IF0_CHROMA1_RPT_PAT 0x1e5f
-#define VIU2_VD1_IF0_LUMA_PSEL 0x1e60
-#define VIU2_VD1_IF0_CHROMA_PSEL 0x1e61
-#define VIU2_VD1_IF0_DUMMY_PIXEL 0x1e62
-#define VIU2_VD1_IF0_LUMA_FIFO_SIZE 0x1e63
-#define VIU2_VD1_IF0_RANGE_MAP_Y 0x1e6a
-#define VIU2_VD1_IF0_RANGE_MAP_CB 0x1e6b
-#define VIU2_VD1_IF0_RANGE_MAP_CR 0x1e6c
-#define VIU2_VD1_IF0_GEN_REG2 0x1e6d
-#define VIU2_VD1_IF0_PROT_CNTL 0x1e6e
-#define VIU2_VD1_FMT_CTRL 0x1e68
-#define VIU2_VD1_FMT_W 0x1e69
-
-/* encode */
-#define ENCP_VFIFO2VD_CTL 0x1b58
-#define ENCP_VFIFO2VD_PIXEL_START 0x1b59
-#define ENCP_VFIFO2VD_PIXEL_END 0x1b5a
-#define ENCP_VFIFO2VD_LINE_TOP_START 0x1b5b
-#define ENCP_VFIFO2VD_LINE_TOP_END 0x1b5c
-#define ENCP_VFIFO2VD_LINE_BOT_START 0x1b5d
-#define ENCP_VFIFO2VD_LINE_BOT_END 0x1b5e
-#define VENC_SYNC_ROUTE 0x1b60
-#define VENC_VIDEO_EXSRC 0x1b61
-#define VENC_DVI_SETTING 0x1b62
-#define VENC_C656_CTRL 0x1b63
-#define VENC_UPSAMPLE_CTRL0 0x1b64
-#define VENC_UPSAMPLE_CTRL1 0x1b65
-#define VENC_UPSAMPLE_CTRL2 0x1b66
-#define TCON_INVERT_CTL 0x1b67
-#define VENC_VIDEO_PROG_MODE 0x1b68
-#define VENC_ENCI_LINE 0x1b69
-#define VENC_ENCI_PIXEL 0x1b6a
-#define VENC_ENCP_LINE 0x1b6b
-#define VENC_ENCP_PIXEL 0x1b6c
-#define VENC_STATA 0x1b6d
-#define VENC_INTCTRL 0x1b6e
-#define VENC_INTFLAG 0x1b6f
-#define VENC_VIDEO_TST_EN 0x1b70
-#define VENC_VIDEO_TST_MDSEL 0x1b71
-#define VENC_VIDEO_TST_Y 0x1b72
-#define VENC_VIDEO_TST_CB 0x1b73
-#define VENC_VIDEO_TST_CR 0x1b74
-#define VENC_VIDEO_TST_CLRBAR_STRT 0x1b75
-#define VENC_VIDEO_TST_CLRBAR_WIDTH 0x1b76
-#define VENC_VIDEO_TST_VDCNT_STSET 0x1b77
-#define VENC_VDAC_DACSEL0 0x1b78
-#define VENC_VDAC_DACSEL1 0x1b79
-#define VENC_VDAC_DACSEL2 0x1b7a
-#define VENC_VDAC_DACSEL3 0x1b7b
-#define VENC_VDAC_DACSEL4 0x1b7c
-#define VENC_VDAC_DACSEL5 0x1b7d
-#define VENC_VDAC_SETTING 0x1b7e
-#define VENC_VDAC_TST_VAL 0x1b7f
-#define VENC_VDAC_DAC0_GAINCTRL 0x1bf0
-#define VENC_VDAC_DAC0_OFFSET 0x1bf1
-#define VENC_VDAC_DAC1_GAINCTRL 0x1bf2
-#define VENC_VDAC_DAC1_OFFSET 0x1bf3
-#define VENC_VDAC_DAC2_GAINCTRL 0x1bf4
-#define VENC_VDAC_DAC2_OFFSET 0x1bf5
-#define VENC_VDAC_DAC3_GAINCTRL 0x1bf6
-#define VENC_VDAC_DAC3_OFFSET 0x1bf7
-#define VENC_VDAC_DAC4_GAINCTRL 0x1bf8
-#define VENC_VDAC_DAC4_OFFSET 0x1bf9
-#define VENC_VDAC_DAC5_GAINCTRL 0x1bfa
-#define VENC_VDAC_DAC5_OFFSET 0x1bfb
-#define VENC_VDAC_FIFO_CTRL 0x1bfc
-#define ENCL_TCON_INVERT_CTL 0x1bfd
-#define ENCP_VIDEO_EN 0x1b80
-#define ENCP_VIDEO_SYNC_MODE 0x1b81
-#define ENCP_MACV_EN 0x1b82
-#define ENCP_VIDEO_Y_SCL 0x1b83
-#define ENCP_VIDEO_PB_SCL 0x1b84
-#define ENCP_VIDEO_PR_SCL 0x1b85
-#define ENCP_VIDEO_SYNC_SCL 0x1b86
-#define ENCP_VIDEO_MACV_SCL 0x1b87
-#define ENCP_VIDEO_Y_OFFST 0x1b88
-#define ENCP_VIDEO_PB_OFFST 0x1b89
-#define ENCP_VIDEO_PR_OFFST 0x1b8a
-#define ENCP_VIDEO_SYNC_OFFST 0x1b8b
-#define ENCP_VIDEO_MACV_OFFST 0x1b8c
-#define ENCP_VIDEO_MODE 0x1b8d
-#define ENCP_VIDEO_MODE_ADV 0x1b8e
-#define ENCP_DBG_PX_RST 0x1b90
-#define ENCP_DBG_LN_RST 0x1b91
-#define ENCP_DBG_PX_INT 0x1b92
-#define ENCP_DBG_LN_INT 0x1b93
-#define ENCP_VIDEO_YFP1_HTIME 0x1b94
-#define ENCP_VIDEO_YFP2_HTIME 0x1b95
-#define ENCP_VIDEO_YC_DLY 0x1b96
-#define ENCP_VIDEO_MAX_PXCNT 0x1b97
-#define ENCP_VIDEO_HSPULS_BEGIN 0x1b98
-#define ENCP_VIDEO_HSPULS_END 0x1b99
-#define ENCP_VIDEO_HSPULS_SWITCH 0x1b9a
-#define ENCP_VIDEO_VSPULS_BEGIN 0x1b9b
-#define ENCP_VIDEO_VSPULS_END 0x1b9c
-#define ENCP_VIDEO_VSPULS_BLINE 0x1b9d
-#define ENCP_VIDEO_VSPULS_ELINE 0x1b9e
-#define ENCP_VIDEO_EQPULS_BEGIN 0x1b9f
-#define ENCP_VIDEO_EQPULS_END 0x1ba0
-#define ENCP_VIDEO_EQPULS_BLINE 0x1ba1
-#define ENCP_VIDEO_EQPULS_ELINE 0x1ba2
-#define ENCP_VIDEO_HAVON_END 0x1ba3
-#define ENCP_VIDEO_HAVON_BEGIN 0x1ba4
-#define ENCP_VIDEO_VAVON_ELINE 0x1baf
-#define ENCP_VIDEO_VAVON_BLINE 0x1ba6
-#define ENCP_VIDEO_HSO_BEGIN 0x1ba7
-#define ENCP_VIDEO_HSO_END 0x1ba8
-#define ENCP_VIDEO_VSO_BEGIN 0x1ba9
-#define ENCP_VIDEO_VSO_END 0x1baa
-#define ENCP_VIDEO_VSO_BLINE 0x1bab
-#define ENCP_VIDEO_VSO_ELINE 0x1bac
-#define ENCP_VIDEO_SYNC_WAVE_CURVE 0x1bad
-#define ENCP_VIDEO_MAX_LNCNT 0x1bae
-#define ENCP_VIDEO_SY_VAL 0x1bb0
-#define ENCP_VIDEO_SY2_VAL 0x1bb1
-#define ENCP_VIDEO_BLANKY_VAL 0x1bb2
-#define ENCP_VIDEO_BLANKPB_VAL 0x1bb3
-#define ENCP_VIDEO_BLANKPR_VAL 0x1bb4
-#define ENCP_VIDEO_HOFFST 0x1bb5
-#define ENCP_VIDEO_VOFFST 0x1bb6
-#define ENCP_VIDEO_RGB_CTRL 0x1bb7
-#define ENCP_VIDEO_FILT_CTRL 0x1bb8
-#define ENCP_VIDEO_OFLD_VPEQ_OFST 0x1bb9
-#define ENCP_VIDEO_OFLD_VOAV_OFST 0x1bba
-#define ENCP_VIDEO_MATRIX_CB 0x1bbb
-#define ENCP_VIDEO_MATRIX_CR 0x1bbc
-#define ENCP_VIDEO_RGBIN_CTRL 0x1bbd
-#define ENCP_MACV_BLANKY_VAL 0x1bc0
-#define ENCP_MACV_MAXY_VAL 0x1bc1
-#define ENCP_MACV_1ST_PSSYNC_STRT 0x1bc2
-#define ENCP_MACV_PSSYNC_STRT 0x1bc3
-#define ENCP_MACV_AGC_STRT 0x1bc4
-#define ENCP_MACV_AGC_END 0x1bc5
-#define ENCP_MACV_WAVE_END 0x1bc6
-#define ENCP_MACV_STRTLINE 0x1bc7
-#define ENCP_MACV_ENDLINE 0x1bc8
-#define ENCP_MACV_TS_CNT_MAX_L 0x1bc9
-#define ENCP_MACV_TS_CNT_MAX_H 0x1bca
-#define ENCP_MACV_TIME_DOWN 0x1bcb
-#define ENCP_MACV_TIME_LO 0x1bcc
-#define ENCP_MACV_TIME_UP 0x1bcd
-#define ENCP_MACV_TIME_RST 0x1bce
-#define ENCP_VBI_CTRL 0x1bd0
-#define ENCP_VBI_SETTING 0x1bd1
-#define ENCP_VBI_BEGIN 0x1bd2
-#define ENCP_VBI_WIDTH 0x1bd3
-#define ENCP_VBI_HVAL 0x1bd4
-#define ENCP_VBI_DATA0 0x1bd5
-#define ENCP_VBI_DATA1 0x1bd6
-#define C656_HS_ST 0x1be0
-#define C656_HS_ED 0x1be1
-#define C656_VS_LNST_E 0x1be2
-#define C656_VS_LNST_O 0x1be3
-#define C656_VS_LNED_E 0x1be4
-#define C656_VS_LNED_O 0x1be5
-#define C656_FS_LNST 0x1be6
-#define C656_FS_LNED 0x1be7
-#define ENCI_VIDEO_MODE 0x1b00
-#define ENCI_VIDEO_MODE_ADV 0x1b01
-#define ENCI_VIDEO_FSC_ADJ 0x1b02
-#define ENCI_VIDEO_BRIGHT 0x1b03
-#define ENCI_VIDEO_CONT 0x1b04
-#define ENCI_VIDEO_SAT 0x1b05
-#define ENCI_VIDEO_HUE 0x1b06
-#define ENCI_VIDEO_SCH 0x1b07
-#define ENCI_SYNC_MODE 0x1b08
-#define ENCI_SYNC_CTRL 0x1b09
-#define ENCI_SYNC_HSO_BEGIN 0x1b0a
-#define ENCI_SYNC_HSO_END 0x1b0b
-#define ENCI_SYNC_VSO_EVN 0x1b0c
-#define ENCI_SYNC_VSO_ODD 0x1b0d
-#define ENCI_SYNC_VSO_EVNLN 0x1b0e
-#define ENCI_SYNC_VSO_ODDLN 0x1b0f
-#define ENCI_SYNC_HOFFST 0x1b10
-#define ENCI_SYNC_VOFFST 0x1b11
-#define ENCI_SYNC_ADJ 0x1b12
-#define ENCI_RGB_SETTING 0x1b13
-#define ENCI_DE_H_BEGIN 0x1b16
-#define ENCI_DE_H_END 0x1b17
-#define ENCI_DE_V_BEGIN_EVEN 0x1b18
-#define ENCI_DE_V_END_EVEN 0x1b19
-#define ENCI_DE_V_BEGIN_ODD 0x1b1a
-#define ENCI_DE_V_END_ODD 0x1b1b
-#define ENCI_VBI_SETTING 0x1b20
-#define ENCI_VBI_CCDT_EVN 0x1b21
-#define ENCI_VBI_CCDT_ODD 0x1b22
-#define ENCI_VBI_CC525_LN 0x1b23
-#define ENCI_VBI_CC625_LN 0x1b24
-#define ENCI_VBI_WSSDT 0x1b25
-#define ENCI_VBI_WSS_LN 0x1b26
-#define ENCI_VBI_CGMSDT_L 0x1b27
-#define ENCI_VBI_CGMSDT_H 0x1b28
-#define ENCI_VBI_CGMS_LN 0x1b29
-#define ENCI_VBI_TTX_HTIME 0x1b2a
-#define ENCI_VBI_TTX_LN 0x1b2b
-#define ENCI_VBI_TTXDT0 0x1b2c
-#define ENCI_VBI_TTXDT1 0x1b2d
-#define ENCI_VBI_TTXDT2 0x1b2e
-#define ENCI_VBI_TTXDT3 0x1b2f
-#define ENCI_MACV_N0 0x1b30
-#define ENCI_MACV_N1 0x1b31
-#define ENCI_MACV_N2 0x1b32
-#define ENCI_MACV_N3 0x1b33
-#define ENCI_MACV_N4 0x1b34
-#define ENCI_MACV_N5 0x1b35
-#define ENCI_MACV_N6 0x1b36
-#define ENCI_MACV_N7 0x1b37
-#define ENCI_MACV_N8 0x1b38
-#define ENCI_MACV_N9 0x1b39
-#define ENCI_MACV_N10 0x1b3a
-#define ENCI_MACV_N11 0x1b3b
-#define ENCI_MACV_N12 0x1b3c
-#define ENCI_MACV_N13 0x1b3d
-#define ENCI_MACV_N14 0x1b3e
-#define ENCI_MACV_N15 0x1b3f
-#define ENCI_MACV_N16 0x1b40
-#define ENCI_MACV_N17 0x1b41
-#define ENCI_MACV_N18 0x1b42
-#define ENCI_MACV_N19 0x1b43
-#define ENCI_MACV_N20 0x1b44
-#define ENCI_MACV_N21 0x1b45
-#define ENCI_MACV_N22 0x1b46
-#define ENCI_DBG_PX_RST 0x1b48
-#define ENCI_DBG_FLDLN_RST 0x1b49
-#define ENCI_DBG_PX_INT 0x1b4a
-#define ENCI_DBG_FLDLN_INT 0x1b4b
-#define ENCI_DBG_MAXPX 0x1b4c
-#define ENCI_DBG_MAXLN 0x1b4d
-#define ENCI_MACV_MAX_AMP 0x1b50
-#define ENCI_MACV_PULSE_LO 0x1b51
-#define ENCI_MACV_PULSE_HI 0x1b52
-#define ENCI_MACV_BKP_MAX 0x1b53
-#define ENCI_CFILT_CTRL 0x1b54
-#define ENCI_CFILT7 0x1b55
-#define ENCI_YC_DELAY 0x1b56
-#define ENCI_VIDEO_EN 0x1b57
-#define ENCI_DVI_HSO_BEGIN 0x1c00
-#define ENCI_DVI_HSO_END 0x1c01
-#define ENCI_DVI_VSO_BLINE_EVN 0x1c02
-#define ENCI_DVI_VSO_BLINE_ODD 0x1c03
-#define ENCI_DVI_VSO_ELINE_EVN 0x1c04
-#define ENCI_DVI_VSO_ELINE_ODD 0x1c05
-#define ENCI_DVI_VSO_BEGIN_EVN 0x1c06
-#define ENCI_DVI_VSO_BEGIN_ODD 0x1c07
-#define ENCI_DVI_VSO_END_EVN 0x1c08
-#define ENCI_DVI_VSO_END_ODD 0x1c09
-#define ENCI_CFILT_CTRL2 0x1c0a
-#define ENCI_DACSEL_0 0x1c0b
-#define ENCI_DACSEL_1 0x1c0c
-#define ENCP_DACSEL_0 0x1c0d
-#define ENCP_DACSEL_1 0x1c0e
-#define ENCP_MAX_LINE_SWITCH_POINT 0x1c0f
-#define ENCI_TST_EN 0x1c10
-#define ENCI_TST_MDSEL 0x1c11
-#define ENCI_TST_Y 0x1c12
-#define ENCI_TST_CB 0x1c13
-#define ENCI_TST_CR 0x1c14
-#define ENCI_TST_CLRBAR_STRT 0x1c15
-#define ENCI_TST_CLRBAR_WIDTH 0x1c16
-#define ENCI_TST_VDCNT_STSET 0x1c17
-#define ENCI_VFIFO2VD_CTL 0x1c18
-#define ENCI_VFIFO2VD_PIXEL_START 0x1c19
-#define ENCI_VFIFO2VD_PIXEL_END 0x1c1a
-#define ENCI_VFIFO2VD_LINE_TOP_START 0x1c1b
-#define ENCI_VFIFO2VD_LINE_TOP_END 0x1c1c
-#define ENCI_VFIFO2VD_LINE_BOT_START 0x1c1d
-#define ENCI_VFIFO2VD_LINE_BOT_END 0x1c1e
-#define ENCI_VFIFO2VD_CTL2 0x1c1f
-#define ENCT_VFIFO2VD_CTL 0x1c20
-#define ENCT_VFIFO2VD_PIXEL_START 0x1c21
-#define ENCT_VFIFO2VD_PIXEL_END 0x1c22
-#define ENCT_VFIFO2VD_LINE_TOP_START 0x1c23
-#define ENCT_VFIFO2VD_LINE_TOP_END 0x1c24
-#define ENCT_VFIFO2VD_LINE_BOT_START 0x1c25
-#define ENCT_VFIFO2VD_LINE_BOT_END 0x1c26
-#define ENCT_VFIFO2VD_CTL2 0x1c27
-#define ENCT_TST_EN 0x1c28
-#define ENCT_TST_MDSEL 0x1c29
-#define ENCT_TST_Y 0x1c2a
-#define ENCT_TST_CB 0x1c2b
-#define ENCT_TST_CR 0x1c2c
-#define ENCT_TST_CLRBAR_STRT 0x1c2d
-#define ENCT_TST_CLRBAR_WIDTH 0x1c2e
-#define ENCT_TST_VDCNT_STSET 0x1c2f
-#define ENCP_DVI_HSO_BEGIN 0x1c30
-#define ENCP_DVI_HSO_END 0x1c31
-#define ENCP_DVI_VSO_BLINE_EVN 0x1c32
-#define ENCP_DVI_VSO_BLINE_ODD 0x1c33
-#define ENCP_DVI_VSO_ELINE_EVN 0x1c34
-#define ENCP_DVI_VSO_ELINE_ODD 0x1c35
-#define ENCP_DVI_VSO_BEGIN_EVN 0x1c36
-#define ENCP_DVI_VSO_BEGIN_ODD 0x1c37
-#define ENCP_DVI_VSO_END_EVN 0x1c38
-#define ENCP_DVI_VSO_END_ODD 0x1c39
-#define ENCP_DE_H_BEGIN 0x1c3a
-#define ENCP_DE_H_END 0x1c3b
-#define ENCP_DE_V_BEGIN_EVEN 0x1c3c
-#define ENCP_DE_V_END_EVEN 0x1c3d
-#define ENCP_DE_V_BEGIN_ODD 0x1c3e
-#define ENCP_DE_V_END_ODD 0x1c3f
-#define ENCI_SYNC_LINE_LENGTH 0x1c40
-#define ENCI_SYNC_PIXEL_EN 0x1c41
-#define ENCI_SYNC_TO_LINE_EN 0x1c42
-#define ENCI_SYNC_TO_PIXEL 0x1c43
-#define ENCP_SYNC_LINE_LENGTH 0x1c44
-#define ENCP_SYNC_PIXEL_EN 0x1c45
-#define ENCP_SYNC_TO_LINE_EN 0x1c46
-#define ENCP_SYNC_TO_PIXEL 0x1c47
-#define ENCT_SYNC_LINE_LENGTH 0x1c48
-#define ENCT_SYNC_PIXEL_EN 0x1c49
-#define ENCT_SYNC_TO_LINE_EN 0x1c4a
-#define ENCT_SYNC_TO_PIXEL 0x1c4b
-#define ENCL_SYNC_LINE_LENGTH 0x1c4c
-#define ENCL_SYNC_PIXEL_EN 0x1c4d
-#define ENCL_SYNC_TO_LINE_EN 0x1c4e
-#define ENCL_SYNC_TO_PIXEL 0x1c4f
-#define ENCP_VFIFO2VD_CTL2 0x1c50
-#define VENC_DVI_SETTING_MORE 0x1c51
-#define VENC_VDAC_DAC4_FILT_CTRL0 0x1c54
-#define VENC_VDAC_DAC4_FILT_CTRL1 0x1c55
-#define VENC_VDAC_DAC5_FILT_CTRL0 0x1c56
-#define VENC_VDAC_DAC5_FILT_CTRL1 0x1c57
-#define VENC_VDAC_DAC0_FILT_CTRL0 0x1c58
-#define VENC_VDAC_DAC0_FILT_CTRL1 0x1c59
-#define VENC_VDAC_DAC1_FILT_CTRL0 0x1c5a
-#define VENC_VDAC_DAC1_FILT_CTRL1 0x1c5b
-#define VENC_VDAC_DAC2_FILT_CTRL0 0x1c5c
-#define VENC_VDAC_DAC2_FILT_CTRL1 0x1c5d
-#define VENC_VDAC_DAC3_FILT_CTRL0 0x1c5e
-#define VENC_VDAC_DAC3_FILT_CTRL1 0x1c5f
-#define ENCT_VIDEO_EN 0x1c60
-#define ENCT_VIDEO_Y_SCL 0x1c61
-#define ENCT_VIDEO_PB_SCL 0x1c62
-#define ENCT_VIDEO_PR_SCL 0x1c63
-#define ENCT_VIDEO_Y_OFFST 0x1c64
-#define ENCT_VIDEO_PB_OFFST 0x1c65
-#define ENCT_VIDEO_PR_OFFST 0x1c66
-#define ENCT_VIDEO_MODE 0x1c67
-#define ENCT_VIDEO_MODE_ADV 0x1c68
-#define ENCT_DBG_PX_RST 0x1c69
-#define ENCT_DBG_LN_RST 0x1c6a
-#define ENCT_DBG_PX_INT 0x1c6b
-#define ENCT_DBG_LN_INT 0x1c6c
-#define ENCT_VIDEO_YFP1_HTIME 0x1c6d
-#define ENCT_VIDEO_YFP2_HTIME 0x1c6e
-#define ENCT_VIDEO_YC_DLY 0x1c6f
-#define ENCT_VIDEO_MAX_PXCNT 0x1c70
-#define ENCT_VIDEO_HAVON_END 0x1c71
-#define ENCT_VIDEO_HAVON_BEGIN 0x1c72
-#define ENCT_VIDEO_VAVON_ELINE 0x1c73
-#define ENCT_VIDEO_VAVON_BLINE 0x1c74
-#define ENCT_VIDEO_HSO_BEGIN 0x1c75
-#define ENCT_VIDEO_HSO_END 0x1c76
-#define ENCT_VIDEO_VSO_BEGIN 0x1c77
-#define ENCT_VIDEO_VSO_END 0x1c78
-#define ENCT_VIDEO_VSO_BLINE 0x1c79
-#define ENCT_VIDEO_VSO_ELINE 0x1c7a
-#define ENCT_VIDEO_MAX_LNCNT 0x1c7b
-#define ENCT_VIDEO_BLANKY_VAL 0x1c7c
-#define ENCT_VIDEO_BLANKPB_VAL 0x1c7d
-#define ENCT_VIDEO_BLANKPR_VAL 0x1c7e
-#define ENCT_VIDEO_HOFFST 0x1c7f
-#define ENCT_VIDEO_VOFFST 0x1c80
-#define ENCT_VIDEO_RGB_CTRL 0x1c81
-#define ENCT_VIDEO_FILT_CTRL 0x1c82
-#define ENCT_VIDEO_OFLD_VPEQ_OFST 0x1c83
-#define ENCT_VIDEO_OFLD_VOAV_OFST 0x1c84
-#define ENCT_VIDEO_MATRIX_CB 0x1c85
-#define ENCT_VIDEO_MATRIX_CR 0x1c86
-#define ENCT_VIDEO_RGBIN_CTRL 0x1c87
-#define ENCT_MAX_LINE_SWITCH_POINT 0x1c88
-#define ENCT_DACSEL_0 0x1c89
-#define ENCT_DACSEL_1 0x1c8a
-#define ENCL_VFIFO2VD_CTL 0x1c90
-#define ENCL_VFIFO2VD_PIXEL_START 0x1c91
-#define ENCL_VFIFO2VD_PIXEL_END 0x1c92
-#define ENCL_VFIFO2VD_LINE_TOP_START 0x1c93
-#define ENCL_VFIFO2VD_LINE_TOP_END 0x1c94
-#define ENCL_VFIFO2VD_LINE_BOT_START 0x1c95
-#define ENCL_VFIFO2VD_LINE_BOT_END 0x1c96
-#define ENCL_VFIFO2VD_CTL2 0x1c97
-#define ENCL_TST_EN 0x1c98
-#define ENCL_TST_MDSEL 0x1c99
-#define ENCL_TST_Y 0x1c9a
-#define ENCL_TST_CB 0x1c9b
-#define ENCL_TST_CR 0x1c9c
-#define ENCL_TST_CLRBAR_STRT 0x1c9d
-#define ENCL_TST_CLRBAR_WIDTH 0x1c9e
-#define ENCL_TST_VDCNT_STSET 0x1c9f
-#define ENCL_VIDEO_EN 0x1ca0
-#define ENCL_VIDEO_Y_SCL 0x1ca1
-#define ENCL_VIDEO_PB_SCL 0x1ca2
-#define ENCL_VIDEO_PR_SCL 0x1ca3
-#define ENCL_VIDEO_Y_OFFST 0x1ca4
-#define ENCL_VIDEO_PB_OFFST 0x1ca5
-#define ENCL_VIDEO_PR_OFFST 0x1ca6
-#define ENCL_VIDEO_MODE 0x1ca7
-#define ENCL_VIDEO_MODE_ADV 0x1ca8
-#define ENCL_DBG_PX_RST 0x1ca9
-#define ENCL_DBG_LN_RST 0x1caa
-#define ENCL_DBG_PX_INT 0x1cab
-#define ENCL_DBG_LN_INT 0x1cac
-#define ENCL_VIDEO_YFP1_HTIME 0x1cad
-#define ENCL_VIDEO_YFP2_HTIME 0x1cae
-#define ENCL_VIDEO_YC_DLY 0x1caf
-#define ENCL_VIDEO_MAX_PXCNT 0x1cb0
-#define ENCL_VIDEO_HAVON_END 0x1cb1
-#define ENCL_VIDEO_HAVON_BEGIN 0x1cb2
-#define ENCL_VIDEO_VAVON_ELINE 0x1cb3
-#define ENCL_VIDEO_VAVON_BLINE 0x1cb4
-#define ENCL_VIDEO_HSO_BEGIN 0x1cb5
-#define ENCL_VIDEO_HSO_END 0x1cb6
-#define ENCL_VIDEO_VSO_BEGIN 0x1cb7
-#define ENCL_VIDEO_VSO_END 0x1cb8
-#define ENCL_VIDEO_VSO_BLINE 0x1cb9
-#define ENCL_VIDEO_VSO_ELINE 0x1cba
-#define ENCL_VIDEO_MAX_LNCNT 0x1cbb
-#define ENCL_VIDEO_BLANKY_VAL 0x1cbc
-#define ENCL_VIDEO_BLANKPB_VAL 0x1cbd
-#define ENCL_VIDEO_BLANKPR_VAL 0x1cbe
-#define ENCL_VIDEO_HOFFST 0x1cbf
-#define ENCL_VIDEO_VOFFST 0x1cc0
-#define ENCL_VIDEO_RGB_CTRL 0x1cc1
-#define ENCL_VIDEO_FILT_CTRL 0x1cc2
-#define ENCL_VIDEO_OFLD_VPEQ_OFST 0x1cc3
-#define ENCL_VIDEO_OFLD_VOAV_OFST 0x1cc4
-#define ENCL_VIDEO_MATRIX_CB 0x1cc5
-#define ENCL_VIDEO_MATRIX_CR 0x1cc6
-#define ENCL_VIDEO_RGBIN_CTRL 0x1cc7
-#define ENCL_MAX_LINE_SWITCH_POINT 0x1cc8
-#define ENCL_DACSEL_0 0x1cc9
-#define ENCL_DACSEL_1 0x1cca
-#define RDMA_AHB_START_ADDR_MAN 0x1100
-#define RDMA_AHB_END_ADDR_MAN 0x1101
-#define RDMA_AHB_START_ADDR_1 0x1102
-#define RDMA_AHB_END_ADDR_1 0x1103
-#define RDMA_AHB_START_ADDR_2 0x1104
-#define RDMA_AHB_END_ADDR_2 0x1105
-#define RDMA_AHB_START_ADDR_3 0x1106
-#define RDMA_AHB_END_ADDR_3 0x1107
-#define RDMA_AHB_START_ADDR_4 0x1108
-#define RDMA_AHB_END_ADDR_4 0x1109
-#define RDMA_AHB_START_ADDR_5 0x110a
-#define RDMA_AHB_END_ADDR_5 0x110b
-#define RDMA_AHB_START_ADDR_6 0x110c
-#define RDMA_AHB_END_ADDR_6 0x110d
-#define RDMA_AHB_START_ADDR_7 0x110e
-#define RDMA_AHB_END_ADDR_7 0x110f
-#define RDMA_ACCESS_AUTO 0x1110
-#define RDMA_ACCESS_AUTO2 0x1111
-#define RDMA_ACCESS_AUTO3 0x1112
-#define RDMA_ACCESS_MAN 0x1113
-#define RDMA_CTRL 0x1114
-#define RDMA_STATUS 0x1115
-#define RDMA_STATUS2 0x1116
-#define RDMA_STATUS3 0x1117
-#define L_GAMMA_CNTL_PORT 0x1400
-#define L_GAMMA_DATA_PORT 0x1401
-#define L_GAMMA_ADDR_PORT 0x1402
-#define L_GAMMA_VCOM_HSWITCH_ADDR 0x1403
-#define L_RGB_BASE_ADDR 0x1405
-#define L_RGB_COEFF_ADDR 0x1406
-#define L_POL_CNTL_ADDR 0x1407
-#define L_DITH_CNTL_ADDR 0x1408
-#define L_GAMMA_PROBE_CTRL 0x1409
-#define L_GAMMA_PROBE_COLOR_L 0x140a
-#define L_GAMMA_PROBE_COLOR_H 0x140b
-#define L_GAMMA_PROBE_HL_COLOR 0x140c
-#define L_GAMMA_PROBE_POS_X 0x140d
-#define L_GAMMA_PROBE_POS_Y 0x140e
-#define L_STH1_HS_ADDR 0x1410
-#define L_STH1_HE_ADDR 0x1411
-#define L_STH1_VS_ADDR 0x1412
-#define L_STH1_VE_ADDR 0x1413
-#define L_STH2_HS_ADDR 0x1414
-#define L_STH2_HE_ADDR 0x1415
-#define L_STH2_VS_ADDR 0x1416
-#define L_STH2_VE_ADDR 0x1417
-#define L_OEH_HS_ADDR 0x1418
-#define L_OEH_HE_ADDR 0x1419
-#define L_OEH_VS_ADDR 0x141a
-#define L_OEH_VE_ADDR 0x141b
-#define L_VCOM_HSWITCH_ADDR 0x141c
-#define L_VCOM_VS_ADDR 0x141d
-#define L_VCOM_VE_ADDR 0x141e
-#define L_CPV1_HS_ADDR 0x141f
-#define L_CPV1_HE_ADDR 0x1420
-#define L_CPV1_VS_ADDR 0x1421
-#define L_CPV1_VE_ADDR 0x1422
-#define L_CPV2_HS_ADDR 0x1423
-#define L_CPV2_HE_ADDR 0x1424
-#define L_CPV2_VS_ADDR 0x1425
-#define L_CPV2_VE_ADDR 0x1426
-#define L_STV1_HS_ADDR 0x1427
-#define L_STV1_HE_ADDR 0x1428
-#define L_STV1_VS_ADDR 0x1429
-#define L_STV1_VE_ADDR 0x142a
-#define L_STV2_HS_ADDR 0x142b
-#define L_STV2_HE_ADDR 0x142c
-#define L_STV2_VS_ADDR 0x142d
-#define L_STV2_VE_ADDR 0x142e
-#define L_OEV1_HS_ADDR 0x142f
-#define L_OEV1_HE_ADDR 0x1430
-#define L_OEV1_VS_ADDR 0x1431
-#define L_OEV1_VE_ADDR 0x1432
-#define L_OEV2_HS_ADDR 0x1433
-#define L_OEV2_HE_ADDR 0x1434
-#define L_OEV2_VS_ADDR 0x1435
-#define L_OEV2_VE_ADDR 0x1436
-#define L_OEV3_HS_ADDR 0x1437
-#define L_OEV3_HE_ADDR 0x1438
-#define L_OEV3_VS_ADDR 0x1439
-#define L_OEV3_VE_ADDR 0x143a
-#define L_LCD_PWR_ADDR 0x143b
-#define L_LCD_PWM0_LO_ADDR 0x143c
-#define L_LCD_PWM0_HI_ADDR 0x143d
-#define L_LCD_PWM1_LO_ADDR 0x143e
-#define L_LCD_PWM1_HI_ADDR 0x143f
-#define L_INV_CNT_ADDR 0x1440
-#define L_TCON_MISC_SEL_ADDR 0x1441
-#define L_DUAL_PORT_CNTL_ADDR 0x1442
-#define MLVDS_CLK_CTL1_HI 0x1443
-#define MLVDS_CLK_CTL1_LO 0x1444
-#define L_TCON_DOUBLE_CTL 0x1449
-#define L_TCON_PATTERN_HI 0x144a
-#define L_TCON_PATTERN_LO 0x144b
-#define LDIM_BL_ADDR_PORT 0x144e
-#define LDIM_BL_DATA_PORT 0x144f
-#define L_DE_HS_ADDR 0x1451
-#define L_DE_HE_ADDR 0x1452
-#define L_DE_VS_ADDR 0x1453
-#define L_DE_VE_ADDR 0x1454
-#define L_HSYNC_HS_ADDR 0x1455
-#define L_HSYNC_HE_ADDR 0x1456
-#define L_HSYNC_VS_ADDR 0x1457
-#define L_HSYNC_VE_ADDR 0x1458
-#define L_VSYNC_HS_ADDR 0x1459
-#define L_VSYNC_HE_ADDR 0x145a
-#define L_VSYNC_VS_ADDR 0x145b
-#define L_VSYNC_VE_ADDR 0x145c
-#define L_LCD_MCU_CTL 0x145d
-#define DUAL_MLVDS_CTL 0x1460
-#define DUAL_MLVDS_LINE_START 0x1461
-#define DUAL_MLVDS_LINE_END 0x1462
-#define DUAL_MLVDS_PIXEL_W_START_L 0x1463
-#define DUAL_MLVDS_PIXEL_W_END_L 0x1464
-#define DUAL_MLVDS_PIXEL_W_START_R 0x1465
-#define DUAL_MLVDS_PIXEL_W_END_R 0x1466
-#define DUAL_MLVDS_PIXEL_R_START_L 0x1467
-#define DUAL_MLVDS_PIXEL_R_CNT_L 0x1468
-#define DUAL_MLVDS_PIXEL_R_START_R 0x1469
-#define DUAL_MLVDS_PIXEL_R_CNT_R 0x146a
-#define V_INVERSION_PIXEL 0x1470
-#define V_INVERSION_LINE 0x1471
-#define V_INVERSION_CONTROL 0x1472
-#define MLVDS2_CONTROL 0x1474
-#define MLVDS2_CONFIG_HI 0x1475
-#define MLVDS2_CONFIG_LO 0x1476
-#define MLVDS2_DUAL_GATE_WR_START 0x1477
-#define MLVDS2_DUAL_GATE_WR_END 0x1478
-#define MLVDS2_DUAL_GATE_RD_START 0x1479
-#define MLVDS2_DUAL_GATE_RD_END 0x147a
-#define MLVDS2_SECOND_RESET_CTL 0x147b
-#define MLVDS2_DUAL_GATE_CTL_HI 0x147c
-#define MLVDS2_DUAL_GATE_CTL_LO 0x147d
-#define MLVDS2_RESET_CONFIG_HI 0x147e
-#define MLVDS2_RESET_CONFIG_LO 0x147f
-#define GAMMA_CNTL_PORT 0x1480
-#define GAMMA_DATA_PORT 0x1481
-#define GAMMA_ADDR_PORT 0x1482
-#define GAMMA_VCOM_HSWITCH_ADDR 0x1483
-#define RGB_BASE_ADDR 0x1485
-#define RGB_COEFF_ADDR 0x1486
-#define POL_CNTL_ADDR 0x1487
-#define DITH_CNTL_ADDR 0x1488
-#define GAMMA_PROBE_CTRL 0x1489
-#define GAMMA_PROBE_COLOR_L 0x148a
-#define GAMMA_PROBE_COLOR_H 0x148b
-#define GAMMA_PROBE_HL_COLOR 0x148c
-#define GAMMA_PROBE_POS_X 0x148d
-#define GAMMA_PROBE_POS_Y 0x148e
-#define STH1_HS_ADDR 0x1490
-#define STH1_HE_ADDR 0x1491
-#define STH1_VS_ADDR 0x1492
-#define STH1_VE_ADDR 0x1493
-#define STH2_HS_ADDR 0x1494
-#define STH2_HE_ADDR 0x1495
-#define STH2_VS_ADDR 0x1496
-#define STH2_VE_ADDR 0x1497
-#define OEH_HS_ADDR 0x1498
-#define OEH_HE_ADDR 0x1499
-#define OEH_VS_ADDR 0x149a
-#define OEH_VE_ADDR 0x149b
-#define VCOM_HSWITCH_ADDR 0x149c
-#define VCOM_VS_ADDR 0x149d
-#define VCOM_VE_ADDR 0x149e
-#define CPV1_HS_ADDR 0x149f
-#define CPV1_HE_ADDR 0x14a0
-#define CPV1_VS_ADDR 0x14a1
-#define CPV1_VE_ADDR 0x14a2
-#define CPV2_HS_ADDR 0x14a3
-#define CPV2_HE_ADDR 0x14a4
-#define CPV2_VS_ADDR 0x14a5
-#define CPV2_VE_ADDR 0x14a6
-#define STV1_HS_ADDR 0x14a7
-#define STV1_HE_ADDR 0x14a8
-#define STV1_VS_ADDR 0x14a9
-#define STV1_VE_ADDR 0x14aa
-#define STV2_HS_ADDR 0x14ab
-#define STV2_HE_ADDR 0x14ac
-#define STV2_VS_ADDR 0x14ad
-#define STV2_VE_ADDR 0x14ae
-#define OEV1_HS_ADDR 0x14af
-#define OEV1_HE_ADDR 0x14b0
-#define OEV1_VS_ADDR 0x14b1
-#define OEV1_VE_ADDR 0x14b2
-#define OEV2_HS_ADDR 0x14b3
-#define OEV2_HE_ADDR 0x14b4
-#define OEV2_VS_ADDR 0x14b5
-#define OEV2_VE_ADDR 0x14b6
-#define OEV3_HS_ADDR 0x14b7
-#define OEV3_HE_ADDR 0x14b8
-#define OEV3_VS_ADDR 0x14b9
-#define OEV3_VE_ADDR 0x14ba
-#define LCD_PWR_ADDR 0x14bb
-#define LCD_PWM0_LO_ADDR 0x14bc
-#define LCD_PWM0_HI_ADDR 0x14bd
-#define LCD_PWM1_LO_ADDR 0x14be
-#define LCD_PWM1_HI_ADDR 0x14bf
-#define INV_CNT_ADDR 0x14c0
-#define TCON_MISC_SEL_ADDR 0x14c1
-#define DUAL_PORT_CNTL_ADDR 0x14c2
-#define MLVDS_CONTROL 0x14c3
-#define MLVDS_RESET_PATTERN_HI 0x14c4
-#define MLVDS_RESET_PATTERN_LO 0x14c5
-#define MLVDS_RESET_PATTERN_EXT 0x14c6
-#define MLVDS_CONFIG_HI 0x14c7
-#define MLVDS_CONFIG_LO 0x14c8
-#define TCON_DOUBLE_CTL 0x14c9
-#define TCON_PATTERN_HI 0x14ca
-#define TCON_PATTERN_LO 0x14cb
-#define TCON_CONTROL_HI 0x14cc
-#define TCON_CONTROL_LO 0x14cd
-#define LVDS_BLANK_DATA_HI 0x14ce
-#define LVDS_BLANK_DATA_LO 0x14cf
-#define LVDS_PACK_CNTL_ADDR 0x14d0
-#define DE_HS_ADDR 0x14d1
-#define DE_HE_ADDR 0x14d2
-#define DE_VS_ADDR 0x14d3
-#define DE_VE_ADDR 0x14d4
-#define HSYNC_HS_ADDR 0x14d5
-#define HSYNC_HE_ADDR 0x14d6
-#define HSYNC_VS_ADDR 0x14d7
-#define HSYNC_VE_ADDR 0x14d8
-#define VSYNC_HS_ADDR 0x14d9
-#define VSYNC_HE_ADDR 0x14da
-#define VSYNC_VS_ADDR 0x14db
-#define VSYNC_VE_ADDR 0x14dc
-#define LCD_MCU_CTL 0x14dd
-#define LCD_MCU_DATA_0 0x14de
-#define LCD_MCU_DATA_1 0x14df
-#define LVDS_GEN_CNTL 0x14e0
-#define LVDS_PHY_CNTL0 0x14e1
-#define LVDS_PHY_CNTL1 0x14e2
-#define LVDS_PHY_CNTL2 0x14e3
-#define LVDS_PHY_CNTL3 0x14e4
-#define LVDS_PHY_CNTL4 0x14e5
-#define LVDS_PHY_CNTL5 0x14e6
-#define LVDS_SRG_TEST 0x14e8
-#define LVDS_BIST_MUX0 0x14e9
-#define LVDS_BIST_MUX1 0x14ea
-#define LVDS_BIST_FIXED0 0x14eb
-#define LVDS_BIST_FIXED1 0x14ec
-#define LVDS_BIST_CNTL0 0x14ed
-#define LVDS_CLKB_CLKA 0x14ee
-#define LVDS_PHY_CLK_CNTL 0x14ef
-#define LVDS_SER_EN 0x14f0
-#define LVDS_PHY_CNTL6 0x14f1
-#define LVDS_PHY_CNTL7 0x14f2
-#define LVDS_PHY_CNTL8 0x14f3
-#define MLVDS_CLK_CTL0_HI 0x14f4
-#define MLVDS_CLK_CTL0_LO 0x14f5
-#define MLVDS_DUAL_GATE_WR_START 0x14f6
-#define MLVDS_DUAL_GATE_WR_END 0x14f7
-#define MLVDS_DUAL_GATE_RD_START 0x14f8
-#define MLVDS_DUAL_GATE_RD_END 0x14f9
-#define MLVDS_SECOND_RESET_CTL 0x14fa
-#define MLVDS_DUAL_GATE_CTL_HI 0x14fb
-#define MLVDS_DUAL_GATE_CTL_LO 0x14fc
-#define MLVDS_RESET_CONFIG_HI 0x14fd
-#define MLVDS_RESET_CONFIG_LO 0x14fe
-#define VPU_OSD1_MMC_CTRL 0x2701
-#define VPU_OSD2_MMC_CTRL 0x2702
-#define VPU_VD1_MMC_CTRL 0x2703
-#define VPU_VD2_MMC_CTRL 0x2704
-#define VPU_DI_IF1_MMC_CTRL 0x2705
-#define VPU_DI_MEM_MMC_CTRL 0x2706
-#define VPU_DI_INP_MMC_CTRL 0x2707
-#define VPU_DI_MTNRD_MMC_CTRL 0x2708
-#define VPU_DI_CHAN2_MMC_CTRL 0x2709
-#define VPU_DI_MTNWR_MMC_CTRL 0x270a
-#define VPU_DI_NRWR_MMC_CTRL 0x270b
-#define VPU_DI_DIWR_MMC_CTRL 0x270c
-#define VPU_VDIN0_MMC_CTRL 0x270d
-#define VPU_VDIN1_MMC_CTRL 0x270e
-#define VPU_BT656_MMC_CTRL 0x270f
-#define VPU_TVD3D_MMC_CTRL 0x2710
-#define VPU_TVDVBI_MMC_CTRL 0x2711
-#define VPU_TVDVBI_VSLATCH_ADDR 0x2712
-#define VPU_TVDVBI_WRRSP_ADDR 0x2713
-#define VPU_VDIN_PRE_ARB_CTRL 0x2714
-#define VPU_VDISP_PRE_ARB_CTRL 0x2715
-#define VPU_VPUARB2_PRE_ARB_CTRL 0x2716
-#define VPU_OSD3_MMC_CTRL 0x2717
-#define VPU_OSD4_MMC_CTRL 0x2718
-#define VPU_VD3_MMC_CTRL 0x2719
-#define VPU_VIU_VENC_MUX_CTRL 0x271a
-#define VIU1_SEL_VENC_MASK 0x3
-#define VIU1_SEL_VENC_ENCL 0
-#define VIU1_SEL_VENC_ENCI 1
-#define VIU1_SEL_VENC_ENCP 2
-#define VIU1_SEL_VENC_ENCT 3
-#define VIU2_SEL_VENC_MASK 0xc
-#define VIU2_SEL_VENC_ENCL 0
-#define VIU2_SEL_VENC_ENCI (1 << 2)
-#define VIU2_SEL_VENC_ENCP (2 << 2)
-#define VIU2_SEL_VENC_ENCT (3 << 2)
-#define VPU_HDMI_SETTING 0x271b
-#define ENCI_INFO_READ 0x271c
-#define ENCP_INFO_READ 0x271d
-#define ENCT_INFO_READ 0x271e
-#define ENCL_INFO_READ 0x271f
-#define VPU_SW_RESET 0x2720
-#define VPU_D2D3_MMC_CTRL 0x2721
-#define VPU_CONT_MMC_CTRL 0x2722
-#define VPU_CLK_GATE 0x2723
-#define VPU_RDMA_MMC_CTRL 0x2724
-#define VPU_MEM_PD_REG0 0x2725
-#define VPU_MEM_PD_REG1 0x2726
-#define VPU_HDMI_DATA_OVR 0x2727
-#define VPU_PROT1_MMC_CTRL 0x2728
-#define VPU_PROT2_MMC_CTRL 0x2729
-#define VPU_PROT3_MMC_CTRL 0x272a
-#define VPU_ARB4_V1_MMC_CTRL 0x272b
-#define VPU_ARB4_V2_MMC_CTRL 0x272c
-#define VPU_VPU_PWM_V0 0x2730
-#define VPU_VPU_PWM_V1 0x2731
-#define VPU_VPU_PWM_V2 0x2732
-#define VPU_VPU_PWM_V3 0x2733
-#define VPU_VPU_PWM_H0 0x2734
-#define VPU_VPU_PWM_H1 0x2735
-#define VPU_VPU_PWM_H2 0x2736
-#define VPU_VPU_PWM_H3 0x2737
-#define VPU_MISC_CTRL 0x2740
-#define VPU_ISP_GCLK_CTRL0 0x2741
-#define VPU_ISP_GCLK_CTRL1 0x2742
-#define VPU_VDIN_ASYNC_HOLD_CTRL 0x2743
-#define VPU_VDISP_ASYNC_HOLD_CTRL 0x2744
-#define VPU_VPUARB2_ASYNC_HOLD_CTRL 0x2745
-
-#define VPU_PROT1_CLK_GATE 0x2750
-#define VPU_PROT1_GEN_CNTL 0x2751
-#define VPU_PROT1_X_START_END 0x2752
-#define VPU_PROT1_Y_START_END 0x2753
-#define VPU_PROT1_Y_LEN_STEP 0x2754
-#define VPU_PROT1_RPT_LOOP 0x2755
-#define VPU_PROT1_RPT_PAT 0x2756
-#define VPU_PROT1_DDR 0x2757
-#define VPU_PROT1_RBUF_ROOM 0x2758
-#define VPU_PROT1_STAT_0 0x2759
-#define VPU_PROT1_STAT_1 0x275a
-#define VPU_PROT1_STAT_2 0x275b
-#define VPU_PROT1_REQ_ONOFF 0x275c
-#define VPU_PROT2_CLK_GATE 0x2760
-#define VPU_PROT2_GEN_CNTL 0x2761
-#define VPU_PROT2_X_START_END 0x2762
-#define VPU_PROT2_Y_START_END 0x2763
-#define VPU_PROT2_Y_LEN_STEP 0x2764
-#define VPU_PROT2_RPT_LOOP 0x2765
-#define VPU_PROT2_RPT_PAT 0x2766
-#define VPU_PROT2_DDR 0x2767
-#define VPU_PROT2_RBUF_ROOM 0x2768
-#define VPU_PROT2_STAT_0 0x2769
-#define VPU_PROT2_STAT_1 0x276a
-#define VPU_PROT2_STAT_2 0x276b
-#define VPU_PROT2_REQ_ONOFF 0x276c
-#define VPU_PROT3_CLK_GATE 0x2770
-#define VPU_PROT3_GEN_CNTL 0x2771
-#define VPU_PROT3_X_START_END 0x2772
-#define VPU_PROT3_Y_START_END 0x2773
-#define VPU_PROT3_Y_LEN_STEP 0x2774
-#define VPU_PROT3_RPT_LOOP 0x2775
-#define VPU_PROT3_RPT_PAT 0x2776
-#define VPU_PROT3_DDR 0x2777
-#define VPU_PROT3_RBUF_ROOM 0x2778
-#define VPU_PROT3_STAT_0 0x2779
-#define VPU_PROT3_STAT_1 0x277a
-#define VPU_PROT3_STAT_2 0x277b
-#define VPU_PROT3_REQ_ONOFF 0x277c
-
-/* osd super scale */
-#define OSDSR_HV_SIZEIN 0x3130
-#define OSDSR_CTRL_MODE 0x3131
-#define OSDSR_ABIC_HCOEF 0x3132
-#define OSDSR_YBIC_HCOEF 0x3133
-#define OSDSR_CBIC_HCOEF 0x3134
-#define OSDSR_ABIC_VCOEF 0x3135
-#define OSDSR_YBIC_VCOEF 0x3136
-#define OSDSR_CBIC_VCOEF 0x3137
-#define OSDSR_VAR_PARA 0x3138
-#define OSDSR_CONST_PARA 0x3139
-#define OSDSR_RKE_EXTWIN 0x313a
-#define OSDSR_UK_GRAD2DDIAG_TH_RATE 0x313b
-#define OSDSR_UK_GRAD2DDIAG_LIMIT 0x313c
-#define OSDSR_UK_GRAD2DADJA_TH_RATE 0x313d
-#define OSDSR_UK_GRAD2DADJA_LIMIT 0x313e
-#define OSDSR_UK_BST_GAIN 0x313f
-#define OSDSR_HVBLEND_TH 0x3140
-#define OSDSR_DEMO_WIND_TB 0x3141
-#define OSDSR_DEMO_WIND_LR 0x3142
-#define OSDSR_INT_BLANK_NUM 0x3143
-#define OSDSR_FRM_END_STAT 0x3144
-#define OSDSR_ABIC_HCOEF0 0x3145
-#define OSDSR_YBIC_HCOEF0 0x3146
-#define OSDSR_CBIC_HCOEF0 0x3147
-#define OSDSR_ABIC_VCOEF0 0x3148
-#define OSDSR_YBIC_VCOEF0 0x3149
-#define OSDSR_CBIC_VCOEF0 0x314a
-
-#endif /* __MESON_REGISTERS_H */
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <drm/drmP.h>
-#include "meson_drv.h"
-#include "meson_vclk.h"
-
-/*
- * VCLK is the "Pixel Clock" frequency generator from a dedicated PLL.
- * We handle the following encodings :
- * - CVBS 27MHz generator via the VCLK2 to the VENCI and VDAC blocks
- *
- * What is missing :
- * - HDMI Pixel Clocks generation
- */
-
-/* HHI Registers */
-#define HHI_VID_PLL_CLK_DIV 0x1a0 /* 0x68 offset in data sheet */
-#define VID_PLL_EN BIT(19)
-#define VID_PLL_BYPASS BIT(18)
-#define VID_PLL_PRESET BIT(15)
-#define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */
-#define VCLK2_DIV_MASK 0xff
-#define VCLK2_DIV_EN BIT(16)
-#define VCLK2_DIV_RESET BIT(17)
-#define CTS_VDAC_SEL_MASK (0xf << 28)
-#define CTS_VDAC_SEL_SHIFT 28
-#define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */
-#define VCLK2_EN BIT(19)
-#define VCLK2_SEL_MASK (0x7 << 16)
-#define VCLK2_SEL_SHIFT 16
-#define VCLK2_SOFT_RESET BIT(15)
-#define VCLK2_DIV1_EN BIT(0)
-#define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */
-#define CTS_ENCI_SEL_MASK (0xf << 28)
-#define CTS_ENCI_SEL_SHIFT 28
-#define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */
-#define CTS_ENCI_EN BIT(0)
-#define CTS_VDAC_EN BIT(4)
-
-#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
-#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
-
-#define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
-#define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */
-#define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in data sheet */
-#define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in data sheet */
-#define HHI_HDMI_PLL_CNTL5 0x330 /* 0xcc offset in data sheet */
-#define HHI_HDMI_PLL_CNTL6 0x334 /* 0xcd offset in data sheet */
-
-#define HDMI_PLL_RESET BIT(28)
-#define HDMI_PLL_LOCK BIT(31)
-
-/*
- * Setup VCLK2 for 27MHz, and enable clocks for ENCI and VDAC
- *
- * TOFIX: Refactor into table to also handle HDMI frequency and paths
- */
-static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
-{
- unsigned int val;
-
- /* Setup PLL to output 1.485GHz */
- if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d);
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00404e00);
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4800023d);
- } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
- meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b);
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300);
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0xa6212844);
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c4d000c);
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
-
- /* Reset PLL */
- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
- HDMI_PLL_RESET, HDMI_PLL_RESET);
- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
- HDMI_PLL_RESET, 0);
- }
-
- /* Poll for lock bit */
- regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
- (val & HDMI_PLL_LOCK), 10, 0);
-
- /* Disable VCLK2 */
- regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
-
- /* Disable vid_pll output clock */
- regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0);
- regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0);
- /* Enable vid_pll bypass to HDMI pll */
- regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
- VID_PLL_BYPASS, VID_PLL_BYPASS);
- /* Enable the vid_pll output clock */
- regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
- VID_PLL_EN, VID_PLL_EN);
-
- /* Setup the VCLK2 divider value to achieve 27MHz */
- regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
- VCLK2_DIV_MASK, (55 - 1));
-
- /* select vid_pll for vclk2 */
- regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
- VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT));
- /* enable vclk2 gate */
- regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
-
- /* select vclk_div1 for enci */
- regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
- CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT));
- /* select vclk_div1 for vdac */
- regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
- CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT));
-
- /* release vclk2_div_reset and enable vclk2_div */
- regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
- VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
-
- /* enable vclk2_div1 gate */
- regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
- VCLK2_DIV1_EN, VCLK2_DIV1_EN);
-
- /* reset vclk2 */
- regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
- VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
- regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
- VCLK2_SOFT_RESET, 0);
-
- /* enable enci_clk */
- regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
- CTS_ENCI_EN, CTS_ENCI_EN);
- /* enable vdac_clk */
- regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
- CTS_VDAC_EN, CTS_VDAC_EN);
-}
-
-void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
- unsigned int freq)
-{
- if (target == MESON_VCLK_TARGET_CVBS && freq == MESON_VCLK_CVBS)
- meson_venci_cvbs_clock_config(priv);
-}
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Video Clock */
-
-#ifndef __MESON_VCLK_H
-#define __MESON_VCLK_H
-
-enum {
- MESON_VCLK_TARGET_CVBS = 0,
-};
-
-/* 27MHz is the CVBS Pixel Clock */
-#define MESON_VCLK_CVBS 27000
-
-void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
- unsigned int freq);
-
-#endif /* __MESON_VCLK_H */
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <drm/drmP.h>
-#include "meson_drv.h"
-#include "meson_venc.h"
-#include "meson_vpp.h"
-#include "meson_vclk.h"
-#include "meson_registers.h"
-
-/*
- * VENC Handle the pixels encoding to the output formats.
- * We handle the following encodings :
- * - CVBS Encoding via the ENCI encoder and VDAC digital to analog converter
- *
- * What is missing :
- * - TMDS/HDMI Encoding via ENCI_DIV and ENCP
- * - Setup of more clock rates for HDMI modes
- * - LCD Panel encoding via ENCL
- * - TV Panel encoding via ENCT
- */
-
-/* HHI Registers */
-#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
-#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
-#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */
-
-struct meson_cvbs_enci_mode meson_cvbs_enci_pal = {
- .mode_tag = MESON_VENC_MODE_CVBS_PAL,
- .hso_begin = 3,
- .hso_end = 129,
- .vso_even = 3,
- .vso_odd = 260,
- .macv_max_amp = 7,
- .video_prog_mode = 0xff,
- .video_mode = 0x13,
- .sch_adjust = 0x28,
- .yc_delay = 0x343,
- .pixel_start = 251,
- .pixel_end = 1691,
- .top_field_line_start = 22,
- .top_field_line_end = 310,
- .bottom_field_line_start = 23,
- .bottom_field_line_end = 311,
- .video_saturation = 9,
- .video_contrast = 0,
- .video_brightness = 0,
- .video_hue = 0,
- .analog_sync_adj = 0x8080,
-};
-
-struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = {
- .mode_tag = MESON_VENC_MODE_CVBS_NTSC,
- .hso_begin = 5,
- .hso_end = 129,
- .vso_even = 3,
- .vso_odd = 260,
- .macv_max_amp = 0xb,
- .video_prog_mode = 0xf0,
- .video_mode = 0x8,
- .sch_adjust = 0x20,
- .yc_delay = 0x333,
- .pixel_start = 227,
- .pixel_end = 1667,
- .top_field_line_start = 18,
- .top_field_line_end = 258,
- .bottom_field_line_start = 19,
- .bottom_field_line_end = 259,
- .video_saturation = 18,
- .video_contrast = 3,
- .video_brightness = 0,
- .video_hue = 0,
- .analog_sync_adj = 0x9c00,
-};
-
-void meson_venci_cvbs_mode_set(struct meson_drm *priv,
- struct meson_cvbs_enci_mode *mode)
-{
- if (mode->mode_tag == priv->venc.current_mode)
- return;
-
- /* CVBS Filter settings */
- writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL));
- writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2));
-
- /* Digital Video Select : Interlace, clk27 clk, external */
- writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
-
- /* Reset Video Mode */
- writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE));
- writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
-
- /* Horizontal sync signal output */
- writel_relaxed(mode->hso_begin,
- priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN));
- writel_relaxed(mode->hso_end,
- priv->io_base + _REG(ENCI_SYNC_HSO_END));
-
- /* Vertical Sync lines */
- writel_relaxed(mode->vso_even,
- priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN));
- writel_relaxed(mode->vso_odd,
- priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
-
- /* Macrovision max amplitude change */
- writel_relaxed(0x8100 + mode->macv_max_amp,
- priv->io_base + _REG(ENCI_MACV_MAX_AMP));
-
- /* Video mode */
- writel_relaxed(mode->video_prog_mode,
- priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
- writel_relaxed(mode->video_mode,
- priv->io_base + _REG(ENCI_VIDEO_MODE));
-
- /* Advanced Video Mode :
- * Demux shifting 0x2
- * Blank line end at line17/22
- * High bandwidth Luma Filter
- * Low bandwidth Chroma Filter
- * Bypass luma low pass filter
- * No macrovision on CSYNC
- */
- writel_relaxed(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
-
- writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH));
-
- /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
- writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE));
-
- /* 0x3 Y, C, and Component Y delay */
- writel_relaxed(mode->yc_delay, priv->io_base + _REG(ENCI_YC_DELAY));
-
- /* Timings */
- writel_relaxed(mode->pixel_start,
- priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START));
- writel_relaxed(mode->pixel_end,
- priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END));
-
- writel_relaxed(mode->top_field_line_start,
- priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START));
- writel_relaxed(mode->top_field_line_end,
- priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END));
-
- writel_relaxed(mode->bottom_field_line_start,
- priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START));
- writel_relaxed(mode->bottom_field_line_end,
- priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END));
-
- /* Internal Venc, Internal VIU Sync, Internal Vencoder */
- writel_relaxed(0, priv->io_base + _REG(VENC_SYNC_ROUTE));
-
- /* UNreset Interlaced TV Encoder */
- writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
-
- /* Enable Vfifo2vd, Y_Cb_Y_Cr select */
- writel_relaxed(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
-
- /* Power UP Dacs */
- writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_SETTING));
-
- /* Video Upsampling */
- writel_relaxed(0x0061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL0));
- writel_relaxed(0x4061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL1));
- writel_relaxed(0x5061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL2));
-
- /* Select Interlace Y DACs */
- writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL0));
- writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL1));
- writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL2));
- writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL3));
- writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL4));
- writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL5));
-
- /* Select ENCI for VIU */
- meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
-
- /* Enable ENCI FIFO */
- writel_relaxed(0x2000, priv->io_base + _REG(VENC_VDAC_FIFO_CTRL));
-
- /* Select ENCI DACs 0, 1, 4, and 5 */
- writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_0));
- writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_1));
-
- /* Interlace video enable */
- writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN));
-
- /* Configure Video Saturation / Contrast / Brightness / Hue */
- writel_relaxed(mode->video_saturation,
- priv->io_base + _REG(ENCI_VIDEO_SAT));
- writel_relaxed(mode->video_contrast,
- priv->io_base + _REG(ENCI_VIDEO_CONT));
- writel_relaxed(mode->video_brightness,
- priv->io_base + _REG(ENCI_VIDEO_BRIGHT));
- writel_relaxed(mode->video_hue,
- priv->io_base + _REG(ENCI_VIDEO_HUE));
-
- /* Enable DAC0 Filter */
- writel_relaxed(0x1, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0));
- writel_relaxed(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1));
-
- /* 0 in Macrovision register 0 */
- writel_relaxed(0, priv->io_base + _REG(ENCI_MACV_N0));
-
- /* Analog Synchronization and color burst value adjust */
- writel_relaxed(mode->analog_sync_adj,
- priv->io_base + _REG(ENCI_SYNC_ADJ));
-
- /* Setup 27MHz vclk2 for ENCI and VDAC */
- meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, MESON_VCLK_CVBS);
-
- priv->venc.current_mode = mode->mode_tag;
-}
-
-/* Returns the current ENCI field polarity */
-unsigned int meson_venci_get_field(struct meson_drm *priv)
-{
- return readl_relaxed(priv->io_base + _REG(ENCI_INFO_READ)) & BIT(29);
-}
-
-void meson_venc_enable_vsync(struct meson_drm *priv)
-{
- writel_relaxed(2, priv->io_base + _REG(VENC_INTCTRL));
-}
-
-void meson_venc_disable_vsync(struct meson_drm *priv)
-{
- writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL));
-}
-
-void meson_venc_init(struct meson_drm *priv)
-{
- /* Disable CVBS VDAC */
- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0);
- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8);
-
- /* Power Down Dacs */
- writel_relaxed(0xff, priv->io_base + _REG(VENC_VDAC_SETTING));
-
- /* Disable HDMI PHY */
- regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
-
- /* Disable HDMI */
- writel_bits_relaxed(0x3, 0,
- priv->io_base + _REG(VPU_HDMI_SETTING));
-
- /* Disable all encoders */
- writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
- writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
- writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
-
- /* Disable VSync IRQ */
- meson_venc_disable_vsync(priv);
-
- priv->venc.current_mode = MESON_VENC_MODE_NONE;
-}
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Video Encoders
- * - ENCI : Interlace Video Encoder
- * - ENCI_DVI : Interlace Video Encoder for DVI/HDMI
- * - ENCP : Progressive Video Encoder
- */
-
-#ifndef __MESON_VENC_H
-#define __MESON_VENC_H
-
-enum {
- MESON_VENC_MODE_NONE = 0,
- MESON_VENC_MODE_CVBS_PAL,
- MESON_VENC_MODE_CVBS_NTSC,
-};
-
-struct meson_cvbs_enci_mode {
- unsigned int mode_tag;
- unsigned int hso_begin; /* HSO begin position */
- unsigned int hso_end; /* HSO end position */
- unsigned int vso_even; /* VSO even line */
- unsigned int vso_odd; /* VSO odd line */
- unsigned int macv_max_amp; /* Macrovision max amplitude */
- unsigned int video_prog_mode;
- unsigned int video_mode;
- unsigned int sch_adjust;
- unsigned int yc_delay;
- unsigned int pixel_start;
- unsigned int pixel_end;
- unsigned int top_field_line_start;
- unsigned int top_field_line_end;
- unsigned int bottom_field_line_start;
- unsigned int bottom_field_line_end;
- unsigned int video_saturation;
- unsigned int video_contrast;
- unsigned int video_brightness;
- unsigned int video_hue;
- unsigned int analog_sync_adj;
-};
-
-/* CVBS Timings and Parameters */
-extern struct meson_cvbs_enci_mode meson_cvbs_enci_pal;
-extern struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc;
-
-void meson_venci_cvbs_mode_set(struct meson_drm *priv,
- struct meson_cvbs_enci_mode *mode);
-unsigned int meson_venci_get_field(struct meson_drm *priv);
-
-void meson_venc_enable_vsync(struct meson_drm *priv);
-void meson_venc_disable_vsync(struct meson_drm *priv);
-
-void meson_venc_init(struct meson_drm *priv);
-
-#endif /* __MESON_VENC_H */
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Written by:
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of_graph.h>
-
-#include <drm/drmP.h>
-#include <drm/drm_edid.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_atomic_helper.h>
-
-#include "meson_venc_cvbs.h"
-#include "meson_venc.h"
-#include "meson_registers.h"
-
-/* HHI VDAC Registers */
-#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
-#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
-
-struct meson_venc_cvbs {
- struct drm_encoder encoder;
- struct drm_connector connector;
- struct meson_drm *priv;
-};
-#define encoder_to_meson_venc_cvbs(x) \
- container_of(x, struct meson_venc_cvbs, encoder)
-
-#define connector_to_meson_venc_cvbs(x) \
- container_of(x, struct meson_venc_cvbs, connector)
-
-/* Supported Modes */
-
-struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT] = {
- { /* PAL */
- .enci = &meson_cvbs_enci_pal,
- .mode = {
- DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
- 720, 732, 795, 864, 0, 576, 580, 586, 625, 0,
- DRM_MODE_FLAG_INTERLACE),
- .vrefresh = 50,
- .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
- },
- },
- { /* NTSC */
- .enci = &meson_cvbs_enci_ntsc,
- .mode = {
- DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
- 720, 739, 801, 858, 0, 480, 488, 494, 525, 0,
- DRM_MODE_FLAG_INTERLACE),
- .vrefresh = 60,
- .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
- },
- },
-};
-
-/* Connector */
-
-static void meson_cvbs_connector_destroy(struct drm_connector *connector)
-{
- drm_connector_cleanup(connector);
-}
-
-static enum drm_connector_status
-meson_cvbs_connector_detect(struct drm_connector *connector, bool force)
-{
- /* FIXME: Add load-detect or jack-detect if possible */
- return connector_status_connected;
-}
-
-static int meson_cvbs_connector_get_modes(struct drm_connector *connector)
-{
- struct drm_device *dev = connector->dev;
- struct drm_display_mode *mode;
- int i;
-
- for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
- struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
-
- mode = drm_mode_duplicate(dev, &meson_mode->mode);
- if (!mode) {
- DRM_ERROR("Failed to create a new display mode\n");
- return 0;
- }
-
- drm_mode_probed_add(connector, mode);
- }
-
- return i;
-}
-
-static int meson_cvbs_connector_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
-{
- /* Validate the modes added in get_modes */
- return MODE_OK;
-}
-
-static const struct drm_connector_funcs meson_cvbs_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
- .detect = meson_cvbs_connector_detect,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .destroy = meson_cvbs_connector_destroy,
- .reset = drm_atomic_helper_connector_reset,
- .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static const
-struct drm_connector_helper_funcs meson_cvbs_connector_helper_funcs = {
- .get_modes = meson_cvbs_connector_get_modes,
- .mode_valid = meson_cvbs_connector_mode_valid,
-};
-
-/* Encoder */
-
-static void meson_venc_cvbs_encoder_destroy(struct drm_encoder *encoder)
-{
- drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs meson_venc_cvbs_encoder_funcs = {
- .destroy = meson_venc_cvbs_encoder_destroy,
-};
-
-static int meson_venc_cvbs_encoder_atomic_check(struct drm_encoder *encoder,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state)
-{
- int i;
-
- for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
- struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
-
- if (drm_mode_equal(&crtc_state->mode, &meson_mode->mode))
- return 0;
- }
-
- return -EINVAL;
-}
-
-static void meson_venc_cvbs_encoder_disable(struct drm_encoder *encoder)
-{
- struct meson_venc_cvbs *meson_venc_cvbs =
- encoder_to_meson_venc_cvbs(encoder);
- struct meson_drm *priv = meson_venc_cvbs->priv;
-
- /* Disable CVBS VDAC */
- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0);
- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8);
-}
-
-static void meson_venc_cvbs_encoder_enable(struct drm_encoder *encoder)
-{
- struct meson_venc_cvbs *meson_venc_cvbs =
- encoder_to_meson_venc_cvbs(encoder);
- struct meson_drm *priv = meson_venc_cvbs->priv;
-
- /* VDAC0 source is not from ATV */
- writel_bits_relaxed(BIT(5), 0, priv->io_base + _REG(VENC_VDAC_DACSEL0));
-
- if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 1);
- else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
- meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0xf0001);
-
- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 0);
-}
-
-static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct meson_venc_cvbs *meson_venc_cvbs =
- encoder_to_meson_venc_cvbs(encoder);
- int i;
-
- for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
- struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
-
- if (drm_mode_equal(mode, &meson_mode->mode)) {
- meson_venci_cvbs_mode_set(meson_venc_cvbs->priv,
- meson_mode->enci);
- break;
- }
- }
-}
-
-static const struct drm_encoder_helper_funcs
- meson_venc_cvbs_encoder_helper_funcs = {
- .atomic_check = meson_venc_cvbs_encoder_atomic_check,
- .disable = meson_venc_cvbs_encoder_disable,
- .enable = meson_venc_cvbs_encoder_enable,
- .mode_set = meson_venc_cvbs_encoder_mode_set,
-};
-
-static bool meson_venc_cvbs_connector_is_available(struct meson_drm *priv)
-{
- struct device_node *ep, *remote;
-
- /* CVBS VDAC output is on the first port, first endpoint */
- ep = of_graph_get_endpoint_by_regs(priv->dev->of_node, 0, 0);
- if (!ep)
- return false;
-
-
- /* If the endpoint node exists, consider it enabled */
- remote = of_graph_get_remote_port(ep);
- if (remote) {
- of_node_put(ep);
- return true;
- }
-
- of_node_put(ep);
- of_node_put(remote);
-
- return false;
-}
-
-int meson_venc_cvbs_create(struct meson_drm *priv)
-{
- struct drm_device *drm = priv->drm;
- struct meson_venc_cvbs *meson_venc_cvbs;
- struct drm_connector *connector;
- struct drm_encoder *encoder;
- int ret;
-
- if (!meson_venc_cvbs_connector_is_available(priv)) {
- dev_info(drm->dev, "CVBS Output connector not available\n");
- return -ENODEV;
- }
-
- meson_venc_cvbs = devm_kzalloc(priv->dev, sizeof(*meson_venc_cvbs),
- GFP_KERNEL);
- if (!meson_venc_cvbs)
- return -ENOMEM;
-
- meson_venc_cvbs->priv = priv;
- encoder = &meson_venc_cvbs->encoder;
- connector = &meson_venc_cvbs->connector;
-
- /* Connector */
-
- drm_connector_helper_add(connector,
- &meson_cvbs_connector_helper_funcs);
-
- ret = drm_connector_init(drm, connector, &meson_cvbs_connector_funcs,
- DRM_MODE_CONNECTOR_Composite);
- if (ret) {
- dev_err(priv->dev, "Failed to init CVBS connector\n");
- return ret;
- }
-
- connector->interlace_allowed = 1;
-
- /* Encoder */
-
- drm_encoder_helper_add(encoder, &meson_venc_cvbs_encoder_helper_funcs);
-
- ret = drm_encoder_init(drm, encoder, &meson_venc_cvbs_encoder_funcs,
- DRM_MODE_ENCODER_TVDAC, "meson_venc_cvbs");
- if (ret) {
- dev_err(priv->dev, "Failed to init CVBS encoder\n");
- return ret;
- }
-
- encoder->possible_crtcs = BIT(0);
-
- drm_mode_connector_attach_encoder(connector, encoder);
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Written by:
- * Jasper St. Pierre <jstpierre@mecheye.net>
- */
-
-#ifndef __MESON_VENC_CVBS_H
-#define __MESON_VENC_CVBS_H
-
-#include "meson_drv.h"
-#include "meson_venc.h"
-
-struct meson_cvbs_mode {
- struct meson_cvbs_enci_mode *enci;
- struct drm_display_mode mode;
-};
-
-#define MESON_CVBS_MODES_COUNT 2
-
-/* Modes supported by the CVBS output */
-extern struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT];
-
-int meson_venc_cvbs_create(struct meson_drm *priv);
-
-#endif /* __MESON_VENC_CVBS_H */
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <drm/drmP.h>
-#include "meson_drv.h"
-#include "meson_viu.h"
-#include "meson_vpp.h"
-#include "meson_venc.h"
-#include "meson_canvas.h"
-#include "meson_registers.h"
-
-/*
- * VIU Handles the Pixel scanout and the basic Colorspace conversions
- * We handle the following features :
- * - OSD1 RGB565/RGB888/xRGB8888 scanout
- * - RGB conversion to x/cb/cr
- * - Progressive or Interlace buffer scanout
- * - OSD1 Commit on Vsync
- * - HDR OSD matrix for GXL/GXM
- *
- * What is missing :
- * - BGR888/xBGR8888/BGRx8888/BGRx8888 modes
- * - YUV4:2:2 Y0CbY1Cr scanout
- * - Conversion to YUV 4:4:4 from 4:2:2 input
- * - Colorkey Alpha matching
- * - Big endian scanout
- * - X/Y reverse scanout
- * - Global alpha setup
- * - OSD2 support, would need interlace switching on vsync
- * - OSD1 full scaling to support TV overscan
- */
-
-/* OSD csc defines */
-
-enum viu_matrix_sel_e {
- VIU_MATRIX_OSD_EOTF = 0,
- VIU_MATRIX_OSD,
-};
-
-enum viu_lut_sel_e {
- VIU_LUT_OSD_EOTF = 0,
- VIU_LUT_OSD_OETF,
-};
-
-#define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2))
-#define MATRIX_5X3_COEF_SIZE 24
-
-#define EOTF_COEFF_NORM(a) ((int)((((a) * 4096.0) + 1) / 2))
-#define EOTF_COEFF_SIZE 10
-#define EOTF_COEFF_RIGHTSHIFT 1
-
-static int RGB709_to_YUV709l_coeff[MATRIX_5X3_COEF_SIZE] = {
- 0, 0, 0, /* pre offset */
- COEFF_NORM(0.181873), COEFF_NORM(0.611831), COEFF_NORM(0.061765),
- COEFF_NORM(-0.100251), COEFF_NORM(-0.337249), COEFF_NORM(0.437500),
- COEFF_NORM(0.437500), COEFF_NORM(-0.397384), COEFF_NORM(-0.040116),
- 0, 0, 0, /* 10'/11'/12' */
- 0, 0, 0, /* 20'/21'/22' */
- 64, 512, 512, /* offset */
- 0, 0, 0 /* mode, right_shift, clip_en */
-};
-
-/* eotf matrix: bypass */
-static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = {
- EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0),
- EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0),
- EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0),
- EOTF_COEFF_RIGHTSHIFT /* right shift */
-};
-
-void meson_viu_set_osd_matrix(struct meson_drm *priv,
- enum viu_matrix_sel_e m_select,
- int *m, bool csc_on)
-{
- if (m_select == VIU_MATRIX_OSD) {
- /* osd matrix, VIU_MATRIX_0 */
- writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff),
- priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET0_1));
- writel(m[2] & 0xfff,
- priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET2));
- writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff),
- priv->io_base + _REG(VIU_OSD1_MATRIX_COEF00_01));
- writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff),
- priv->io_base + _REG(VIU_OSD1_MATRIX_COEF02_10));
- writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff),
- priv->io_base + _REG(VIU_OSD1_MATRIX_COEF11_12));
- writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff),
- priv->io_base + _REG(VIU_OSD1_MATRIX_COEF20_21));
-
- if (m[21]) {
- writel(((m[11] & 0x1fff) << 16) | (m[12] & 0x1fff),
- priv->io_base +
- _REG(VIU_OSD1_MATRIX_COEF22_30));
- writel(((m[13] & 0x1fff) << 16) | (m[14] & 0x1fff),
- priv->io_base +
- _REG(VIU_OSD1_MATRIX_COEF31_32));
- writel(((m[15] & 0x1fff) << 16) | (m[16] & 0x1fff),
- priv->io_base +
- _REG(VIU_OSD1_MATRIX_COEF40_41));
- writel(m[17] & 0x1fff, priv->io_base +
- _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
- } else
- writel((m[11] & 0x1fff) << 16, priv->io_base +
- _REG(VIU_OSD1_MATRIX_COEF22_30));
-
- writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff),
- priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET0_1));
- writel(m[20] & 0xfff,
- priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET2));
-
- writel_bits_relaxed(3 << 30, m[21] << 30,
- priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
- writel_bits_relaxed(7 << 16, m[22] << 16,
- priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
-
- /* 23 reserved for clipping control */
- writel_bits_relaxed(BIT(0), csc_on ? BIT(0) : 0,
- priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
- writel_bits_relaxed(BIT(1), 0,
- priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
- } else if (m_select == VIU_MATRIX_OSD_EOTF) {
- int i;
-
- /* osd eotf matrix, VIU_MATRIX_OSD_EOTF */
- for (i = 0; i < 5; i++)
- writel(((m[i * 2] & 0x1fff) << 16) |
- (m[i * 2 + 1] & 0x1fff), priv->io_base +
- _REG(VIU_OSD1_EOTF_CTL + i + 1));
-
- writel_bits_relaxed(BIT(30), csc_on ? BIT(30) : 0,
- priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
- writel_bits_relaxed(BIT(31), csc_on ? BIT(31) : 0,
- priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
- }
-}
-
-#define OSD_EOTF_LUT_SIZE 33
-#define OSD_OETF_LUT_SIZE 41
-
-void meson_viu_set_osd_lut(struct meson_drm *priv, enum viu_lut_sel_e lut_sel,
- unsigned int *r_map, unsigned int *g_map,
- unsigned int *b_map,
- bool csc_on)
-{
- unsigned int addr_port;
- unsigned int data_port;
- unsigned int ctrl_port;
- int i;
-
- if (lut_sel == VIU_LUT_OSD_EOTF) {
- addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT;
- data_port = VIU_OSD1_EOTF_LUT_DATA_PORT;
- ctrl_port = VIU_OSD1_EOTF_CTL;
- } else if (lut_sel == VIU_LUT_OSD_OETF) {
- addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT;
- data_port = VIU_OSD1_OETF_LUT_DATA_PORT;
- ctrl_port = VIU_OSD1_OETF_CTL;
- } else
- return;
-
- if (lut_sel == VIU_LUT_OSD_OETF) {
- writel(0, priv->io_base + _REG(addr_port));
-
- for (i = 0; i < 20; i++)
- writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
- priv->io_base + _REG(data_port));
-
- writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16),
- priv->io_base + _REG(data_port));
-
- for (i = 0; i < 20; i++)
- writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
- priv->io_base + _REG(data_port));
-
- for (i = 0; i < 20; i++)
- writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
- priv->io_base + _REG(data_port));
-
- writel(b_map[OSD_OETF_LUT_SIZE - 1],
- priv->io_base + _REG(data_port));
-
- if (csc_on)
- writel_bits_relaxed(0x7 << 29, 7 << 29,
- priv->io_base + _REG(ctrl_port));
- else
- writel_bits_relaxed(0x7 << 29, 0,
- priv->io_base + _REG(ctrl_port));
- } else if (lut_sel == VIU_LUT_OSD_EOTF) {
- writel(0, priv->io_base + _REG(addr_port));
-
- for (i = 0; i < 20; i++)
- writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
- priv->io_base + _REG(data_port));
-
- writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16),
- priv->io_base + _REG(data_port));
-
- for (i = 0; i < 20; i++)
- writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
- priv->io_base + _REG(data_port));
-
- for (i = 0; i < 20; i++)
- writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
- priv->io_base + _REG(data_port));
-
- writel(b_map[OSD_EOTF_LUT_SIZE - 1],
- priv->io_base + _REG(data_port));
-
- if (csc_on)
- writel_bits_relaxed(7 << 27, 7 << 27,
- priv->io_base + _REG(ctrl_port));
- else
- writel_bits_relaxed(7 << 27, 0,
- priv->io_base + _REG(ctrl_port));
-
- writel_bits_relaxed(BIT(31), BIT(31),
- priv->io_base + _REG(ctrl_port));
- }
-}
-
-/* eotf lut: linear */
-static unsigned int eotf_33_linear_mapping[OSD_EOTF_LUT_SIZE] = {
- 0x0000, 0x0200, 0x0400, 0x0600,
- 0x0800, 0x0a00, 0x0c00, 0x0e00,
- 0x1000, 0x1200, 0x1400, 0x1600,
- 0x1800, 0x1a00, 0x1c00, 0x1e00,
- 0x2000, 0x2200, 0x2400, 0x2600,
- 0x2800, 0x2a00, 0x2c00, 0x2e00,
- 0x3000, 0x3200, 0x3400, 0x3600,
- 0x3800, 0x3a00, 0x3c00, 0x3e00,
- 0x4000
-};
-
-/* osd oetf lut: linear */
-static unsigned int oetf_41_linear_mapping[OSD_OETF_LUT_SIZE] = {
- 0, 0, 0, 0,
- 0, 32, 64, 96,
- 128, 160, 196, 224,
- 256, 288, 320, 352,
- 384, 416, 448, 480,
- 512, 544, 576, 608,
- 640, 672, 704, 736,
- 768, 800, 832, 864,
- 896, 928, 960, 992,
- 1023, 1023, 1023, 1023,
- 1023
-};
-
-static void meson_viu_load_matrix(struct meson_drm *priv)
-{
- /* eotf lut bypass */
- meson_viu_set_osd_lut(priv, VIU_LUT_OSD_EOTF,
- eotf_33_linear_mapping, /* R */
- eotf_33_linear_mapping, /* G */
- eotf_33_linear_mapping, /* B */
- false);
-
- /* eotf matrix bypass */
- meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD_EOTF,
- eotf_bypass_coeff,
- false);
-
- /* oetf lut bypass */
- meson_viu_set_osd_lut(priv, VIU_LUT_OSD_OETF,
- oetf_41_linear_mapping, /* R */
- oetf_41_linear_mapping, /* G */
- oetf_41_linear_mapping, /* B */
- false);
-
- /* osd matrix RGB709 to YUV709 limit */
- meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD,
- RGB709_to_YUV709l_coeff,
- true);
-}
-
-void meson_viu_init(struct meson_drm *priv)
-{
- uint32_t reg;
-
- /* Disable OSDs */
- writel_bits_relaxed(BIT(0) | BIT(21), 0,
- priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
- writel_bits_relaxed(BIT(0) | BIT(21), 0,
- priv->io_base + _REG(VIU_OSD2_CTRL_STAT));
-
- /* On GXL/GXM, Use the 10bit HDR conversion matrix */
- if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
- meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
- meson_viu_load_matrix(priv);
-
- /* Initialize OSD1 fifo control register */
- reg = BIT(0) | /* Urgent DDR request priority */
- (4 << 5) | /* hold_fifo_lines */
- (3 << 10) | /* burst length 64 */
- (32 << 12) | /* fifo_depth_val: 32*8=256 */
- (2 << 22) | /* 4 words in 1 burst */
- (2 << 24);
- writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
- writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
-
- /* Set OSD alpha replace value */
- writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
- 0xff << OSD_REPLACE_SHIFT,
- priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
- writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
- 0xff << OSD_REPLACE_SHIFT,
- priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
-
- priv->viu.osd1_enabled = false;
- priv->viu.osd1_commit = false;
- priv->viu.osd1_interlace = false;
-}
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Video Input Unit */
-
-#ifndef __MESON_VIU_H
-#define __MESON_VIU_H
-
-/* OSDx_BLKx_CFG */
-#define OSD_CANVAS_SEL 16
-
-#define OSD_ENDIANNESS_LE BIT(15)
-#define OSD_ENDIANNESS_BE (0)
-
-#define OSD_BLK_MODE_422 (0x03 << 8)
-#define OSD_BLK_MODE_16 (0x04 << 8)
-#define OSD_BLK_MODE_32 (0x05 << 8)
-#define OSD_BLK_MODE_24 (0x07 << 8)
-
-#define OSD_OUTPUT_COLOR_RGB BIT(7)
-#define OSD_OUTPUT_COLOR_YUV (0)
-
-#define OSD_COLOR_MATRIX_32_RGBA (0x00 << 2)
-#define OSD_COLOR_MATRIX_32_ARGB (0x01 << 2)
-#define OSD_COLOR_MATRIX_32_ABGR (0x02 << 2)
-#define OSD_COLOR_MATRIX_32_BGRA (0x03 << 2)
-
-#define OSD_COLOR_MATRIX_24_RGB (0x00 << 2)
-
-#define OSD_COLOR_MATRIX_16_RGB655 (0x00 << 2)
-#define OSD_COLOR_MATRIX_16_RGB565 (0x04 << 2)
-
-#define OSD_INTERLACE_ENABLED BIT(1)
-#define OSD_INTERLACE_ODD BIT(0)
-#define OSD_INTERLACE_EVEN (0)
-
-/* OSDx_CTRL_STAT */
-#define OSD_ENABLE BIT(21)
-#define OSD_BLK0_ENABLE BIT(0)
-
-#define OSD_GLOBAL_ALPHA_SHIFT 12
-
-/* OSDx_CTRL_STAT2 */
-#define OSD_REPLACE_EN BIT(14)
-#define OSD_REPLACE_SHIFT 6
-
-void meson_viu_init(struct meson_drm *priv);
-
-#endif /* __MESON_VIU_H */
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- * Copyright (C) 2014 Endless Mobile
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <drm/drmP.h>
-#include "meson_drv.h"
-#include "meson_vpp.h"
-#include "meson_registers.h"
-
-/*
- * VPP Handles all the Post Processing after the Scanout from the VIU
- * We handle the following post processings :
- * - Postblend : Blends the OSD1 only
- * We exclude OSD2, VS1, VS1 and Preblend output
- * - Vertical OSD Scaler for OSD1 only, we disable vertical scaler and
- * use it only for interlace scanout
- * - Intermediate FIFO with default Amlogic values
- *
- * What is missing :
- * - Preblend for video overlay pre-scaling
- * - OSD2 support for cursor framebuffer
- * - Video pre-scaling before postblend
- * - Full Vertical/Horizontal OSD scaling to support TV overscan
- * - HDR conversion
- */
-
-void meson_vpp_setup_mux(struct meson_drm *priv, unsigned int mux)
-{
- writel(mux, priv->io_base + _REG(VPU_VIU_VENC_MUX_CTRL));
-}
-
-/*
- * When the output is interlaced, the OSD must switch between
- * each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0
- * at each vsync.
- * But the vertical scaler can provide such funtionnality if
- * is configured for 2:1 scaling with interlace options enabled.
- */
-void meson_vpp_setup_interlace_vscaler_osd1(struct meson_drm *priv,
- struct drm_rect *input)
-{
- writel_relaxed(BIT(3) /* Enable scaler */ |
- BIT(2), /* Select OSD1 */
- priv->io_base + _REG(VPP_OSD_SC_CTRL0));
-
- writel_relaxed(((drm_rect_width(input) - 1) << 16) |
- (drm_rect_height(input) - 1),
- priv->io_base + _REG(VPP_OSD_SCI_WH_M1));
- /* 2:1 scaling */
- writel_relaxed(((input->x1) << 16) | (input->x2),
- priv->io_base + _REG(VPP_OSD_SCO_H_START_END));
- writel_relaxed(((input->y1 >> 1) << 16) | (input->y2 >> 1),
- priv->io_base + _REG(VPP_OSD_SCO_V_START_END));
-
- /* 2:1 scaling values */
- writel_relaxed(BIT(16), priv->io_base + _REG(VPP_OSD_VSC_INI_PHASE));
- writel_relaxed(BIT(25), priv->io_base + _REG(VPP_OSD_VSC_PHASE_STEP));
-
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
-
- writel_relaxed((4 << 0) /* osd_vsc_bank_length */ |
- (4 << 3) /* osd_vsc_top_ini_rcv_num0 */ |
- (1 << 8) /* osd_vsc_top_rpt_p0_num0 */ |
- (6 << 11) /* osd_vsc_bot_ini_rcv_num0 */ |
- (2 << 16) /* osd_vsc_bot_rpt_p0_num0 */ |
- BIT(23) /* osd_prog_interlace */ |
- BIT(24), /* Enable vertical scaler */
- priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
-}
-
-void meson_vpp_disable_interlace_vscaler_osd1(struct meson_drm *priv)
-{
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0));
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
-}
-
-static unsigned int vpp_filter_coefs_4point_bspline[] = {
- 0x15561500, 0x14561600, 0x13561700, 0x12561800,
- 0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00,
- 0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200,
- 0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700,
- 0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01,
- 0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201,
- 0x05473301, 0x05463401, 0x04453601, 0x04433702,
- 0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02,
- 0x033d3d03
-};
-
-static void meson_vpp_write_scaling_filter_coefs(struct meson_drm *priv,
- const unsigned int *coefs,
- bool is_horizontal)
-{
- int i;
-
- writel_relaxed(is_horizontal ? BIT(8) : 0,
- priv->io_base + _REG(VPP_OSD_SCALE_COEF_IDX));
- for (i = 0; i < 33; i++)
- writel_relaxed(coefs[i],
- priv->io_base + _REG(VPP_OSD_SCALE_COEF));
-}
-
-void meson_vpp_init(struct meson_drm *priv)
-{
- /* set dummy data default YUV black */
- if (meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
- writel_relaxed(0x108080, priv->io_base + _REG(VPP_DUMMY_DATA1));
- else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu")) {
- writel_bits_relaxed(0xff << 16, 0xff << 16,
- priv->io_base + _REG(VIU_MISC_CTRL1));
- writel_relaxed(0x20000, priv->io_base + _REG(VPP_DOLBY_CTRL));
- writel_relaxed(0x1020080,
- priv->io_base + _REG(VPP_DUMMY_DATA1));
- }
-
- /* Initialize vpu fifo control registers */
- writel_relaxed(readl_relaxed(priv->io_base + _REG(VPP_OFIFO_SIZE)) |
- 0x77f, priv->io_base + _REG(VPP_OFIFO_SIZE));
- writel_relaxed(0x08080808, priv->io_base + _REG(VPP_HOLD_LINES));
-
- /* Turn off preblend */
- writel_bits_relaxed(VPP_PREBLEND_ENABLE, 0,
- priv->io_base + _REG(VPP_MISC));
-
- /* Turn off POSTBLEND */
- writel_bits_relaxed(VPP_POSTBLEND_ENABLE, 0,
- priv->io_base + _REG(VPP_MISC));
-
- /* Force all planes off */
- writel_bits_relaxed(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND |
- VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND, 0,
- priv->io_base + _REG(VPP_MISC));
-
- /* Disable Scalers */
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0));
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
-
- /* Write in the proper filter coefficients. */
- meson_vpp_write_scaling_filter_coefs(priv,
- vpp_filter_coefs_4point_bspline, false);
- meson_vpp_write_scaling_filter_coefs(priv,
- vpp_filter_coefs_4point_bspline, true);
-}
+++ /dev/null
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Video Post Process */
-
-#ifndef __MESON_VPP_H
-#define __MESON_VPP_H
-
-/* Mux VIU/VPP to ENCI */
-#define MESON_VIU_VPP_MUX_ENCI 0x5
-
-void meson_vpp_setup_mux(struct meson_drm *priv, unsigned int mux);
-
-void meson_vpp_setup_interlace_vscaler_osd1(struct meson_drm *priv,
- struct drm_rect *input);
-void meson_vpp_disable_interlace_vscaler_osd1(struct meson_drm *priv);
-
-void meson_vpp_init(struct meson_drm *priv);
-
-#endif /* __MESON_VPP_H */
int val;
phandle phandle;
struct device_node *init_data;
+ struct device_node *drm_node;
#endif
/* HDMITX pinctrl config for hdp and ddc*/
pr_info(SYS "not find pwr_ctl\n");
}
/* Get drm feature information */
- ret = of_property_read_u32(pdev->dev.of_node, "drm_feature",
- &(hdmitx_device.drm_feature));
- if (ret)
- pr_info(SYS "not find drm_feature\n");
- else
- pr_info(SYS "hdmitx_device.drm_feature : %d\n",
- hdmitx_device.drm_feature);
+ drm_node = of_find_node_by_path("/drm-amhdmitx");
+ if (drm_node) {
+ ret = of_property_read_u32(drm_node, "drm_feature",
+ &(hdmitx_device.drm_feature));
+ if (ret)
+ pr_info(SYS "not find drm_feature\n");
+ else
+ pr_info(SYS "hdmitx_device.drm_feature : %d\n",
+ hdmitx_device.drm_feature);
+ } else {
+ pr_info(SYS "not find drm_amhdmitx\n");
+ }
}
#else
{
.compatible = "amlogic, amhdmitx",
},
- {
- .compatible = "amlogic, drm_amhdmitx",
- },
{},
};
#else
{
return lcd_driver;
}
+EXPORT_SYMBOL(aml_lcd_get_driver);
/* ********************************************************* */
static void lcd_power_ctrl(int status)