From 7d10644f530a5015c6684527094ef15f38b11153 Mon Sep 17 00:00:00 2001 From: pengcheng chen Date: Thu, 14 Dec 2017 19:21:23 +0800 Subject: [PATCH] osd: add osd support for g12a PD#156734: osd: add osd support for g12a Change-Id: I7192f0377da899846219af8d934a50f57fecbe29 Signed-off-by: pengcheng chen --- arch/arm64/boot/dts/amlogic/axg_pxp.dts | 2 +- arch/arm64/boot/dts/amlogic/axg_s400.dts | 2 +- arch/arm64/boot/dts/amlogic/axg_s400_v03.dts | 2 +- arch/arm64/boot/dts/amlogic/axg_s400emmc.dts | 2 +- arch/arm64/boot/dts/amlogic/axg_s400emmc_v03.dts | 2 +- arch/arm64/boot/dts/amlogic/g12a_pxp.dts | 28 +- arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts | 2 +- .../boot/dts/amlogic/gxl_p212_1g_buildroot.dts | 2 +- arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts | 2 +- .../boot/dts/amlogic/gxl_p212_2g_buildroot.dts | 2 +- arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts | 2 +- .../boot/dts/amlogic/gxl_p230_2g_buildroot.dts | 2 +- arch/arm64/boot/dts/amlogic/gxl_p231_1g.dts | 2 +- arch/arm64/boot/dts/amlogic/gxl_p231_2g.dts | 2 +- .../boot/dts/amlogic/gxl_p231_2g_buildroot.dts | 2 +- arch/arm64/boot/dts/amlogic/gxl_p241_1g.dts | 2 +- .../boot/dts/amlogic/gxl_p241_1g_buildroot.dts | 2 +- arch/arm64/boot/dts/amlogic/gxl_p241_v2-1g.dts | 2 +- .../boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts | 2 +- arch/arm64/boot/dts/amlogic/gxl_p400_2g.dts | 2 +- arch/arm64/boot/dts/amlogic/gxl_p401_2g.dts | 2 +- arch/arm64/boot/dts/amlogic/gxl_skt.dts | 2 +- arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts | 3 +- arch/arm64/boot/dts/amlogic/gxm_skt.dts | 2 +- arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts | 2 +- arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts | 2 +- drivers/amlogic/drm/am_meson_crtc.c | 17 +- drivers/amlogic/drm/am_meson_plane.c | 6 +- drivers/amlogic/drm/meson_crtc.h | 1 + drivers/amlogic/drm/meson_drv.c | 185 +- drivers/amlogic/media/osd/Makefile | 2 +- drivers/amlogic/media/osd/osd.h | 203 +- drivers/amlogic/media/osd/osd_backup.c | 64 +- drivers/amlogic/media/osd/osd_backup.h | 7 +- drivers/amlogic/media/osd/osd_debug.c | 218 +- drivers/amlogic/media/osd/osd_drm.c | 182 +- drivers/amlogic/media/osd/osd_drm.h | 4 +- drivers/amlogic/media/osd/osd_fb.c | 617 ++- drivers/amlogic/media/osd/osd_fb.h | 7 +- drivers/amlogic/media/osd/osd_hw.c | 4780 ++++++++++++++------ drivers/amlogic/media/osd/osd_hw.h | 33 +- drivers/amlogic/media/osd/osd_hw_def.h | 102 +- drivers/amlogic/media/osd/osd_io.c | 23 +- drivers/amlogic/media/osd/osd_io.h | 5 +- drivers/amlogic/media/osd/osd_logo.c | 8 +- drivers/amlogic/media/osd/osd_progressbar.c | 3 +- drivers/amlogic/media/osd/osd_rdma.c | 35 +- drivers/amlogic/media/osd/osd_rdma.h | 7 +- drivers/amlogic/media/osd/osd_reg.h | 170 + 49 files changed, 4850 insertions(+), 1908 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/axg_pxp.dts b/arch/arm64/boot/dts/amlogic/axg_pxp.dts index fee68b5..269ff3c 100644 --- a/arch/arm64/boot/dts/amlogic/axg_pxp.dts +++ b/arch/arm64/boot/dts/amlogic/axg_pxp.dts @@ -217,7 +217,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-axg"; memory-region = <&fb_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/axg_s400.dts b/arch/arm64/boot/dts/amlogic/axg_s400.dts index 17561c3..910fded 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400.dts @@ -785,7 +785,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-axg"; memory-region = <&fb_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts b/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts index 894e512..1a1e52c 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts @@ -787,7 +787,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-axg"; memory-region = <&fb_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/axg_s400emmc.dts b/arch/arm64/boot/dts/amlogic/axg_s400emmc.dts index 7342e6d..2f488cd 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400emmc.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400emmc.dts @@ -787,7 +787,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-axg"; memory-region = <&fb_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/axg_s400emmc_v03.dts b/arch/arm64/boot/dts/amlogic/axg_s400emmc_v03.dts index 7171d16..f60fa1a 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400emmc_v03.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400emmc_v03.dts @@ -788,7 +788,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-axg"; memory-region = <&fb_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/g12a_pxp.dts b/arch/arm64/boot/dts/amlogic/g12a_pxp.dts index da3a4b6..efcf30e 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_pxp.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_pxp.dts @@ -54,14 +54,19 @@ reg = <0x0 0x05300000 0x0 0x2000000>; no-map; }; - + logo_reserved:linux,meson-fb { + compatible = "shared-dma-pool"; + reusable; + size = <0x0 0x800000>; + alignment = <0x0 0x400000>; + alloc-ranges = <0x0 0x3f800000 0x0 0x800000>; + }; ion_cma_reserved:linux,ion-dev { compatible = "shared-dma-pool"; reusable; size = <0x0 0x8000000>; alignment = <0x0 0x400000>; }; - }; vout { @@ -149,6 +154,25 @@ "clk_ge2d_gate"; reg = <0x0 0xff940000 0x0 0x10000>; }; + meson-fb { + compatible = "amlogic, meson-g12a"; + memory-region = <&logo_reserved>; + dev_name = "meson-fb"; + status = "okay"; + interrupts = <0 3 1 + 0 89 1>; + interrupt-names = "viu-vsync", "rdma"; + mem_size = <0x00800000 0x1980000 0x100000 0x100000>; + /* uboot logo,fb0/fb1 memory size,if afbcd fb0=0x01851000*/ + display_mode_default = "1080p60hz"; + scale_mode = <1>; + /** 0:VPU free scale 1:OSD free scale 2:OSD super scale */ + display_size_default = <1920 1080 1920 2160 32>; + /*1920*1080*4*3 = 0x17BB000*/ + pxp_mode = <1>; /** 0:normal mode 1:pxp mode */ + mem_alloc = <1>; + logo_addr = "0x3f800000"; + }; }; /* end of / */ &aobus{ diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts index e761e5d..421df7b 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts @@ -737,7 +737,7 @@ interrupt-names = "irq_keyup", "irq_keydown"; }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&logo_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts index 52e7d4a..b91fb78 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts @@ -713,7 +713,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&fb_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts index 9e99807..349ad46 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts @@ -747,7 +747,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&logo_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts index c5075aa..2b8a7e2c 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts @@ -715,7 +715,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; dev_name = "meson-fb"; status = "okay"; interrupts = <0 3 1 diff --git a/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts index 9f63a7e..09cdec2 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts @@ -736,7 +736,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&logo_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p230_2g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p230_2g_buildroot.dts index dd82f40..9113159 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p230_2g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p230_2g_buildroot.dts @@ -722,7 +722,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&logo_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p231_1g.dts b/arch/arm64/boot/dts/amlogic/gxl_p231_1g.dts index 605ac8d..c2dfffc 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p231_1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p231_1g.dts @@ -663,7 +663,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&logo_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p231_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p231_2g.dts index 26794dc..0812442 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p231_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p231_2g.dts @@ -663,7 +663,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&logo_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p231_2g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p231_2g_buildroot.dts index b114130..1ffd9c5 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p231_2g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p231_2g_buildroot.dts @@ -655,7 +655,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&fb_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p241_1g.dts b/arch/arm64/boot/dts/amlogic/gxl_p241_1g.dts index 3b9225e..68103f1 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p241_1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p241_1g.dts @@ -809,7 +809,7 @@ interrupt-names = "irq_keyup", "irq_keydown"; }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&logo_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p241_1g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p241_1g_buildroot.dts index a9a5b4c..b64bcae 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p241_1g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p241_1g_buildroot.dts @@ -803,7 +803,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; dev_name = "meson-fb"; status = "okay"; interrupts = <0 3 1 diff --git a/arch/arm64/boot/dts/amlogic/gxl_p241_v2-1g.dts b/arch/arm64/boot/dts/amlogic/gxl_p241_v2-1g.dts index 793cd29..2da9393 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p241_v2-1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p241_v2-1g.dts @@ -786,7 +786,7 @@ interrupt-names = "irq_keyup", "irq_keydown"; }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&logo_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts index 9730cbf..81d4ee0 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts @@ -772,7 +772,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; dev_name = "meson-fb"; status = "okay"; interrupts = <0 3 1 diff --git a/arch/arm64/boot/dts/amlogic/gxl_p400_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p400_2g.dts index b796b89..49774de 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p400_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p400_2g.dts @@ -463,7 +463,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&fb_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p401_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p401_2g.dts index de253d3..93664fc 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p401_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p401_2g.dts @@ -551,7 +551,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&fb_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_skt.dts b/arch/arm64/boot/dts/amlogic/gxl_skt.dts index 428fc73..e3e6dbe 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_skt.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_skt.dts @@ -713,7 +713,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxl"; memory-region = <&logo_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts b/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts index 53e54b7..69fc386 100644 --- a/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts @@ -759,7 +759,8 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxm"; + memory-region = <&logo_reserved>; dev_name = "meson-fb"; status = "okay"; interrupts = <0 3 1 diff --git a/arch/arm64/boot/dts/amlogic/gxm_skt.dts b/arch/arm64/boot/dts/amlogic/gxm_skt.dts index d50a289..d8f970c 100644 --- a/arch/arm64/boot/dts/amlogic/gxm_skt.dts +++ b/arch/arm64/boot/dts/amlogic/gxm_skt.dts @@ -640,7 +640,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-gxm"; memory-region = <&logo_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts index 3fb341d..249aa0b 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts @@ -231,7 +231,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-txlx"; memory-region = <&fb_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts index d364814..de2928f 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts @@ -232,7 +232,7 @@ }; meson-fb { - compatible = "amlogic, meson-fb"; + compatible = "amlogic, meson-txlx"; memory-region = <&fb_reserved>; dev_name = "meson-fb"; status = "okay"; diff --git a/drivers/amlogic/drm/am_meson_crtc.c b/drivers/amlogic/drm/am_meson_crtc.c index 66654e8..ac89ea7 100644 --- a/drivers/amlogic/drm/am_meson_crtc.c +++ b/drivers/amlogic/drm/am_meson_crtc.c @@ -25,6 +25,7 @@ #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) @@ -231,7 +232,7 @@ int meson_crtc_create(struct meson_drm *priv) } drm_crtc_helper_add(crtc, &am_crtc_helper_funcs); - osd_drm_init(); + osd_drm_init(&osd_meson_dev); priv->crtc = crtc; return 0; @@ -245,3 +246,17 @@ void meson_crtc_irq(struct meson_drm *priv) 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; +} diff --git a/drivers/amlogic/drm/am_meson_plane.c b/drivers/amlogic/drm/am_meson_plane.c index c957613..a7d9719 100644 --- a/drivers/amlogic/drm/am_meson_plane.c +++ b/drivers/amlogic/drm/am_meson_plane.c @@ -90,7 +90,11 @@ void am_osd_do_display( switch (fb->pixel_format) { case DRM_FORMAT_XRGB8888: - format = COLOR_INDEX_32_XRGB; + /* + *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; diff --git a/drivers/amlogic/drm/meson_crtc.h b/drivers/amlogic/drm/meson_crtc.h index b62b9e5..dff75d9 100644 --- a/drivers/amlogic/drm/meson_crtc.h +++ b/drivers/amlogic/drm/meson_crtc.h @@ -29,4 +29,5 @@ 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 */ diff --git a/drivers/amlogic/drm/meson_drv.c b/drivers/amlogic/drm/meson_drv.c index 15c5e31..7bf7354 100644 --- a/drivers/amlogic/drm/meson_drv.c +++ b/drivers/amlogic/drm/meson_drv.c @@ -75,6 +75,165 @@ * - 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, +}; + +static struct osd_device_data_s osd_gxtvbb = { + .cpu_id = __MESON_CPU_MAJOR_ID_GXTVBB, + .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 = 0x0, +}; + +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, +}; + +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 */ +}; + +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, +}; + +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, +}; + +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, +}; + +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, +}; + +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 @@ -328,6 +487,21 @@ static int meson_drv_probe(struct platform_device *pdev) 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)) { @@ -478,13 +652,8 @@ static int meson_drv_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id dt_match[] = { - { .compatible = "amlogic,meson-gxbb-vpu" }, - { .compatible = "amlogic,meson-gxl-vpu" }, - { .compatible = "amlogic,meson-gxm-vpu" }, - {} -}; -MODULE_DEVICE_TABLE(of, dt_match); + +MODULE_DEVICE_TABLE(of, meson_drm_dt_match); static struct platform_driver meson_drm_platform_driver = { .probe = meson_drv_probe, @@ -492,7 +661,7 @@ static struct platform_driver meson_drm_platform_driver = { .driver = { .owner = THIS_MODULE, .name = DRIVER_NAME, - .of_match_table = dt_match, + .of_match_table = meson_drm_dt_match, }, }; diff --git a/drivers/amlogic/media/osd/Makefile b/drivers/amlogic/media/osd/Makefile index 5800967..2ead743 100644 --- a/drivers/amlogic/media/osd/Makefile +++ b/drivers/amlogic/media/osd/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_AMLOGIC_MEDIA_FB) += fb.o fb-objs = osd_hw.o osd_fb.o osd_debug.o osd_backup.o osd_logo.o osd_io.o fb-objs += osd_antiflicker.o osd_clone.o fb-objs += osd_drm.o -obj-$(CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA) += osd_rdma.o +fb-objs += osd_rdma.o obj-$(CONFIG_INSTABOOT) += osd_progressbar.o diff --git a/drivers/amlogic/media/osd/osd.h b/drivers/amlogic/media/osd/osd.h index 64d4765..240e9fd 100644 --- a/drivers/amlogic/media/osd/osd.h +++ b/drivers/amlogic/media/osd/osd.h @@ -94,16 +94,21 @@ enum color_index_e { #define FBIOPUT_OSD_ROTATE_ANGLE 0x4517 #define FBIOPUT_OSD_SYNC_ADD 0x4518 #define FBIOPUT_OSD_SYNC_RENDER_ADD 0x4519 +#define FBIOPUT_OSD_HWC_ENABLE 0x451a +#define FBIOPUT_OSD_DO_HWC 0x451b #define FB_IOC_MAGIC 'O' #define FBIOPUT_OSD_CURSOR \ _IOWR(FB_IOC_MAGIC, 0x0, struct fb_cursor_user) + + /* OSD color definition */ #define KEYCOLOR_FLAG_TARGET 1 #define KEYCOLOR_FLAG_ONHOLD 2 #define KEYCOLOR_FLAG_CURRENT 4 -#define HW_OSD_COUNT 2 +#define HW_OSD_COUNT 3 +#define OSD_BLEND_LAYERS 4 /* OSD block definition */ #define HW_OSD_BLOCK_COUNT 4 #define HW_OSD_BLOCK_REG_COUNT (HW_OSD_BLOCK_COUNT*2) @@ -131,11 +136,17 @@ enum color_index_e { #define INT_VIU2_VSYNC 45 #define INT_RDMA 121 -#define OSD_MAX_BUF_NUM 3 /* fence relative */ +#define OSD_MAX_BUF_NUM 1 /* fence relative */ +#define MALI_AFBC_16X16_PIXEL 0 +#define MALI_AFBC_32X8_PIXEL 1 + +#define MALI_AFBC_SPLIT_OFF 0 +#define MALI_AFBC_SPLIT_ON 1 enum osd_index_e { OSD1 = 0, - OSD2 + OSD2, + OSD3 }; enum osd_enable_e { @@ -203,6 +214,7 @@ struct para_osd_info_s { enum osd_dev_e { DEV_OSD0 = 0, DEV_OSD1, + DEV_OSD2, DEV_ALL, DEV_MAX }; @@ -232,6 +244,72 @@ enum hw_reg_index_e { HW_REG_INDEX_MAX }; +enum cpuid_type_e { + __MESON_CPU_MAJOR_ID_M8B = 0x1B, + __MESON_CPU_MAJOR_ID_GXBB = 0x1F, + __MESON_CPU_MAJOR_ID_GXTVBB, + __MESON_CPU_MAJOR_ID_GXL, + __MESON_CPU_MAJOR_ID_GXM, + __MESON_CPU_MAJOR_ID_TXL, + __MESON_CPU_MAJOR_ID_TXLX, + __MESON_CPU_MAJOR_ID_AXG, + __MESON_CPU_MAJOR_ID_GXLX, + __MESON_CPU_MAJOR_ID_TXHD, + __MESON_CPU_MAJOR_ID_G12A, + __MESON_CPU_MAJOR_ID_UNKNOWN, +}; + +enum osd_afbc_e { + NO_AFBC = 0, + MESON_AFBC, + MALI_AFBC +}; + +enum osd_ver_e { + OSD_SIMPLE = 0, + OSD_NORMAL, + OSD_HIGH_ONE, + OSD_HIGH_OTHER +}; + +enum osd_blend_din_index_e { + BLEND_DIN1 = 0, + BLEND_DIN2, + BLEND_DIN3, + BLEND_DIN4 +}; + +enum osd_zorder_e { + LAYER_1 = 1, + LAYER_2, + LAYER_3, + LAYER_UNSUPPORT +}; + +/* + * OSD_BLEND_ABC: (OSD1 & (OSD2+SC & OSD3+SC)) +SC + * OSD_BLEND_AB_C: (OSD1 & OSD2 + SC) + SC, OSD3+SC + * OSD_BLEND_A_BC: OSD1+SC, (OSD2 +SC & OSD3 +SC) + */ +enum osd_blend_mode_e { + OSD_BLEND_NONE, + OSD_BLEND_ABC, + OSD_BLEND_AB_C, + OSD_BLEND_A_BC, +}; + +enum afbc_pix_format_e { + R8 = 0, + YUV422_8B, + RGB565, + RGBA5551, + RGBA4444, + RGBA8888, + RGB888 = 7, + YUV422_10B, + RGBA1010102, +}; + struct pandata_s { s32 x_start; s32 x_end; @@ -239,6 +317,13 @@ struct pandata_s { s32 y_end; }; +struct dispdata_s { + s32 x; + s32 y; + s32 w; + s32 h; +}; + struct fb_geometry_s { u32 width; /* in byte unit */ u32 height; @@ -290,6 +375,12 @@ struct osd_fence_map_s { u32 dst_h; int byte_stride; int pxiel_stride; + u32 background_w; + u32 background_h; + u32 zorder; + u32 premult_en; + u32 afbc_en; + u32 afbc_inter_format; u32 reserve; struct fence *in_fence; }; @@ -301,9 +392,88 @@ struct afbcd_data_s { u32 frame_width; u32 frame_height; u32 conv_lbuf_len; + u32 out_addr_id; + u32 format; + u32 inter_format; + u32 afbc_start; +}; + +struct osd_device_data_s { + enum cpuid_type_e cpu_id; + enum osd_ver_e osd_ver; /* axg: simple, others: normal; g12: high */ + enum osd_afbc_e afbc_type;/* 0:no afbc; 1: meson-afbc 2:mali-afbc */ + u8 osd_count; + u8 has_deband; + u8 has_lut; + u8 has_rdma; + u8 has_dolby_vision; + u8 osd_fifo_len; + u32 vpp_fifo_len; + u32 dummy_data; }; -typedef void (*update_func_t)(void); +struct hw_osd_reg_s { + u32 osd_ctrl_stat; /* VIU_OSD1_CTRL_STAT */ + u32 osd_ctrl_stat2;/* VIU_OSD1_CTRL_STAT2 */ + u32 osd_color_addr;/* VIU_OSD1_COLOR_ADDR */ + u32 osd_color;/* VIU_OSD1_COLOR */ + u32 osd_tcolor_ag0; /* VIU_OSD1_TCOLOR_AG0 */ + u32 osd_tcolor_ag1; /* VIU_OSD1_TCOLOR_AG1 */ + u32 osd_tcolor_ag2; /* VIU_OSD1_TCOLOR_AG2 */ + u32 osd_tcolor_ag3; /* VIU_OSD1_TCOLOR_AG3 */ + u32 osd_blk0_cfg_w0;/* VIU_OSD1_BLK0_CFG_W0 */ + u32 osd_blk0_cfg_w1;/* VIU_OSD1_BLK0_CFG_W1 */ + u32 osd_blk0_cfg_w2;/* VIU_OSD1_BLK0_CFG_W2 */ + u32 osd_blk0_cfg_w3;/* VIU_OSD1_BLK0_CFG_W3 */ + u32 osd_blk0_cfg_w4;/* VIU_OSD1_BLK0_CFG_W4 */ + u32 osd_blk1_cfg_w4;/* VIU_OSD1_BLK1_CFG_W4 */ + u32 osd_blk2_cfg_w4;/* VIU_OSD1_BLK2_CFG_W4 */ + u32 osd_fifo_ctrl_stat;/* VIU_OSD1_FIFO_CTRL_STAT */ + u32 osd_test_rddata;/* VIU_OSD1_TEST_RDDATA */ + u32 osd_prot_ctrl;/* VIU_OSD1_PROT_CTRL */ + u32 osd_mali_unpack_ctrl;/* VIU_OSD1_MALI_UNPACK_CTRL */ + u32 osd_dimm_ctrl;/* VIU_OSD1_DIMM_CTRL */ + //u32 osd_blend_din_scope_h; /* VIU_OSD_BLEND_DIN0_SCOPE_H */ + //u32 osd_blend_din_scope_v; /* VIU_OSD_BLEND_DIN0_SCOPE_V */ + + u32 osd_scale_coef_idx;/* VPP_OSD_SCALE_COEF_IDX */ + u32 osd_scale_coef;/* VPP_OSD_SCALE_COEF */ + u32 osd_vsc_phase_step;/* VPP_OSD_VSC_PHASE_STEP */ + u32 osd_vsc_init_phase;/* VPP_OSD_VSC_INI_PHASE */ + u32 osd_vsc_ctrl0;/* VPP_OSD_VSC_CTRL0 */ + u32 osd_hsc_phase_step;/* VPP_OSD_HSC_PHASE_STEP */ + u32 osd_hsc_init_phase;/* VPP_OSD_HSC_INI_PHASE */ + u32 osd_hsc_ctrl0;/* VPP_OSD_HSC_CTRL0 */ + u32 osd_sc_dummy_data;/* VPP_OSD_SC_DUMMY_DATA */ + u32 osd_sc_ctrl0;/* VPP_OSD_SC_CTRL0 */ + u32 osd_sci_wh_m1;/* VPP_OSD_SCI_WH_M1 */ + u32 osd_sco_h_start_end;/* VPP_OSD_SCO_H_START_END */ + u32 osd_sco_v_start_end;/* VPP_OSD_SCO_V_START_END */ + u32 afbc_header_buf_addr_low_s;/* VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0 */ + u32 afbc_header_buf_addr_high_s;/* VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0 */ + u32 afbc_format_specifier_s;/* VPU_MAFBC_FORMAT_SPECIFIER_S0 */ + u32 afbc_buffer_width_s;/* VPU_MAFBC_BUFFER_WIDTH_S0 */ + u32 afbc_buffer_hight_s;/* VPU_MAFBC_BUFFER_HEIGHT_S0 */ + u32 afbc_boundings_box_x_start_s;/* VPU_MAFBC_BOUNDING_BOX_X_START_S0 */ + u32 afbc_boundings_box_x_end_s;/* VPU_MAFBC_BOUNDING_BOX_X_END_S0 */ + u32 afbc_boundings_box_y_start_s;/* VPU_MAFBC_BOUNDING_BOX_Y_START_S0 */ + u32 afbc_boundings_box_y_end_s;/* VPU_MAFBC_BOUNDING_BOX_Y_END_S0 */ + u32 afbc_output_buf_addr_low_s;/* VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0 */ + u32 afbc_output_buf_addr_high_s;/* VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0 */ + u32 afbc_output_buf_stride_s;/* VPU_MAFBC_OUTPUT_BUF_STRIDE_S0 */ + u32 afbc_prefetch_cfg_s;/* VPU_MAFBC_PREFETCH_CFG_S0 */ +}; + +struct hw_osd_blending_s { + u8 osd_to_bdin_table[OSD_BLEND_LAYERS]; + u8 reorder[HW_OSD_COUNT]; + u32 input_src_w[HW_OSD_COUNT]; + u32 din_reoder_sel; + u32 layer_cnt; +}; + +extern struct hw_osd_reg_s hw_osd_reg_array[HW_OSD_COUNT]; +typedef void (*update_func_t)(u32); struct hw_list_s { struct list_head list; update_func_t update_func; @@ -320,6 +490,8 @@ struct hw_para_s { struct pandata_s free_dst_data_backup[HW_OSD_COUNT]; /* struct pandata_s rotation_pandata[HW_OSD_COUNT]; */ struct pandata_s cursor_dispdata[HW_OSD_COUNT]; + struct dispdata_s src_data[HW_OSD_COUNT]; + struct dispdata_s dst_data[HW_OSD_COUNT]; u32 buffer_alloc[HW_OSD_COUNT]; u32 gbl_alpha[HW_OSD_COUNT]; @@ -339,7 +511,12 @@ struct hw_para_s { const struct color_bit_define_s *color_info[HW_OSD_COUNT]; const struct color_bit_define_s *color_backup[HW_OSD_COUNT]; u32 scan_mode[HW_OSD_COUNT]; - u32 order; + u32 order[HW_OSD_COUNT]; + u32 premult_en[HW_OSD_COUNT]; + u32 osd_blend_mode; + u32 background_w; + u32 background_h; + struct osd_3d_mode_s mode_3d[HW_OSD_COUNT]; u32 updated[HW_OSD_COUNT]; /* u32 block_windows[HW_OSD_COUNT][HW_OSD_BLOCK_REG_COUNT]; */ @@ -348,7 +525,9 @@ struct hw_para_s { u32 free_scale_mode_backup[HW_OSD_COUNT]; u32 osd_reverse[HW_OSD_COUNT]; /* struct osd_rotate_s rotate[HW_OSD_COUNT]; */ - struct hw_list_s reg[HW_OSD_COUNT][HW_REG_INDEX_MAX]; + int use_h_filter_mode[HW_OSD_COUNT]; + int use_v_filter_mode[HW_OSD_COUNT]; + struct hw_list_s reg[HW_REG_INDEX_MAX]; u32 field_out_en; u32 scale_workaround; u32 fb_for_4k2k; @@ -358,8 +537,8 @@ struct hw_para_s { u32 bot_type; u32 hw_reset_flag; struct afbcd_data_s osd_afbcd[HW_OSD_COUNT]; + struct osd_device_data_s osd_meson_dev; u32 urgent[HW_OSD_COUNT]; - u32 osd_fifo[HW_OSD_COUNT]; u32 osd_deband_enable; u32 osd_fps; u32 osd_fps_start; @@ -372,7 +551,13 @@ struct hw_para_s { u32 vinfo_width; u32 vinfo_height; u32 fb_drvier_probe; + u32 afbc_restart_in_vsync; + u32 afbc_force_reset; + u32 afbc_status_err_reset; + u32 afbc_use_latch; + u32 hwc_enable; + u32 osd_use_latch; + u32 hw_cursor_en; + u32 hw_rdma_en; }; - - #endif /* _OSD_H_ */ diff --git a/drivers/amlogic/media/osd/osd_backup.c b/drivers/amlogic/media/osd/osd_backup.c index 3c05c22..ce4aa24 100644 --- a/drivers/amlogic/media/osd/osd_backup.c +++ b/drivers/amlogic/media/osd/osd_backup.c @@ -19,12 +19,11 @@ #include #include #include -/* Amlogic Headers */ -#include /* Local Headers */ #include "osd_io.h" #include "osd_backup.h" +#include "osd_hw.h" const u16 osd_reg_backup[OSD_REG_BACKUP_COUNT] = { 0x1a10, 0x1a13, @@ -37,14 +36,27 @@ const u16 osd_afbc_reg_backup[OSD_AFBC_REG_BACKUP_COUNT] = { 0x31a6, 0x31a5, 0x31a4, 0x31a3, 0x31a2, 0x31a1, 0x31a0 }; +const u16 mali_afbc_reg_backup[MALI_AFBC_REG_BACKUP_COUNT] = { + 0x3a05, 0x3a07, + 0x3a10, 0x3a11, 0x3a12, 0x3a13, 0x3a14, 0x3a15, 0x3a16, + 0x3a17, 0x3a18, 0x3a19, 0x3a1a, 0x3a1b, 0x3a1c, + 0x3a30, 0x3a31, 0x3a32, 0x3a33, 0x3a34, 0x3a35, 0x3a36, + 0x3a37, 0x3a38, 0x3a39, 0x3a3a, 0x3a3b, 0x3a3c, + 0x3a50, 0x3a51, 0x3a52, 0x3a53, 0x3a54, 0x3a55, 0x3a56, + 0x3a57, 0x3a58, 0x3a59, 0x3a5a, 0x3a5b, 0x3a5c +}; static u32 osd_backup_count = OSD_VALUE_COUNT; static u32 afbc_backup_count = OSD_AFBC_VALUE_COUNT; +static u32 mali_afbc_backup_count = MALI_AFBC_REG_BACKUP_COUNT; u32 osd_backup[OSD_VALUE_COUNT]; u32 osd_afbc_backup[OSD_AFBC_VALUE_COUNT]; +u32 mali_afbc_backup[MALI_AFBC_VALUE_COUNT]; module_param_array(osd_backup, uint, &osd_backup_count, 0444); MODULE_PARM_DESC(osd_backup, "\n osd register backup\n"); module_param_array(osd_afbc_backup, uint, &afbc_backup_count, 0444); MODULE_PARM_DESC(osd_afbc_backup, "\n osd afbc register backup\n"); +module_param_array(mali_afbc_backup, uint, &mali_afbc_backup_count, 0444); +MODULE_PARM_DESC(mali_afbc_backup, "\n mali afbc register backup\n"); /* 0: not backup */ static u32 backup_enable; @@ -59,12 +71,21 @@ void update_backup_reg(u32 addr, u32 value) (addr <= OSD1_AFBCD_PIXEL_VSCOPE) && (backup_enable & HW_RESET_AFBCD_REGS)) { osd_afbc_backup[addr - base] = value; + return; } base = VIU_OSD1_CTRL_STAT; if ((addr >= VIU_OSD1_CTRL_STAT) && (addr <= VIU_OSD1_CTRL_STAT2) && (backup_enable & HW_RESET_OSD1_REGS)) { osd_backup[addr - base] = value; + return; + } + base = VPU_MAFBC_COMMAND; + if ((addr >= VPU_MAFBC_COMMAND) + && (addr <= VPU_MAFBC_PREFETCH_CFG_S2) && + (backup_enable & HW_RESET_MALI_AFBCD_REGS)) { + mali_afbc_backup[addr - base] = value; + return; } } @@ -95,6 +116,16 @@ s32 get_backup_reg(u32 addr, u32 *value) return 0; } } + base = VPU_MAFBC_COMMAND; + if ((addr >= VPU_MAFBC_COMMAND) && + (addr <= VPU_MAFBC_PREFETCH_CFG_S2) && + (backup_enable & HW_RESET_MALI_AFBCD_REGS)) { + for (i = 0; i < MALI_AFBC_REG_BACKUP_COUNT; i++) + if (addr == mali_afbc_reg_backup[i]) { + *value = mali_afbc_backup[addr - base]; + return 0; + } + } return -1; } @@ -123,6 +154,15 @@ void backup_regs_init(u32 backup_mask) osd_reg_read(addr); i++; } + i = 0; + base = VPU_MAFBC_COMMAND; + while ((backup_mask & HW_RESET_MALI_AFBCD_REGS) + && (i < MALI_AFBC_REG_BACKUP_COUNT)) { + addr = mali_afbc_reg_backup[i]; + mali_afbc_backup[addr - base] = + osd_reg_read(addr); + i++; + } backup_enable = backup_mask; } @@ -131,7 +171,6 @@ u32 is_backup(void) return backup_enable; } -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA /* recovery section */ #define INVAILD_REG_ITEM {0xffff, 0x0, 0x0, 0x0} #define REG_RECOVERY_TABLE 5 @@ -251,6 +290,7 @@ static struct reg_item misc_recovery_table[] = { void recovery_regs_init(void) { int i = 0, j; + int cpu_id = osd_hw.osd_meson_dev.cpu_id; if (recovery_enable) return; @@ -261,9 +301,9 @@ void recovery_regs_init(void) gRecovery[i].table = (struct reg_item *)&osd1_recovery_table[0]; - if ((get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX) - || (get_cpu_type() == MESON_CPU_MAJOR_ID_TXL) - || (get_cpu_type() == MESON_CPU_MAJOR_ID_TXHD)) { + if ((cpu_id == __MESON_CPU_MAJOR_ID_TXLX) + || (cpu_id == __MESON_CPU_MAJOR_ID_TXL) + || (cpu_id == __MESON_CPU_MAJOR_ID_TXHD)) { for (j = 0; j < gRecovery[i].size; j++) { if (gRecovery[i].table[j].addr == VIU_OSD1_FIFO_CTRL_STAT) { @@ -308,6 +348,7 @@ int update_recovery_item(u32 addr, u32 value) int i; struct reg_item *table = NULL; int ret = -1; + int cpu_id = osd_hw.osd_meson_dev.cpu_id; if (!recovery_enable) return ret; @@ -382,8 +423,8 @@ int update_recovery_item(u32 addr, u32 value) } if (((addr == DOLBY_CORE2A_SWAP_CTRL1) || (addr == DOLBY_CORE2A_SWAP_CTRL2)) - && !is_meson_txlx_cpu() - && !is_meson_gxm_cpu()) + && (cpu_id != __MESON_CPU_MAJOR_ID_TXLX) + && (cpu_id != __MESON_CPU_MAJOR_ID_GXM)) return ret; if ((addr == VIU_OSD2_BLK0_CFG_W4) || (addr == VIU_OSD2_BLK1_CFG_W4) || @@ -415,6 +456,7 @@ s32 get_recovery_item(u32 addr, u32 *value, u32 *mask) int i; struct reg_item *table = NULL; int ret = -1; + int cpu_id = osd_hw.osd_meson_dev.cpu_id; if (!recovery_enable) return ret; @@ -482,8 +524,8 @@ s32 get_recovery_item(u32 addr, u32 *value, u32 *mask) if (((addr == DOLBY_CORE2A_SWAP_CTRL1) || (addr == DOLBY_CORE2A_SWAP_CTRL2)) - && !is_meson_txlx_cpu() - && !is_meson_gxm_cpu()) + && (cpu_id != __MESON_CPU_MAJOR_ID_TXLX) + && (cpu_id != __MESON_CPU_MAJOR_ID_GXM)) return ret; if ((addr == VIU_OSD2_BLK0_CFG_W4) || @@ -532,7 +574,7 @@ s32 get_recovery_item(u32 addr, u32 *value, u32 *mask) */ return ret; } -#else +#if 0 void recovery_regs_init(void) { } diff --git a/drivers/amlogic/media/osd/osd_backup.h b/drivers/amlogic/media/osd/osd_backup.h index b61df4a..877b8b9 100644 --- a/drivers/amlogic/media/osd/osd_backup.h +++ b/drivers/amlogic/media/osd/osd_backup.h @@ -22,20 +22,25 @@ #define OSD_REG_BACKUP_COUNT 12 #define OSD_AFBC_REG_BACKUP_COUNT 9 - +#define MALI_AFBC_REG_BACKUP_COUNT 41 #define OSD_VALUE_COUNT (VIU_OSD1_CTRL_STAT2 - VIU_OSD1_CTRL_STAT + 1) #define OSD_AFBC_VALUE_COUNT (OSD1_AFBCD_PIXEL_VSCOPE - OSD1_AFBCD_ENABLE + 1) +#define MALI_AFBC_VALUE_COUNT \ + (VPU_MAFBC_PREFETCH_CFG_S2 - VPU_MAFBC_COMMAND + 1) extern const u16 osd_reg_backup[OSD_REG_BACKUP_COUNT]; extern const u16 osd_afbc_reg_backup[OSD_AFBC_REG_BACKUP_COUNT]; +extern const u16 mali_afbc_reg_backup[MALI_AFBC_REG_BACKUP_COUNT]; extern u32 osd_backup[OSD_VALUE_COUNT]; extern u32 osd_afbc_backup[OSD_AFBC_VALUE_COUNT]; +extern u32 mali_afbc_backup[MALI_AFBC_VALUE_COUNT]; enum hw_reset_flag_e { HW_RESET_NONE = 0, HW_RESET_AFBCD_REGS = 0x80000000, HW_RESET_OSD1_REGS = 0x00000001, HW_RESET_AFBCD_HARDWARE = 0x80000000, + HW_RESET_MALI_AFBCD_REGS = 0x200000, }; struct reg_item { diff --git a/drivers/amlogic/media/osd/osd_debug.c b/drivers/amlogic/media/osd/osd_debug.c index 0a41f0d..76776ce 100644 --- a/drivers/amlogic/media/osd/osd_debug.c +++ b/drivers/amlogic/media/osd/osd_debug.c @@ -24,7 +24,6 @@ #include /* Amlogic Headers */ -#include #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS #include #include @@ -66,12 +65,12 @@ static void osd_debug_dump_value(void) return; osd_log_info("--- OSD ---\n"); - osd_log_info("order: %d\n", hwpara->order); osd_log_info("bot_type: %d\n", hwpara->bot_type); osd_log_info("field_out_en: %d\n", hwpara->field_out_en); for (index = 0; index < HW_OSD_COUNT; index++) { osd_log_info("\n--- OSD%d ---\n", index); + osd_log_info("order: %d\n", hwpara->order[index]); osd_log_info("scan_mode: %d\n", hwpara->scan_mode[index]); osd_log_info("enable: %d\n", hwpara->enable[index]); osd_log_info("2x-scale enable.h:%d .v: %d\n", @@ -123,9 +122,9 @@ static void osd_debug_dump_value(void) static void osd_debug_dump_register_all(void) { u32 reg = 0; - u32 offset = 0; u32 index = 0; - u32 count = 2; + u32 count = osd_hw.osd_meson_dev.osd_count; + struct hw_osd_reg_s *osd_reg = NULL; reg = VPU_VIU_VENC_MUX_CTRL; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); @@ -135,48 +134,186 @@ static void osd_debug_dump_register_all(void) osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = VPP_HOLD_LINES; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = VPP_OSD_SC_CTRL0; - osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = VPP_OSD_SCI_WH_M1; - osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = VPP_OSD_SCO_H_START_END; - osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = VPP_OSD_SCO_V_START_END; - osd_log_info("reg[0x%x]: 0x%08x\n\n", reg, osd_reg_read(reg)); - if (get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX) { + if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) { + reg = OSD_PATH_MISC_CTRL; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_CTRL; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_DIN0_SCOPE_H; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_DIN0_SCOPE_V; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_DIN1_SCOPE_H; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_DIN1_SCOPE_V; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_DIN2_SCOPE_H; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_DIN2_SCOPE_V; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_DIN3_SCOPE_H; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_DIN3_SCOPE_V; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_DUMMY_DATA0; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_DUMMY_ALPHA; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_BLEND0_SIZE; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VIU_OSD_BLEND_BLEND1_SIZE; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + + reg = VPP_OSD1_IN_SIZE; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VPP_OSD1_BLD_H_SCOPE; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VPP_OSD1_BLD_V_SCOPE; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VPP_OSD2_BLD_H_SCOPE; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VPP_OSD2_BLD_V_SCOPE; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = OSD1_BLEND_SRC_CTRL; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = OSD2_BLEND_SRC_CTRL; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VPP_POSTBLEND_H_SIZE; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VPP_OUT_H_V_SIZE; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + + } + if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) { + reg = VPP_OSD_SC_CTRL0; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VPP_OSD_SCI_WH_M1; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VPP_OSD_SCO_H_START_END; + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + reg = VPP_OSD_SCO_V_START_END; + osd_log_info("reg[0x%x]: 0x%08x\n\n", reg, osd_reg_read(reg)); + } + if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) { reg = OSD_DB_FLT_CTRL; osd_log_info("reg[0x%x]: 0x%08x\n\n", reg, osd_reg_read(reg)); } - if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) - count = 1; - for (index = 0; index < count; index++) { - if (index == 1) - offset = REG_OFFSET; - - reg = offset + VIU_OSD1_FIFO_CTRL_STAT; + osd_reg = &hw_osd_reg_array[index]; + reg = osd_reg->osd_fifo_ctrl_stat; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = offset + VIU_OSD1_CTRL_STAT; + reg = osd_reg->osd_ctrl_stat; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = offset + VIU_OSD1_CTRL_STAT2; + reg = osd_reg->osd_ctrl_stat2; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = offset + VIU_OSD1_BLK0_CFG_W0; + reg = osd_reg->osd_blk0_cfg_w0; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = offset + VIU_OSD1_BLK0_CFG_W1; + reg = osd_reg->osd_blk0_cfg_w1; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = offset + VIU_OSD1_BLK0_CFG_W2; + reg = osd_reg->osd_blk0_cfg_w2; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = offset + VIU_OSD1_BLK0_CFG_W3; + reg = osd_reg->osd_blk0_cfg_w3; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = VIU_OSD1_BLK0_CFG_W4; - if (index == 1) - reg = VIU_OSD2_BLK0_CFG_W4; + reg = osd_reg->osd_blk0_cfg_w4; osd_log_info("reg[0x%x]: 0x%08x\n\n", reg, osd_reg_read(reg)); + + if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) { + reg = osd_reg->osd_blk1_cfg_w4; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_blk2_cfg_w4; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_prot_ctrl; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_mali_unpack_ctrl; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_dimm_ctrl; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + + reg = osd_reg->osd_vsc_phase_step; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_vsc_init_phase; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_vsc_ctrl0; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_hsc_phase_step; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_hsc_init_phase; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_hsc_ctrl0; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_sc_dummy_data; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_sc_ctrl0; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_sci_wh_m1; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_sco_h_start_end; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = osd_reg->osd_sco_v_start_end; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + } + if ((osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) && + (osd_hw.osd_afbcd[index].enable)) { + reg = osd_reg->afbc_header_buf_addr_low_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_header_buf_addr_high_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_format_specifier_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_buffer_width_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_buffer_hight_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_boundings_box_x_start_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_boundings_box_x_end_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_boundings_box_y_start_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_boundings_box_y_end_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_output_buf_addr_low_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_output_buf_addr_high_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_output_buf_stride_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + reg = osd_reg->afbc_prefetch_cfg_s; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); + } } - if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM)) { + if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) { reg = VIU_MISC_CTRL1; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); @@ -184,14 +321,18 @@ static void osd_debug_dump_register_all(void) reg <= OSD1_AFBCD_PIXEL_VSCOPE; reg++) osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); + } else if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) { + reg = OSD_PATH_MISC_CTRL; + osd_log_info("reg[0x%x]: 0x%08x\n\n", + reg, osd_reg_read(reg)); } - if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) { - reg = VIU_OSD1_BLK1_CFG_W4; + if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) { + reg = hw_osd_reg_array[OSD1].osd_blk1_cfg_w4; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); - reg = VIU_OSD1_BLK2_CFG_W4; + reg = hw_osd_reg_array[OSD1].osd_blk2_cfg_w4; osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); } @@ -209,10 +350,9 @@ static void osd_debug_dump_register(int argc, char **argv) int reg_start, reg_end; int ret; -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) + if (!(osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) && + (osd_hw.hw_rdma_en)) read_rdma_table(); -#endif if ((argc == 3) && argv[1] && argv[2]) { ret = kstrtoint(argv[1], 16, ®_start); ret = kstrtoint(argv[2], 16, ®_end); @@ -325,7 +465,7 @@ static void osd_test_rect(void) struct ge2d_context_s *context = ge2d_context; #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS - if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) { + if (!osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) { canvas_read(OSD1_CANVAS_INDEX, &cs); cs_addr = cs.addr; cs_width = cs.width; @@ -440,7 +580,7 @@ static void osd_test_rect(void) static void osd_debug_auto_test(void) { - if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) + if (!osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) osd_test_colorbar(); osd_test_dummydata(); diff --git a/drivers/amlogic/media/osd/osd_drm.c b/drivers/amlogic/media/osd/osd_drm.c index 8e62a8b..bcfd3ff 100644 --- a/drivers/amlogic/media/osd/osd_drm.c +++ b/drivers/amlogic/media/osd/osd_drm.c @@ -37,6 +37,7 @@ #include #include "osd_drm.h" #include "osd_hw.h" +#include "osd_io.h" #include "osd.h" #include "osd_log.h" @@ -391,11 +392,13 @@ static ssize_t osd_afbcd_read_file(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { + struct seq_file *s = file->private_data; + int osd_id = *(int *)s; char buf[128]; ssize_t len; unsigned int enable_afbcd = 0; - enable_afbcd = osd_get_afbc(); + enable_afbcd = osd_get_afbc(osd_id); len = snprintf(buf, 128, "%d\n", enable_afbcd); return simple_read_from_buffer(userbuf, count, ppos, buf, len); } @@ -404,6 +407,8 @@ static ssize_t osd_afbcd_write_file(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { + struct seq_file *s = file->private_data; + int osd_id = *(int *)s; char buf[128]; unsigned int enable_afbcd = 0; int ret = 0; @@ -414,7 +419,7 @@ static ssize_t osd_afbcd_write_file(struct file *file, buf[count] = 0; ret = kstrtoint(buf, 0, &enable_afbcd); osd_log_info("afbc: %d\n", enable_afbcd); - osd_set_afbc(enable_afbcd); + osd_set_afbc(osd_id, enable_afbcd); return count; } @@ -460,6 +465,107 @@ static ssize_t osd_dump_write_file(struct file *file, return 0; } +static void parse_param(char *buf_orig, char **parm) +{ + char *ps, *token; + unsigned int n = 0; + char delim1[3] = " "; + char delim2[2] = "\n"; + + ps = buf_orig; + strcat(delim1, delim2); + while (1) { + token = strsep(&ps, delim1); + if (token == NULL) + break; + if (*token == '\0') + continue; + parm[n++] = token; + } +} + +static ssize_t osd_reg_write_file(struct file *file, + const char __user *userbuf, + size_t count, loff_t *ppos) +{ + char buf[128]; + char *buf_orig, *parm[8] = {NULL}; + long val = 0; + unsigned int reg_addr, reg_val; + + count = min_t(size_t, count, (sizeof(buf)-1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + buf[count] = 0; + buf_orig = kstrdup(buf, GFP_KERNEL); + parse_param(buf_orig, (char **)&parm); + if (!strcmp(parm[0], "rv")) { + if (kstrtoul(parm[1], 16, &val) < 0) + return -EINVAL; + reg_addr = val; + reg_val = osd_reg_read(reg_addr); + pr_info("reg[0x%04x]=0x%08x\n", reg_addr, reg_val); + } else if (!strcmp(parm[0], "wv")) { + if (kstrtoul(parm[1], 16, &val) < 0) + return -EINVAL; + reg_addr = val; + if (kstrtoul(parm[2], 16, &val) < 0) + return -EINVAL; + reg_val = val; + osd_reg_write(reg_addr, reg_val); + } + return count; +} + +static ssize_t osd_hwc_enable_read_file(struct file *file, + char __user *userbuf, + size_t count, loff_t *ppos) +{ + char buf[128]; + ssize_t len; + unsigned int hwc_enable = 0; + + osd_get_hwc_enable(&hwc_enable); + len = snprintf(buf, 128, "%d\n", hwc_enable); + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} + +static ssize_t osd_hwc_enable_write_file(struct file *file, + const char __user *userbuf, + size_t count, loff_t *ppos) +{ + char buf[128]; + unsigned int hwc_enable = 0; + int ret = 0; + + count = min_t(size_t, count, (sizeof(buf)-1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + buf[count] = 0; + ret = kstrtoint(buf, 0, &hwc_enable); + osd_log_info("hwc enable: %d\n", hwc_enable); + osd_set_hwc_enable(hwc_enable); + return count; +} + +static ssize_t osd_do_hwc_write_file(struct file *file, + const char __user *userbuf, + size_t count, loff_t *ppos) +{ + char buf[128]; + unsigned int do_hwc = 0; + int ret = 0; + + count = min_t(size_t, count, (sizeof(buf)-1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + buf[count] = 0; + ret = kstrtoint(buf, 0, &do_hwc); + osd_log_info("do_hwc: %d\n", do_hwc); + if (do_hwc) + osd_do_hwc(); + return count; +} static const struct file_operations loglevel_file_ops = { .open = simple_open, @@ -537,6 +643,21 @@ static const struct file_operations osd_dump_file_ops = { .write = osd_dump_write_file, }; +static const struct file_operations osd_reg_file_ops = { + .open = simple_open, + .write = osd_reg_write_file, +}; + +static const struct file_operations osd_hwc_enable_file_ops = { + .open = simple_open, + .read = osd_hwc_enable_read_file, + .write = osd_hwc_enable_write_file, +}; + +static const struct file_operations osd_do_hwc_file_ops = { + .open = simple_open, + .write = osd_do_hwc_write_file, +}; struct osd_drm_debugfs_files_s { const char *name; @@ -558,6 +679,10 @@ static struct osd_drm_debugfs_files_s osd_drm_debugfs_files[] = { {"osd_afbcd", S_IFREG | 0640, &osd_afbcd_file_ops}, {"osd_clear", S_IFREG | 0220, &osd_clear_file_ops}, {"osd_dump", S_IFREG | 0640, &osd_dump_file_ops}, + {"osd_reg", S_IFREG | 0220, &osd_reg_file_ops}, + {"osd_hwc_enable", S_IFREG | 0640, &osd_hwc_enable_file_ops}, + {"osd_do_hwc", S_IFREG | 0220, &osd_do_hwc_file_ops}, + }; void osd_drm_debugfs_add( @@ -602,25 +727,26 @@ EXPORT_SYMBOL(osd_drm_debugfs_exit); void osd_drm_vsync_isr_handler(void) { -#ifndef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - osd_update_scan_mode(); - /* go through update list */ - walk_through_update_list(); - osd_update_3d_mode(); - osd_update_vsync_hit(); - osd_hw_reset(); -#else - if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) - osd_rdma_interrupt_done_clear(); - else { + if (osd_hw.hw_rdma_en) { osd_update_scan_mode(); /* go through update list */ walk_through_update_list(); osd_update_3d_mode(); osd_update_vsync_hit(); osd_hw_reset(); + osd_mali_afbc_restart(); + } else { + if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) + osd_rdma_interrupt_done_clear(); + else { + osd_update_scan_mode(); + /* go through update list */ + walk_through_update_list(); + osd_update_3d_mode(); + osd_update_vsync_hit(); + osd_hw_reset(); + } } -#endif } EXPORT_SYMBOL(osd_drm_vsync_isr_handler); @@ -636,12 +762,12 @@ void osd_drm_plane_enable_hw(u32 index, u32 enable) } EXPORT_SYMBOL(osd_drm_plane_enable_hw); -int osd_drm_init(void) +int osd_drm_init(struct osd_device_data_s *osd_meson_dev) { int ret; /* osd hw init */ - ret = osd_io_remap(); + ret = osd_io_remap(osd_meson_dev->osd_ver == OSD_SIMPLE); if (!ret) { osd_log_err("osd_io_remap failed\n"); return -1; @@ -649,18 +775,20 @@ int osd_drm_init(void) /* init osd logo */ ret = logo_work_init(); if (ret == 0) - osd_init_hw(1, 0); + osd_init_hw(1, 0, osd_meson_dev); else - osd_init_hw(0, 0); - /* freescale switch from osd2 to osd1*/ - osd_log_info("freescale switch from osd2 to osd1\n"); - osd_set_free_scale_mode_hw(OSD2, 1); - osd_set_free_scale_enable_hw(OSD2, 0); - osd_set_free_scale_mode_hw(OSD1, 1); - osd_set_free_scale_axis_hw(OSD1, 0, 0, 1919, 1279); - osd_set_window_axis_hw(OSD1, 0, 0, 1919, 1279); - osd_set_free_scale_enable_hw(OSD1, 0x10001); - osd_enable_hw(OSD1, 1); + osd_init_hw(0, 0, osd_meson_dev); + if (osd_meson_dev->osd_ver <= OSD_NORMAL) { + /* freescale switch from osd2 to osd1*/ + osd_log_info("freescale switch from osd2 to osd1\n"); + osd_set_free_scale_mode_hw(OSD2, 1); + osd_set_free_scale_enable_hw(OSD2, 0); + osd_set_free_scale_mode_hw(OSD1, 1); + osd_set_free_scale_axis_hw(OSD1, 0, 0, 1919, 1279); + osd_set_window_axis_hw(OSD1, 0, 0, 1919, 1279); + osd_set_free_scale_enable_hw(OSD1, 0x10001); + osd_enable_hw(OSD1, 1); + } return 0; } EXPORT_SYMBOL(osd_drm_init); diff --git a/drivers/amlogic/media/osd/osd_drm.h b/drivers/amlogic/media/osd/osd_drm.h index 92a6067..8e0ecbc 100644 --- a/drivers/amlogic/media/osd/osd_drm.h +++ b/drivers/amlogic/media/osd/osd_drm.h @@ -17,7 +17,7 @@ #ifndef _OSD_DRM_H_ #define _OSD_DRM_H_ - +#include "osd.h" struct osd_plane_map_s { u32 plane_index; u32 zorder; @@ -36,7 +36,7 @@ struct osd_plane_map_s { u32 reserve; }; -int osd_drm_init(void); +int osd_drm_init(struct osd_device_data_s *osd_meson_dev); void osd_drm_debugfs_add( struct dentry **plane_debugfs_dir, char *name, diff --git a/drivers/amlogic/media/osd/osd_fb.c b/drivers/amlogic/media/osd/osd_fb.c index 36b871e1..69aaadc 100644 --- a/drivers/amlogic/media/osd/osd_fb.c +++ b/drivers/amlogic/media/osd/osd_fb.c @@ -46,7 +46,6 @@ #include #include /* Amlogic Headers */ -#include #include #include #ifdef CONFIG_INSTABOOT @@ -60,6 +59,7 @@ #include "osd_sync.h" #include "osd_io.h" static __u32 var_screeninfo[5]; +static struct osd_device_data_s osd_meson_dev; struct osd_info_s osd_info = { .index = 0, @@ -237,40 +237,65 @@ static struct fb_var_screeninfo fb_def_var[] = { .sync = 0, .vmode = FB_VMODE_NONINTERLACED, .rotate = 0, - } -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE - , + }, { - .xres = 32, - .yres = 32, - .xres_virtual = 32, - .yres_virtual = 32, - .xoffset = 0, - .yoffset = 0, + .xres = 1920, + .yres = 1080, + .xres_virtual = 1920, + .yres_virtual = 1080, + .xoffset = 0, + .yoffset = 0, .bits_per_pixel = 32, - .grayscale = 0, - /* leave as it is ,set by system. */ - .red = {0, 0, 0}, - .green = {0, 0, 0}, - .blue = {0, 0, 0}, + .grayscale = 0, + .red = {0, 0, 0}, + .green = {0, 0, 0}, + .blue = {0, 0, 0}, .transp = {0, 0, 0}, .nonstd = 0, - .activate = FB_ACTIVATE_NOW, + .activate = FB_ACTIVATE_NOW, .height = -1, .width = -1, .accel_flags = 0, - .pixclock = 0, - .left_margin = 0, - .right_margin = 0, - .upper_margin = 0, - .lower_margin = 0, - .hsync_len = 0, - .vsync_len = 0, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, + .pixclock = 0, + .left_margin = 0, + .right_margin = 0, + .upper_margin = 0, + .lower_margin = 0, + .hsync_len = 0, + .vsync_len = 0, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .rotate = 0, + }, + { + .xres = 1920, + .yres = 1080, + .xres_virtual = 1920, + .yres_virtual = 1080, + .xoffset = 0, + .yoffset = 0, + .bits_per_pixel = 32, + .grayscale = 0, + .red = {0, 0, 0}, + .green = {0, 0, 0}, + .blue = {0, 0, 0}, + .transp = {0, 0, 0}, + .nonstd = 0, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .accel_flags = 0, + .pixclock = 0, + .left_margin = 0, + .right_margin = 0, + .upper_margin = 0, + .lower_margin = 0, + .hsync_len = 0, + .vsync_len = 0, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, .rotate = 0, } -#endif }; static struct fb_fix_screeninfo fb_def_fix = { @@ -300,13 +325,11 @@ static int osd_shutdown_flag; unsigned int osd_log_level; int int_viu_vsync = -ENXIO; -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA int int_rdma = INT_RDMA; -#endif struct osd_fb_dev_s *gp_fbdev_list[OSD_COUNT] = {}; -static u32 fb_memsize[3]; -struct page *osd_page[3]; -static phys_addr_t fb_rmem_paddr[2]; +static u32 fb_memsize[HW_OSD_COUNT + 1]; +struct page *osd_page[HW_OSD_COUNT + 1]; +static phys_addr_t fb_rmem_paddr[OSD_COUNT]; static void __iomem *fb_rmem_vaddr[OSD_COUNT]; static size_t fb_rmem_size[OSD_COUNT]; static phys_addr_t fb_rmem_afbc_paddr[OSD_COUNT][OSD_MAX_BUF_NUM]; @@ -315,17 +338,15 @@ static size_t fb_rmem_afbc_size[OSD_COUNT][OSD_MAX_BUF_NUM]; struct ion_client *fb_ion_client; -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE -struct ion_handle *fb_ion_handle[OSD_COUNT][OSD_MAX_BUF_NUM] = { +struct ion_handle *fb_ion_handle[OSD_COUNT][OSD_MAX_BUF_NUM]; +#if 0 += { {NULL, NULL, NULL}, {NULL, NULL, NULL} }; -static int osd_cursor(struct fb_info *fbi, struct fb_cursor *var); -#else -struct ion_handle *fb_ion_handle[OSD_COUNT][OSD_MAX_BUF_NUM] = { - {NULL, NULL, NULL} -}; #endif +static int osd_cursor(struct fb_info *fbi, struct fb_cursor *var); + phys_addr_t get_fb_rmem_paddr(int index) { if (index < 0 || index > 1) @@ -515,7 +536,7 @@ static int osd_check_fbsize(struct fb_var_screeninfo *var, struct fb_info *info) { struct osd_fb_dev_s *fbdev = (struct osd_fb_dev_s *)info->par; - if (fbdev->fb_index == 0 && osd_get_afbc()) { + if (osd_meson_dev.afbc_type && osd_get_afbc(fbdev->fb_index)) { /* fb_afbc_len = fbdev->fb_afbc_len[0] * ((info->node == 0) ? * OSD_MAX_BUF_NUM : 1); */ @@ -663,6 +684,7 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) s32 osd_dst_axis[4] = {0}; u32 block_windows[8] = {0}; u32 block_mode; + u32 hwc_enable; unsigned long ret; u32 flush_rate; struct fb_sync_request_s sync_request; @@ -729,6 +751,11 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) case FBIOPUT_OSD_CURSOR: ret = copy_from_user(&cursor, argp, sizeof(cursor)); break; + case FBIOPUT_OSD_HWC_ENABLE: + ret = copy_from_user(&hwc_enable, argp, sizeof(u32)); + break; + case FBIOPUT_OSD_DO_HWC: + break; default: osd_log_err("command 0x%x not supported (%s)\n", cmd, current->comm); @@ -928,12 +955,11 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) break; case FBIOGET_OSD_DMABUF: #ifdef CONFIG_ION - if (info->node == DEV_OSD0 && osd_get_afbc()) { + if (osd_get_afbc(info->node)) { dmaexp.fd = ion_share_dma_buf_fd( - fb_ion_client, - fb_ion_handle[info->node] - [dmaexp.buffer_idx]); + fb_ion_client, + fb_ion_handle[info->node][dmaexp.buffer_idx]); } else { dmaexp.fd = ion_share_dma_buf_fd( @@ -958,6 +984,12 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) ret = EINVAL; #endif break; + case FBIOPUT_OSD_HWC_ENABLE: + osd_set_hwc_enable(hwc_enable); + break; + case FBIOPUT_OSD_DO_HWC: + osd_setting_blend(); + break; default: break; } @@ -1068,13 +1100,8 @@ static int malloc_osd_memory(struct fb_info *info) fbdev = (struct osd_fb_dev_s *)info->par; pdev = fbdev->dev; fb_index = fbdev->fb_index; - if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) - if (fb_index >= 1) + if (osd_meson_dev.osd_count <= fb_index) return -1; - #ifndef CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE - if (fb_index >= 1) - return -1; - #endif fix = &info->fix; var = &info->var; if (!fb_ion_client) @@ -1082,17 +1109,17 @@ static int malloc_osd_memory(struct fb_info *info) /* read cma/fb-reserved memory first */ if ((b_reserved_mem == true) && ((fb_memsize[0] + fb_memsize[1] + - fb_memsize[2] <= size) && + fb_memsize[2] + fb_memsize[3] <= size) && (fb_memsize[fb_index + 1] > 0))) { fb_rmem_size[fb_index] = fb_memsize[fb_index + 1]; if (fb_index == DEV_OSD0) fb_rmem_paddr[fb_index] = base + fb_memsize[0]; else if (fb_index == DEV_OSD1) { - if ((OSD_COUNT == 2) && - ((fb_memsize[0] + fb_memsize[1] + - fb_memsize[2]) <= size)) - fb_rmem_paddr[fb_index] = - base + fb_memsize[0] + fb_memsize[1]; + fb_rmem_paddr[fb_index] = + base + fb_memsize[0] + fb_memsize[1]; + } else if (fb_index == DEV_OSD2) { + fb_rmem_paddr[fb_index] = base + fb_memsize[0] + + fb_memsize[1] + fb_memsize[2]; } pr_info("%s, %d, fb_index=%d,fb_rmem_size=%ld\n", __func__, __LINE__, fb_index, @@ -1129,7 +1156,7 @@ static int malloc_osd_memory(struct fb_info *info) fb_rmem_vaddr[fb_index] = page_address(osd_page[fb_index+1]); if (!fb_rmem_vaddr[fb_index]) - osd_log_err("fb[%d] ioremap error", + osd_log_err("fb[%d] get page_address error", fb_index); pr_info("%s, cma mem\n", __func__); } @@ -1152,8 +1179,9 @@ static int malloc_osd_memory(struct fb_info *info) } else { #ifdef CONFIG_AMLOGIC_ION pr_info("use ion buffer for fb memory\n"); - if (fb_index == DEV_OSD0 && osd_get_afbc()) { - pr_info("OSD0 as afbcd mode\n"); + if (osd_meson_dev.afbc_type && osd_get_afbc(fb_index)) { + pr_info("OSD%d as afbcd mode,afbc_type=%d\n", + fb_index, osd_meson_dev.afbc_type); for (j = 0; j < OSD_MAX_BUF_NUM; j++) { fb_ion_handle[fb_index][j] = ion_alloc(fb_ion_client, @@ -1245,7 +1273,7 @@ static int malloc_osd_memory(struct fb_info *info) osd_log_info(" %d, phy: 0x%p, vir:0x%p, size=%dK\n\n", fb_index, (void *)fbdev->fb_mem_paddr, fbdev->fb_mem_vaddr, fbdev->fb_len >> 10); - if (fb_index == DEV_OSD0 && osd_get_afbc()) { + if (osd_meson_dev.afbc_type && osd_get_afbc(fb_index)) { for (j = 0; j < OSD_MAX_BUF_NUM; j++) { fbdev->fb_afbc_len[j] = fb_rmem_afbc_size[fb_index][j]; @@ -1272,17 +1300,20 @@ static int malloc_osd_memory(struct fb_info *info) osd_backup_screen_info(fb_index, info->screen_base, info->screen_size); logo_index = osd_get_logo_index(); + osd_log_info("logo_index=%x,fb_index=%d\n", + logo_index, fb_index); if (osd_check_fbsize(var, info)) return -ENOMEM; /* clear osd buffer if not logo layer */ if (((logo_index < 0) || (logo_index != fb_index)) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)) { + (osd_meson_dev.cpu_id == __MESON_CPU_MAJOR_ID_AXG) || + (osd_meson_dev.cpu_id == __MESON_CPU_MAJOR_ID_G12A)) { osd_log_info("---------------clear fb%d memory %p\n", fb_index, fbdev->fb_mem_vaddr); set_logo_loaded(); if (fbdev->fb_mem_vaddr) memset(fbdev->fb_mem_vaddr, 0x0, fbdev->fb_len); - if (fb_index == DEV_OSD0 && osd_get_afbc()) { + if (osd_meson_dev.afbc_type && osd_get_afbc(fb_index)) { for (j = 1; j < OSD_MAX_BUF_NUM; j++) { osd_log_info( "---------------clear fb%d memory %p\n", @@ -1323,14 +1354,8 @@ static int osd_open(struct fb_info *info, int arg) return 0; fb_index = fbdev->fb_index; - if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) - if (fb_index >= 1) - return -1; - #ifndef CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE - if (fb_index >= 1) + if (osd_meson_dev.osd_count <= fb_index) return -1; - #endif - if (b_alloc_mem) { /* alloc mem when osd_open */ if (info->screen_base == NULL) { @@ -1443,7 +1468,6 @@ static int osd_pan_display(struct fb_var_screeninfo *var, return 0; } -#if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) static int osd_cursor(struct fb_info *fbi, struct fb_cursor *var) { s16 startx = 0, starty = 0; @@ -1457,7 +1481,6 @@ static int osd_cursor(struct fb_info *fbi, struct fb_cursor *var) (s16)starty, fbi->var.xres, fbi->var.yres); return 0; } -#endif static int osd_sync(struct fb_info *info) { @@ -1477,9 +1500,8 @@ static struct fb_ops osd_ops = { .fb_imageblit = cfb_imageblit, #ifdef CONFIG_FB_SOFT_CURSOR .fb_cursor = soft_cursor, -#elif defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) - .fb_cursor = osd_cursor, #endif + .fb_cursor = osd_cursor, .fb_ioctl = osd_ioctl, #ifdef CONFIG_COMPAT .fb_compat_ioctl = osd_compat_ioctl, @@ -1529,20 +1551,9 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd, osd_log_info("current vmode=%s, cmd: 0x%lx\n", vinfo->name, cmd); switch (cmd) { -#if 0 - case VOUT_EVENT_MODE_CHANGE_PRE: - for (i = 0; i < OSD_COUNT; i++) { - fb_dev = gp_fbdev_list[i]; - if (osd_hw.enable[i]) { - fb_dev->dis_osd_mchange = true; - osd_enable_hw(i, false); - } - } - break; -#endif case VOUT_EVENT_MODE_CHANGE: set_osd_logo_freescaler(); - for (i = 0; i < OSD_COUNT; i++) { + for (i = 0; i < osd_meson_dev.osd_count; i++) { fb_dev = gp_fbdev_list[i]; if (fb_dev == NULL) continue; @@ -1550,22 +1561,20 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd, &fb_dev->osd_ctl, vinfo); console_lock(); osddev_update_disp_axis(fb_dev, 1); -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE - osd_set_antiflicker_hw(DEV_OSD1, vinfo, - gp_fbdev_list[DEV_OSD1]->fb_info->var.yres); -#endif + if ((osd_meson_dev.osd_ver == OSD_NORMAL) + || (osd_meson_dev.osd_ver == OSD_SIMPLE)) + osd_set_antiflicker_hw(DEV_OSD1, vinfo, + gp_fbdev_list + [DEV_OSD1]->fb_info->var.yres); + else if (osd_meson_dev.osd_ver == OSD_HIGH_ONE) + osd_set_antiflicker_hw(i, vinfo, + gp_fbdev_list[i]->fb_info->var.yres); console_unlock(); -#if 0 - if (fb_dev->dis_osd_mchange) { - fb_dev->dis_osd_mchange = false; - osd_enable_hw(i, true); - } -#endif } break; case VOUT_EVENT_OSD_BLANK: blank = *(int *)para; - for (i = 0; i < OSD_COUNT; i++) { + for (i = 0; i < osd_meson_dev.osd_count; i++) { fb_dev = gp_fbdev_list[i]; if (fb_dev == NULL) continue; @@ -1576,7 +1585,7 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd, break; case VOUT_EVENT_OSD_DISP_AXIS: disp_rect = (struct disp_rect_s *)para; - for (i = 0; i < OSD_COUNT; i++) { + for (i = 0; i < osd_meson_dev.osd_count; i++) { if (!disp_rect) break; fb_dev = gp_fbdev_list[i]; @@ -2020,7 +2029,10 @@ static ssize_t store_debug(struct device *device, struct device_attribute *attr, static ssize_t show_afbcd(struct device *device, struct device_attribute *attr, char *buf) { - u32 enable = osd_get_afbc(); + struct fb_info *fb_info = dev_get_drvdata(device); + u32 enable; + + enable = osd_get_afbc(fb_info->node); return snprintf(buf, PAGE_SIZE, "%d\n", enable); } @@ -2030,11 +2042,12 @@ static ssize_t store_afbcd(struct device *device, struct device_attribute *attr, { u32 res = 0; int ret = 0; + struct fb_info *fb_info = dev_get_drvdata(device); ret = kstrtoint(buf, 0, &res); osd_log_info("afbc: %d\n", res); - osd_set_afbc(res); + osd_set_afbc(fb_info->node, res); return count; } @@ -2241,36 +2254,6 @@ static ssize_t store_update_freescale(struct device *device, return count; } -static ssize_t show_ver_angle(struct device *device, - struct device_attribute *attr, - char *buf) -{ - unsigned int osd_angle = 0; - struct fb_info *fb_info = dev_get_drvdata(device); - - osd_get_angle_hw(fb_info->node, &osd_angle); - return snprintf(buf, PAGE_SIZE, "osd_angle:[%d]\n", osd_angle); -} - -static ssize_t store_ver_angle(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned int osd_angle = 0; - struct fb_info *fb_info = dev_get_drvdata(device); - int res = 0; - int ret = 0; - - ret = kstrtoint(buf, 0, &res); - osd_angle = res; - memset((char *)fb_info->screen_base, 0x80, fb_info->screen_size); -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE - osd_set_angle_hw(fb_info->node, osd_angle, fb_def_var[DEV_OSD1].yres, - fb_info->var.yres); -#endif - return count; -} - static ssize_t show_ver_clone(struct device *device, struct device_attribute *attr, char *buf) @@ -2316,6 +2299,7 @@ static ssize_t show_reset_status(struct device *device, return snprintf(buf, PAGE_SIZE, "0x%x\n", status); } +/* Todo: how to use uboot logo */ static ssize_t free_scale_switch(struct device *device, struct device_attribute *attr, const char *buf, size_t count) @@ -2460,6 +2444,161 @@ static ssize_t store_osd_display_debug(struct device *device, return count; } + +static ssize_t show_osd_background_size(struct device *device, + struct device_attribute *attr, + char *buf) +{ + u32 osd_background_size_w, osd_background_size_h; + + osd_get_background_size(&osd_background_size_w, + &osd_background_size_h); + return snprintf(buf, 40, "%d %d\n", + osd_background_size_w, + osd_background_size_h); +} + +static ssize_t store_osd_background_size(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int parsed[2]; + + if (likely(parse_para(buf, 2, parsed) == 2)) + osd_set_background_size( + parsed[0], parsed[1]); + else + osd_log_err("set background size error\n"); + + return count; +} + +static ssize_t show_osd_premult( + struct device *device, struct device_attribute *attr, + char *buf) +{ + struct fb_info *fb_info = dev_get_drvdata(device); + u32 premult_en; + + premult_en = osd_get_premult(fb_info->node); + + return snprintf(buf, PAGE_SIZE, "%d\n", premult_en); +} + +static ssize_t store_osd_premult( + struct device *device, struct device_attribute *attr, + const char *buf, size_t count) +{ + u32 res = 0; + int ret = 0; + struct fb_info *fb_info = dev_get_drvdata(device); + + ret = kstrtoint(buf, 0, &res); + osd_log_info("premult_en: %d\n", res); + + osd_set_premult(fb_info->node, res); + + return count; +} + +static ssize_t show_osd_afbc_debug(struct device *device, + struct device_attribute *attr, + char *buf) +{ + u32 debug_val[4]; + + osd_get_afbc_debug(&debug_val[0], &debug_val[1], + &debug_val[2], &debug_val[3]); + return snprintf(buf, 40, "%d %d %d %d\n", + debug_val[0], debug_val[1], + debug_val[2], debug_val[3]); +} + +static ssize_t store_osd_afbc_debug(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int parsed[4]; + + if (likely(parse_para(buf, 4, parsed) == 4)) + osd_set_afbc_debug( + parsed[0], parsed[1], parsed[2], parsed[3]); + else + osd_log_err("set afbc debug size error\n"); + + return count; +} + +static ssize_t show_osd_afbc_format( + struct device *device, struct device_attribute *attr, + char *buf) +{ + struct fb_info *fb_info = dev_get_drvdata(device); + u32 format[2]; + + osd_get_afbc_format(fb_info->node, &format[0], &format[1]); + + return snprintf(buf, PAGE_SIZE, "%d %d\n", format[0], format[1]); +} + +static ssize_t store_osd_afbc_format( + struct device *device, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fb_info *fb_info = dev_get_drvdata(device); + int parsed[2]; + + if (likely(parse_para(buf, 2, parsed) == 2)) + osd_set_afbc_format(fb_info->node, + parsed[0], parsed[1]); + else + osd_log_err("set afbc_format size error\n"); + + return count; +} + +static ssize_t show_osd_hwc_enalbe(struct device *device, + struct device_attribute *attr, + char *buf) +{ + u32 hwc_enalbe; + + osd_get_hwc_enable(&hwc_enalbe); + return snprintf(buf, 40, "%d\n", + hwc_enalbe); +} + +static ssize_t store_osd_hwc_enalbe(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int res = 0; + int ret = 0; + + ret = kstrtoint(buf, 0, &res); + if (ret < 0) + return -EINVAL; + osd_set_hwc_enable(res); + + return count; +} + +static ssize_t store_do_hwc(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int res = 0; + int ret = 0; + + ret = kstrtoint(buf, 0, &res); + if (ret < 0) + return -EINVAL; + if (res) + osd_do_hwc(); + + return count; +} + static inline int str2lower(char *str) { while (*str != '\0') { @@ -2626,8 +2765,6 @@ static struct device_attribute osd_attrs[] = { show_antiflicker, store_antiflicker), __ATTR(update_freescale, 0644, show_update_freescale, store_update_freescale), - __ATTR(ver_angle, 0644, - show_ver_angle, store_ver_angle), __ATTR(ver_clone, 0644, show_ver_clone, store_ver_clone), __ATTR(ver_update_pan, 0220, @@ -2648,6 +2785,19 @@ static struct device_attribute osd_attrs[] = { NULL, store_osd_reg), __ATTR(osd_display_debug, 0644, show_osd_display_debug, store_osd_display_debug), + __ATTR(osd_background_size, 0644, + show_osd_background_size, store_osd_background_size), + __ATTR(osd_premult, 0644, + show_osd_premult, store_osd_premult), + __ATTR(osd_afbc_debug, 0644, + show_osd_afbc_debug, store_osd_afbc_debug), + __ATTR(osd_afbc_format, 0644, + show_osd_afbc_format, store_osd_afbc_format), + __ATTR(osd_hwc_enable, 0644, + show_osd_hwc_enalbe, store_osd_hwc_enalbe), + __ATTR(osd_do_hwc, 0220, + NULL, store_do_hwc), + }; #ifdef CONFIG_PM @@ -2791,6 +2941,160 @@ static void mem_free_work(struct work_struct *work) } } +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, +}; + +static struct osd_device_data_s osd_gxtvbb = { + .cpu_id = __MESON_CPU_MAJOR_ID_GXTVBB, + .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 = 0x0, +}; + +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, +}; + +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 */ +}; + +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, +}; + +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, +}; + +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, +}; + +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, +}; + +static const struct of_device_id meson_fb_dt_match[] = { + { + .compatible = "amlogic, meson-gxbb", + .data = &osd_gxbb, + + }, + { + .compatible = "amlogic, meson-gxtvbb", + .data = &osd_gxtvbb, + + }, + { + .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, + }, + {}, +}; + static int osd_probe(struct platform_device *pdev) { struct fb_info *fbi = NULL; @@ -2808,6 +3112,27 @@ static int osd_probe(struct platform_device *pdev) int i; int ret = 0; + if (pdev->dev.of_node) { + const struct of_device_id *match; + struct osd_device_data_s *osd_meson; + struct device_node *of_node = pdev->dev.of_node; + + match = of_match_node(meson_fb_dt_match, of_node); + if (match) { + osd_meson = (struct osd_device_data_s *)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 -ENODEV; + } + } else { + pr_err("%s NOT match\n", __func__); + return -ENODEV; + } + } + /* get interrupt resource */ int_viu_vsync = platform_get_irq_byname(pdev, "viu-vsync"); if (int_viu_vsync == -ENXIO) { @@ -2815,16 +3140,14 @@ static int osd_probe(struct platform_device *pdev) goto failed1; } else osd_log_info("viu vsync irq: %d\n", int_viu_vsync); -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) { + if (osd_meson_dev.has_rdma) { int_rdma = platform_get_irq_byname(pdev, "rdma"); if (int_viu_vsync == -ENXIO) { osd_log_err("cannot get osd rdma irq resource\n"); goto failed1; } } -#endif - ret = osd_io_remap(); + ret = osd_io_remap(osd_meson_dev.osd_ver == OSD_SIMPLE); if (!ret) { osd_log_err("osd_io_remap failed\n"); goto failed1; @@ -2833,19 +3156,19 @@ static int osd_probe(struct platform_device *pdev) /* init osd logo */ ret = logo_work_init(); if (ret == 0) - osd_init_hw(1, 1); + osd_init_hw(1, 1, &osd_meson_dev); else - osd_init_hw(0, 1); + osd_init_hw(0, 1, &osd_meson_dev); /* get buffer size from dt */ ret = of_property_read_u32_array(pdev->dev.of_node, - "mem_size", fb_memsize, 3); + "mem_size", fb_memsize, osd_meson_dev.osd_count + 1); if (ret) { osd_log_err("not found mem_size from dtd\n"); goto failed1; } - osd_log_dbg("%d, mem_size: 0x%x, 0x%x, 0x%x\n", - __LINE__, fb_memsize[0], fb_memsize[1], fb_memsize[2]); + for (i = 0; i < (HW_OSD_COUNT + 1); i++) + osd_log_info("mem_size: 0x%x\n", fb_memsize[i]); /* init reserved memory */ ret = of_reserved_mem_device_init(&pdev->dev); @@ -2880,6 +3203,7 @@ static int osd_probe(struct platform_device *pdev) prop = of_get_property(pdev->dev.of_node, "scale_mode", NULL); if (prop) prop_idx = of_read_ulong(prop, 1); + /* Todo: only osd0 */ osd_set_free_scale_mode_hw(DEV_OSD0, prop_idx); prop = of_get_property(pdev->dev.of_node, "4k2k_fb", NULL); if (prop) @@ -2904,7 +3228,7 @@ static int osd_probe(struct platform_device *pdev) b_alloc_mem = of_read_ulong(prop, 1); vinfo = get_current_vinfo(); - for (index = 0; index < OSD_COUNT; index++) { + for (index = 0; index < osd_meson_dev.osd_count; index++) { /* register frame buffer memory */ fbi = framebuffer_alloc(sizeof(struct osd_fb_dev_s), &pdev->dev); @@ -2998,11 +3322,10 @@ static int osd_probe(struct platform_device *pdev) /* init osd reverse */ if (osd_info.index == DEV_ALL) { - osd_set_reverse_hw(0, osd_info.osd_reverse); - osd_set_reverse_hw(1, osd_info.osd_reverse); + for (i = 0; i < osd_meson_dev.osd_count; i++) + osd_set_reverse_hw(i, osd_info.osd_reverse); } else osd_set_reverse_hw(osd_info.index, osd_info.osd_reverse); - /* register vout client */ vout_register_client(&osd_notifier_nb); INIT_DELAYED_WORK(&osd_dwork, mem_free_work); @@ -3029,7 +3352,7 @@ static int osd_remove(struct platform_device *pdev) unregister_early_suspend(&early_suspend); #endif vout_unregister_client(&osd_notifier_nb); - for (i = 0; i < OSD_COUNT; i++) { + for (i = 0; i < osd_meson_dev.osd_count; i++) { int j; if (gp_fbdev_list[i]) { @@ -3039,7 +3362,7 @@ static int osd_remove(struct platform_device *pdev) for (j = 0; j < ARRAY_SIZE(osd_attrs); j++) device_remove_file(fbi->dev, &osd_attrs[j]); iounmap(fbdev->fb_mem_vaddr); - if (i == DEV_OSD0 && osd_get_afbc()) { + if (osd_get_afbc(i)) { for (j = 1; j < OSD_MAX_BUF_NUM; j++) iounmap(fbdev->fb_mem_afbc_vaddr[j]); } @@ -3119,10 +3442,6 @@ static int __init rmem_fb_setup(struct reserved_mem *rmem) } RESERVEDMEM_OF_DECLARE(fb, "amlogic, fb-memory", rmem_fb_setup); -static const struct of_device_id meson_fb_dt_match[] = { - {.compatible = "amlogic, meson-fb",}, - {}, -}; #ifdef CONFIG_HIBERNATION const struct dev_pm_ops osd_pm = { diff --git a/drivers/amlogic/media/osd/osd_fb.h b/drivers/amlogic/media/osd/osd_fb.h index 4025018..aecc4a2 100644 --- a/drivers/amlogic/media/osd/osd_fb.h +++ b/drivers/amlogic/media/osd/osd_fb.h @@ -27,12 +27,7 @@ /* Local Headers */ #include "osd.h" -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE -#define OSD_COUNT 2 /* enable two OSD layers */ -#else -#define OSD_COUNT 1 /* only enable one OSD layer */ -#endif - +#define OSD_COUNT (HW_OSD_COUNT) #define INVALID_BPP_ITEM {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} struct osd_fb_dev_s { diff --git a/drivers/amlogic/media/osd/osd_hw.c b/drivers/amlogic/media/osd/osd_hw.c index e5fa201..47e41af 100644 --- a/drivers/amlogic/media/osd/osd_hw.c +++ b/drivers/amlogic/media/osd/osd_hw.c @@ -34,7 +34,6 @@ #include /* Amlogic Headers */ -#include #include #include #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS @@ -84,11 +83,175 @@ static DECLARE_WAIT_QUEUE_HEAD(osd_vsync_wq); static bool vsync_hit; static bool osd_update_window_axis; static int osd_afbc_dec_enable; -static u32 extern_canvas[2] = {EXTERN1_CANVAS, EXTERN2_CANVAS}; +//static u32 extern_canvas[2] = {EXTERN1_CANVAS, EXTERN2_CANVAS}; static int ext_canvas_id; +static int osd_extra_idx[3][2]; static void osd_clone_pan(u32 index, u32 yoffset, int debug_flag); -static void osd_set_dummy_data(u32 alpha); +static void osd_set_dummy_data(u32 index, u32 alpha); + +#if 1 +struct hw_osd_reg_s hw_osd_reg_array[HW_OSD_COUNT] = { + { + VIU_OSD1_CTRL_STAT, + VIU_OSD1_CTRL_STAT2, + VIU_OSD1_COLOR_ADDR, + VIU_OSD1_COLOR, + VIU_OSD1_TCOLOR_AG0, + VIU_OSD1_TCOLOR_AG1, + VIU_OSD1_TCOLOR_AG2, + VIU_OSD1_TCOLOR_AG3, + VIU_OSD1_BLK0_CFG_W0, + VIU_OSD1_BLK0_CFG_W1, + VIU_OSD1_BLK0_CFG_W2, + VIU_OSD1_BLK0_CFG_W3, + VIU_OSD1_BLK0_CFG_W4, + VIU_OSD1_BLK1_CFG_W4, + VIU_OSD1_BLK2_CFG_W4, + VIU_OSD1_FIFO_CTRL_STAT, + VIU_OSD1_TEST_RDDATA, + VIU_OSD1_PROT_CTRL, + VIU_OSD1_MALI_UNPACK_CTRL, + VIU_OSD1_DIMM_CTRL, + //VIU_OSD_BLEND_DIN0_SCOPE_H, + //VIU_OSD_BLEND_DIN0_SCOPE_V, + + VPP_OSD_SCALE_COEF_IDX, + VPP_OSD_SCALE_COEF, + VPP_OSD_VSC_PHASE_STEP, + VPP_OSD_VSC_INI_PHASE, + VPP_OSD_VSC_CTRL0, + VPP_OSD_HSC_PHASE_STEP, + VPP_OSD_HSC_INI_PHASE, + VPP_OSD_HSC_CTRL0, + VPP_OSD_SC_DUMMY_DATA, + VPP_OSD_SC_CTRL0, + VPP_OSD_SCI_WH_M1, + VPP_OSD_SCO_H_START_END, + VPP_OSD_SCO_V_START_END, + VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0, + VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0, + VPU_MAFBC_FORMAT_SPECIFIER_S0, + VPU_MAFBC_BUFFER_WIDTH_S0, + VPU_MAFBC_BUFFER_HEIGHT_S0, + VPU_MAFBC_BOUNDING_BOX_X_START_S0, + VPU_MAFBC_BOUNDING_BOX_X_END_S0, + VPU_MAFBC_BOUNDING_BOX_Y_START_S0, + VPU_MAFBC_BOUNDING_BOX_Y_END_S0, + VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0, + VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0, + VPU_MAFBC_OUTPUT_BUF_STRIDE_S0, + VPU_MAFBC_PREFETCH_CFG_S0, + + + }, + { + VIU_OSD2_CTRL_STAT, + VIU_OSD2_CTRL_STAT2, + VIU_OSD2_COLOR_ADDR, + VIU_OSD2_COLOR, + VIU_OSD2_TCOLOR_AG0, + VIU_OSD2_TCOLOR_AG1, + VIU_OSD2_TCOLOR_AG2, + VIU_OSD2_TCOLOR_AG3, + VIU_OSD2_BLK0_CFG_W0, + VIU_OSD2_BLK0_CFG_W1, + VIU_OSD2_BLK0_CFG_W2, + VIU_OSD2_BLK0_CFG_W3, + VIU_OSD2_BLK0_CFG_W4, + VIU_OSD2_BLK1_CFG_W4, + VIU_OSD2_BLK2_CFG_W4, + VIU_OSD2_FIFO_CTRL_STAT, + VIU_OSD2_TEST_RDDATA, + VIU_OSD2_PROT_CTRL, + VIU_OSD2_MALI_UNPACK_CTRL, + VIU_OSD2_DIMM_CTRL, + //VIU_OSD_BLEND_DIN2_SCOPE_H, + //VIU_OSD_BLEND_DIN2_SCOPE_V, + + OSD2_SCALE_COEF_IDX, + OSD2_SCALE_COEF, + OSD2_VSC_PHASE_STEP, + OSD2_VSC_INI_PHASE, + OSD2_VSC_CTRL0, + OSD2_HSC_PHASE_STEP, + OSD2_HSC_INI_PHASE, + OSD2_HSC_CTRL0, + OSD2_SC_DUMMY_DATA, + OSD2_SC_CTRL0, + OSD2_SCI_WH_M1, + OSD2_SCO_H_START_END, + OSD2_SCO_V_START_END, + VPU_MAFBC_HEADER_BUF_ADDR_LOW_S1, + VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S1, + VPU_MAFBC_FORMAT_SPECIFIER_S1, + VPU_MAFBC_BUFFER_WIDTH_S1, + VPU_MAFBC_BUFFER_HEIGHT_S1, + VPU_MAFBC_BOUNDING_BOX_X_START_S1, + VPU_MAFBC_BOUNDING_BOX_X_END_S1, + VPU_MAFBC_BOUNDING_BOX_Y_START_S1, + VPU_MAFBC_BOUNDING_BOX_Y_END_S1, + VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S1, + VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S1, + VPU_MAFBC_OUTPUT_BUF_STRIDE_S1, + VPU_MAFBC_PREFETCH_CFG_S1, + + }, + { + VIU_OSD3_CTRL_STAT, + VIU_OSD3_CTRL_STAT2, + VIU_OSD3_COLOR_ADDR, + VIU_OSD3_COLOR, + VIU_OSD3_TCOLOR_AG0, + VIU_OSD3_TCOLOR_AG1, + VIU_OSD3_TCOLOR_AG2, + VIU_OSD3_TCOLOR_AG3, + VIU_OSD3_BLK0_CFG_W0, + VIU_OSD3_BLK0_CFG_W1, + VIU_OSD3_BLK0_CFG_W2, + VIU_OSD3_BLK0_CFG_W3, + VIU_OSD3_BLK0_CFG_W4, + VIU_OSD3_BLK1_CFG_W4, + VIU_OSD3_BLK2_CFG_W4, + VIU_OSD3_FIFO_CTRL_STAT, + VIU_OSD3_TEST_RDDATA, + VIU_OSD3_PROT_CTRL, + VIU_OSD3_MALI_UNPACK_CTRL, + VIU_OSD3_DIMM_CTRL, + //VIU_OSD_BLEND_DIN3_SCOPE_H, + //VIU_OSD_BLEND_DIN3_SCOPE_V, + + OSD34_SCALE_COEF_IDX, + OSD34_SCALE_COEF, + OSD34_VSC_PHASE_STEP, + OSD34_VSC_INI_PHASE, + OSD34_VSC_CTRL0, + OSD34_HSC_PHASE_STEP, + OSD34_HSC_INI_PHASE, + OSD34_HSC_CTRL0, + OSD34_SC_DUMMY_DATA, + OSD34_SC_CTRL0, + OSD34_SCI_WH_M1, + OSD34_SCO_H_START_END, + OSD34_SCO_V_START_END, + VPU_MAFBC_HEADER_BUF_ADDR_LOW_S2, + VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S2, + VPU_MAFBC_FORMAT_SPECIFIER_S2, + VPU_MAFBC_BUFFER_WIDTH_S2, + VPU_MAFBC_BUFFER_HEIGHT_S2, + VPU_MAFBC_BOUNDING_BOX_X_START_S2, + VPU_MAFBC_BOUNDING_BOX_X_END_S2, + VPU_MAFBC_BOUNDING_BOX_Y_START_S2, + VPU_MAFBC_BOUNDING_BOX_Y_END_S2, + VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S2, + VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S2, + VPU_MAFBC_OUTPUT_BUF_STRIDE_S2, + VPU_MAFBC_PREFETCH_CFG_S2, + }, +}; +#endif + + #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE /* sync fence relative varible. */ @@ -102,6 +265,8 @@ struct kthread_work buffer_toggle_work; struct list_head post_fence_list; struct mutex post_fence_list_lock; static void osd_pan_display_fence(struct osd_fence_map_s *fence_map); +static int osd_setting_blending_scope(u32 index); +static int vpp_blend_setting_default(u32 index); static void *osd_timeline_create(void) { @@ -168,8 +333,6 @@ static void osd_put_fenceobj(struct fence *fence) static int pxp_mode; -static __nosavedata int use_h_filter_mode = -1; -static __nosavedata int use_v_filter_mode = -1; static unsigned int osd_h_filter_mode = 1; #define CANVAS_ALIGNED(x) (((x) + 31) & ~31) @@ -322,29 +485,14 @@ static void osd_vpu_power_on(void) switch_vpu_mem_pd_vmod(VPU_VIU_OSD1, VPU_MEM_POWER_ON); switch_vpu_mem_pd_vmod(VPU_VIU_OSD2, VPU_MEM_POWER_ON); switch_vpu_mem_pd_vmod(VPU_VIU_OSD_SCALE, VPU_MEM_POWER_ON); - if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM)) { + if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) { switch_vpu_mem_pd_vmod(VPU_AFBC_DEC, VPU_MEM_POWER_ON); - } -#endif -} - -#ifdef CONFIG_AMLOGIC_SUPERSCALER -static void osd_super_scale_mem_power_on(void) -{ -#ifdef CONFIG_AMLOGIC_VPU - switch_vpu_mem_pd_vmod(VPU_VIU_OSDSR, VPU_MEM_POWER_ON); -#endif -} + } else if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) { -static void osd_super_scale_mem_power_off(void) -{ -#ifdef CONFIG_AMLOGIC_VPU - switch_vpu_mem_pd_vmod(VPU_VIU_OSDSR, VPU_MEM_POWER_DOWN); + } #endif } -#endif #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE static inline int find_buf_num(u32 yres, u32 yoffset) @@ -485,6 +633,7 @@ int osd_sync_request_render(u32 index, u32 yres, fence_map->in_fence = osd_get_fenceobj(in_fence_fd); fence_map->out_fd = out_fence_create(&out_fence_fd, &val, buf_num); + /* Todo: */ list_add_tail(&fence_map->list, &post_fence_list); mutex_unlock(&post_fence_list_lock); kthread_queue_work(&buffer_toggle_worker, &buffer_toggle_work); @@ -536,11 +685,12 @@ int osd_sync_request_render(u32 index, u32 yres, void osd_update_3d_mode(void) { + int i = 0; + /* only called by vsync irq or rdma irq */ - if (osd_hw.mode_3d[OSD1].enable) - osd1_update_disp_3d_mode(); - if (osd_hw.mode_3d[OSD2].enable) - osd2_update_disp_3d_mode(); + for (i = 0; i <= OSD2; i++) + if (osd_hw.mode_3d[i].enable) + osd_update_disp_3d_mode(i); } static inline void wait_vsync_wakeup(void) @@ -625,6 +775,38 @@ static u32 line_stride_calc( return line_stride; } +static u32 line_stride_calc_afbc( + u32 fmt_mode, + u32 hsize, + u32 stride_align_32bytes) +{ + u32 line_stride = 0; + + switch (fmt_mode) { + case R8: + line_stride = ((hsize << 3) + 127) >> 7; + break; + case YUV422_8B: + case RGB565: + case RGBA5551: + case RGBA4444: + line_stride = ((hsize << 4) + 127) >> 7; + break; + case RGBA8888: + case RGB888: + case YUV422_10B: + case RGBA1010102: + line_stride = ((hsize << 5) + 127) >> 7; + break; + } + /* need wr ddr is 32bytes aligned */ + if (stride_align_32bytes) + line_stride = ((line_stride+1) >> 1) << 1; + else + line_stride = line_stride; + return line_stride; +} + static void osd_update_phy_addr(u32 index) { @@ -638,26 +820,35 @@ static void osd_update_phy_addr(u32 index) line_stride = line_stride_calc(fmt_mode, osd_hw.fb_gem[index].width / bpp, 1); VSYNCOSD_WR_MPEG_REG( - VIU_OSD1_BLK1_CFG_W4, + hw_osd_reg_array[index].osd_blk1_cfg_w4, osd_hw.fb_gem[index].addr); VSYNCOSD_WR_MPEG_REG_BITS( - VIU_OSD1_BLK2_CFG_W4, + hw_osd_reg_array[index].osd_blk2_cfg_w4, line_stride, 0, 12); } +/* only need judge osd1 and osd2 index, osd3 same with osd1 */ static void osd_update_interlace_mode(int index) { /* only called by vsync irq or rdma irq */ unsigned int fb0_cfg_w0 = 0, fb1_cfg_w0 = 0; + unsigned int fb2_cfg_w0 = 0; unsigned int scan_line_number = 0; unsigned int odd_even; spin_lock_irqsave(&osd_lock, lock_flags); - if ((index & (1 << OSD1)) == (1 << OSD1)) - fb0_cfg_w0 = VSYNCOSD_RD_MPEG_REG(VIU_OSD1_BLK0_CFG_W0); + if ((index & (1 << OSD1)) == (1 << OSD1)) { + fb0_cfg_w0 = VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w0); + if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) + fb2_cfg_w0 = VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[OSD3].osd_blk0_cfg_w0); + } if ((index & (1 << OSD2)) == (1 << OSD2)) - fb1_cfg_w0 = VSYNCOSD_RD_MPEG_REG(VIU_OSD2_BLK0_CFG_W0); + fb1_cfg_w0 = VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w0); + if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12)) { /* 1080I */ scan_line_number = ((osd_reg_read(ENCP_INFO_READ)) @@ -688,20 +879,27 @@ static void osd_update_interlace_mode(int index) OSD_TYPE_BOT_FIELD : OSD_TYPE_TOP_FIELD; } } -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.has_rdma && osd_hw.hw_rdma_en) /* when RDMA enabled, top/bottom fields changed in next vsync */ odd_even = (odd_even == OSD_TYPE_TOP_FIELD) ? OSD_TYPE_BOT_FIELD : OSD_TYPE_TOP_FIELD; -#endif fb0_cfg_w0 &= ~1; fb1_cfg_w0 &= ~1; + fb2_cfg_w0 &= ~1; fb0_cfg_w0 |= odd_even; fb1_cfg_w0 |= odd_even; - if ((index & (1 << OSD1)) == (1 << OSD1)) - VSYNCOSD_IRQ_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W0, fb0_cfg_w0); + fb2_cfg_w0 |= odd_even; + if ((index & (1 << OSD1)) == (1 << OSD1)) { + VSYNCOSD_IRQ_WR_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w0, fb0_cfg_w0); + if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) + VSYNCOSD_IRQ_WR_MPEG_REG( + hw_osd_reg_array[OSD3].osd_blk0_cfg_w0, fb0_cfg_w0); + } if ((index & (1 << OSD2)) == (1 << OSD2)) - VSYNCOSD_IRQ_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W0, fb1_cfg_w0); + VSYNCOSD_IRQ_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w0, fb1_cfg_w0); + spin_unlock_irqrestore(&osd_lock, lock_flags); } @@ -714,34 +912,54 @@ void osd_update_scan_mode(void) output_type = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3; osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE; osd_hw.scan_mode[OSD2] = SCAN_MODE_PROGRESSIVE; + osd_hw.scan_mode[OSD3] = SCAN_MODE_PROGRESSIVE; switch (output_type) { case VOUT_ENCP: if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12)) { /* 1080i */ osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE; osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE; + osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE; } break; case VOUT_ENCI: if (osd_reg_read(ENCI_VIDEO_EN) & 1) { osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE; osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE; + osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE; } break; } - if (osd_hw.free_scale_enable[OSD1]) - osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE; - if (osd_hw.osd_afbcd[OSD1].enable) - osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE; - if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE) - index |= 1 << OSD1; - if (osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE) - index |= 1 << OSD2; + if (osd_hw.hw_cursor_en) { + /* 3 layers osd don't support osd2 cursor */ + if (osd_hw.free_scale_enable[OSD1]) + osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE; + if (osd_hw.osd_afbcd[OSD1].enable) + osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE; + + if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE) + index |= 1 << OSD1; + if (osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE) + index |= 1 << OSD2; + } else { + int i; + + for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) { + if (osd_hw.free_scale_enable[i]) + osd_hw.scan_mode[i] = SCAN_MODE_PROGRESSIVE; + if (osd_hw.osd_afbcd[i].enable) + osd_hw.scan_mode[i] = SCAN_MODE_PROGRESSIVE; + if (osd_hw.scan_mode[i] == SCAN_MODE_INTERLACE) + index |= 1 << i; + } + } + if ((osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE) || (osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE)) osd_update_interlace_mode(index); } +//not rdma will call update func; void walk_through_update_list(void) { u32 i, j; @@ -750,7 +968,7 @@ void walk_through_update_list(void) j = 0; while (osd_hw.updated[i] && j < 32) { if (osd_hw.updated[i] & (1 << j)) { - osd_hw.reg[i][j].update_func(); + osd_hw.reg[j].update_func(i); remove_from_update_list(i, j); } j++; @@ -759,27 +977,38 @@ void walk_through_update_list(void) } /*************** for GXL/GXM hardware alpha bug workaround ***************/ -u32 osd_get_hw_reset_flag(void) +static bool mali_afbc_get_error(void) +{ + u32 status; + bool error = false; + + status = VSYNCOSD_RD_MPEG_REG(VPU_MAFBC_IRQ_RAW_STATUS); + if (status & 0x3c) { + osd_log_dbg("afbc error happened\n"); + error = true; + } + return error; +} +static u32 osd_get_hw_reset_flag(void) { u32 hw_reset_flag = HW_RESET_NONE; - u32 cpu_type; - cpu_type = get_cpu_type(); /* check hw version */ - switch (cpu_type) { - case MESON_CPU_MAJOR_ID_GXTVBB: + switch (osd_hw.osd_meson_dev.cpu_id) { + case __MESON_CPU_MAJOR_ID_GXTVBB: if (osd_hw.osd_afbcd[OSD1].enable) hw_reset_flag |= HW_RESET_AFBCD_REGS; break; - case MESON_CPU_MAJOR_ID_GXM: + case __MESON_CPU_MAJOR_ID_GXM: + case __MESON_CPU_MAJOR_ID_TXLX: /* same bit, but gxm only reset hardware, not top reg*/ if (osd_hw.osd_afbcd[OSD1].enable) hw_reset_flag |= HW_RESET_AFBCD_HARDWARE; #ifndef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM break; #else - case MESON_CPU_MAJOR_ID_GXL: - case MESON_CPU_MAJOR_ID_TXL: + case __MESON_CPU_MAJOR_ID_GXL: + case __MESON_CPU_MAJOR_ID_TXL: if (((hdr_osd_reg.viu_osd1_matrix_ctrl & 0x00000001) != 0x0) || ((hdr_osd_reg.viu_osd1_eotf_ctl & 0x80000000) @@ -794,6 +1023,21 @@ u32 osd_get_hw_reset_flag(void) } break; #endif + case __MESON_CPU_MAJOR_ID_G12A: + { + int i, afbc_enable = 0; + + for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) + afbc_enable |= osd_hw.osd_afbcd[i].enable; + if (afbc_enable && + osd_hw.afbc_force_reset) + hw_reset_flag |= HW_RESET_MALI_AFBCD_REGS; + if (afbc_enable && + osd_hw.afbc_status_err_reset && + mali_afbc_get_error()) + hw_reset_flag |= HW_RESET_MALI_AFBCD_REGS; + } + break; default: hw_reset_flag = HW_RESET_NONE; break; @@ -817,55 +1061,75 @@ void osd_hw_reset(void) && !(backup_mask & HW_RESET_OSD1_REGS)) reset_bit &= ~HW_RESET_OSD1_REGS; - if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) + if ((osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) && (reset_bit & HW_RESET_AFBCD_REGS) && !(backup_mask & HW_RESET_AFBCD_REGS)) reset_bit &= ~HW_RESET_AFBCD_REGS; -#ifndef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - /* if not osd rdma, don't reset osd1 for hdr */ - reset_bit &= ~HW_RESET_OSD1_REGS; - backup_mask &= ~HW_RESET_OSD1_REGS; - - VSYNCOSD_IRQ_WR_MPEG_REG( - VIU_SW_RESET, reset_bit); - VSYNCOSD_IRQ_WR_MPEG_REG( - VIU_SW_RESET, 0); - - if (reset_bit & HW_RESET_OSD1_REGS) { - /* restore osd regs */ - int i; - u32 addr; - u32 base = VIU_OSD1_CTRL_STAT; + if ((osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) + && (reset_bit & HW_RESET_MALI_AFBCD_REGS) + && !(backup_mask & HW_RESET_MALI_AFBCD_REGS)) + reset_bit &= ~HW_RESET_MALI_AFBCD_REGS; - for (i = 0; i < OSD_REG_BACKUP_COUNT; i++) { - addr = osd_reg_backup[i]; - VSYNCOSD_IRQ_WR_MPEG_REG( - addr, osd_backup[addr - base]); + if (!osd_hw.hw_rdma_en) { + /* if not osd rdma, don't reset osd1 for hdr */ + reset_bit &= ~HW_RESET_OSD1_REGS; + backup_mask &= ~HW_RESET_OSD1_REGS; + + VSYNCOSD_IRQ_WR_MPEG_REG( + VIU_SW_RESET, reset_bit); + VSYNCOSD_IRQ_WR_MPEG_REG( + VIU_SW_RESET, 0); + if (reset_bit == HW_RESET_MALI_AFBCD_REGS) + osd_log_dbg("reset_bit=%x\n", reset_bit); + if (reset_bit & HW_RESET_OSD1_REGS) { + /* restore osd regs */ + int i; + u32 addr; + u32 base = hw_osd_reg_array[OSD1].osd_ctrl_stat; + + for (i = 0; i < OSD_REG_BACKUP_COUNT; i++) { + addr = osd_reg_backup[i]; + VSYNCOSD_IRQ_WR_MPEG_REG( + addr, osd_backup[addr - base]); + } } - } - if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) - && (reset_bit & HW_RESET_AFBCD_REGS)) { - /* restore osd afbcd regs */ - int i; - u32 addr; - u32 value; - u32 base = OSD1_AFBCD_ENABLE; - - for (i = 0; i < OSD_AFBC_REG_BACKUP_COUNT; i++) { - addr = osd_afbc_reg_backup[i]; - value = osd_afbc_backup[addr - base]; - if (addr == OSD1_AFBCD_ENABLE) - value |= 0x100; - VSYNCOSD_IRQ_WR_MPEG_REG( - addr, value); + if ((osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) + && (reset_bit & HW_RESET_AFBCD_REGS)) { + /* restore osd afbcd regs */ + int i; + u32 addr; + u32 value; + u32 base = OSD1_AFBCD_ENABLE; + + for (i = 0; i < OSD_AFBC_REG_BACKUP_COUNT; i++) { + addr = osd_afbc_reg_backup[i]; + value = osd_afbc_backup[addr - base]; + if (addr == OSD1_AFBCD_ENABLE) + value |= 0x100; + VSYNCOSD_IRQ_WR_MPEG_REG( + addr, value); + } } - } -#else - if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) + if ((osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) + && (reset_bit & HW_RESET_MALI_AFBCD_REGS)) { + /* restore mali afbcd regs */ + int i; + u32 addr; + u32 value; + u32 base = VPU_MAFBC_COMMAND; + + for (i = 0; i < MALI_AFBC_REG_BACKUP_COUNT; i++) { + addr = mali_afbc_reg_backup[i]; + value = mali_afbc_backup[addr - base]; + VSYNCOSD_IRQ_WR_MPEG_REG( + addr, value); + } + } + + } else if (osd_hw.osd_meson_dev.has_rdma) osd_rdma_reset_and_flush(reset_bit); -#endif spin_unlock_irqrestore(&osd_lock, lock_flags); /* maybe change reset bit */ osd_hw.hw_reset_flag = reset_bit; @@ -880,14 +1144,14 @@ static int notify_to_amvideo(void) pr_debug( "osd notify_to_amvideo vpp misc:0x%08x, mask:0x%08x\n", para[0], para[1]); -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA + if (osd_hw.hw_rdma_en) { #ifdef CONFIG_AMLOGIC_VIDEO - if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) - amvideo_notifier_call_chain( - AMVIDEO_UPDATE_OSD_MODE, - (void *)¶[0]); -#endif + if (osd_hw.osd_meson_dev.has_rdma) + amvideo_notifier_call_chain( + AMVIDEO_UPDATE_OSD_MODE, + (void *)¶[0]); #endif + } return 0; } /*************** end of GXL/GXM hardware alpha bug workaround ***************/ @@ -903,25 +1167,26 @@ static void osd_fiq_isr(void) static irqreturn_t vsync_isr(int irq, void *dev_id) #endif { -#ifndef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - osd_update_scan_mode(); - /* go through update list */ - walk_through_update_list(); - osd_update_3d_mode(); - osd_update_vsync_hit(); - osd_hw_reset(); -#else - if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) - osd_rdma_interrupt_done_clear(); - else { + if (!osd_hw.hw_rdma_en) { osd_update_scan_mode(); /* go through update list */ walk_through_update_list(); osd_update_3d_mode(); osd_update_vsync_hit(); osd_hw_reset(); + osd_mali_afbc_restart(); + } else { + if (osd_hw.osd_meson_dev.has_rdma) + osd_rdma_interrupt_done_clear(); + else { + osd_update_scan_mode(); + /* go through update list */ + walk_through_update_list(); + osd_update_3d_mode(); + osd_update_vsync_hit(); + osd_hw_reset(); + } } -#endif #ifndef FIQ_VSYNC return IRQ_HANDLED; #endif @@ -931,16 +1196,18 @@ void osd_set_pxp_mode(u32 mode) { pxp_mode = mode; } -void osd_set_afbc(u32 enable) +void osd_set_afbc(u32 index, u32 enable) { - if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM)) - osd_hw.osd_afbcd[OSD1].enable = enable; + if (osd_hw.osd_meson_dev.afbc_type) + osd_hw.osd_afbcd[index].enable = enable; + osd_log_info("afbc_type=%d,enable=%d\n", + osd_hw.osd_meson_dev.afbc_type, + osd_hw.osd_afbcd[index].enable); } -u32 osd_get_afbc(void) +u32 osd_get_afbc(u32 index) { - return osd_hw.osd_afbcd[OSD1].enable; + return osd_hw.osd_afbcd[index].enable; } u32 osd_get_reset_status(void) @@ -1003,6 +1270,7 @@ int osd_set_scan_mode(u32 index) if (is_interlaced(vinfo)) { osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE; osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE; + osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE; y_end = osd_hw.free_src_data[index].y_end; if ((vinfo->width == 720) && (vinfo->height == 480)) { @@ -1069,8 +1337,7 @@ int osd_set_scan_mode(u32 index) && (vinfo->height == 2160))) { if ((osd_hw.fb_for_4k2k) && (osd_hw.free_scale_enable[index])) - if (!(is_meson_gxtvbb_cpu() || - is_meson_gxm_cpu())) + if (!(osd_hw.osd_meson_dev.afbc_type)) osd_hw.scale_workaround = 1; osd_hw.field_out_en = 0; } else if (((vinfo->width == 720) @@ -1096,9 +1363,11 @@ int osd_set_scan_mode(u32 index) if (index == OSD2) { if (osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE) return 1; - data32 = (VSYNCOSD_RD_MPEG_REG(VIU_OSD2_BLK0_CFG_W0) & 3) >> 1; + data32 = (VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[index].osd_blk0_cfg_w0) & 3) >> 1; } else - data32 = (VSYNCOSD_RD_MPEG_REG(VIU_OSD1_BLK0_CFG_W0) & 3) >> 1; + data32 = (VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[index].osd_blk0_cfg_w0) & 3) >> 1; if (data32 == osd_hw.scan_mode[index]) return 1; else @@ -1196,9 +1465,6 @@ void osd_update_disp_axis_hw( struct pandata_s disp_data; struct pandata_s pan_data; - if (index == OSD2) - return; - if (osd_hw.color_info[index] == NULL) return; disp_data.x_start = display_h_start; @@ -1232,8 +1498,8 @@ void osd_update_disp_axis_hw( disp_data.y_end); spin_lock_irqsave(&osd_lock, lock_flags); if (mode_change) /* modify pandata . */ - osd_hw.reg[index][OSD_COLOR_MODE].update_func(); - osd_hw.reg[index][DISP_GEOMETRY].update_func(); + osd_hw.reg[OSD_COLOR_MODE].update_func(index); + osd_hw.reg[DISP_GEOMETRY].update_func(index); spin_unlock_irqrestore(&osd_lock, lock_flags); osd_wait_vsync_hw(); } @@ -1259,33 +1525,22 @@ void osd_setup_hw(u32 index, int update_color_mode = 0; int update_geometry = 0; u32 w = (color->bpp * xres_virtual + 7) >> 3; - u32 i, cpu_type; + u32 i; osd_hw.buffer_alloc[index] = 1; pan_data.x_start = xoffset; pan_data.y_start = yoffset; disp_data.x_start = disp_start_x; disp_data.y_start = disp_start_y; - if (likely(osd_hw.free_scale_enable[OSD1] && index == OSD1)) { - if (!(osd_hw.free_scale_mode[OSD1])) { - osd_log_info( - "osd[%d] osd_setup_hw scale mode is error %d\n", - index, osd_hw.free_scale_mode[OSD1]); - } else { - pan_data.x_end = xoffset + (disp_end_x - disp_start_x); - pan_data.y_end = yoffset + (disp_end_y - disp_start_y); - disp_data.x_end = disp_end_x; - disp_data.y_end = disp_end_y; - } - } else { - pan_data.x_end = xoffset + (disp_end_x - disp_start_x); - pan_data.y_end = yoffset + (disp_end_y - disp_start_y); - disp_data.x_end = disp_end_x; - disp_data.y_end = disp_end_y; - } + + pan_data.x_end = xoffset + (disp_end_x - disp_start_x); + pan_data.y_end = yoffset + (disp_end_y - disp_start_y); + disp_data.x_end = disp_end_x; + disp_data.y_end = disp_end_y; /* need always set color mode for osd2 */ - if ((color != osd_hw.color_info[index]) || (index == OSD2)) { + if ((color != osd_hw.color_info[index]) || + (index == (osd_hw.osd_meson_dev.osd_count - 1))) { update_color_mode = 1; osd_hw.color_info[index] = color; osd_hw.color_backup[index] = color; @@ -1297,8 +1552,7 @@ void osd_setup_hw(u32 index, osd_hw.fb_gem[index].addr = fbmem; osd_hw.fb_gem[index].width = w; osd_hw.fb_gem[index].height = yres_virtual; - if (index == OSD1 && - osd_hw.osd_afbcd[OSD1].enable == ENABLE && + if (osd_hw.osd_afbcd[index].enable == ENABLE && afbc_fbmem != NULL) { osd_hw.osd_afbcd[index].frame_width = xres; /* osd_hw.osd_afbcd[index].frame_height = @@ -1319,18 +1573,28 @@ void osd_setup_hw(u32 index, * update_geometry = 1; * update_color_mode = 1; */ - if (xres <= 128) - osd_hw.osd_afbcd[index].conv_lbuf_len = 32; - else if (xres <= 256) - osd_hw.osd_afbcd[index].conv_lbuf_len = 64; - else if (xres <= 512) - osd_hw.osd_afbcd[index].conv_lbuf_len = 128; - else if (xres <= 1024) - osd_hw.osd_afbcd[index].conv_lbuf_len = 256; - else if (xres <= 2048) - osd_hw.osd_afbcd[index].conv_lbuf_len = 512; - else - osd_hw.osd_afbcd[index].conv_lbuf_len = 1024; + if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) { + if (xres <= 128) + osd_hw.osd_afbcd[index] + .conv_lbuf_len = 32; + else if (xres <= 256) + osd_hw.osd_afbcd[index] + .conv_lbuf_len = 64; + else if (xres <= 512) + osd_hw.osd_afbcd[index] + .conv_lbuf_len = 128; + else if (xres <= 1024) + osd_hw.osd_afbcd[index] + .conv_lbuf_len = 256; + else if (xres <= 2048) + osd_hw.osd_afbcd[index] + .conv_lbuf_len = 512; + else + osd_hw.osd_afbcd[index] + .conv_lbuf_len = 1024; + } else if (osd_hw.osd_meson_dev.afbc_type + == MALI_AFBC) + osd_hw.osd_afbcd[index].out_addr_id = index + 1; } osd_hw.fb_gem[index].xres = xres; osd_hw.fb_gem[index].yres = yres; @@ -1347,8 +1611,7 @@ void osd_setup_hw(u32 index, osd_log_info("osd[%d] frame.height=%d\n", index, osd_hw.fb_gem[index].yres); - cpu_type = get_cpu_type(); - if (cpu_type == MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) osd_update_phy_addr(0); #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS else { @@ -1383,9 +1646,9 @@ void osd_setup_hw(u32 index, } spin_lock_irqsave(&osd_lock, lock_flags); if (update_color_mode) - osd_hw.reg[index][OSD_COLOR_MODE].update_func(); + osd_hw.reg[OSD_COLOR_MODE].update_func(index); if (update_geometry) - osd_hw.reg[index][DISP_GEOMETRY].update_func(); + osd_hw.reg[DISP_GEOMETRY].update_func(index); spin_unlock_irqrestore(&osd_lock, lock_flags); if (osd_hw.antiflicker_mode) @@ -1406,43 +1669,40 @@ void osd_setpal_hw(u32 index, unsigned int transp ) { - int do_lut; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { - if ((is_meson_txlx_cpu() || is_meson_txhd_cpu()) - && (index == OSD2)) { - do_lut = 1; - } else - return; - } + if ((osd_hw.osd_meson_dev.has_lut) + /*&& (index == OSD2)*/) { + if (regno < 256) { + u32 pal; - if (regno < 256) { - u32 pal; - - pal = ((red & 0xff) << 24) | - ((green & 0xff) << 16) | - ((blue & 0xff) << 8) | - (transp & 0xff); - spin_lock_irqsave(&osd_lock, lock_flags); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_COLOR_ADDR + REG_OFFSET * index, + pal = ((red & 0xff) << 24) | + ((green & 0xff) << 16) | + ((blue & 0xff) << 8) | + (transp & 0xff); + spin_lock_irqsave(&osd_lock, lock_flags); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[index].osd_color_addr, regno); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_COLOR + REG_OFFSET * index, pal); - spin_unlock_irqrestore(&osd_lock, lock_flags); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[index].osd_color, pal); + spin_unlock_irqrestore(&osd_lock, lock_flags); + } } } void osd_get_order_hw(u32 index, u32 *order) { - *order = osd_hw.order & 0x3; + *order = osd_hw.order[index] & 0x3; } void osd_set_order_hw(u32 index, u32 order) { + #if 0 if ((order != OSD_ORDER_01) && (order != OSD_ORDER_10)) return; - osd_hw.order = order; - add_to_update_list(index, OSD_CHANGE_ORDER); - osd_wait_vsync_hw(); + #endif + osd_hw.order[index] = order; + //add_to_update_list(index, OSD_CHANGE_ORDER); + //osd_wait_vsync_hw(); } /* osd free scale mode */ @@ -1452,7 +1712,7 @@ static void osd_set_free_scale_enable_mode1(u32 index, u32 enable) unsigned int v_enable = 0; int ret = 0; - if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) return; h_enable = (enable & 0xffff0000 ? 1 : 0); v_enable = (enable & 0xffff ? 1 : 0); @@ -1466,20 +1726,20 @@ static void osd_set_free_scale_enable_mode1(u32 index, u32 enable) ret = osd_set_scan_mode(index); spin_lock_irqsave(&osd_lock, lock_flags); if (ret) - osd_hw.reg[index][OSD_COLOR_MODE].update_func(); - osd_hw.reg[index][OSD_FREESCALE_COEF].update_func(); - osd_hw.reg[index][DISP_GEOMETRY].update_func(); - osd_hw.reg[index][DISP_FREESCALE_ENABLE].update_func(); - osd_hw.reg[index][OSD_ENABLE].update_func(); + osd_hw.reg[OSD_COLOR_MODE].update_func(index); + osd_hw.reg[OSD_FREESCALE_COEF].update_func(index); + osd_hw.reg[DISP_GEOMETRY].update_func(index); + osd_hw.reg[DISP_FREESCALE_ENABLE].update_func(index); + osd_hw.reg[OSD_ENABLE].update_func(index); spin_unlock_irqrestore(&osd_lock, lock_flags); } else { ret = osd_set_scan_mode(index); spin_lock_irqsave(&osd_lock, lock_flags); if (ret) - osd_hw.reg[index][OSD_COLOR_MODE].update_func(); - osd_hw.reg[index][DISP_GEOMETRY].update_func(); - osd_hw.reg[index][DISP_FREESCALE_ENABLE].update_func(); - osd_hw.reg[index][OSD_ENABLE].update_func(); + osd_hw.reg[OSD_COLOR_MODE].update_func(index); + osd_hw.reg[DISP_GEOMETRY].update_func(index); + osd_hw.reg[DISP_FREESCALE_ENABLE].update_func(index); + osd_hw.reg[OSD_ENABLE].update_func(index); spin_unlock_irqrestore(&osd_lock, lock_flags); } osd_wait_vsync_hw(); @@ -1546,6 +1806,10 @@ void osd_set_free_scale_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1) osd_hw.free_src_data_backup[index].y_start = y0; osd_hw.free_src_data_backup[index].x_end = x1; osd_hw.free_src_data_backup[index].y_end = y1; + osd_hw.src_data[index].x = x0; + osd_hw.src_data[index].y = y0; + osd_hw.src_data[index].w = x1 - x0 + 1; + osd_hw.src_data[index].h = y1 - y0 + 1; } void osd_get_scale_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1) @@ -1616,19 +1880,19 @@ void osd_set_window_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1) osd_hw.free_dst_data_backup[index].y_end = temp_y1; osd_hw.free_dst_data_backup[index].x_start = x0; osd_hw.free_dst_data_backup[index].x_end = x1; -#if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) - osd_hw.cursor_dispdata[index].x_start = x0; - osd_hw.cursor_dispdata[index].x_end = x1; - osd_hw.cursor_dispdata[index].y_start = temp_y0; - osd_hw.cursor_dispdata[index].y_end = temp_y1; -#endif - osd_log_info("free_dst_data(%d,%d,%d,%d)\n", - osd_hw.free_dst_data[index].x_start, - osd_hw.free_dst_data[index].y_start, - osd_hw.free_dst_data[index].x_end, - osd_hw.free_dst_data[index].y_end); + if (osd_hw.hw_cursor_en) { + osd_hw.cursor_dispdata[index].x_start = x0; + osd_hw.cursor_dispdata[index].x_end = x1; + osd_hw.cursor_dispdata[index].y_start = temp_y0; + osd_hw.cursor_dispdata[index].y_end = temp_y1; + } + osd_hw.dst_data[index].x = x0; + osd_hw.dst_data[index].y = y0; + osd_hw.dst_data[index].w = x1 - x0 + 1; + osd_hw.dst_data[index].h = y1 - y0 + 1; + if (osd_hw.free_dst_data[index].y_end >= 2159) - osd_set_dummy_data(0xff); + osd_set_dummy_data(index, 0xff); osd_update_window_axis = true; mutex_unlock(&osd_mutex); } @@ -1702,12 +1966,16 @@ void osd_enable_hw(u32 index, u32 enable) } /* reset viu 31bit ?? */ - if (index == OSD1 && - !osd_hw.enable[index] && + if (!osd_hw.enable[index] && osd_hw.osd_afbcd[index].enable && enable) { spin_lock_irqsave(&osd_lock, lock_flags); - osd_reg_write(VIU_SW_RESET, 0x80000000); - osd_reg_write(VIU_SW_RESET, 0); + if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) { + osd_reg_write(VIU_SW_RESET, 0x80000000); + osd_reg_write(VIU_SW_RESET, 0); + } + //else + // osd_reg_write(VIU_SW_RESET, 0x200000); + spin_unlock_irqrestore(&osd_lock, lock_flags); osd_afbc_dec_enable = 0; @@ -1751,8 +2019,8 @@ void osd_set_2x_scale_hw(u32 index, u16 h_scale_enable, u16 v_scale_enable) osd_hw.scale[index].h_enable = h_scale_enable; osd_hw.scale[index].v_enable = v_scale_enable; spin_lock_irqsave(&osd_lock, lock_flags); - osd_hw.reg[index][DISP_SCALE_ENABLE].update_func(); - osd_hw.reg[index][DISP_GEOMETRY].update_func(); + osd_hw.reg[DISP_SCALE_ENABLE].update_func(index); + osd_hw.reg[DISP_GEOMETRY].update_func(index); spin_unlock_irqrestore(&osd_lock, lock_flags); osd_wait_vsync_hw(); } @@ -1788,6 +2056,7 @@ void osd_get_antiflicker_hw(u32 index, u32 *on_off) *on_off = osd_hw.antiflicker_mode; } +/* Todo: how to expand to 3 osd */ void osd_clone_pan(u32 index, u32 yoffset, int debug_flag) { s32 offset = 0; @@ -1817,6 +2086,7 @@ void osd_clone_pan(u32 index, u32 yoffset, int debug_flag) } } +/* Todo: how to expand to 3 osd */ void osd_set_angle_hw(u32 index, u32 angle, u32 virtual_osd1_yres, u32 virtual_osd2_yres) { @@ -1900,6 +2170,7 @@ void osd_get_reverse_hw(u32 index, u32 *reverse) *reverse = osd_hw.osd_reverse[index]; } +/* Todo: how to do with uboot logo */ void osd_switch_free_scale( u32 pre_index, u32 pre_enable, u32 pre_scale, u32 next_index, u32 next_enable, u32 next_scale) @@ -1953,23 +2224,23 @@ void osd_switch_free_scale( osd_reg_write(VIU_SW_RESET, 0x80000000); osd_reg_write(VIU_SW_RESET, 0); osd_afbc_dec_enable = 0; - osd_hw.reg[next_index][OSD_GBL_ALPHA].update_func(); + osd_hw.reg[OSD_GBL_ALPHA].update_func(next_index); } - osd_hw.reg[pre_index][OSD_COLOR_MODE].update_func(); + osd_hw.reg[OSD_COLOR_MODE].update_func(pre_index); if (pre_scale) - osd_hw.reg[pre_index][OSD_FREESCALE_COEF].update_func(); - osd_hw.reg[pre_index][DISP_GEOMETRY].update_func(); - osd_hw.reg[pre_index][DISP_FREESCALE_ENABLE].update_func(); - osd_hw.reg[pre_index][OSD_ENABLE].update_func(); + osd_hw.reg[OSD_FREESCALE_COEF].update_func(pre_index); + osd_hw.reg[DISP_GEOMETRY].update_func(pre_index); + osd_hw.reg[DISP_FREESCALE_ENABLE].update_func(pre_index); + osd_hw.reg[OSD_ENABLE].update_func(pre_index); - osd_hw.reg[next_index][OSD_COLOR_MODE].update_func(); + osd_hw.reg[OSD_COLOR_MODE].update_func(next_index); if (next_scale) - osd_hw.reg[next_index] - [OSD_FREESCALE_COEF].update_func(); - osd_hw.reg[next_index][DISP_GEOMETRY].update_func(); - osd_hw.reg[next_index][DISP_FREESCALE_ENABLE].update_func(); - osd_hw.reg[next_index][OSD_ENABLE].update_func(); + osd_hw.reg + [OSD_FREESCALE_COEF].update_func(next_index); + osd_hw.reg[DISP_GEOMETRY].update_func(next_index); + osd_hw.reg[DISP_FREESCALE_ENABLE].update_func(next_index); + osd_hw.reg[OSD_ENABLE].update_func(next_index); spin_unlock_irqrestore(&osd_lock, lock_flags); osd_wait_vsync_hw(); @@ -2000,9 +2271,10 @@ void osd_set_deband(u32 osd_deband_enable) { u32 data32; - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX) { + if (osd_hw.osd_meson_dev.has_deband) { if (osd_hw.free_scale_enable[OSD1] - || osd_hw.free_scale_enable[OSD2]) { + || osd_hw.free_scale_enable[OSD2] + || osd_hw.free_scale_enable[OSD3]) { osd_hw.osd_deband_enable = osd_deband_enable; spin_lock_irqsave(&osd_lock, lock_flags); @@ -2063,7 +2335,75 @@ void osd_set_display_debug(u32 osd_display_debug_enable) osd_hw.osd_display_debug = osd_display_debug_enable; } +void osd_get_background_size(u32 *background_w, u32 *background_h) +{ + *background_w = osd_hw.background_w; + *background_h = osd_hw.background_h; +} + +void osd_set_background_size(u32 background_w, u32 background_h) +{ + osd_hw.background_w = background_w; + osd_hw.background_h = background_h; +} + +u32 osd_get_premult(u32 index) +{ + return osd_hw.premult_en[index]; +} + +void osd_set_premult(u32 index, u32 premult) +{ + + osd_hw.premult_en[index] = premult; +} + +void osd_get_afbc_debug(u32 *val1, u32 *val2, u32 *val3, u32 *val4) +{ + *val1 = osd_hw.afbc_restart_in_vsync; + *val2 = osd_hw.afbc_force_reset; + *val3 = osd_hw.afbc_status_err_reset; + *val4 = osd_hw.afbc_use_latch; +} + +void osd_set_afbc_debug(u32 val1, u32 val2, u32 val3, u32 val4) +{ + osd_hw.afbc_restart_in_vsync = val1; + osd_hw.afbc_force_reset = val2; + osd_hw.afbc_status_err_reset = val3; + osd_hw.afbc_use_latch = val4; +} + +void osd_get_afbc_format(u32 index, u32 *format, u32 *inter_format) +{ + *format = osd_hw.osd_afbcd[index].format; + *inter_format = osd_hw.osd_afbcd[index].inter_format; +} + +void osd_set_afbc_format(u32 index, u32 format, u32 inter_format) +{ + + osd_hw.osd_afbcd[index].format = format; + osd_hw.osd_afbcd[index].inter_format = inter_format; +} + +void osd_get_hwc_enable(u32 *hwc_enable) +{ + *hwc_enable = osd_hw.hwc_enable; +} + +void osd_set_hwc_enable(u32 hwc_enable) +{ + osd_hw.hwc_enable = hwc_enable; + /* setting default hwc path */ + if (!hwc_enable) + osd_setting_blend(); +} +void osd_do_hwc(void) +{ + osd_setting_blend(); +} #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE enum { HAL_PIXEL_FORMAT_RGBA_8888 = 1, @@ -2190,11 +2530,12 @@ static bool osd_ge2d_compose_pan_display(struct osd_fence_map_s *fence_map) return free_scale_set; } +#if 1 static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) { u32 index = fence_map->fb_index; u32 ext_addr = fence_map->ext_addr; - u32 width_src, width_dst, height_src, height_dst; + u32 width_src = 0, width_dst = 0, height_src = 0, height_dst = 0; u32 x_start, x_end, y_start, y_end; bool freescale_update = false; struct pandata_s freescale_dst[HW_OSD_COUNT]; @@ -2203,12 +2544,63 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) ext_addr = ext_addr + fence_map->byte_stride * fence_map->yoffset; vaddr = phys_to_virt(ext_addr); - canvas_config(osd_hw.fb_gem[index].canvas_idx, - ext_addr, - fence_map->byte_stride, - fence_map->height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + if (!osd_hw.osd_afbcd[index].enable) { + canvas_config(osd_hw.fb_gem[index].canvas_idx, + ext_addr, + fence_map->byte_stride, + fence_map->height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + } else { + osd_hw.osd_afbcd[index].phy_addr = ext_addr; + osd_hw.osd_afbcd[index].frame_width = + fence_map->width; + osd_hw.osd_afbcd[index].frame_height = + fence_map->height; + if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) { + if (fence_map->width <= 128) + osd_hw.osd_afbcd[index].conv_lbuf_len = 32; + else if (fence_map->width <= 256) + osd_hw.osd_afbcd[index].conv_lbuf_len = 64; + else if (fence_map->width <= 512) + osd_hw.osd_afbcd[index].conv_lbuf_len = 128; + else if (fence_map->width <= 1024) + osd_hw.osd_afbcd[index].conv_lbuf_len = 256; + else if (fence_map->width <= 2048) + osd_hw.osd_afbcd[index].conv_lbuf_len = 512; + else + osd_hw.osd_afbcd[index].conv_lbuf_len = 1024; + } else if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) { + } + } + if (osd_hw.hwc_enable) { + #if 1 + fence_map->zorder = 1; + fence_map->premult_en = 0; + fence_map->background_w = 1920; + fence_map->background_h = 1080; + fence_map->afbc_inter_format = 0x3; + #endif + /* just get para, need update via do_hwc */ + osd_hw.order[index] = fence_map->zorder; + osd_hw.premult_en[index] = fence_map->premult_en; + osd_hw.background_w = fence_map->background_w; + osd_hw.background_h = fence_map->background_h; + osd_hw.osd_afbcd[index].enable = fence_map->afbc_en; + osd_hw.osd_afbcd[index].inter_format = + fence_map->afbc_inter_format; + + osd_hw.src_data[index].x = fence_map->xoffset; + osd_hw.src_data[index].y = fence_map->yoffset; + osd_hw.src_data[index].w = fence_map->width; + osd_hw.src_data[index].h = fence_map->height; + + osd_hw.dst_data[index].x = fence_map->dst_x; + osd_hw.dst_data[index].y = fence_map->dst_y; + osd_hw.dst_data[index].w = fence_map->dst_w; + osd_hw.dst_data[index].h = fence_map->dst_h; + return 0; + } width_dst = osd_hw.free_dst_data_backup[index].x_end - osd_hw.free_dst_data_backup[index].x_start + 1; width_src = osd_hw.free_src_data_backup[index].x_end - @@ -2218,7 +2610,6 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) osd_hw.free_dst_data_backup[index].y_start + 1; height_src = osd_hw.free_src_data_backup[index].y_end - osd_hw.free_src_data_backup[index].y_start + 1; - osd_hw.screen_base[index] = vaddr; osd_hw.screen_size[index] = fence_map->byte_stride * fence_map->height; if (osd_hw.free_scale_enable[index] || @@ -2232,7 +2623,8 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) osd_hw.free_scale_mode[index] = 1; if (osd_hw.free_scale_enable[index] != osd_hw.free_scale_enable_backup[index]) { - osd_set_scan_mode(OSD1); + /* Todo: */ + osd_set_scan_mode(index); freescale_update = true; } @@ -2242,6 +2634,7 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) osd_hw.pandata[index].y_start = 0; osd_hw.pandata[index].y_end = fence_map->height - 1; + freescale_dst[index].x_start = osd_hw.free_dst_data_backup[index].x_start + (fence_map->dst_x * width_dst) / width_src; @@ -2257,7 +2650,8 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) osd_hw.free_dst_data_backup[index].y_start + ((fence_map->dst_y + fence_map->dst_h) * height_dst) / height_src - 1; - if (osd_hw.osd_reverse[OSD1] == REVERSE_TRUE) { + + if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { x_start = osd_hw.vinfo_width - freescale_dst[index].x_end - 1; y_start = osd_hw.vinfo_height @@ -2270,7 +2664,7 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) freescale_dst[index].y_start = y_start; freescale_dst[index].x_end = x_end; freescale_dst[index].y_end = y_end; - } else if (osd_hw.osd_reverse[OSD1] == REVERSE_X) { + } else if (osd_hw.osd_reverse[index] == REVERSE_X) { x_start = osd_hw.vinfo_width - freescale_dst[index].x_end - 1; x_end = osd_hw.vinfo_width @@ -2278,7 +2672,7 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) freescale_dst[index].x_start = x_start; freescale_dst[index].x_end = x_end; - } else if (osd_hw.osd_reverse[OSD1] == REVERSE_Y) { + } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { y_start = osd_hw.vinfo_height - freescale_dst[index].y_end - 1; y_end = osd_hw.vinfo_height @@ -2302,9 +2696,9 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) if ((height_dst != height_src) || (width_dst != width_src)) - osd_set_dummy_data(0); + osd_set_dummy_data(index, 0); else - osd_set_dummy_data(0xff); + osd_set_dummy_data(index, 0xff); osd_log_dbg("direct pandata x=%d,x_end=%d,y=%d,y_end=%d,width=%d,height=%d\n", osd_hw.pandata[index].x_start, osd_hw.pandata[index].x_end, @@ -2334,7 +2728,7 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) osd_hw.dispdata[index].y_start = fence_map->dst_y; osd_hw.dispdata[index].y_end = fence_map->dst_y + fence_map->dst_h - 1; - if (osd_hw.osd_reverse[OSD1] == REVERSE_TRUE) { + if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { x_start = osd_hw.vinfo_width - osd_hw.dispdata[index].x_end - 1; y_start = osd_hw.vinfo_height @@ -2347,7 +2741,7 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) osd_hw.dispdata[index].y_start = y_start; osd_hw.dispdata[index].x_end = x_end; osd_hw.dispdata[index].y_end = y_end; - } else if (osd_hw.osd_reverse[OSD1] == REVERSE_X) { + } else if (osd_hw.osd_reverse[index] == REVERSE_X) { x_start = osd_hw.vinfo_width - osd_hw.dispdata[index].x_end - 1; x_end = osd_hw.vinfo_width @@ -2355,7 +2749,7 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) osd_hw.dispdata[index].x_start = x_start; osd_hw.dispdata[index].x_end = x_end; - } else if (osd_hw.osd_reverse[OSD1] == REVERSE_Y) { + } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { y_start = osd_hw.vinfo_height - osd_hw.dispdata[index].y_end - 1; y_end = osd_hw.vinfo_height @@ -2367,6 +2761,7 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) fence_map->ext_addr = ext_addr; return freescale_update; } + static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) { s32 ret = 1; @@ -2381,8 +2776,13 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) bool skip = false; const struct vinfo_s *vinfo; - if (index >= 2) - return; + if (!osd_hw.hwc_enable) { + if (index >= OSD1) + return; + } else { + if (index >= OSD3) + return; + } if (timeline_created) { /* out fence created success. */ ret = osd_wait_buf_ready(fence_map); if (ret < 0) @@ -2396,18 +2796,26 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) skip = true; else osd_enable = (fence_map->op & 1) ? DISABLE : ENABLE; + /* need update via direct render interface later */ + fence_map->afbc_en = osd_hw.osd_afbcd[index].enable; vinfo = get_current_vinfo(); if (vinfo) { osd_hw.vinfo_width = vinfo->width; osd_hw.vinfo_height = vinfo->height; } + /* Todo: */ if (fence_map->ext_addr && fence_map->width - && fence_map->height && index == OSD1) { + && fence_map->height) { spin_lock_irqsave(&osd_lock, lock_flags); use_ext = true; - osd_hw.fb_gem[index].canvas_idx = - extern_canvas[ext_canvas_id]; - ext_canvas_id ^= 1; + if (!fence_map->afbc_en) { + osd_hw.fb_gem[index].canvas_idx = + osd_extra_idx[index][ext_canvas_id]; + ext_canvas_id ^= 1; + osd_hw.osd_afbcd[index].enable = DISABLE; + } else + osd_hw.osd_afbcd[index].enable = ENABLE; + color = convert_hal_format(fence_map->format); if (color) { osd_hw.color_info[index] = color; @@ -2424,38 +2832,36 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) freescale_update = osd_ge2d_compose_pan_display(fence_map); if (freescale_update) - osd_set_dummy_data(0xff); + osd_set_dummy_data(index, 0xff); } - if (index == OSD1 && - osd_hw.osd_afbcd[index].enable == ENABLE) - osd_hw.osd_afbcd[index].phy_addr = - fence_map->ext_addr; - osd_hw.reg[index][OSD_COLOR_MODE].update_func(); - osd_hw.reg[index][DISP_GEOMETRY].update_func(); - if ((osd_hw.free_scale_enable[index] - && osd_update_window_axis) - || freescale_update) { - if (!osd_hw.osd_display_debug) - osd_hw.reg[index][DISP_FREESCALE_ENABLE] - .update_func(); - osd_update_window_axis = false; + osd_hw.reg[OSD_COLOR_MODE].update_func(index); + if (!osd_hw.hwc_enable) { + /* geometry and freescale need update with ioctl */ + osd_hw.reg[DISP_GEOMETRY].update_func(index); + if ((osd_hw.free_scale_enable[index] + && osd_update_window_axis) + || freescale_update) { + if (!osd_hw.osd_display_debug) + osd_hw.reg[DISP_FREESCALE_ENABLE] + .update_func(index); + osd_update_window_axis = false; + } } - if ((osd_hw.osd_afbcd[index].enable == DISABLE) - && (osd_enable != osd_hw.enable[index]) + if ((osd_enable != osd_hw.enable[index]) && skip == false) { osd_hw.enable[index] = osd_enable; if (!osd_hw.osd_display_debug) - osd_hw.reg[index][OSD_ENABLE] - .update_func(); + osd_hw.reg[OSD_ENABLE] + .update_func(index); } spin_unlock_irqrestore(&osd_lock, lock_flags); osd_wait_vsync_hw(); } else if (xoffset != osd_hw.pandata[index].x_start || yoffset != osd_hw.pandata[index].y_start - || (use_ext && index == OSD1)) { + || (use_ext /*&& index == OSD1*/)) { spin_lock_irqsave(&osd_lock, lock_flags); - if ((use_ext) && (index == OSD1)) { + if ((use_ext)) { osd_hw.fb_gem[index].canvas_idx = OSD1_CANVAS_INDEX; @@ -2495,7 +2901,7 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) memcpy(&osd_hw.free_dst_data[index], &osd_hw.free_dst_data_backup[index], sizeof(struct pandata_s)); - osd_set_dummy_data(0xff); + osd_set_dummy_data(index, 0xff); osd_log_dbg("switch back dispdata_backup x=%d,x_end=%d,y=%d,y_end=%d\n", osd_hw.dispdata_backup[index].x_start, osd_hw.dispdata_backup[index].x_end, @@ -2504,10 +2910,10 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) osd_hw.color_info[index] = osd_hw.color_backup[index]; - canvas_config(osd_hw.fb_gem[0].canvas_idx, - osd_hw.fb_gem[0].addr, - osd_hw.fb_gem[0].width, - osd_hw.fb_gem[0].height, + canvas_config(osd_hw.fb_gem[index].canvas_idx, + osd_hw.fb_gem[index].addr, + osd_hw.fb_gem[index].width, + osd_hw.fb_gem[index].height, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); use_ext = false; @@ -2523,7 +2929,7 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) osd_hw.pandata[index].y_start += diff_y; osd_hw.pandata[index].y_end += diff_y; } - if (index == OSD1 && + if (/* index == OSD1 && */ osd_hw.osd_afbcd[index].enable == ENABLE) { /* osd_hw.osd_afbcd[index].phy_addr = * (osd_hw.pandata[index].y_start / @@ -2539,36 +2945,33 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) osd_hw.osd_afbcd[index].frame_height]; } if (color_mode) - osd_hw.reg[index][OSD_COLOR_MODE].update_func(); - osd_hw.reg[index][DISP_GEOMETRY].update_func(); + osd_hw.reg[OSD_COLOR_MODE].update_func(index); + osd_hw.reg[DISP_GEOMETRY].update_func(index); if ((osd_hw.free_scale_enable[index] && osd_update_window_axis) || (osd_hw.free_scale_enable[index] && freescale_update)) { if (!osd_hw.osd_display_debug) - osd_hw.reg[index][DISP_FREESCALE_ENABLE] - .update_func(); + osd_hw.reg[DISP_FREESCALE_ENABLE] + .update_func(index); osd_update_window_axis = false; } - if ((osd_hw.osd_afbcd[index].enable == DISABLE) - && (osd_enable != osd_hw.enable[index]) + if ((osd_enable != osd_hw.enable[index]) && skip == false) { osd_hw.enable[index] = osd_enable; if (!osd_hw.osd_display_debug) - osd_hw.reg[index][OSD_ENABLE] - .update_func(); + osd_hw.reg[OSD_ENABLE] + .update_func(index); } spin_unlock_irqrestore(&osd_lock, lock_flags); osd_wait_vsync_hw(); } else if ((osd_enable != osd_hw.enable[index]) && skip == false) { spin_lock_irqsave(&osd_lock, lock_flags); - if (osd_hw.osd_afbcd[index].enable == DISABLE) { - osd_hw.enable[index] = osd_enable; - if (!osd_hw.osd_display_debug) - osd_hw.reg[index][OSD_ENABLE] - .update_func(); - } + osd_hw.enable[index] = osd_enable; + if (!osd_hw.osd_display_debug) + osd_hw.reg[OSD_ENABLE] + .update_func(index); spin_unlock_irqrestore(&osd_lock, lock_flags); osd_wait_vsync_hw(); } @@ -2590,366 +2993,577 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) osd_hw.pandata[index].y_start, osd_hw.pandata[index].y_end); } -#endif - -void osd_pan_display_hw(u32 index, unsigned int xoffset, unsigned int yoffset) -{ - long diff_x, diff_y; - -#if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) - if (index >= 1) #else - if (index >= 2) -#endif - return; - if (xoffset != osd_hw.pandata[index].x_start - || yoffset != osd_hw.pandata[index].y_start) { - diff_x = xoffset - osd_hw.pandata[index].x_start; - diff_y = yoffset - osd_hw.pandata[index].y_start; - osd_hw.pandata[index].x_start += diff_x; - osd_hw.pandata[index].x_end += diff_x; - osd_hw.pandata[index].y_start += diff_y; - osd_hw.pandata[index].y_end += diff_y; - add_to_update_list(index, DISP_GEOMETRY); - if (osd_hw.osd_fps_start) - osd_hw.osd_fps++; - osd_wait_vsync_hw(); - } -#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT - osd_ext_clone_pan(index); -#endif - osd_log_dbg2("offset[%d-%d]x[%d-%d]y[%d-%d]\n", - xoffset, yoffset, - osd_hw.pandata[index].x_start, - osd_hw.pandata[index].x_end, - osd_hw.pandata[index].y_start, - osd_hw.pandata[index].y_end); -} - -void osd_get_info(u32 index, u32 *addr, u32 *width, u32 *height) +static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) { - *addr = osd_hw.fb_gem[index].addr; - *width = osd_hw.fb_gem[index].width; - *height = osd_hw.fb_gem[index].yres; + u32 index = fence_map->fb_index; + u32 ext_addr = fence_map->ext_addr; + u32 width_src, width_dst, height_src, height_dst; + u32 x_start, x_end, y_start, y_end; + bool freescale_update = false; + struct pandata_s freescale_dst[HW_OSD_COUNT]; + void *vaddr = NULL; + + ext_addr = ext_addr + fence_map->byte_stride * fence_map->yoffset; + vaddr = phys_to_virt(ext_addr); + + if (!osd_hw.osd_afbcd[index].enable) { + canvas_config(osd_hw.fb_gem[index].canvas_idx, + ext_addr, + fence_map->byte_stride, + fence_map->height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + } else { + osd_hw.osd_afbcd[index].phy_addr = ext_addr; + osd_hw.osd_afbcd[index].frame_width = + fence_map->width; + osd_hw.osd_afbcd[index].frame_height = + fence_map->height; + if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) { + if (fence_map->width <= 128) + osd_hw.osd_afbcd[index].conv_lbuf_len = 32; + else if (fence_map->width <= 256) + osd_hw.osd_afbcd[index].conv_lbuf_len = 64; + else if (fence_map->width <= 512) + osd_hw.osd_afbcd[index].conv_lbuf_len = 128; + else if (fence_map->width <= 1024) + osd_hw.osd_afbcd[index].conv_lbuf_len = 256; + else if (fence_map->width <= 2048) + osd_hw.osd_afbcd[index].conv_lbuf_len = 512; + else + osd_hw.osd_afbcd[index].conv_lbuf_len = 1024; + } else if (osd_hw.osd_meson_dev.afbc_type + == MALI_AFBC) { + + } + } + + width_dst = osd_hw.free_dst_data_backup[index].x_end - + osd_hw.free_dst_data_backup[index].x_start + 1; + width_src = osd_hw.free_src_data_backup[index].x_end - + osd_hw.free_src_data_backup[index].x_start + 1; + + height_dst = osd_hw.free_dst_data_backup[index].y_end - + osd_hw.free_dst_data_backup[index].y_start + 1; + height_src = osd_hw.free_src_data_backup[index].y_end - + osd_hw.free_src_data_backup[index].y_start + 1; + + osd_hw.screen_base[index] = vaddr; + osd_hw.screen_size[index] = fence_map->byte_stride * fence_map->height; + if (osd_hw.free_scale_enable[index] || + (width_src != width_dst) || + (height_src != height_dst) || + (fence_map->width != fence_map->dst_w) || + (fence_map->height != fence_map->dst_h)) { + osd_hw.free_scale[index].h_enable = 1; + osd_hw.free_scale[index].v_enable = 1; + osd_hw.free_scale_enable[index] = 0x10001; + osd_hw.free_scale_mode[index] = 1; + if (osd_hw.free_scale_enable[index] != + osd_hw.free_scale_enable_backup[index]) { + osd_set_scan_mode(index); + freescale_update = true; + } + + osd_hw.pandata[index].x_start = fence_map->xoffset; + osd_hw.pandata[index].x_end = + fence_map->xoffset + fence_map->width - 1; + osd_hw.pandata[index].y_start = 0; + osd_hw.pandata[index].y_end = fence_map->height - 1; + + freescale_dst[index].x_start = + osd_hw.free_dst_data_backup[index].x_start + + (fence_map->dst_x * width_dst) / width_src; + freescale_dst[index].x_end = + osd_hw.free_dst_data_backup[index].x_start + + ((fence_map->dst_x + fence_map->dst_w) * + width_dst) / width_src - 1; + + freescale_dst[index].y_start = + osd_hw.free_dst_data_backup[index].y_start + + (fence_map->dst_y * height_dst) / height_src; + freescale_dst[index].y_end = + osd_hw.free_dst_data_backup[index].y_start + + ((fence_map->dst_y + fence_map->dst_h) * + height_dst) / height_src - 1; + if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { + x_start = osd_hw.vinfo_width + - freescale_dst[index].x_end - 1; + y_start = osd_hw.vinfo_height + - freescale_dst[index].y_end - 1; + x_end = osd_hw.vinfo_width + - freescale_dst[index].x_start - 1; + y_end = osd_hw.vinfo_height + - freescale_dst[index].y_start - 1; + freescale_dst[index].x_start = x_start; + freescale_dst[index].y_start = y_start; + freescale_dst[index].x_end = x_end; + freescale_dst[index].y_end = y_end; + } else if (osd_hw.osd_reverse[index] == REVERSE_X) { + x_start = osd_hw.vinfo_width + - freescale_dst[index].x_end - 1; + x_end = osd_hw.vinfo_width + - freescale_dst[index].x_start - 1; + freescale_dst[index].x_start = x_start; + freescale_dst[index].x_end = x_end; + + } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { + y_start = osd_hw.vinfo_height + - freescale_dst[index].y_end - 1; + y_end = osd_hw.vinfo_height + - freescale_dst[index].y_start - 1; + freescale_dst[index].y_start = y_start; + freescale_dst[index].y_end = y_end; + } + if (memcmp(&(osd_hw.free_src_data[index]), + &osd_hw.pandata[index], + sizeof(struct pandata_s)) != 0 || + memcmp(&(osd_hw.free_dst_data[index]), + &freescale_dst[index], + sizeof(struct pandata_s)) != 0) { + memcpy(&(osd_hw.free_src_data[index]), + &osd_hw.pandata[index], + sizeof(struct pandata_s)); + memcpy(&(osd_hw.free_dst_data[index]), + &freescale_dst[index], + sizeof(struct pandata_s)); + freescale_update = true; + + if ((height_dst != height_src) || + (width_dst != width_src)) + osd_set_dummy_data(index, 0); + else + osd_set_dummy_data(index, 0xff); + osd_log_dbg("direct pandata x=%d,x_end=%d,y=%d,y_end=%d,width=%d,height=%d\n", + osd_hw.pandata[index].x_start, + osd_hw.pandata[index].x_end, + osd_hw.pandata[index].y_start, + osd_hw.pandata[index].y_end, + fence_map->width, + fence_map->height); + osd_log_dbg("fence_map:xoffset=%d,yoffset=%d\n", + fence_map->xoffset, + fence_map->yoffset); + osd_log_dbg("fence_map:dst_x=%d,dst_y=%d,dst_w=%d,dst_h=%d,byte_stride=%d\n", + fence_map->dst_x, + fence_map->dst_y, + fence_map->dst_w, + fence_map->dst_h, + fence_map->byte_stride); + } + } else { + osd_hw.pandata[index].x_start = 0; + osd_hw.pandata[index].x_end = fence_map->width - 1; + osd_hw.pandata[index].y_start = 0; + osd_hw.pandata[index].y_end = fence_map->height - 1; + + osd_hw.dispdata[index].x_start = fence_map->dst_x; + osd_hw.dispdata[index].x_end = + fence_map->dst_x + fence_map->dst_w - 1; + osd_hw.dispdata[index].y_start = fence_map->dst_y; + osd_hw.dispdata[index].y_end = + fence_map->dst_y + fence_map->dst_h - 1; + if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { + x_start = osd_hw.vinfo_width + - osd_hw.dispdata[index].x_end - 1; + y_start = osd_hw.vinfo_height + - osd_hw.dispdata[index].y_end - 1; + x_end = osd_hw.vinfo_width + - osd_hw.dispdata[index].x_start - 1; + y_end = osd_hw.vinfo_height + - osd_hw.dispdata[index].y_start - 1; + osd_hw.dispdata[index].x_start = x_start; + osd_hw.dispdata[index].y_start = y_start; + osd_hw.dispdata[index].x_end = x_end; + osd_hw.dispdata[index].y_end = y_end; + } else if (osd_hw.osd_reverse[index] == REVERSE_X) { + x_start = osd_hw.vinfo_width + - osd_hw.dispdata[index].x_end - 1; + x_end = osd_hw.vinfo_width + - osd_hw.dispdata[index].x_start - 1; + osd_hw.dispdata[index].x_start = x_start; + osd_hw.dispdata[index].x_end = x_end; + + } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { + y_start = osd_hw.vinfo_height + - osd_hw.dispdata[index].y_end - 1; + y_end = osd_hw.vinfo_height + - osd_hw.dispdata[index].y_start - 1; + osd_hw.dispdata[index].y_start = y_start; + osd_hw.dispdata[index].y_end = y_end; + } + } + fence_map->ext_addr = ext_addr; + return freescale_update; } -static void osd1_update_disp_scale_enable(void) -{ - if (osd_hw.scale[OSD1].h_enable) - VSYNCOSD_SET_MPEG_REG_MASK(VIU_OSD1_BLK0_CFG_W0, 3 << 12); - else - VSYNCOSD_CLR_MPEG_REG_MASK(VIU_OSD1_BLK0_CFG_W0, 3 << 12); - if (osd_hw.scan_mode[OSD1] != SCAN_MODE_INTERLACE) { - if (osd_hw.scale[OSD1].v_enable) - VSYNCOSD_SET_MPEG_REG_MASK( - VIU_OSD1_BLK0_CFG_W0, 1 << 14); +static void osd_pan_display_fence(struct osd_fence_map_s *fence_map) +{ + s32 ret = 1; + long diff_x, diff_y; + u32 index = fence_map->fb_index; + u32 xoffset = fence_map->xoffset; + u32 yoffset = fence_map->yoffset; + const struct color_bit_define_s *color = NULL; + bool color_mode = false; + bool freescale_update = false; + u32 osd_enable = 0; + bool skip = false; + const struct vinfo_s *vinfo; + + if (index >= 2) + return; + if (timeline_created) { /* out fence created success. */ + ret = osd_wait_buf_ready(fence_map); + if (ret < 0) + osd_log_dbg("fence wait ret %d\n", ret); + } + if (ret) { + osd_hw.buffer_alloc[index] = 1; + if (osd_hw.osd_fps_start) + osd_hw.osd_fps++; + if (fence_map->op == 0xffffffff) + skip = true; + else + osd_enable = (fence_map->op & 1) ? DISABLE : ENABLE; + /* need update via direct render interface later */ + fence_map->afbc_en = osd_hw.osd_afbcd[OSD1].enable; + vinfo = get_current_vinfo(); + if (vinfo) { + osd_hw.vinfo_width = vinfo->width; + osd_hw.vinfo_height = vinfo->height; + } + if (fence_map->ext_addr && fence_map->width + && fence_map->height) { + spin_lock_irqsave(&osd_lock, lock_flags); + use_ext = true; + if (!fence_map->afbc_en) { + osd_hw.fb_gem[index].canvas_idx = + osd_extra_idx[index][ext_canvas_id]; + ext_canvas_id ^= 1; + osd_hw.osd_afbcd[index].enable = DISABLE; + } else + osd_hw.osd_afbcd[index].enable = ENABLE; + + color = convert_hal_format(fence_map->format); + if (color) { + osd_hw.color_info[index] = color; + } else + osd_log_err("fence color format error %d\n", + fence_map->format); + + if (DIRECT_COMPOSE_MODE == + fence_map->compose_type) + freescale_update = + osd_direct_compose_pan_display(fence_map); + else if (GE2D_COMPOSE_MODE == + fence_map->compose_type) { + freescale_update = + osd_ge2d_compose_pan_display(fence_map); + if (freescale_update) + osd_set_dummy_data(index, 0xff); + } + + osd_hw.reg[OSD_COLOR_MODE].update_func(index); + osd_hw.reg[DISP_GEOMETRY].update_func(index); + if ((osd_hw.free_scale_enable[index] + && osd_update_window_axis) + || freescale_update) { + if (!osd_hw.osd_display_debug) + osd_hw.reg[DISP_FREESCALE_ENABLE] + .update_func(index); + osd_update_window_axis = false; + } + if ((osd_enable != osd_hw.enable[index]) + && skip == false) { + osd_hw.enable[index] = osd_enable; + if (!osd_hw.osd_display_debug) + osd_hw.reg[OSD_ENABLE] + .update_func(index); + } + spin_unlock_irqrestore(&osd_lock, lock_flags); + osd_wait_vsync_hw(); + } else if (xoffset != osd_hw.pandata[index].x_start + || yoffset != osd_hw.pandata[index].y_start + || (use_ext && index == OSD1)) { + spin_lock_irqsave(&osd_lock, lock_flags); + if ((use_ext)) { + osd_hw.fb_gem[index].canvas_idx = + OSD1_CANVAS_INDEX; + + osd_hw.pandata[index].x_start = xoffset; + osd_hw.pandata[index].x_end = xoffset + + osd_hw.fb_gem[index].xres - 1; + osd_hw.pandata[index].y_start = yoffset; + osd_hw.pandata[index].y_end = yoffset + + osd_hw.fb_gem[index].yres - 1; + osd_hw.screen_base[index] = + osd_hw.screen_base_backup[index]; + osd_hw.screen_size[index] = + osd_hw.screen_size_backup[index]; + + osd_hw.dispdata[index].x_start = + osd_hw.dispdata_backup[index].x_start; + osd_hw.dispdata[index].x_end = + osd_hw.dispdata_backup[index].x_end; + osd_hw.dispdata[index].y_start = + osd_hw.dispdata_backup[index].y_start; + osd_hw.dispdata[index].y_end = + osd_hw.dispdata_backup[index].y_end; + + /* restore free_scale info */ + osd_hw.free_scale[index].h_enable = + osd_hw.free_scale_backup[index].h_enable; + osd_hw.free_scale[index].v_enable = + osd_hw.free_scale_backup[index].v_enable; + osd_hw.free_scale_enable[index] = + osd_hw.free_scale_enable_backup[index]; + osd_hw.free_scale_mode[index] = + osd_hw.free_scale_mode_backup[index]; + + memcpy(&osd_hw.free_src_data[index], + &osd_hw.free_src_data_backup[index], + sizeof(struct pandata_s)); + memcpy(&osd_hw.free_dst_data[index], + &osd_hw.free_dst_data_backup[index], + sizeof(struct pandata_s)); + osd_set_dummy_data(index, 0xff); + osd_log_dbg("switch back dispdata_backup x=%d,x_end=%d,y=%d,y_end=%d\n", + osd_hw.dispdata_backup[index].x_start, + osd_hw.dispdata_backup[index].x_end, + osd_hw.dispdata_backup[index].y_start, + osd_hw.dispdata_backup[index].y_end); + + osd_hw.color_info[index] = + osd_hw.color_backup[index]; + canvas_config(osd_hw.fb_gem[index].canvas_idx, + osd_hw.fb_gem[index].addr, + osd_hw.fb_gem[index].width, + osd_hw.fb_gem[index].height, + CANVAS_ADDR_NOWRAP, + CANVAS_BLKMODE_LINEAR); + use_ext = false; + color_mode = true; + freescale_update = true; + } else { + diff_x = xoffset - + osd_hw.pandata[index].x_start; + diff_y = yoffset - + osd_hw.pandata[index].y_start; + osd_hw.pandata[index].x_start += diff_x; + osd_hw.pandata[index].x_end += diff_x; + osd_hw.pandata[index].y_start += diff_y; + osd_hw.pandata[index].y_end += diff_y; + } + if (/* index == OSD1 && */ + osd_hw.osd_afbcd[index].enable == ENABLE) { + /* osd_hw.osd_afbcd[index].phy_addr = + * (osd_hw.pandata[index].y_start / + * osd_hw.osd_afbcd[index].frame_height) * + * osd_hw.osd_afbcd[index].frame_height * + * osd_hw.fb_gem[index].width; + * osd_hw.osd_afbcd[index].phy_addr += + * osd_hw.fb_gem[index].addr; + */ + osd_hw.osd_afbcd[index].phy_addr = + osd_hw.osd_afbcd[index].addr + [osd_hw.pandata[index].y_start / + osd_hw.osd_afbcd[index].frame_height]; + } + if (color_mode) + osd_hw.reg[OSD_COLOR_MODE].update_func(index); + osd_hw.reg[DISP_GEOMETRY].update_func(index); + if ((osd_hw.free_scale_enable[index] + && osd_update_window_axis) + || (osd_hw.free_scale_enable[index] + && freescale_update)) { + if (!osd_hw.osd_display_debug) + osd_hw.reg[DISP_FREESCALE_ENABLE] + .update_func(index); + osd_update_window_axis = false; + } + if ((osd_enable != osd_hw.enable[index]) + && skip == false) { + osd_hw.enable[index] = osd_enable; + if (!osd_hw.osd_display_debug) + osd_hw.reg[OSD_ENABLE] + .update_func(index); + } + spin_unlock_irqrestore(&osd_lock, lock_flags); + osd_wait_vsync_hw(); + } else if ((osd_enable != osd_hw.enable[index]) + && skip == false) { + spin_lock_irqsave(&osd_lock, lock_flags); + osd_hw.enable[index] = osd_enable; + if (!osd_hw.osd_display_debug) + osd_hw.reg[OSD_ENABLE] + .update_func(index); + spin_unlock_irqrestore(&osd_lock, lock_flags); + osd_wait_vsync_hw(); + } + } + if (timeline_created) { + if (ret) + osd_timeline_increase(); else - VSYNCOSD_CLR_MPEG_REG_MASK( - VIU_OSD1_BLK0_CFG_W0, 1 << 14); + osd_log_err("------NOT signal out_fence ERROR\n"); } - remove_from_update_list(OSD1, DISP_SCALE_ENABLE); +#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT + if (ret) + osd_ext_clone_pan(index); +#endif + osd_log_dbg2("offset[%d-%d]x[%d-%d]y[%d-%d]\n", + xoffset, yoffset, + osd_hw.pandata[index].x_start, + osd_hw.pandata[index].x_end, + osd_hw.pandata[index].y_start, + osd_hw.pandata[index].y_end); } -static void osd2_update_disp_scale_enable(void) -{ - if (osd_hw.scale[OSD2].h_enable) { -#if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) - VSYNCOSD_CLR_MPEG_REG_MASK(VIU_OSD2_BLK0_CFG_W0, 3 << 12); -#else - VSYNCOSD_SET_MPEG_REG_MASK(VIU_OSD2_BLK0_CFG_W0, 3 << 12); #endif - } else - VSYNCOSD_CLR_MPEG_REG_MASK(VIU_OSD2_BLK0_CFG_W0, 3 << 12); - if (osd_hw.scan_mode[OSD2] != SCAN_MODE_INTERLACE) { - if (osd_hw.scale[OSD2].v_enable) { -#if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) - VSYNCOSD_CLR_MPEG_REG_MASK(VIU_OSD2_BLK0_CFG_W0, - 1 << 14); -#else - VSYNCOSD_SET_MPEG_REG_MASK(VIU_OSD2_BLK0_CFG_W0, - 1 << 14); + #endif - } else - VSYNCOSD_CLR_MPEG_REG_MASK(VIU_OSD2_BLK0_CFG_W0, - 1 << 14); - } - remove_from_update_list(OSD2, DISP_SCALE_ENABLE); -} -#ifdef CONFIG_AMLOGIC_SUPERSCALER -static void osd_super_scale_enable(u32 index) +void osd_pan_display_hw(u32 index, unsigned int xoffset, unsigned int yoffset) { - u32 data32 = 0x0; - u32 src_w = 0, src_h = 0; - - osd_super_scale_mem_power_on(); + long diff_x, diff_y; - /* enable osd scaler path */ - if (index == OSD1) - data32 = 8; - else { - data32 = 1; /* select osd2 input */ - data32 |= 1 << 3; /* enable osd scaler path */ - } - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SC_CTRL0, data32); - /* enable osd super scaler */ - data32 = (1 << 0) | (1 << 1) | (1 << 2); - VSYNCOSD_WR_MPEG_REG(OSDSR_CTRL_MODE, data32); - /* config osd super scaler setting */ - VSYNCOSD_WR_MPEG_REG(OSDSR_UK_GRAD2DDIAG_LIMIT, 0xffffff); - VSYNCOSD_WR_MPEG_REG(OSDSR_UK_GRAD2DADJA_LIMIT, 0xffffff); - VSYNCOSD_WR_MPEG_REG(OSDSR_UK_BST_GAIN, 0x7a7a3a50); - /* config osd super scaler input size */ - src_w = osd_hw.free_src_data[OSD1].x_end - - osd_hw.free_src_data[OSD1].x_start + 1; - src_h = osd_hw.free_src_data[OSD1].y_end - - osd_hw.free_src_data[OSD1].y_start + 1; - data32 = (src_w & 0x1fff) | (src_h & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(OSDSR_HV_SIZEIN, data32); - /* config osd super scaler output size */ - data32 = ((osd_hw.free_dst_data[index].x_end & 0xfff) | - (osd_hw.free_dst_data[index].x_start & 0xfff) << 16); - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCO_H_START_END, data32); - data32 = ((osd_hw.free_dst_data[index].y_end & 0xfff) | - (osd_hw.free_dst_data[index].y_start & 0xfff) << 16); - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCO_V_START_END, data32); -} - -static void osd_super_scale_disable(void) -{ - /* disable osd scaler path */ - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SC_CTRL0, 0); - /* disable osd super scaler */ - VSYNCOSD_WR_MPEG_REG(OSDSR_HV_SIZEIN, 0); - VSYNCOSD_WR_MPEG_REG(OSDSR_CTRL_MODE, 0); - osd_super_scale_mem_power_off(); -} + if (index >= HW_OSD_COUNT) + return; + if (xoffset != osd_hw.pandata[index].x_start + || yoffset != osd_hw.pandata[index].y_start) { + diff_x = xoffset - osd_hw.pandata[index].x_start; + diff_y = yoffset - osd_hw.pandata[index].y_start; + osd_hw.pandata[index].x_start += diff_x; + osd_hw.pandata[index].x_end += diff_x; + osd_hw.pandata[index].y_start += diff_y; + osd_hw.pandata[index].y_end += diff_y; + add_to_update_list(index, DISP_GEOMETRY); + if (osd_hw.osd_fps_start) + osd_hw.osd_fps++; + osd_wait_vsync_hw(); + } +#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT + osd_ext_clone_pan(index); #endif -static void osd_set_dummy_data(u32 alpha) -{ - if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SC_DUMMY_DATA, 0x00202000 | alpha); - else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SC_DUMMY_DATA, alpha); - else - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SC_DUMMY_DATA, 0x00808000 | alpha); + osd_log_dbg2("offset[%d-%d]x[%d-%d]y[%d-%d]\n", + xoffset, yoffset, + osd_hw.pandata[index].x_start, + osd_hw.pandata[index].x_end, + osd_hw.pandata[index].y_start, + osd_hw.pandata[index].y_end); } -static void osd1_update_disp_freescale_enable(void) -{ - int hf_phase_step, vf_phase_step; - int src_w, src_h, dst_w, dst_h; - int bot_ini_phase; - int vsc_ini_rcv_num, vsc_ini_rpt_p0_num; - int vsc_bot_rcv_num = 0, vsc_bot_rpt_p0_num = 0; - int hsc_ini_rcv_num, hsc_ini_rpt_p0_num; - int hf_bank_len = 4; - int vf_bank_len = 0; - u32 data32 = 0x0; - - if (osd_hw.scale_workaround) - vf_bank_len = 2; - else - vf_bank_len = 4; - if (osd_hw.bot_type == 1) { - vsc_bot_rcv_num = 4; - vsc_bot_rpt_p0_num = 1; - } else if (osd_hw.bot_type == 2) { - vsc_bot_rcv_num = 6; - vsc_bot_rpt_p0_num = 2; - } else if (osd_hw.bot_type == 3) { - vsc_bot_rcv_num = 8; - vsc_bot_rpt_p0_num = 3; - } - hsc_ini_rcv_num = hf_bank_len; - vsc_ini_rcv_num = vf_bank_len; - hsc_ini_rpt_p0_num = hf_bank_len / 2 - 1; - vsc_ini_rpt_p0_num = - (vf_bank_len / 2 - 1) > 0 ? (vf_bank_len / 2 - 1) : 0; - src_w = osd_hw.free_src_data[OSD1].x_end - - osd_hw.free_src_data[OSD1].x_start + 1; - src_h = osd_hw.free_src_data[OSD1].y_end - - osd_hw.free_src_data[OSD1].y_start + 1; - dst_w = osd_hw.free_dst_data[OSD1].x_end - - osd_hw.free_dst_data[OSD1].x_start + 1; - dst_h = osd_hw.free_dst_data[OSD1].y_end - - osd_hw.free_dst_data[OSD1].y_start + 1; - #ifdef CONFIG_AMLOGIC_SUPERSCALER - /* super scaler mode */ - if (osd_hw.free_scale_mode[OSD1] & 0x2) { - if (osd_hw.free_scale_enable[OSD1]) - osd_super_scale_enable(OSD1); - else - osd_super_scale_disable(); - remove_from_update_list(OSD1, DISP_FREESCALE_ENABLE); - return; - } - #endif - data32 = 0x0; - if (osd_hw.free_scale_enable[OSD1]) { - /* enable osd scaler */ - if (osd_hw.free_scale_mode[OSD1] & 0x1) { - data32 |= 1 << 2; /* enable osd scaler */ - data32 |= 1 << 3; /* enable osd scaler path */ - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SC_CTRL0, data32); - } - } else { - /* disable osd scaler path */ - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SC_CTRL0, 0); - } - hf_phase_step = (src_w << 18) / dst_w; - hf_phase_step = (hf_phase_step << 6); - vf_phase_step = (src_h << 20) / dst_h; - if (osd_hw.field_out_en) /* interface output */ - bot_ini_phase = ((vf_phase_step / 2) >> 4); - else - bot_ini_phase = 0; - vf_phase_step = (vf_phase_step << 4); - /* config osd scaler in/out hv size */ - data32 = 0x0; - if (osd_hw.free_scale_enable[OSD1]) { - data32 = (((src_h - 1) & 0x1fff) - | ((src_w - 1) & 0x1fff) << 16); - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCI_WH_M1, data32); - data32 = ((osd_hw.free_dst_data[OSD1].x_end & 0xfff) | - (osd_hw.free_dst_data[OSD1].x_start & 0xfff) << 16); - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCO_H_START_END, data32); - data32 = ((osd_hw.free_dst_data[OSD1].y_end & 0xfff) | - (osd_hw.free_dst_data[OSD1].y_start & 0xfff) << 16); - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCO_V_START_END, data32); - } - data32 = 0x0; - if (osd_hw.free_scale[OSD1].v_enable) { - data32 |= (vf_bank_len & 0x7) - | ((vsc_ini_rcv_num & 0xf) << 3) - | ((vsc_ini_rpt_p0_num & 0x3) << 8); - if (osd_hw.field_out_en) - data32 |= ((vsc_bot_rcv_num & 0xf) << 11) - | ((vsc_bot_rpt_p0_num & 0x3) << 16) - | (1 << 23); - if (osd_hw.scale_workaround) - data32 |= 1 << 21; - data32 |= 1 << 24; - } - VSYNCOSD_WR_MPEG_REG(VPP_OSD_VSC_CTRL0, data32); - data32 = 0x0; - if (osd_hw.free_scale[OSD1].h_enable) { - data32 |= (hf_bank_len & 0x7) - | ((hsc_ini_rcv_num & 0xf) << 3) - | ((hsc_ini_rpt_p0_num & 0x3) << 8); - data32 |= 1 << 22; - } - VSYNCOSD_WR_MPEG_REG(VPP_OSD_HSC_CTRL0, data32); - data32 = 0x0; - if (osd_hw.free_scale_enable[OSD1]) { - data32 |= (bot_ini_phase & 0xffff) << 16; - VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_PHASE_STEP, - hf_phase_step, 0, 28); - VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_INI_PHASE, 0, 0, 16); - VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_PHASE_STEP, - vf_phase_step, 0, 28); - VSYNCOSD_WR_MPEG_REG(VPP_OSD_VSC_INI_PHASE, data32); - } - remove_from_update_list(OSD1, DISP_FREESCALE_ENABLE); +void osd_get_info(u32 index, u32 *addr, u32 *width, u32 *height) +{ + *addr = osd_hw.fb_gem[index].addr; + *width = osd_hw.fb_gem[index].width; + *height = osd_hw.fb_gem[index].yres; } -static void osd1_update_coef(void) +static void osd_update_disp_scale_enable(u32 index) { - int i; - bool need_update_coef = false; - int hf_coef_wren = 1; - int vf_coef_wren = 1; - int *hf_coef, *vf_coef; + u32 osd2_cursor = 0; + struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index]; - if (osd_hw.scale_workaround) { - if (use_v_filter_mode != 3) { - use_v_filter_mode = 3; - need_update_coef = true; - } else - need_update_coef = false; - } else { - if (use_v_filter_mode != osd_v_filter_mode) { - use_v_filter_mode = osd_v_filter_mode; - need_update_coef = true; - } else - need_update_coef = false; - } - if (need_update_coef) { - vf_coef = filter_table[use_v_filter_mode]; - if (vf_coef_wren) { - osd_reg_set_bits(VPP_OSD_SCALE_COEF_IDX, 0x0000, 0, 9); - for (i = 0; i < 33; i++) - osd_reg_write(VPP_OSD_SCALE_COEF, vf_coef[i]); - } - } - need_update_coef = false; - if (use_h_filter_mode != osd_h_filter_mode) { - use_h_filter_mode = osd_h_filter_mode; - need_update_coef = true; - } - hf_coef = filter_table[use_h_filter_mode]; - if (need_update_coef) { - if (hf_coef_wren) { - osd_reg_set_bits(VPP_OSD_SCALE_COEF_IDX, 0x0100, 0, 9); - for (i = 0; i < 33; i++) - osd_reg_write(VPP_OSD_SCALE_COEF, hf_coef[i]); + if (osd_hw.hw_cursor_en) + osd2_cursor = 1; + + if (osd_hw.scale[index].h_enable) { + VSYNCOSD_SET_MPEG_REG_MASK( + osd_reg->osd_blk0_cfg_w0, 3 << 12); + if ((index == OSD2) && osd2_cursor) { + VSYNCOSD_CLR_MPEG_REG_MASK( + osd_reg->osd_blk0_cfg_w0, 3 << 12); } + } else + VSYNCOSD_CLR_MPEG_REG_MASK( + osd_reg->osd_blk0_cfg_w0, 3 << 12); + + if (osd_hw.scan_mode[index] != SCAN_MODE_INTERLACE) { + if (osd_hw.scale[index].v_enable) { + VSYNCOSD_SET_MPEG_REG_MASK( + osd_reg->osd_blk0_cfg_w0, 1 << 14); + if ((index == OSD2) && osd2_cursor) { + VSYNCOSD_CLR_MPEG_REG_MASK( + osd_reg->osd_blk0_cfg_w0, 1 << 14); + } + } else + VSYNCOSD_CLR_MPEG_REG_MASK( + osd_reg->osd_blk0_cfg_w0, 1 << 14); } - remove_from_update_list(OSD1, OSD_FREESCALE_COEF); + remove_from_update_list(index, DISP_SCALE_ENABLE); +} + +static void osd_set_dummy_data(u32 index, u32 alpha) +{ + VSYNCOSD_WR_MPEG_REG(hw_osd_reg_array[index].osd_sc_dummy_data, + osd_hw.osd_meson_dev.dummy_data | alpha); } -static void osd2_update_disp_freescale_enable(void) +static void osd_update_disp_freescale_enable(u32 index) { int hf_phase_step, vf_phase_step; int src_w, src_h, dst_w, dst_h; int bot_ini_phase; int vsc_ini_rcv_num, vsc_ini_rpt_p0_num; - int vsc_bot_rcv_num = 6, vsc_bot_rpt_p0_num = 2; + int vsc_bot_rcv_num = 0, vsc_bot_rpt_p0_num = 0; int hsc_ini_rcv_num, hsc_ini_rpt_p0_num; int hf_bank_len = 4; int vf_bank_len = 4; + struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index]; u32 data32 = 0x0; if (osd_hw.scale_workaround) vf_bank_len = 2; + else + vf_bank_len = 4; + + if (osd_hw.bot_type == 1) { + vsc_bot_rcv_num = 4; + vsc_bot_rpt_p0_num = 1; + } else if (osd_hw.bot_type == 2) { + vsc_bot_rcv_num = 6; + vsc_bot_rpt_p0_num = 2; + } else if (osd_hw.bot_type == 3) { + vsc_bot_rcv_num = 8; + vsc_bot_rpt_p0_num = 3; + } + hsc_ini_rcv_num = hf_bank_len; vsc_ini_rcv_num = vf_bank_len; hsc_ini_rpt_p0_num = hf_bank_len / 2 - 1; vsc_ini_rpt_p0_num = (vf_bank_len / 2 - 1) > 0 ? (vf_bank_len / 2 - 1) : 0; - src_w = osd_hw.free_src_data[OSD2].x_end - - osd_hw.free_src_data[OSD2].x_start + 1; - src_h = osd_hw.free_src_data[OSD2].y_end - - osd_hw.free_src_data[OSD2].y_start + 1; - dst_w = osd_hw.free_dst_data[OSD2].x_end - - osd_hw.free_dst_data[OSD2].x_start + 1; - dst_h = osd_hw.free_dst_data[OSD2].y_end - - osd_hw.free_dst_data[OSD2].y_start + 1; - #ifdef CONFIG_AMLOGIC_SUPERSCALER - /* super scaler mode */ - if (osd_hw.free_scale_mode[OSD2] & 0x2) { - if (osd_hw.free_scale_enable[OSD2]) - osd_super_scale_enable(OSD2); - else - osd_super_scale_disable(); - remove_from_update_list(OSD2, DISP_FREESCALE_ENABLE); - return; - #endif + src_w = osd_hw.free_src_data[index].x_end - + osd_hw.free_src_data[index].x_start + 1; + src_h = osd_hw.free_src_data[index].y_end - + osd_hw.free_src_data[index].y_start + 1; + dst_w = osd_hw.free_dst_data[index].x_end - + osd_hw.free_dst_data[index].x_start + 1; + dst_h = osd_hw.free_dst_data[index].y_end - + osd_hw.free_dst_data[index].y_start + 1; + /* config osd sc control reg */ data32 = 0x0; - if (osd_hw.free_scale_enable[OSD2]) { + if (osd_hw.free_scale_enable[index]) { /* enable osd scaler */ - if (osd_hw.free_scale_mode[OSD2] & 0x1) { - data32 |= 1; /* select osd2 input */ + if (osd_hw.free_scale_mode[index] & 0x1) { + /* Todo: */ + if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) + data32 |= index; /* select osd1/2 input */ + /* Todo: vd alpha */ data32 |= 1 << 2; /* enable osd scaler */ data32 |= 1 << 3; /* enable osd scaler path */ - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SC_CTRL0, data32); + VSYNCOSD_WR_MPEG_REG( + osd_reg->osd_sc_ctrl0, data32); } } else { /* disable osd scaler path */ - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SC_CTRL0, 0); + VSYNCOSD_WR_MPEG_REG(osd_reg->osd_sc_ctrl0, 0); } + hf_phase_step = (src_w << 18) / dst_w; hf_phase_step = (hf_phase_step << 6); vf_phase_step = (src_h << 20) / dst_h; @@ -2958,33 +3572,27 @@ static void osd2_update_disp_freescale_enable(void) else bot_ini_phase = 0; vf_phase_step = (vf_phase_step << 4); + /* config osd scaler in/out hv size */ data32 = 0x0; - if (osd_hw.free_scale_enable[OSD2]) { + if (osd_hw.free_scale_enable[index]) { data32 = (((src_h - 1) & 0x1fff) | ((src_w - 1) & 0x1fff) << 16); - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCI_WH_M1, data32); - data32 = ((osd_hw.free_dst_data[OSD2].x_end & 0xfff) | - (osd_hw.free_dst_data[OSD2].x_start & 0xfff) << 16); - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCO_H_START_END, data32); - data32 = ((osd_hw.free_dst_data[OSD2].y_end & 0xfff) | - (osd_hw.free_dst_data[OSD2].y_start & 0xfff) << 16); - VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCO_V_START_END, data32); + VSYNCOSD_WR_MPEG_REG(osd_reg->osd_sci_wh_m1, data32); + data32 = ((osd_hw.free_dst_data[index].x_end & 0xfff) | + (osd_hw.free_dst_data[index].x_start & 0xfff) << 16); + VSYNCOSD_WR_MPEG_REG(osd_reg->osd_sco_h_start_end, data32); + data32 = ((osd_hw.free_dst_data[index].y_end & 0xfff) | + (osd_hw.free_dst_data[index].y_start & 0xfff) << 16); + VSYNCOSD_WR_MPEG_REG(osd_reg->osd_sco_v_start_end, data32); } + data32 = 0x0; - if (osd_hw.free_scale[OSD2].h_enable) { - data32 |= (hf_bank_len & 0x7) - | ((hsc_ini_rcv_num & 0xf) << 3) - | ((hsc_ini_rpt_p0_num & 0x3) << 8); - data32 |= 1 << 22; - } - VSYNCOSD_WR_MPEG_REG(VPP_OSD_HSC_CTRL0, data32); - data32 = 0x0; - if (osd_hw.free_scale[OSD2].v_enable) { + if (osd_hw.free_scale[index].v_enable) { data32 |= (vf_bank_len & 0x7) | ((vsc_ini_rcv_num & 0xf) << 3) | ((vsc_ini_rpt_p0_num & 0x3) << 8); - if (osd_hw.field_out_en) /* interface output */ + if (osd_hw.field_out_en) data32 |= ((vsc_bot_rcv_num & 0xf) << 11) | ((vsc_bot_rpt_p0_num & 0x3) << 16) | (1 << 23); @@ -2992,28 +3600,53 @@ static void osd2_update_disp_freescale_enable(void) data32 |= 1 << 21; data32 |= 1 << 24; } - VSYNCOSD_WR_MPEG_REG(VPP_OSD_VSC_CTRL0, data32); + VSYNCOSD_WR_MPEG_REG(osd_reg->osd_vsc_ctrl0, data32); data32 = 0x0; - if (osd_hw.free_scale_enable[OSD2]) { + if (osd_hw.free_scale[index].h_enable) { + data32 |= (hf_bank_len & 0x7) + | ((hsc_ini_rcv_num & 0xf) << 3) + | ((hsc_ini_rpt_p0_num & 0x3) << 8); + data32 |= 1 << 22; + } + VSYNCOSD_WR_MPEG_REG(osd_reg->osd_hsc_ctrl0, data32); + + data32 = 0x0; + if (osd_hw.free_scale_enable[index]) { data32 |= (bot_ini_phase & 0xffff) << 16; - VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_PHASE_STEP, - hf_phase_step, 0, 28); - VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_INI_PHASE, 0, 0, 16); - VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_PHASE_STEP, - vf_phase_step, 0, 28); - VSYNCOSD_WR_MPEG_REG(VPP_OSD_VSC_INI_PHASE, data32); + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_hsc_phase_step, + hf_phase_step, 0, 28); + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_hsc_init_phase, 0, 0, 16); + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_vsc_phase_step, + vf_phase_step, 0, 28); + VSYNCOSD_WR_MPEG_REG( + osd_reg->osd_vsc_init_phase, data32); + } + osd_log_dbg("osd_hw.hwc_enable=%x\n", osd_hw.hwc_enable); + if ((osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) + && (!osd_hw.hwc_enable)) { + osd_setting_blending_scope(index); + vpp_blend_setting_default(index); } - remove_from_update_list(OSD2, DISP_FREESCALE_ENABLE); + + remove_from_update_list(index, DISP_FREESCALE_ENABLE); } -static void osd2_update_coef(void) + +static void osd_update_coef(u32 index) { int i; bool need_update_coef = false; - int hf_coef_wren = 1; - int vf_coef_wren = 1; int *hf_coef, *vf_coef; + int use_v_filter_mode, use_h_filter_mode; + int OSD_SCALE_COEF_IDX, OSD_SCALE_COEF; + OSD_SCALE_COEF_IDX = hw_osd_reg_array[index].osd_scale_coef_idx; + OSD_SCALE_COEF = hw_osd_reg_array[index].osd_scale_coef; + use_v_filter_mode = osd_hw.use_v_filter_mode[index]; + use_h_filter_mode = osd_hw.use_h_filter_mode[index]; if (osd_hw.scale_workaround) { if (use_v_filter_mode != 3) { use_v_filter_mode = 3; @@ -3027,13 +3660,13 @@ static void osd2_update_coef(void) } else need_update_coef = false; } - vf_coef = filter_table[use_v_filter_mode]; + osd_log_dbg("osd vf scaler need_update_coef=%d\n", + need_update_coef); if (need_update_coef) { - if (vf_coef_wren) { - osd_reg_set_bits(VPP_OSD_SCALE_COEF_IDX, 0x0000, 0, 9); - for (i = 0; i < 33; i++) - osd_reg_write(VPP_OSD_SCALE_COEF, vf_coef[i]); - } + vf_coef = filter_table[use_v_filter_mode]; + osd_reg_set_bits(OSD_SCALE_COEF_IDX, 0x0000, 0, 9); + for (i = 0; i < 33; i++) + osd_reg_write(OSD_SCALE_COEF, vf_coef[i]); } need_update_coef = false; if (use_h_filter_mode != osd_h_filter_mode) { @@ -3041,602 +3674,1681 @@ static void osd2_update_coef(void) need_update_coef = true; } hf_coef = filter_table[use_h_filter_mode]; + osd_log_dbg("osd hf scaler need_update_coef=%d\n", + need_update_coef); if (need_update_coef) { - if (hf_coef_wren) { - osd_reg_set_bits(VPP_OSD_SCALE_COEF_IDX, 0x0100, 0, 9); - for (i = 0; i < 33; i++) - osd_reg_write(VPP_OSD_SCALE_COEF, hf_coef[i]); - } + osd_reg_set_bits(OSD_SCALE_COEF_IDX, 0x0100, 0, 9); + for (i = 0; i < 33; i++) + osd_reg_write(OSD_SCALE_COEF, hf_coef[i]); + } + osd_hw.use_v_filter_mode[index] = use_v_filter_mode; + osd_hw.use_h_filter_mode[index] = use_h_filter_mode; + + remove_from_update_list(index, OSD_FREESCALE_COEF); +} + +static int afbc_pix_format(u32 fmt_mode) +{ + u32 pix_format = RGBA8888; + + switch (fmt_mode) { + case COLOR_INDEX_YUV_422: + pix_format = YUV422_8B; + break; + case COLOR_INDEX_16_565: + pix_format = RGB565; + break; + case COLOR_INDEX_16_1555_A: + pix_format = RGBA5551; + break; + case COLOR_INDEX_16_4444_R: + case COLOR_INDEX_16_4444_A: + pix_format = RGBA4444; + break; + case COLOR_INDEX_32_BGRX: + case COLOR_INDEX_32_XBGR: + case COLOR_INDEX_32_RGBX: + case COLOR_INDEX_32_XRGB: + case COLOR_INDEX_32_BGRA: + case COLOR_INDEX_32_ABGR: + case COLOR_INDEX_32_RGBA: + case COLOR_INDEX_32_ARGB: + pix_format = RGBA8888; + break; + case COLOR_INDEX_24_888_B: + case COLOR_INDEX_24_RGB: + pix_format = RGB888; + break; + default: + osd_log_err("unsupport fmt:%x\n", fmt_mode); + break; } - remove_from_update_list(OSD2, OSD_FREESCALE_COEF); + return pix_format; } -static void osd1_update_color_mode(void) + +static void osd_update_color_mode(u32 index) { u32 data32 = 0; + struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index]; + + if (osd_hw.color_info[index] != NULL) { + enum color_index_e idx = + osd_hw.color_info[index]->color_index; - if (osd_hw.color_info[OSD1] != NULL) { - data32 = (osd_hw.scan_mode[OSD1] == + data32 = (osd_hw.scan_mode[index] == SCAN_MODE_INTERLACE) ? 2 : 0; - data32 |= VSYNCOSD_RD_MPEG_REG(VIU_OSD1_BLK0_CFG_W0) + data32 |= VSYNCOSD_RD_MPEG_REG( + osd_reg->osd_blk0_cfg_w0) & 0x30007040; - data32 |= osd_hw.fb_gem[OSD1].canvas_idx << 16; - /* if (!osd_hw.rotate[OSD1].on_off) */ - data32 |= OSD_DATA_LITTLE_ENDIAN << 15; - data32 |= osd_hw.color_info[OSD1]->hw_colormat << 2; - if (get_cpu_type() < MESON_CPU_MAJOR_ID_GXTVBB) { - if (osd_hw.color_info[OSD1]->color_index < + data32 |= osd_hw.fb_gem[index].canvas_idx << 16; + if ((osd_hw.osd_afbcd[index].enable) && + (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC)) + data32 |= OSD_DATA_BIG_ENDIAN << 15; + else + data32 |= OSD_DATA_LITTLE_ENDIAN << 15; + data32 |= osd_hw.color_info[index]->hw_colormat << 2; + + /* Todo: what about osd3 */ + if ((osd_hw.osd_meson_dev.cpu_id < __MESON_CPU_MAJOR_ID_GXTVBB) + && (index == OSD1)) { + if (osd_hw.color_info[index]->color_index < + COLOR_INDEX_YUV_422) + data32 |= 1 << 7; /* yuv enable */ + } + if ((osd_hw.osd_meson_dev.cpu_id != __MESON_CPU_MAJOR_ID_GXTVBB) + && (index == OSD2)) { + if (osd_hw.color_info[index]->color_index < COLOR_INDEX_YUV_422) data32 |= 1 << 7; /* yuv enable */ } /* osd_blk_mode */ - data32 |= osd_hw.color_info[OSD1]->hw_blkmode << 8; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W0, data32); + data32 |= osd_hw.color_info[index]->hw_blkmode << 8; + VSYNCOSD_WR_MPEG_REG( + osd_reg->osd_blk0_cfg_w0, data32); /* * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK1_CFG_W0, data32); * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK2_CFG_W0, data32); * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK3_CFG_W0, data32); */ - if (osd_hw.osd_afbcd[OSD1].enable) { - /* only the RGBA32 mode */ - VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_MODE, - (3 << 24) | - (4 << 16) | /* hold_line_num */ - (0xe4 << 8) | - (1 << 6) | - (1 << 5) | - (0x15 << 0)); /* pixel_packing_fmt */ - /* TODO: add pixel_packing_fmt setting */ - VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_CONV_CTRL, - (osd_hw.osd_afbcd[OSD1].conv_lbuf_len - & 0xffff)); - /* afbc mode RGBA32 -> RGB24 - * data32 = (0x1b << 24) | - * (osd_hw.osd_afbcd[OSD1].phy_addr & 0xffffff); - * VSYNCOSD_WR_MPEG_REG( - * OSD1_AFBCD_CHROMA_PTR, - * data32); - */ + if (osd_hw.osd_afbcd[index].enable) { + if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) { + /* only the RGBA32 mode */ + VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_MODE, + (3 << 24) | + (4 << 16) | /* hold_line_num */ + (0xe4 << 8) | + (1 << 6) | + (1 << 5) | + (0x15 << 0)); /* pixel_packing_fmt */ + /* TODO: add pixel_packing_fmt setting */ + VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_CONV_CTRL, + (osd_hw.osd_afbcd[index].conv_lbuf_len + & 0xffff)); + /* afbc mode RGBA32 -> RGB24 + * data32 = (0x1b << 24) | + * (osd_hw.osd_afbcd[OSD1].phy_addr + * & 0xffffff); + * VSYNCOSD_WR_MPEG_REG( + * OSD1_AFBCD_CHROMA_PTR, + * data32); + */ + VSYNCOSD_WR_MPEG_REG_BITS( + OSD1_AFBCD_CHROMA_PTR, 0xe4, 24, 8); + /* + * data32 = (0xe4 << 24) | + * (osd_hw.osd_afbcd[OSD1].phy_addr + * & 0xffffff); + * VSYNCOSD_WR_MPEG_REG( + * OSD1_AFBCD_CHROMA_PTR, + * data32); + */ + } else if ( + osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) { + u32 bpp, pixel_format; + u32 line_stride, output_stride; + //u32 fmt_mode = COLOR_INDEX_32_ABGR; + u32 aligned_32 = 1; /* need get from hwc line */ + u32 super_block_aspect = MALI_AFBC_16X16_PIXEL; + /* 00:16x16 pixels + * 01:32x8 pixels + */ + u32 block_split = MALI_AFBC_SPLIT_ON; + /* 0 Block split mode off. + * 1 Block split mode on. + */ + u32 yuv_transform = 0; + /* 0 Internal YUV transform off. + * 1 Internal YUV transform on. + */ + u32 afbc_color_reorder = 0x4321; + /* 0x4321 = ABGR + * 0x1234 = RGBA + */ + #if 0 + if (osd_hw.color_info[index]) + fmt_mode = osd_hw.color_info + [index]->color_index; + #endif + pixel_format = afbc_pix_format( + osd_hw.osd_afbcd[index].format); + bpp = osd_hw.color_info[index]->bpp >> 3; + line_stride = line_stride_calc_afbc( + pixel_format, + osd_hw.osd_afbcd[index].frame_width, + aligned_32); + super_block_aspect = + osd_hw.osd_afbcd[index].inter_format + >> 1 & 0x3; + block_split = + osd_hw.osd_afbcd[index].inter_format + & 0x1; + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_format_specifier_s, + (super_block_aspect & 0x3) << 16 | + (block_split & 0x1) << 9 | + (yuv_transform & 0x1) << 8 | + (pixel_format & 0xf)); + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_mali_unpack_ctrl, + afbc_color_reorder, + 0, 16); + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_blk2_cfg_w4, + line_stride, 0, 12); + osd_log_dbg("line_stride=%x\n", + line_stride); + output_stride = + osd_hw.osd_afbcd[index].frame_width + * bpp; + osd_log_dbg("output_stride=%x\n", + output_stride); + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_output_buf_stride_s, + output_stride); + } + } else { + if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) { + /* line stride */ + VSYNCOSD_WR_MPEG_REG( + osd_reg->osd_blk2_cfg_w4, 0); + } + } + if (idx >= COLOR_INDEX_32_BGRX + && idx <= COLOR_INDEX_32_XRGB) VSYNCOSD_WR_MPEG_REG_BITS( - OSD1_AFBCD_CHROMA_PTR, 0xe4, 24, 8); - /* - * data32 = (0xe4 << 24) | - * (osd_hw.osd_afbcd[OSD1].phy_addr & 0xffffff); - * VSYNCOSD_WR_MPEG_REG( - * OSD1_AFBCD_CHROMA_PTR, - * data32); - */ + osd_reg->osd_ctrl_stat2, + 0x1ff, 6, 9); + else + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_ctrl_stat2, + 0, 6, 9); + } + remove_from_update_list(index, OSD_COLOR_MODE); +} + + +static void osd_update_enable(u32 index) +{ + u32 temp_val = 0; + struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index]; + + if (!osd_hw.buffer_alloc[index]) + return; + if ((osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) && + (osd_hw.enable[index] == ENABLE)) { + /* only for osd1 */ + if ((VSYNCOSD_RD_MPEG_REG(VPU_RDARB_MODE_L1C2) & + (1 << 16)) == 0) { + VSYNCOSD_WR_MPEG_REG_BITS( + VPU_RDARB_MODE_L1C2, 1, 16, 1); + } + } + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + if (index == OSD1) + temp_val = VPP_OSD1_POSTBLEND; + else if (index == OSD2) + temp_val = VPP_OSD2_POSTBLEND; + if (osd_hw.enable[index] == ENABLE) + osd_vpp_misc |= temp_val; + else + osd_vpp_misc &= ~temp_val; + + } + if (osd_hw.enable[index] == ENABLE) { + VSYNCOSD_SET_MPEG_REG_MASK( + osd_reg->osd_ctrl_stat, 1 << 0); + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + VSYNCOSD_SET_MPEG_REG_MASK(VPP_MISC, + temp_val | VPP_POSTBLEND_EN); + notify_to_amvideo(); + } + } else { + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + notify_to_amvideo(); + VSYNCOSD_CLR_MPEG_REG_MASK(VPP_MISC, temp_val); } - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { - enum color_index_e idx = - osd_hw.color_info[OSD1]->color_index; - if (idx >= COLOR_INDEX_32_BGRX - && idx <= COLOR_INDEX_32_XRGB) + VSYNCOSD_CLR_MPEG_REG_MASK( + osd_reg->osd_ctrl_stat, 1 << 0); + } + if (osd_hw.osd_afbcd[index].enable == ENABLE) { + if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) { + if (osd_hw.enable[index] == ENABLE) { + if (!osd_afbc_dec_enable && + osd_hw.osd_afbcd[index].phy_addr != 0) { + VSYNCOSD_WR_MPEG_REG( + OSD1_AFBCD_ENABLE, 0x8100); + osd_afbc_dec_enable = 1; + } VSYNCOSD_WR_MPEG_REG_BITS( - VIU_OSD1_CTRL_STAT2, 0x1ff, 6, 9); - else + osd_reg->osd_ctrl_stat2, 1, 15, 1); + } else { + if (osd_afbc_dec_enable) { + VSYNCOSD_WR_MPEG_REG( + OSD1_AFBCD_ENABLE, 0x8000); + osd_afbc_dec_enable = 0; + } + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_ctrl_stat2, 0, 15, 1); + } + if ((VSYNCOSD_RD_MPEG_REG(VIU_MISC_CTRL1) & + (0xff << 8)) != 0x9000) { + VSYNCOSD_WR_MPEG_REG_BITS( + VIU_MISC_CTRL1, 0x90, 8, 8); + } + } else if ( + osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) { + if (osd_hw.enable[index] == ENABLE) { + /* enable mali afbc */ + VSYNCOSD_WR_MPEG_REG_BITS( + VPU_MAFBC_SURFACE_CFG, + 1, index, 1); + osd_log_dbg("set surface index=%d\n", index); + osd_hw.osd_afbcd[index].afbc_start = 1; + } else { + /* disable mali afbc */ VSYNCOSD_WR_MPEG_REG_BITS( - VIU_OSD1_CTRL_STAT2, 0, 6, 9); + VPU_MAFBC_SURFACE_CFG, + 0, index, 1); + osd_hw.osd_afbcd[index].afbc_start = 0; + } + } + } + remove_from_update_list(index, OSD_ENABLE); +} + +static void osd_update_disp_osd_reverse(u32 index) +{ + if (osd_hw.osd_reverse[index] == REVERSE_TRUE) + VSYNCOSD_WR_MPEG_REG_BITS( + hw_osd_reg_array[index].osd_blk0_cfg_w0, 3, 28, 2); + else if (osd_hw.osd_reverse[index] == REVERSE_X) + VSYNCOSD_WR_MPEG_REG_BITS( + hw_osd_reg_array[index].osd_blk0_cfg_w0, 1, 28, 2); + else if (osd_hw.osd_reverse[index] == REVERSE_Y) + VSYNCOSD_WR_MPEG_REG_BITS( + hw_osd_reg_array[index].osd_blk0_cfg_w0, 2, 28, 2); + else + VSYNCOSD_WR_MPEG_REG_BITS( + hw_osd_reg_array[index].osd_blk0_cfg_w0, 0, 28, 2); + remove_from_update_list(index, DISP_OSD_REVERSE); +} + +static void osd_update_disp_osd_rotate(u32 index) +{ + remove_from_update_list(index, DISP_OSD_ROTATE); +} + +static void osd_update_color_key(u32 index) +{ + VSYNCOSD_WR_MPEG_REG(hw_osd_reg_array[index].osd_tcolor_ag0, + osd_hw.color_key[index]); + remove_from_update_list(index, OSD_COLOR_KEY); +} + +static void osd_update_color_key_enable(u32 index) +{ + u32 data32; + + data32 = VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[index].osd_blk0_cfg_w0); + data32 &= ~(1 << 6); + data32 |= (osd_hw.color_key_enable[index] << 6); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[index].osd_blk0_cfg_w0, data32); + /* + * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK1_CFG_W0, data32); + * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK2_CFG_W0, data32); + * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK3_CFG_W0, data32); + */ + remove_from_update_list(index, OSD_COLOR_KEY_ENABLE); +} + +static void osd_update_gbl_alpha(u32 index) +{ + u32 data32; + + data32 = VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[index].osd_ctrl_stat); + data32 &= ~(0x1ff << 12); + data32 |= osd_hw.gbl_alpha[index] << 12; + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[index].osd_ctrl_stat, data32); + remove_from_update_list(index, OSD_GBL_ALPHA); +} + +static void osd_update_order(u32 index) +{ + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + switch (osd_hw.order[index]) { + case OSD_ORDER_01: + if (!osd_hw.hw_rdma_en) + osd_reg_clr_mask(VPP_MISC, + VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); + osd_vpp_misc &= ~(VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); + break; + case OSD_ORDER_10: + /* OSD2 is top */ + if (!osd_hw.hw_rdma_en) + osd_reg_set_mask(VPP_MISC, + VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); + osd_vpp_misc |= (VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); + break; + default: + break; + } + notify_to_amvideo(); + } + + remove_from_update_list(index, OSD_CHANGE_ORDER); +} + + +static void osd1_2x_scale_update_geometry(void) +{ + u32 data32; + + data32 = (osd_hw.scaledata[OSD1].x_start & 0x1fff) | + (osd_hw.scaledata[OSD1].x_end & 0x1fff) << 16; + VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1, data32); + + if (osd_hw.osd_afbcd[OSD1].enable) { + data32 = (osd_hw.scaledata[OSD1].x_end & 0x1fff) | + (osd_hw.scaledata[OSD1].x_start & 0x1fff) << 16; + VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_PIXEL_HSCOPE, data32); + data32 = (osd_hw.scaledata[OSD1].y_end & 0x1fff) | + (osd_hw.scaledata[OSD1].y_start & 0x1fff) << 16; + VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_PIXEL_VSCOPE, data32); + VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_HDR_PTR, + osd_hw.osd_afbcd[OSD1].phy_addr >> 4); + VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_FRAME_PTR, + osd_hw.osd_afbcd[OSD1].phy_addr >> 4); + data32 = (0xe4 << 24) | + (osd_hw.osd_afbcd[OSD1].phy_addr & 0xffffff); + VSYNCOSD_WR_MPEG_REG( + OSD1_AFBCD_CHROMA_PTR, + data32); + } + + data32 = ((osd_hw.scaledata[OSD1].y_start + + osd_hw.pandata[OSD1].y_start) & 0x1fff) + | ((osd_hw.scaledata[OSD1].y_end + + osd_hw.pandata[OSD1].y_start) & 0x1fff) << 16; + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w2, data32); + /* adjust display x-axis */ + if (osd_hw.scale[OSD1].h_enable) { + data32 = (osd_hw.dispdata[OSD1].x_start & 0xfff) + | ((osd_hw.dispdata[OSD1].x_start + + (osd_hw.scaledata[OSD1].x_end + - osd_hw.scaledata[OSD1].x_start) * 2 + 1) + & 0xfff) << 16; + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w3, data32); + if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE) { + data32 = ((osd_hw.dispdata[OSD1].y_start >> 1) & 0xfff) + | (((((osd_hw.dispdata[OSD1].y_start + + (osd_hw.scaledata[OSD1].y_end + - osd_hw.scaledata[OSD1].y_start) * 2) + + 1) >> 1) - 1) & 0xfff) << 16; + } else { + data32 = (osd_hw.dispdata[OSD1].y_start & 0xfff) + | (((osd_hw.dispdata[OSD1].y_start + + (osd_hw.scaledata[OSD1].y_end + - osd_hw.scaledata[OSD1].y_start) * 2)) + & 0xfff) << 16; + } + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w4, data32); + } + /* adjust display y-axis */ + if (osd_hw.scale[OSD1].v_enable) { + data32 = (osd_hw.dispdata[OSD1].x_start & 0xfff) + | ((osd_hw.dispdata[OSD1].x_start + + (osd_hw.scaledata[OSD1].x_end + - osd_hw.scaledata[OSD1].x_start) * 2 + 1) + & 0xfff) << 16; + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w3, data32); + if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE) { + data32 = ((osd_hw.dispdata[OSD1].y_start >> 1) & 0xfff) + | (((((osd_hw.dispdata[OSD1].y_start + + (osd_hw.scaledata[OSD1].y_end + - osd_hw.scaledata[OSD1].y_start) * 2) + + 1) >> 1) - 1) & 0xfff) << 16; + } else { + data32 = (osd_hw.dispdata[OSD1].y_start & 0xfff) + | (((osd_hw.dispdata[OSD1].y_start + + (osd_hw.scaledata[OSD1].y_end + - osd_hw.scaledata[OSD1].y_start) * 2)) + & 0xfff) << 16; } + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w4, data32); } - remove_from_update_list(OSD1, OSD_COLOR_MODE); } -static void osd2_update_color_mode(void) + +static u32 _set_bits(u32 data32, u32 bits, u32 value) { - u32 data32 = 0; + data32 &= ~(1 << bits); + data32 |= (value << bits); + return data32; +} - if (osd_hw.color_info[OSD2] != NULL) { - data32 = (osd_hw.scan_mode[OSD2] == - SCAN_MODE_INTERLACE) ? 2 : 0; - data32 |= VSYNCOSD_RD_MPEG_REG(VIU_OSD2_BLK0_CFG_W0) - & 0x30007040; - data32 |= osd_hw.fb_gem[OSD2].canvas_idx << 16; - /* if (!osd_hw.rotate[OSD2].on_off) */ - data32 |= OSD_DATA_LITTLE_ENDIAN << 15; - data32 |= osd_hw.color_info[OSD2]->hw_colormat << 2; - if (get_cpu_type() != MESON_CPU_MAJOR_ID_GXTVBB) { - if (osd_hw.color_info[OSD2]->color_index < - COLOR_INDEX_YUV_422) - data32 |= 1 << 7; /* yuv enable */ - } - /* osd_blk_mode */ - data32 |= osd_hw.color_info[OSD2]->hw_blkmode << 8; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W0, data32); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { - enum color_index_e idx = - osd_hw.color_info[OSD2]->color_index; - if (idx >= COLOR_INDEX_32_BGRX - && idx <= COLOR_INDEX_32_XRGB) - VSYNCOSD_WR_MPEG_REG_BITS( - VIU_OSD2_CTRL_STAT2, 0x1ff, 6, 9); - else - VSYNCOSD_WR_MPEG_REG_BITS( - VIU_OSD2_CTRL_STAT2, 0, 6, 9); +void insert_sort(u32 *array, int length) +{ + int i = 0, j = 0; + u32 temp; + + for (j = 0; j < length; j++) { + for (i = j + 1; i <= length; i++) { + if (array[j] < array[i]) { + temp = array[j]; + array[j] = array[i]; + array[i] = temp; + } } } - remove_from_update_list(OSD2, OSD_COLOR_MODE); } -static void osd1_update_enable(void) +static int get_available_layers(void) { - if (!osd_hw.buffer_alloc[OSD1]) - return; - if (((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM)) && - (osd_hw.enable[OSD1] == ENABLE)) { - if ((VSYNCOSD_RD_MPEG_REG(VPU_RDARB_MODE_L1C2) & - (1 << 16)) == 0) { - VSYNCOSD_WR_MPEG_REG_BITS( - VPU_RDARB_MODE_L1C2, 1, 16, 1); - } - } + int i; + int available_layer = 0; - if (osd_hw.enable[OSD1] == ENABLE) - osd_vpp_misc |= VPP_OSD1_POSTBLEND; - else - osd_vpp_misc &= ~VPP_OSD1_POSTBLEND; + for (i = 0 ; i < osd_hw.osd_meson_dev.osd_count; i++) { + if (osd_hw.enable[i]) + available_layer++; + } + return available_layer; +} - if (osd_hw.enable[OSD1] == ENABLE) { - VSYNCOSD_SET_MPEG_REG_MASK(VIU_OSD1_CTRL_STAT, 1 << 0); - VSYNCOSD_SET_MPEG_REG_MASK(VPP_MISC, - VPP_OSD1_POSTBLEND | VPP_POSTBLEND_EN); - notify_to_amvideo(); - } else { - notify_to_amvideo(); - VSYNCOSD_CLR_MPEG_REG_MASK(VPP_MISC, VPP_OSD1_POSTBLEND); - VSYNCOSD_CLR_MPEG_REG_MASK(VIU_OSD1_CTRL_STAT, 1 << 0); - - } - if ((osd_hw.osd_afbcd[OSD1].enable == ENABLE) && - ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM))) { - if (osd_hw.enable[OSD1] == ENABLE) { - if (!osd_afbc_dec_enable && - osd_hw.osd_afbcd[OSD1].phy_addr != 0) { - VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_ENABLE, 0x8100); - osd_afbc_dec_enable = 1; - } - VSYNCOSD_WR_MPEG_REG_BITS( - VIU_OSD1_CTRL_STAT2, 1, 15, 1); +static int check_order_continuous(u32 *order) +{ + int i = 0, j = 0; + int save_order[3] = {0, 0, 0}; + bool continuous = false; - } else { - if (osd_afbc_dec_enable) { - VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_ENABLE, 0x8000); - osd_afbc_dec_enable = 0; - } - VSYNCOSD_WR_MPEG_REG_BITS( - VIU_OSD1_CTRL_STAT2, 0, 15, 1); - } - if ((VSYNCOSD_RD_MPEG_REG(VIU_MISC_CTRL1) & - (0xff << 8)) != 0x9000) { - VSYNCOSD_WR_MPEG_REG_BITS(VIU_MISC_CTRL1, 0x90, 8, 8); + for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) { + if (order[i]) { + save_order[j] = order[i]; + j++; } } - remove_from_update_list(OSD1, OSD_ENABLE); + for (i = 0; i < j; i++) + osd_log_dbg("save_order:%d\n", save_order[i]); + switch (j) { + case 0: + break; + case 1: + continuous = true; + break; + case 2: + if (save_order[0] == save_order[1] + 1) + continuous = true; + break; + case 3: + if ((save_order[0] == save_order[1] + 1) + && (save_order[1] == save_order[2] + 1)) + continuous = true; + break; + } + osd_log_dbg("continuous=%d\n", continuous); + return continuous; } -static void osd2_update_enable(void) + +static int blend_din_to_osd( + u32 blend_din_index, struct hw_osd_blending_s *blending) { - if (!osd_hw.buffer_alloc[OSD2]) - return; - if (osd_hw.enable[OSD2] == ENABLE) - osd_vpp_misc |= VPP_OSD2_POSTBLEND; - else - osd_vpp_misc &= ~VPP_OSD2_POSTBLEND; + u32 osd_index = 0; - if (osd_hw.enable[OSD2] == ENABLE) { - VSYNCOSD_SET_MPEG_REG_MASK(VIU_OSD2_CTRL_STAT, 1 << 0); - VSYNCOSD_SET_MPEG_REG_MASK( - VPP_MISC, VPP_OSD2_POSTBLEND | VPP_POSTBLEND_EN); - notify_to_amvideo(); - } else { - notify_to_amvideo(); - VSYNCOSD_CLR_MPEG_REG_MASK(VPP_MISC, VPP_OSD2_POSTBLEND); - VSYNCOSD_CLR_MPEG_REG_MASK(VIU_OSD2_CTRL_STAT, 1 << 0); - } - remove_from_update_list(OSD2, OSD_ENABLE); + osd_index = + blending->osd_to_bdin_table[blend_din_index]; + if ((osd_index > OSD3) + || (osd_index < OSD1)) { + osd_log_err("blend_din:%d no match osd find!\n", + blend_din_index); + return -1; + } else + return osd_index; } -static void osd1_update_disp_osd_reverse(void) + +static bool osd_need_scaler(u32 index) { - if (osd_hw.osd_reverse[OSD1] == REVERSE_TRUE) - VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD1_BLK0_CFG_W0, 3, 28, 2); - else if (osd_hw.osd_reverse[OSD1] == REVERSE_X) - VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD1_BLK0_CFG_W0, 1, 28, 2); - else if (osd_hw.osd_reverse[OSD1] == REVERSE_Y) - VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD1_BLK0_CFG_W0, 2, 28, 2); + bool scaler; + + if ((osd_hw.src_data[index].w == osd_hw.dst_data[index].w) + && (osd_hw.src_data[index].h == osd_hw.dst_data[index].h)) + scaler = false; else - VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD1_BLK0_CFG_W0, 0, 28, 2); - remove_from_update_list(OSD1, DISP_OSD_REVERSE); + scaler = true; + return scaler; } -static void osd2_update_disp_osd_reverse(void) +static bool is_osd_scaling_same(u32 index1, u32 index2) { - if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) - VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD2_BLK0_CFG_W0, 3, 28, 2); - else if (osd_hw.osd_reverse[OSD2] == REVERSE_X) - VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD2_BLK0_CFG_W0, 1, 28, 2); - else if (osd_hw.osd_reverse[OSD2] == REVERSE_Y) - VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD2_BLK0_CFG_W0, 2, 28, 2); + bool same; + + if (((osd_hw.dst_data[index1].w * osd_hw.src_data[index2].w) == + (osd_hw.dst_data[index2].w * osd_hw.src_data[index1].w)) && + ((osd_hw.dst_data[index1].h * osd_hw.src_data[index2].h) == + (osd_hw.dst_data[index2].h * osd_hw.src_data[index1].h))) + same = true; else - VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD2_BLK0_CFG_W0, 0, 28, 2); - remove_from_update_list(OSD2, DISP_OSD_REVERSE); + same = false; + return same; } -static void osd1_update_disp_osd_rotate(void) + +static void set_freescale_para(u32 index, u32 w, u32 h) { - remove_from_update_list(OSD1, DISP_OSD_ROTATE); + osd_hw.free_scale_enable[index] = 0x10001; + + osd_hw.free_src_data[index].x_start = + osd_hw.src_data[index].x; + osd_hw.free_src_data[index].x_end = + osd_hw.src_data[index].x + + osd_hw.src_data[index].w - 1; + osd_hw.free_src_data[index].y_start = + osd_hw.src_data[index].y; + osd_hw.free_src_data[index].y_end = + osd_hw.src_data[index].y + + osd_hw.src_data[index].h - 1; + + osd_hw.free_dst_data[index].x_start = + osd_hw.dst_data[index].x; + osd_hw.free_dst_data[index].x_end = + osd_hw.dst_data[index].x + + osd_hw.dst_data[index].w * w / + osd_hw.background_w - 1; + osd_hw.free_dst_data[index].y_start = + osd_hw.dst_data[index].y; + osd_hw.free_dst_data[index].y_end = + osd_hw.dst_data[index].y + + osd_hw.dst_data[index].h * h / + osd_hw.background_h - 1; } -static void osd2_update_disp_osd_rotate(void) +static void adjust_freescale_para(struct hw_osd_blending_s *blending) { - remove_from_update_list(OSD2, DISP_OSD_ROTATE); -} + int i; + int osd_index; + int width = 0, height = 0; + if (blending->layer_cnt >= 1) { + osd_index = blend_din_to_osd(BLEND_DIN1, blending); + set_freescale_para(osd_index, + osd_hw.vinfo_width, osd_hw.vinfo_height); + } + if (blending->layer_cnt == 2) { + if (osd_hw.osd_blend_mode == OSD_BLEND_ABC) { + width = osd_hw.background_w; + height = osd_hw.background_h; + } else if (osd_hw.osd_blend_mode == OSD_BLEND_AB_C) { + width = osd_hw.vinfo_width; + height = osd_hw.vinfo_height; + } + osd_index = blend_din_to_osd(BLEND_DIN4, blending); + set_freescale_para(osd_index, width, height); + } else if (blending->layer_cnt == 3) { + if (osd_hw.osd_blend_mode == OSD_BLEND_ABC) { + width = osd_hw.background_w; + height = osd_hw.background_h; + } else if (osd_hw.osd_blend_mode == OSD_BLEND_A_BC) { + width = osd_hw.vinfo_width; + height = osd_hw.vinfo_height; + } + osd_index = blend_din_to_osd(BLEND_DIN3, blending); + set_freescale_para(osd_index, width, height); + osd_index = blend_din_to_osd(BLEND_DIN4, blending); + set_freescale_para(osd_index, width, height); + } + for (i = 0; i < 3; i++) { + osd_log_dbg("free_src_data:%d,%d,%d,%d\n", + osd_hw.free_src_data[i].x_start, + osd_hw.free_src_data[i].y_start, + osd_hw.free_src_data[i].x_end, + osd_hw.free_src_data[i].y_end); + osd_log_dbg("free_dst_data:%d,%d,%d,%d\n", + osd_hw.free_dst_data[i].x_start, + osd_hw.free_dst_data[i].y_start, + osd_hw.free_dst_data[i].x_end, + osd_hw.free_dst_data[i].y_end); + } -static void osd1_update_color_key(void) -{ - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_TCOLOR_AG0, osd_hw.color_key[OSD1]); - remove_from_update_list(OSD1, OSD_COLOR_KEY); } -static void osd2_update_color_key(void) +static void generate_blend_din_table(struct hw_osd_blending_s *blending) { - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_TCOLOR_AG0, osd_hw.color_key[OSD2]); - remove_from_update_list(OSD2, OSD_COLOR_KEY); + int i = 0; + int osd_count = osd_hw.osd_meson_dev.osd_count; + + /* reorder[i] = osd[i]'s display layer */ + for (i = 0; i < OSD_BLEND_LAYERS; i++) + blending->osd_to_bdin_table[i] = -1; + blending->din_reoder_sel = 0; + switch (blending->layer_cnt) { + case 0: + break; + case 1: + for (i = 0; i < osd_count; i++) { + if (blending->reorder[i] != LAYER_UNSUPPORT) { + /* blend_din1 */ + blending->din_reoder_sel |= (i + 1) << 0; + /* blend_din1 -- osdx */ + blending->osd_to_bdin_table[0] = i; + break; + } + } + break; + case 2: + { + int temp_index[2]; + int j = 0; + + for (i = 0; i < osd_count; i++) { + if (blending->reorder[i] != LAYER_UNSUPPORT) { + /* save the osd index */ + temp_index[j] = i; + j++; + } + } + if (blending->reorder[temp_index[0]] < + blending->reorder[temp_index[1]]) { + //printf("blend_din4==%d\n",reorder[temp_index[0]]); + //printf("blend_din1==%d\n",reorder[temp_index[1]]); + /* blend_din4 */ + blending->din_reoder_sel |= (temp_index[0] + 1) << 12; + /* blend_din3 -- osdx */ + blending->osd_to_bdin_table[3] = temp_index[0]; + /* blend_din1 */ + blending->din_reoder_sel |= (temp_index[1] + 1) << 0; + /* blend_din1 -- osdx */ + blending->osd_to_bdin_table[0] = temp_index[1]; + } else { + //printf("blend_din1==%d\n",reorder[temp_index[0]]); + //printf("blend_din4==%d\n",reorder[temp_index[1]]); + /* blend_din1 */ + blending->din_reoder_sel |= (temp_index[0] + 1) << 0; + /* blend_din1 -- osdx */ + blending->osd_to_bdin_table[0] = temp_index[0]; + /* blend_din3 */ + blending->din_reoder_sel |= (temp_index[1] + 1) << 12; + /* blend_din3 -- osdx */ + blending->osd_to_bdin_table[3] = temp_index[1]; + } + break; + } + case 3: + for (i = 0; i < osd_count; i++) { + switch (blending->reorder[i]) { + /* blend_din1 is bottom, blend_din4 is top layer */ + case LAYER_1: + /* blend_din4 */ + blending->din_reoder_sel |= (i + 1) << 12; + /* blend_din4 -- osdx */ + blending->osd_to_bdin_table[3] = i; + break; + case LAYER_2: + /* blend_din3 */ + blending->din_reoder_sel |= (i + 1) << 8; + /* blend_din3 -- osdx */ + blending->osd_to_bdin_table[2] = i; + break; + case LAYER_3: + /* blend_din1 */ + blending->din_reoder_sel |= (i + 1) << 0; + /* blend_din1 -- osdx */ + blending->osd_to_bdin_table[0] = i; + break; + } + } + break; + } + osd_log_dbg("osd_to_bdin_table[i]=[%x,%x,%x,%x]\n", + blending->osd_to_bdin_table[0], + blending->osd_to_bdin_table[1], + blending->osd_to_bdin_table[2], + blending->osd_to_bdin_table[3]); + osd_log_dbg("blend_din1 == osd%d\n", + blend_din_to_osd(BLEND_DIN1, blending) + 1); + osd_log_dbg("blend_din3 == osd%d\n", + blend_din_to_osd(BLEND_DIN3, blending) + 1); + osd_log_dbg("blend_din4 == osd%d\n", + blend_din_to_osd(BLEND_DIN4, blending) + 1); } -static void osd1_update_color_key_enable(void) +static void adjust_blend_din_table(struct hw_osd_blending_s *blending) { - u32 data32; + int i = 0; - data32 = VSYNCOSD_RD_MPEG_REG(VIU_OSD1_BLK0_CFG_W0); - data32 &= ~(1 << 6); - data32 |= (osd_hw.color_key_enable[OSD1] << 6); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W0, data32); - /* - * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK1_CFG_W0, data32); - * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK2_CFG_W0, data32); - * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK3_CFG_W0, data32); - */ - remove_from_update_list(OSD1, OSD_COLOR_KEY_ENABLE); + /* adjust osd_to_bdin_table */ + /* reorder[i] = osd[i]'s display layer */ + /* tow osd_x input to vpp, default osd2 is top */ + blending->din_reoder_sel = 0; + for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) { + switch (blending->reorder[i]) { + /* blend_din1 is top, blend_din(3 4) is bottom layer */ + case LAYER_1: + blending->din_reoder_sel |= (i + 1) << 8;//blend_din3 + blending->osd_to_bdin_table[2] = i;//blend_din3 -- osdx + break; + case LAYER_2: + blending->din_reoder_sel |= (i + 1) << 0;//blend_din1 + blending->osd_to_bdin_table[0] = i;//blend_din4 -- osdx + break; + case LAYER_3: + blending->din_reoder_sel |= (i + 1) << 12;//blend_din4 + blending->osd_to_bdin_table[3] = i;//blend_din4 -- osdx + break; + } + } + osd_log_dbg("osd_to_bdin_table[i]=[%x,%x,%x,%x]\n", + blending->osd_to_bdin_table[0], + blending->osd_to_bdin_table[1], + blending->osd_to_bdin_table[2], + blending->osd_to_bdin_table[3]); } -static void osd2_update_color_key_enable(void) +static int osd_setting_blending_scope(u32 index) { - u32 data32; + u32 bld_osd_h_start, bld_osd_h_end; + u32 bld_osd_v_start, bld_osd_v_end; + u32 reg_offset = 2; - data32 = VSYNCOSD_RD_MPEG_REG(VIU_OSD2_BLK0_CFG_W0); - data32 &= ~(1 << 6); - data32 |= (osd_hw.color_key_enable[OSD2] << 6); - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W0, data32); - remove_from_update_list(OSD2, OSD_COLOR_KEY_ENABLE); + if (index > OSD3) { + osd_log_err("error osd index=%d\n", index); + return -1; + } + if (index == OSD1) { + /* use freescale after blend2 */ + if (osd_hw.free_scale_enable[index]) { + bld_osd_h_start = + osd_hw.free_src_data[index].x_start; + bld_osd_h_end = + osd_hw.free_src_data[index].x_end; + bld_osd_v_start = + osd_hw.free_src_data[index].y_start; + bld_osd_v_end = + osd_hw.free_src_data[index].y_end; + } else { + bld_osd_h_start = + osd_hw.pandata[index].x_start; + bld_osd_h_end = + osd_hw.pandata[index].x_end; + bld_osd_v_start = + osd_hw.pandata[index].y_start; + bld_osd_v_end = + osd_hw.pandata[index].y_end; + osd_log_dbg("freescale disable, index=%x\n", index); + } + } else { + if (osd_hw.free_scale_enable[index]) { + bld_osd_h_start = + osd_hw.free_dst_data[index].x_start; + bld_osd_h_end = + osd_hw.free_dst_data[index].x_end; + bld_osd_v_start = + osd_hw.free_dst_data[index].y_start; + bld_osd_v_end = + osd_hw.free_dst_data[index].y_end; + } else { + bld_osd_h_start = + osd_hw.dispdata[index].x_start; + bld_osd_h_end = + osd_hw.dispdata[index].x_end; + bld_osd_v_start = + osd_hw.dispdata[index].y_start; + bld_osd_v_end = + osd_hw.dispdata[index].y_end; + } + } + /* it is setting for osdx */ + VSYNCOSD_WR_MPEG_REG( + VIU_OSD_BLEND_DIN0_SCOPE_H + reg_offset * index, + bld_osd_h_end << 16 | + bld_osd_h_start); + VSYNCOSD_WR_MPEG_REG( + VIU_OSD_BLEND_DIN0_SCOPE_V + reg_offset * index, + bld_osd_v_end << 16 | + bld_osd_v_start); + return 0; } -static void osd1_update_gbl_alpha(void) -{ - u32 data32; - data32 = VSYNCOSD_RD_MPEG_REG(VIU_OSD1_CTRL_STAT); - data32 &= ~(0x1ff << 12); - data32 |= osd_hw.gbl_alpha[OSD1] << 12; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_CTRL_STAT, data32); - remove_from_update_list(OSD1, OSD_GBL_ALPHA); -} -static void osd2_update_gbl_alpha(void) +static int vpp_blend_setting(struct hw_osd_blending_s *blending) { - u32 data32; + u32 index; + u32 osd1_dst_h = 0, osd1_dst_v = 0; + u32 osd1_h_start = 0, osd1_h_end = 0; + u32 osd1_v_start = 0, osd1_v_end = 0; + u32 osd2_h_start = 0, osd2_h_end = 0; + u32 osd2_v_start = 0, osd2_v_end = 0; - data32 = VSYNCOSD_RD_MPEG_REG(VIU_OSD2_CTRL_STAT); - data32 &= ~(0x1ff << 12); - data32 |= osd_hw.gbl_alpha[OSD2] << 12; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_CTRL_STAT, data32); - remove_from_update_list(OSD2, OSD_GBL_ALPHA); -} -static void osd2_update_order(void) -{ - switch (osd_hw.order) { - case OSD_ORDER_01: -#ifndef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - osd_reg_clr_mask(VPP_MISC, VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); -#endif - osd_vpp_misc &= ~(VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); - break; - case OSD_ORDER_10: -#ifndef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - osd_reg_set_mask(VPP_MISC, VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); -#endif - osd_vpp_misc |= (VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); - break; - default: - break; + index = blend_din_to_osd(BLEND_DIN1, blending); + if (index > OSD3) { + osd_log_err("error osd index=%d\n", index); + return -1; + } + if (osd_hw.free_scale_enable[index]) { + osd1_dst_h = osd_hw.free_dst_data[index].x_end + - osd_hw.free_dst_data[index].x_start + 1; + osd1_dst_v = osd_hw.free_dst_data[index].y_end + - osd_hw.free_dst_data[index].y_start + 1; + osd1_h_start = osd_hw.free_dst_data[index].x_start; + osd1_h_end = osd_hw.free_dst_data[index].x_end; + osd1_v_start = osd_hw.free_dst_data[index].y_start; + osd1_v_end = osd_hw.free_dst_data[index].y_end; + } else { + osd1_dst_h = osd_hw.dispdata[index].x_end + - osd_hw.dispdata[index].x_start + 1; + osd1_dst_v = osd_hw.dispdata[index].y_end + - osd_hw.dispdata[index].y_start + 1; + osd1_h_start = osd_hw.dispdata[index].x_start; + osd1_h_end = osd_hw.dispdata[index].x_end; + osd1_v_start = osd_hw.dispdata[index].y_start; + osd1_v_end = osd_hw.dispdata[index].y_end; + } + VSYNCOSD_WR_MPEG_REG(VPP_OSD1_IN_SIZE, + osd1_dst_h | osd1_dst_v << 16); + + /* setting blend scope */ + VSYNCOSD_WR_MPEG_REG(VPP_OSD1_BLD_H_SCOPE, + osd1_h_start << 16 | osd1_h_end); + VSYNCOSD_WR_MPEG_REG(VPP_OSD1_BLD_V_SCOPE, + osd1_v_start << 16 | osd1_v_end); + + if (osd_hw.osd_blend_mode == OSD_BLEND_AB_C) { + if (blending->layer_cnt == 3) + index = blend_din_to_osd(BLEND_DIN4, blending); + else if (blending->layer_cnt == 2) + index = blend_din_to_osd(BLEND_DIN4, blending); + if (osd_hw.free_scale_enable[index]) { + osd2_h_start = osd_hw.free_dst_data[index].x_start; + osd2_h_end = osd_hw.free_dst_data[index].x_end; + osd2_v_start = osd_hw.free_dst_data[index].y_start; + osd2_v_end = osd_hw.free_dst_data[index].y_end; + } else { + osd2_h_start = osd_hw.dispdata[index].x_start; + osd2_h_end = osd_hw.dispdata[index].x_end; + osd2_v_start = osd_hw.dispdata[index].y_start; + osd2_v_end = osd_hw.dispdata[index].y_end; + } + } else if (osd_hw.osd_blend_mode == OSD_BLEND_A_BC) { + osd2_h_start = 0; + osd2_h_end = osd_hw.background_w - 1; + osd2_v_start = 0; + osd2_v_end = osd_hw.background_h - 1; } - notify_to_amvideo(); - remove_from_update_list(OSD2, OSD_CHANGE_ORDER); + + osd_log_dbg("index=%d,osd2_h_end=%d,dst_end=%d\n", + index, osd2_h_end, + osd_hw.free_dst_data[index].x_end); + VSYNCOSD_WR_MPEG_REG(VPP_OSD2_BLD_H_SCOPE, + osd2_h_start << 16 | osd2_h_end); + VSYNCOSD_WR_MPEG_REG(VPP_OSD2_BLD_V_SCOPE, + osd2_v_start << 16 | osd2_v_end); + + osd_log_dbg("vinfo_height=%d,vinfo_width=%d\n", + osd_hw.vinfo_height, osd_hw.vinfo_width); + VSYNCOSD_WR_MPEG_REG(VPP_POSTBLEND_H_SIZE, + osd_hw.vinfo_height << 16 | + osd_hw.vinfo_width); + VSYNCOSD_WR_MPEG_REG(VPP_OUT_H_V_SIZE, + osd_hw.vinfo_height << 16 | + osd_hw.vinfo_width); + + VSYNCOSD_WR_MPEG_REG(VPP_POST_BLEND_BLEND_DUMMY_DATA, + 0x00000000);//yuv 0x000080880 + VSYNCOSD_WR_MPEG_REG(VPP_POST_BLEND_DUMMY_ALPHA, + 0x00000000);//dummy alpha yuv 0x10000000 + + VSYNCOSD_WR_MPEG_REG(VPP_MISC, + (1 << 7) | (0 << 6)); + return 0; } -static void osd1_update_order(void) + +static int vpp_blend_setting_default(u32 index) { - switch (osd_hw.order) { - case OSD_ORDER_01: -#ifndef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - osd_reg_clr_mask(VPP_MISC, VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); -#endif - osd_vpp_misc &= ~(VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); - break; - case OSD_ORDER_10: -#ifndef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - osd_reg_set_mask(VPP_MISC, VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); -#endif - osd_vpp_misc |= (VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); - break; - default: - break; + u32 osd1_dst_h = 0, osd1_dst_v = 0; + u32 osd1_h_start = 0, osd1_h_end = 0; + u32 osd1_v_start = 0, osd1_v_end = 0; + const struct vinfo_s *vinfo; + + osd_log_dbg("vpp_blend_setting_default\n"); + vinfo = get_current_vinfo(); + if (vinfo) { + osd_hw.vinfo_width = vinfo->width; + osd_hw.vinfo_height = vinfo->height; + } else { + osd_hw.vinfo_width = 1920; + osd_hw.vinfo_height = 1080; + } + + + if (index > OSD3) { + osd_log_err("error osd index=%d\n", index); + return -1; + } + if (osd_hw.free_scale_enable[index]) { + osd1_dst_h = osd_hw.free_dst_data[index].x_end + - osd_hw.free_dst_data[index].x_start + 1; + osd1_dst_v = osd_hw.free_dst_data[index].y_end + - osd_hw.free_dst_data[index].y_start + 1; + osd1_h_start = osd_hw.free_dst_data[index].x_start; + osd1_h_end = osd_hw.free_dst_data[index].x_end; + osd1_v_start = osd_hw.free_dst_data[index].y_start; + osd1_v_end = osd_hw.free_dst_data[index].y_end; + } else { + osd1_dst_h = osd_hw.dispdata[index].x_end + - osd_hw.dispdata[index].x_start + 1; + osd1_dst_v = osd_hw.dispdata[index].y_end + - osd_hw.dispdata[index].y_start + 1; + osd1_h_start = osd_hw.dispdata[index].x_start; + osd1_h_end = osd_hw.dispdata[index].x_end; + osd1_v_start = osd_hw.dispdata[index].y_start; + osd1_v_end = osd_hw.dispdata[index].y_end; } - notify_to_amvideo(); - remove_from_update_list(OSD1, OSD_CHANGE_ORDER); + VSYNCOSD_WR_MPEG_REG(VPP_OSD1_IN_SIZE, + osd1_dst_h | osd1_dst_v << 16); + + /* setting blend scope */ + VSYNCOSD_WR_MPEG_REG(VPP_OSD1_BLD_H_SCOPE, + osd1_h_start << 16 | osd1_h_end); + VSYNCOSD_WR_MPEG_REG(VPP_OSD1_BLD_V_SCOPE, + osd1_v_start << 16 | osd1_v_end); + + osd_log_dbg("vinfo_height=%d,vinfo_width=%d\n", + osd_hw.vinfo_height, osd_hw.vinfo_width); + VSYNCOSD_WR_MPEG_REG(VPP_POSTBLEND_H_SIZE, + osd_hw.vinfo_height << 16 | + osd_hw.vinfo_width); + VSYNCOSD_WR_MPEG_REG(VPP_OUT_H_V_SIZE, + osd_hw.vinfo_height << 16 | + osd_hw.vinfo_width); + + VSYNCOSD_WR_MPEG_REG(VPP_POST_BLEND_BLEND_DUMMY_DATA, + 0x00000000);//yuv 0x000080880 + VSYNCOSD_WR_MPEG_REG(VPP_POST_BLEND_DUMMY_ALPHA, + 0x00000000);//dummy alpha yuv 0x10000000 + + VSYNCOSD_WR_MPEG_REG(VPP_MISC, + (1 << 7) | (0 << 6)); + return 0; } -#if 0 -static void osd_block_update_disp_geometry(u32 index) -{ - u32 data32; - u32 data_w1, data_w2, data_w3, data_w4; - u32 coef[4][2] = {{0, 0}, {1, 0}, {0, 1}, {1, 1} }; - u32 xoff, yoff; - u32 i; - u32 block_num; - - block_num = 4; - switch (osd_hw.block_mode[index] & HW_OSD_BLOCK_LAYOUT_MASK) { - case HW_OSD_BLOCK_LAYOUT_HORIZONTAL: - yoff = ((osd_hw.pandata[index].y_end & 0x1fff) - - (osd_hw.pandata[index].y_start & 0x1fff) + 1) >> 2; - data_w1 = (osd_hw.pandata[index].x_start & 0x1fff) | - (osd_hw.pandata[index].x_end & 0x1fff) << 16; - data_w3 = (osd_hw.dispdata[index].x_start & 0xfff) | - (osd_hw.dispdata[index].x_end & 0xfff) << 16; - for (i = 0; i < block_num; i++) { - if (i == 3) { - data_w2 = ((osd_hw.pandata[index].y_start - + yoff * i) & 0x1fff) - | (osd_hw.pandata[index].y_end - & 0x1fff) << 16; - data_w4 = ((osd_hw.dispdata[index].y_start - + yoff * i) & 0xfff) - | (osd_hw.dispdata[index].y_end - & 0xfff) << 16; - } else { - data_w2 = ((osd_hw.pandata[index].y_start - + yoff * i) & 0x1fff) - | ((osd_hw.pandata[index].y_start - + yoff * (i + 1) - 1) & 0x1fff) << 16; - data_w4 = ((osd_hw.dispdata[index].y_start - + yoff * i) & 0xfff) - | ((osd_hw.dispdata[index].y_start - + yoff * (i + 1) - 1) & 0xfff) << 16; + +static u32 order[HW_OSD_COUNT]; +static struct hw_osd_blending_s osd_blending; + +static int osd_setting_order(void) +{ + u32 ret; + u32 blend2_premult_en = 0, din_premult_en = 0; + u32 blend_din_en = 0x0; + /* blend_din0 input to blend0 */ + u32 din0_byp_blend = 0; + /* blend1_dout to blend2 */ + u32 din2_osd_sel = 0; + /* blend1_din3 input to blend1 */ + u32 din3_osd_sel = 0; + u32 postbld_src3_sel = 0, postbld_src4_sel = 0; + u32 postbld_osd1_premult = 0, postbld_osd2_premult = 0; + u32 org_order[HW_OSD_COUNT]; + int i = 0, j = 0, osd_index; + int osd_blend_mode = 0; + bool b_exchange = false, b_continuous = false; + u32 blend_hsize, blend_vsize; + + /* number largest is top layer */ + for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) { + org_order[i] = osd_hw.order[i]; + if (!osd_hw.enable[i]) + org_order[i] = 0; + order[i] = org_order[i]; + } + insert_sort(order, osd_hw.osd_meson_dev.osd_count); + b_continuous = check_order_continuous(order); + osd_log_dbg("after sort:zorder:%d,%d,%d\n", + order[0], order[1], order[2]); + + /* reorder[i] = osd[i]'s display layer */ + for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) { + for (j = 0; j < osd_hw.osd_meson_dev.osd_count; j++) { + if (order[i] == org_order[j]) { + if (osd_hw.enable[j]) + osd_blending.reorder[j] = LAYER_1 + i; + else + osd_blending.reorder[j] = + LAYER_UNSUPPORT; } - if (osd_hw.scan_mode == SCAN_MODE_INTERLACE) { - data32 = data_w4; - data_w4 = ((data32 & 0xfff) >> 1) | - ((((((data32 >> 16) & 0xfff) + 1) >> 1) - - 1) << 16); + } + } + osd_blending.layer_cnt = get_available_layers(); + + osd_log_dbg("after reorder:zorder:%d,%d,%d\n", + osd_blending.reorder[0], + osd_blending.reorder[1], + osd_blending.reorder[2]); + generate_blend_din_table(&osd_blending); + osd_log_dbg("layer_cnt:%d\n", osd_blending.layer_cnt); + + postbld_src3_sel = 3;//src1 is bottom + postbld_src4_sel = 4;//src4 is top + switch (osd_blending.layer_cnt) { + case 0: + osd_blend_mode = OSD_BLEND_NONE; + postbld_src3_sel = 0; //close vpp osd1 + postbld_src4_sel = 0; //close vpp osd2 + break; + case 1: + /* select blend_din1 always */ + osd_blend_mode = OSD_BLEND_ABC; + postbld_src3_sel = 3; + postbld_src4_sel = 0;//close vpp osd2 + break; + case 2: + /* select blend_din1, blend_din4 always */ + osd_blend_mode = OSD_BLEND_AB_C; + if (b_continuous) { + osd_index = blend_din_to_osd( + BLEND_DIN1, &osd_blending); + if (!osd_need_scaler(osd_index)) { + /* do not need scaler, mode ABC */ + osd_blend_mode = OSD_BLEND_ABC; + postbld_src4_sel = 0; + } else { + u32 index4; + + index4 = blend_din_to_osd( + BLEND_DIN4, &osd_blending); + if (is_osd_scaling_same( + osd_index, index4)) { + /* scaler is same, mode ABC */ + osd_blend_mode = OSD_BLEND_ABC; + postbld_src4_sel = 0; + } } - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1 + (i << 4), - data_w1); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W2 + (i << 4), - data_w2); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W3 + (i << 4), - data_w3); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W4 + (i << 2), - data_w4); - osd_hw.block_windows[index][i << 1] = data_w1; - osd_hw.block_windows[index][(i << 1) + 1] = data_w2; } break; - case HW_OSD_BLOCK_LAYOUT_VERTICAL: - xoff = ((osd_hw.pandata[index].x_end & 0x1fff) - - (osd_hw.pandata[index].x_start & 0x1fff) + 1) >> 2; - data_w2 = (osd_hw.pandata[index].y_start & 0x1fff) | - (osd_hw.pandata[index].y_end & 0x1fff) << 16; - data_w4 = (osd_hw.dispdata[index].y_start & 0xfff) | - (osd_hw.dispdata[index].y_end & 0xfff) << 16; - if (osd_hw.scan_mode == SCAN_MODE_INTERLACE) { - data32 = data_w4; - data_w4 = ((data32 & 0xfff) >> 1) - | ((((((data32 >> 16) & 0xfff) + 1) >> 1) - 1) - << 16); + case 3: + if (order[0] == order[1] + 1) { + if (order[1] == order[2] + 1) { + osd_index = blend_din_to_osd( + BLEND_DIN1, &osd_blending); + if (!osd_need_scaler(osd_index)) { + /* do not need scaler, mode ABC */ + osd_blend_mode = OSD_BLEND_ABC; + postbld_src4_sel = 0; + } else { + u32 index3, index4; + + index3 = blend_din_to_osd(BLEND_DIN3, + &osd_blending); + index4 = blend_din_to_osd(BLEND_DIN4, + &osd_blending); + osd_log_dbg( + "BLEND_DIN1 need scaler,check osd%d, osd%d\n", + index3, index4); + if ((is_osd_scaling_same( + osd_index, index3)) + && (is_osd_scaling_same( + osd_index, index4))) { + /* scaler is same */ + osd_blend_mode = OSD_BLEND_ABC; + postbld_src4_sel = 0; + } else + osd_blend_mode = OSD_BLEND_A_BC; + } + } else + osd_blend_mode = OSD_BLEND_A_BC; + } else { + osd_log_dbg("adjust din map\n"); + osd_blend_mode = OSD_BLEND_A_BC; + b_exchange = 1; + adjust_blend_din_table(&osd_blending); + } + break; + } + osd_log_dbg("is osd_blend_mode=%d\n", osd_blend_mode); + osd_log_dbg("blend_din1 == osd%d\n", + blend_din_to_osd(BLEND_DIN1, &osd_blending) + 1); + osd_log_dbg("blend_din3 == osd%d\n", + blend_din_to_osd(BLEND_DIN3, &osd_blending) + 1); + osd_log_dbg("blend_din4 == osd%d\n", + blend_din_to_osd(BLEND_DIN4, &osd_blending) + 1); + osd_log_dbg("din_reoder_sel=%x\n", + osd_blending.din_reoder_sel); + + for (i = 0; i < OSD_BLEND_LAYERS; i++) { + /* find osd index */ + osd_index = blend_din_to_osd(i, &osd_blending); + if ((osd_index >= OSD1) && (osd_index <= OSD3)) { + /* depend on osd enable */ + blend_din_en = _set_bits( + blend_din_en, + i, + osd_hw.enable[osd_index]); + din_premult_en = _set_bits( + din_premult_en, + i, + osd_hw.premult_en[osd_index]); } - for (i = 0; i < block_num; i++) { - data_w1 = ((osd_hw.pandata[index].x_start + xoff * i) - & 0x1fff) - | ((osd_hw.pandata[index].x_start - + xoff * (i + 1) - 1) & 0x1fff) << 16; - data_w3 = ((osd_hw.dispdata[index].x_start + xoff * i) - & 0xfff) - | ((osd_hw.dispdata[index].x_start - + xoff * (i + 1) - 1) & 0xfff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1 + (i << 4), - data_w1); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W2 + (i << 4), - data_w2); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W3 + (i << 4), - data_w3); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W4 + (i << 2), - data_w4); - osd_hw.block_windows[index][i << 1] = data_w1; - osd_hw.block_windows[index][(i << 1) + 1] = data_w2; + } + switch (osd_blend_mode) { + case OSD_BLEND_ABC: + /* blend1_dout to blend1 */ + din2_osd_sel = 0; + /* blend1_din3 input to blend1 */ + din3_osd_sel = 0; + + switch (osd_blending.layer_cnt) { + case 1: + /* blend_din0 bypass to dout0 */ + din0_byp_blend = 1; + break; + case 2: + case 3: + /* blend_din0 input to blend0 */ + din0_byp_blend = 0; + /* if one blend input, output is premult = 1 */ + blend2_premult_en = _set_bits( + blend2_premult_en, + 0, 1); + blend2_premult_en = _set_bits( + blend2_premult_en, + 1, 1); + /* depend on blend2_premult_en */ + postbld_osd1_premult = _set_bits( + postbld_osd1_premult, + 0, + (blend2_premult_en & 0x3) ? 1 : 0); + /* no vpp_osd2 */ + /* need close vpp_osd2 input */ + break; } + #if 0 + blend2_premult_en = _set_bits( + blend2_premult_en, + 1, + (din_premult_en & 0xc0) ? 1 : 0); + #endif break; - case HW_OSD_BLOCK_LAYOUT_GRID: - xoff = ((osd_hw.pandata[index].x_end & 0x1fff) - - (osd_hw.pandata[index].x_start & 0x1fff) + 1) >> 1; - yoff = ((osd_hw.pandata[index].y_end & 0x1fff) - - (osd_hw.pandata[index].y_start & 0x1fff) + 1) >> 1; - for (i = 0; i < block_num; i++) { - data_w1 = ((osd_hw.pandata[index].x_start - + xoff * coef[i][0]) & 0x1fff) - | ((osd_hw.pandata[index].x_start - + xoff * (coef[i][0] + 1) - 1) & 0x1fff) << 16; - data_w2 = ((osd_hw.pandata[index].y_start - + yoff * coef[i][1]) & 0x1fff) - | ((osd_hw.pandata[index].y_start - + yoff * (coef[i][1] + 1) - 1) & 0x1fff) << 16; - data_w3 = ((osd_hw.dispdata[index].x_start - + xoff * coef[i][0]) & 0xfff) - | ((osd_hw.dispdata[index].x_start - + xoff * (coef[i][0] + 1) - 1) & 0xfff) << 16; - data_w4 = ((osd_hw.dispdata[index].y_start - + yoff * coef[i][1]) & 0xfff) - | ((osd_hw.dispdata[index].y_start - + yoff * (coef[i][1] + 1) - 1) & 0xfff) << 16; - if (osd_hw.scan_mode == SCAN_MODE_INTERLACE) { - data32 = data_w4; - data_w4 = ((data32 & 0xfff) >> 1) - | ((((((data32 >> 16) & 0xfff) - + 1) >> 1) - 1) << 16); - } - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1 + (i << 4), - data_w1); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W2 + (i << 4), - data_w2); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W3 + (i << 4), - data_w3); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W4 + (i << 2), - data_w4); - osd_hw.block_windows[index][i << 1] = data_w1; - osd_hw.block_windows[index][(i << 1) + 1] = data_w2; + case OSD_BLEND_AB_C: + if (osd_blending.layer_cnt == 3) { + /* blend_din0 input to blend0 */ + din0_byp_blend = 0; + /* blend1_dout to blend2 */ + din2_osd_sel = 0; + /* blend1_din3 bypass to dout1 */ + din3_osd_sel = 1; + blend2_premult_en = _set_bits( + blend2_premult_en, + 0, + 1); + blend2_premult_en = _set_bits( + blend2_premult_en, + 1, + 1); + /* depend on blend2_premult_en */ + postbld_osd1_premult = _set_bits( + postbld_osd1_premult, + 0, + (blend2_premult_en & 0x3) ? 1 : 0); + /* depend on din_premult_en bit 4 */ + postbld_osd2_premult = _set_bits( + postbld_osd2_premult, + 0, + (din_premult_en & 0x8) ? 1 : 0); + } else if (osd_blending.layer_cnt == 2) { + /* blend_din0 input to blend0 */ + din0_byp_blend = 1; + /* blend1_dout to dout1 */ + din2_osd_sel = 1; + /* blend1_din3 input to blend1 */ + din3_osd_sel = 1; + + /* depend on din0_premult_en */ + postbld_osd1_premult = _set_bits( + postbld_osd1_premult, + 0, + (din_premult_en & 0x1) ? 1 : 0); + /* depend on din_premult_en bit 4 */ + postbld_osd2_premult = _set_bits( + postbld_osd2_premult, + 0, + (din_premult_en & 0x8) ? 1 : 0); + osd_log_dbg("postbld_osd1_premult=%x\n", + postbld_osd1_premult); + osd_log_dbg("postbld_osd2_premult=%x\n", + postbld_osd2_premult); } break; - case HW_OSD_BLOCK_LAYOUT_CUSTOMER: - for (i = 0; i < block_num; i++) { - if (((osd_hw.block_windows[index][i << 1] >> 16) - & 0x1fff) > - osd_hw.pandata[index].x_end) { - osd_hw.block_windows[index][i << 1] = - (osd_hw.block_windows[index][i << 1] - & 0x1fff) - | ((osd_hw.pandata[index].x_end - & 0x1fff) << 16); + case OSD_BLEND_A_BC: + /* blend_din0 bypass to dout0 */ + din0_byp_blend = 1; + /* blend1_dout to dout1 */ + din2_osd_sel = 1; + /* blend1_din3 input to blend1 */ + din3_osd_sel = 0; + /* no input to blend0 & blend1 */ + /* depend on din_premult_en bit 1 */ + postbld_osd1_premult = _set_bits( + postbld_osd1_premult, + 0, + (din_premult_en & 0x1) ? 1 : 0); + /* via blend2 always premult */ + postbld_osd2_premult = _set_bits( + postbld_osd2_premult, + 0, 1); + #if 0 + /* depend on din_premult_en bit 3_4 */ + postbld_osd2_premult = _set_bits( + postbld_osd2_premult, + 0, + (din_premult_en & 0xc) ? 1 : 0); + #endif + break; + } + if (b_exchange) { + u32 temp = 0; + + postbld_src3_sel = 4;//src1 is bottom + postbld_src4_sel = 3;//src4 is top + temp = postbld_osd1_premult; + postbld_osd1_premult = postbld_osd2_premult; + postbld_osd2_premult = temp; + } + osd_log_dbg("blend_din_en=%x,din_premult_en=%x,blend2_premult_en=%x\n", + blend_din_en, + din_premult_en, + blend2_premult_en); + + osd_log_dbg("din0_sel=%x,din2_sel=%x,din3_sel=%x\n", + din0_byp_blend, + din2_osd_sel, + din3_osd_sel); + + osd_log_dbg("postbld_osd1_premult=%x,postbld_osd2_premult=%x\n", + postbld_osd1_premult, + postbld_osd2_premult); + + //spin_lock_irqsave(&osd_lock, lock_flags); + for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) { + adjust_freescale_para(&osd_blending); + osd_hw.free_scale[i].h_enable = 1; + osd_hw.free_scale[i].v_enable = 1; + //osd_hw.free_scale_backup[i].h_enable = 1; + //osd_hw.free_scale_backup[i].v_enable = 1; + ret = osd_set_scan_mode(i); + if (ret) + osd_hw.reg[OSD_COLOR_MODE].update_func(i); + osd_hw.reg[OSD_FREESCALE_COEF].update_func(i); + osd_hw.reg[DISP_GEOMETRY].update_func(i); + osd_hw.reg[DISP_FREESCALE_ENABLE].update_func(i); + osd_hw.reg[OSD_ENABLE].update_func(i); + } + /* osd blend ctrl */ + VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_CTRL, + 4 << 29| + blend2_premult_en << 27| + din0_byp_blend << 26| + din2_osd_sel << 25| + din3_osd_sel << 24| + blend_din_en << 20| + din_premult_en << 16| + osd_blending.din_reoder_sel); + /* vpp osd1 blend ctrl */ + VSYNCOSD_WR_MPEG_REG(OSD1_BLEND_SRC_CTRL, + (0 & 0xf) << 0 | + (0 & 0x1) << 4 | + (postbld_src3_sel & 0xf) << 8 | + (postbld_osd1_premult & 0x1) << 16| + (1 & 0x1) << 20); + /* vpp osd2 blend ctrl */ + VSYNCOSD_WR_MPEG_REG(OSD2_BLEND_SRC_CTRL, + (0 & 0xf) << 0 | + (0 & 0x1) << 4 | + (postbld_src4_sel & 0xf) << 8 | + (postbld_osd2_premult & 0x1) << 16 | + (1 & 0x1) << 20); + blend_hsize = osd_hw.background_w; + blend_vsize = osd_hw.background_h; + + VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND0_SIZE, + blend_vsize << 16 | + blend_hsize); + VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND1_SIZE, + blend_vsize << 16 | + blend_hsize); + #if 0 + /* close vd1, vd2 for debug */ + VSYNCOSD_WR_MPEG_REG(VD1_BLEND_SRC_CTRL, 0); + VSYNCOSD_WR_MPEG_REG(VD2_BLEND_SRC_CTRL, 0); + + VSYNCOSD_WR_MPEG_REG_BITS(DOLBY_PATH_CTRL, + 0xf, 0, 4); + #endif + for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) { + if (osd_hw.enable[i]) + ret = osd_setting_blending_scope(i); + } + osd_hw.osd_blend_mode = osd_blend_mode; + ret = vpp_blend_setting(&osd_blending); + //spin_unlock_irqrestore(&osd_lock, lock_flags); + return ret; + + return 0; +} + +/* only one layer */ +static void osd_setting_default_hwc(void) +{ + u32 blend_hsize, blend_vsize; + u32 blend2_premult_en = 1, din_premult_en = 0; + u32 blend_din_en = 0x1; + /* blend_din0 input to blend0 */ + u32 din0_byp_blend = 1; + /* blend1_dout to blend2 */ + u32 din2_osd_sel = 1; + /* blend1_din3 input to blend1 */ + u32 din3_osd_sel = 1; + u32 din_reoder_sel = 0x1; + u32 postbld_src3_sel = 3, postbld_src4_sel = 0; + u32 postbld_osd1_premult = 1, postbld_osd2_premult = 0; + + osd_log_dbg("osd_setting_default_hwc\n"); + /* depend on din0_premult_en */ + postbld_osd1_premult = 1; + /* depend on din_premult_en bit 4 */ + postbld_osd2_premult = 0; + /* osd blend ctrl */ + VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_CTRL, + 4 << 29| + blend2_premult_en << 27| + din0_byp_blend << 26| + din2_osd_sel << 25| + din3_osd_sel << 24| + blend_din_en << 20| + din_premult_en << 16| + din_reoder_sel); + /* vpp osd1 blend ctrl */ + VSYNCOSD_WR_MPEG_REG(OSD1_BLEND_SRC_CTRL, + (0 & 0xf) << 0 | + (0 & 0x1) << 4 | + (postbld_src3_sel & 0xf) << 8 | + (postbld_osd1_premult & 0x1) << 16| + (1 & 0x1) << 20); + /* vpp osd2 blend ctrl */ + VSYNCOSD_WR_MPEG_REG(OSD2_BLEND_SRC_CTRL, + (0 & 0xf) << 0 | + (0 & 0x1) << 4 | + (postbld_src4_sel & 0xf) << 8 | + (postbld_osd2_premult & 0x1) << 16 | + (1 & 0x1) << 20); + + /* Do later: different format select different dummy_data */ + /* used default dummy data */ + VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_DUMMY_DATA0, + 0x0 << 16 | + 0x0 << 8 | + 0x0); + /* used default dummy alpha data */ + VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_DUMMY_ALPHA, + 0x0 << 20 | + 0x0 << 11 | + 0x0); + + blend_hsize = osd_hw.background_w; + blend_vsize = osd_hw.background_h; + + VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND0_SIZE, + blend_vsize << 16 | + blend_hsize); + VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND1_SIZE, + blend_vsize << 16 | + blend_hsize); + + /* close vd1, vd2 for debug */ + VSYNCOSD_WR_MPEG_REG(VD1_BLEND_SRC_CTRL, 0); + VSYNCOSD_WR_MPEG_REG(VD2_BLEND_SRC_CTRL, 0); + + VSYNCOSD_WR_MPEG_REG_BITS(DOLBY_PATH_CTRL, + 0xf, 0, 4); +} + +int osd_setting_blend(void) +{ + int ret; + const struct vinfo_s *vinfo; + + vinfo = get_current_vinfo(); + if (vinfo) { + osd_hw.vinfo_width = vinfo->width; + osd_hw.vinfo_height = vinfo->height; + } else { + osd_hw.vinfo_width = 1920; + osd_hw.vinfo_height = 1080; + } + + if (osd_hw.osd_meson_dev.osd_ver < OSD_HIGH_ONE) + return 0; + if (osd_hw.hwc_enable) { + ret = osd_setting_order(); + if (ret < 0) + return -1; + } else + osd_setting_default_hwc(); + + return 0; +} + + +void osd_mali_afbc_restart(void) +{ + int i, osd_count, afbc_enable; + + afbc_enable = 0; + osd_count = osd_hw.osd_meson_dev.osd_count; + if ((osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) + && osd_hw.afbc_restart_in_vsync) { + VSYNCOSD_WR_MPEG_REG(VPU_MAFBC_IRQ_MASK, 0xf); + for (i = 0; i < osd_count; i++) { + if (osd_hw.osd_afbcd[i].afbc_start) { + /* enable mali afbc */ + VSYNCOSD_WR_MPEG_REG_BITS( + VPU_MAFBC_SURFACE_CFG, + 1, i, 1); + afbc_enable = 1; } - data_w1 = osd_hw.block_windows[index][i << 1] - & 0x1fff1fff; - data_w2 = ((osd_hw.pandata[index].y_start & 0x1fff) + - (osd_hw.block_windows[index][(i << 1) + 1] - & 0x1fff)) - | (((osd_hw.pandata[index].y_start & 0x1fff) - << 16) - + (osd_hw.block_windows[index][(i << 1) + 1] - & 0x1fff0000)); - data_w3 = (osd_hw.dispdata[index].x_start - + (data_w1 & 0xfff)) - | (((osd_hw.dispdata[index].x_start & 0xfff) - << 16) + (data_w1 & 0xfff0000)); - data_w4 = (osd_hw.dispdata[index].y_start - + (osd_hw.block_windows[index][(i << 1) + 1] - & 0xfff)) - | (((osd_hw.dispdata[index].y_start & 0xfff) - << 16) - + (osd_hw.block_windows[index][(i << 1) + 1] - & 0xfff0000)); - if (osd_hw.scan_mode == SCAN_MODE_INTERLACE) { - data32 = data_w4; - data_w4 = ((data32 & 0xfff) >> 1) - | ((((((data32 >> 16) & 0xfff) + 1) - >> 1) - 1) << 16); + } + if (afbc_enable) { + if (osd_hw.afbc_use_latch) + VSYNCOSD_WR_MPEG_REG(VPU_MAFBC_COMMAND, 0x2); + else { + osd_log_dbg("start afbc decode\n"); + /* start decode */ + VSYNCOSD_WR_MPEG_REG(VPU_MAFBC_COMMAND, 1); } - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1 + (i << 4), - data_w1); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W2 + (i << 4), - data_w2); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W3 + (i << 4), - data_w3); - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W4 + (i << 2), - data_w4); } - break; - default: - osd_log_err("ERROR block_mode: 0x%x\n", - osd_hw.block_mode[index]); - break; } } -#endif -static void osd1_2x_scale_update_geometry(void) + +static void osd_basic_update_disp_geometry(u32 index) { + struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index]; u32 data32; - data32 = (osd_hw.scaledata[OSD1].x_start & 0x1fff) | - (osd_hw.scaledata[OSD1].x_end & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1, data32); + data32 = (osd_hw.dispdata[index].x_start & 0xfff) + | (osd_hw.dispdata[index].x_end & 0xfff) << 16; + VSYNCOSD_WR_MPEG_REG( + osd_reg->osd_blk0_cfg_w3, data32); + if (osd_hw.scan_mode[index] == SCAN_MODE_INTERLACE) + data32 = ((osd_hw.dispdata[index].y_start >> 1) & 0xfff) + | ((((osd_hw.dispdata[index].y_end + 1) + >> 1) - 1) & 0xfff) << 16; + else + data32 = (osd_hw.dispdata[index].y_start & 0xfff) + | (osd_hw.dispdata[index].y_end + & 0xfff) << 16; + VSYNCOSD_WR_MPEG_REG( + osd_reg->osd_blk0_cfg_w4, data32); - if (osd_hw.osd_afbcd[OSD1].enable) { - data32 = (osd_hw.scaledata[OSD1].x_end & 0x1fff) | - (osd_hw.scaledata[OSD1].x_start & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_PIXEL_HSCOPE, data32); - data32 = (osd_hw.scaledata[OSD1].y_end & 0x1fff) | - (osd_hw.scaledata[OSD1].y_start & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_PIXEL_VSCOPE, data32); - VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_HDR_PTR, - osd_hw.osd_afbcd[OSD1].phy_addr >> 4); - VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_FRAME_PTR, - osd_hw.osd_afbcd[OSD1].phy_addr >> 4); - data32 = (0xe4 << 24) | - (osd_hw.osd_afbcd[OSD1].phy_addr & 0xffffff); - VSYNCOSD_WR_MPEG_REG( - OSD1_AFBCD_CHROMA_PTR, - data32); - } + if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) { + if (osd_hw.osd_afbcd[index].enable) { + long int headr_addr, out_addr; + + /* set frame addr in linear: out_addr_id */ + headr_addr = osd_hw.osd_afbcd[index].phy_addr; + out_addr = osd_hw.osd_afbcd[index].out_addr_id << 24; + + /* 0:canvas_araddr + * 1:linear_araddr + */ + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_ctrl_stat, 0x1, 2, 1); + VSYNCOSD_WR_MPEG_REG( + osd_reg->osd_blk1_cfg_w4, out_addr); + /* unpac mali src */ + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_mali_unpack_ctrl, 0x1, 31, 1); - data32 = ((osd_hw.scaledata[OSD1].y_start - + osd_hw.pandata[OSD1].y_start) & 0x1fff) - | ((osd_hw.scaledata[OSD1].y_end - + osd_hw.pandata[OSD1].y_start) & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W2, data32); - /* adjust display x-axis */ - if (osd_hw.scale[OSD1].h_enable) { - data32 = (osd_hw.dispdata[OSD1].x_start & 0xfff) - | ((osd_hw.dispdata[OSD1].x_start - + (osd_hw.scaledata[OSD1].x_end - - osd_hw.scaledata[OSD1].x_start) * 2 + 1) - & 0xfff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W3, data32); - if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE) { - data32 = ((osd_hw.dispdata[OSD1].y_start >> 1) & 0xfff) - | (((((osd_hw.dispdata[OSD1].y_start - + (osd_hw.scaledata[OSD1].y_end - - osd_hw.scaledata[OSD1].y_start) * 2) - + 1) >> 1) - 1) & 0xfff) << 16; + /* osd swtich to mali */ + VSYNCOSD_WR_MPEG_REG_BITS( + OSD_PATH_MISC_CTRL, 0x01, (index + 4), 1); + + /* 0:canvas_araddr + * 1:linear_araddr + */ + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_ctrl_stat, 0x1, 2, 1); + /* set lens 0 */ + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_fifo_ctrl_stat, + 0x2, 22, 2); + /* read from mali afbd decoder */ + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_blk0_cfg_w0, 0x1, 30, 1); + + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_header_buf_addr_low_s, + headr_addr & 0xffffffff); + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_header_buf_addr_high_s, + (headr_addr >> 32) & 0xffffffff); + VSYNCOSD_WR_MPEG_REG(osd_reg->afbc_buffer_width_s, + osd_hw.osd_afbcd[index].frame_width); + VSYNCOSD_WR_MPEG_REG(osd_reg->afbc_buffer_hight_s, + osd_hw.osd_afbcd[index].frame_height); + + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_output_buf_addr_low_s, + out_addr & 0xffffffff); + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_output_buf_addr_high_s, + (out_addr >> 32) & 0xffffffff); } else { - data32 = (osd_hw.dispdata[OSD1].y_start & 0xfff) - | (((osd_hw.dispdata[OSD1].y_start - + (osd_hw.scaledata[OSD1].y_end - - osd_hw.scaledata[OSD1].y_start) * 2)) - & 0xfff) << 16; + /* osd swtich to mali */ + VSYNCOSD_WR_MPEG_REG_BITS( + OSD_PATH_MISC_CTRL, 0x0, (index + 4), 1); + /* unpac normal src */ + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_mali_unpack_ctrl, 0x0, 31, 1); + /* read from ddr */ + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_blk0_cfg_w0, 0x0, 30, 1); + /* use canvas addr */ + VSYNCOSD_WR_MPEG_REG_BITS( + osd_reg->osd_ctrl_stat, 0x0, 2, 1); + /* set lens 0 */ + VSYNCOSD_WR_MPEG_REG_BITS(osd_reg->osd_fifo_ctrl_stat, + 0x0, 22, 2); } - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W4, data32); } - /* adjust display y-axis */ - if (osd_hw.scale[OSD1].v_enable) { - data32 = (osd_hw.dispdata[OSD1].x_start & 0xfff) - | ((osd_hw.dispdata[OSD1].x_start - + (osd_hw.scaledata[OSD1].x_end - - osd_hw.scaledata[OSD1].x_start) * 2 + 1) - & 0xfff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W3, data32); - if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE) { - data32 = ((osd_hw.dispdata[OSD1].y_start >> 1) & 0xfff) - | (((((osd_hw.dispdata[OSD1].y_start - + (osd_hw.scaledata[OSD1].y_end - - osd_hw.scaledata[OSD1].y_start) * 2) - + 1) >> 1) - 1) & 0xfff) << 16; - } else { - data32 = (osd_hw.dispdata[OSD1].y_start & 0xfff) - | (((osd_hw.dispdata[OSD1].y_start - + (osd_hw.scaledata[OSD1].y_end - - osd_hw.scaledata[OSD1].y_start) * 2)) - & 0xfff) << 16; + if (osd_hw.free_scale_enable[index] + && (osd_hw.free_src_data[index].x_end > 0) + && (osd_hw.free_src_data[index].y_end > 0)) { + /* enable osd free scale */ + data32 = (osd_hw.free_src_data[index].x_start & 0x1fff) | + (osd_hw.free_src_data[index].x_end & 0x1fff) << 16; + VSYNCOSD_WR_MPEG_REG( + osd_reg->osd_blk0_cfg_w1, data32); + if (osd_hw.osd_afbcd[index].enable) { + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_boundings_box_x_start_s, + osd_hw.free_src_data[index].x_start); + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_boundings_box_x_end_s, + osd_hw.free_src_data[index].x_end); + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_boundings_box_y_start_s, + osd_hw.free_src_data[index].y_start); + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_boundings_box_y_end_s, + osd_hw.free_src_data[index].y_end); + } + data32 = ((osd_hw.free_src_data[index].y_start + + osd_hw.pandata[index].y_start) & 0x1fff) + | ((osd_hw.free_src_data[index].y_end + + osd_hw.pandata[index].y_start) & 0x1fff) << 16; + VSYNCOSD_WR_MPEG_REG(osd_reg->osd_blk0_cfg_w2, data32); + } else { + /* normal mode */ + data32 = (osd_hw.pandata[index].x_start & 0x1fff) + | (osd_hw.pandata[index].x_end & 0x1fff) << 16; + VSYNCOSD_WR_MPEG_REG( + osd_reg->osd_blk0_cfg_w1, data32); + if (osd_hw.osd_afbcd[index].enable) { + u32 virtual_y_start, virtual_y_end; + + virtual_y_start = osd_hw.pandata[index].y_start % + osd_hw.osd_afbcd[index].frame_height; + virtual_y_end = osd_hw.pandata[index].y_end - + osd_hw.pandata[index].y_start + virtual_y_start; + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_boundings_box_x_start_s, + osd_hw.pandata[index].x_start); + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_boundings_box_x_end_s, + osd_hw.pandata[index].x_end); + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_boundings_box_y_start_s, + virtual_y_start); + VSYNCOSD_WR_MPEG_REG( + osd_reg->afbc_boundings_box_y_end_s, + virtual_y_end); } - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W4, data32); + data32 = (osd_hw.pandata[index].y_start & 0x1fff) + | (osd_hw.pandata[index].y_end & 0x1fff) << 16; + VSYNCOSD_WR_MPEG_REG(osd_reg->osd_blk0_cfg_w2, data32); } + data32 = VSYNCOSD_RD_MPEG_REG(osd_reg->osd_ctrl_stat); + data32 &= ~0x1ff008;//0x1ff00e; + data32 |= osd_hw.gbl_alpha[index] << 12; + /* data32 |= HW_OSD_BLOCK_ENABLE_0; */ + VSYNCOSD_WR_MPEG_REG(osd_reg->osd_ctrl_stat, data32); + remove_from_update_list(index, DISP_GEOMETRY); } static void osd1_basic_update_disp_geometry(void) @@ -3645,7 +5357,8 @@ static void osd1_basic_update_disp_geometry(void) u32 buffer_w, buffer_h; data32 = (osd_hw.dispdata[OSD1].x_start & 0xfff) | (osd_hw.dispdata[OSD1].x_end & 0xfff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W3, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w3, data32); if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE) data32 = ((osd_hw.dispdata[OSD1].y_start >> 1) & 0xfff) | ((((osd_hw.dispdata[OSD1].y_end + 1) @@ -3654,7 +5367,8 @@ static void osd1_basic_update_disp_geometry(void) data32 = (osd_hw.dispdata[OSD1].y_start & 0xfff) | (osd_hw.dispdata[OSD1].y_end & 0xfff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W4, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w4, data32); if (osd_hw.osd_afbcd[OSD1].enable) VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_SIZE_IN, @@ -3666,9 +5380,11 @@ static void osd1_basic_update_disp_geometry(void) /* enable osd 2x scale */ if (osd_hw.scale[OSD1].h_enable || osd_hw.scale[OSD1].v_enable) { osd1_2x_scale_update_geometry(); - data32 = VSYNCOSD_RD_MPEG_REG(VIU_OSD1_BLK0_CFG_W1); + data32 = VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w1); buffer_w = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1; - data32 = VSYNCOSD_RD_MPEG_REG(VIU_OSD1_BLK0_CFG_W2); + data32 = VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w2); buffer_h = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1; } else if (osd_hw.free_scale_enable[OSD1] && (osd_hw.free_src_data[OSD1].x_end > 0) @@ -3676,7 +5392,8 @@ static void osd1_basic_update_disp_geometry(void) /* enable osd free scale */ data32 = (osd_hw.free_src_data[OSD1].x_start & 0x1fff) | (osd_hw.free_src_data[OSD1].x_end & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w1, data32); buffer_w = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1; if (osd_hw.osd_afbcd[OSD1].enable) { data32 = @@ -3709,7 +5426,8 @@ static void osd1_basic_update_disp_geometry(void) /* normal mode */ data32 = (osd_hw.pandata[OSD1].x_start & 0x1fff) | (osd_hw.pandata[OSD1].x_end & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w1, data32); buffer_w = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1; if (osd_hw.osd_afbcd[OSD1].enable) { u32 virtual_y_start, virtual_y_end; @@ -3736,10 +5454,11 @@ static void osd1_basic_update_disp_geometry(void) } data32 = (osd_hw.pandata[OSD1].y_start & 0x1fff) | (osd_hw.pandata[OSD1].y_end & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W2, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD1].osd_blk0_cfg_w2, data32); buffer_h = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1; } - if (is_meson_txlx_cpu()) { + if (osd_hw.osd_meson_dev.has_dolby_vision) { VSYNCOSD_WR_MPEG_REG( DOLBY_CORE2A_SWAP_CTRL1, ((buffer_w + 0x40) << 16) @@ -3754,42 +5473,23 @@ static void osd1_basic_update_disp_geometry(void) VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_ENABLE, 0x8100); osd_afbc_dec_enable = 1; } - data32 = VSYNCOSD_RD_MPEG_REG(VIU_OSD1_CTRL_STAT); + data32 = VSYNCOSD_RD_MPEG_REG(hw_osd_reg_array[OSD1].osd_ctrl_stat); data32 &= ~0x1ff00e; data32 |= osd_hw.gbl_alpha[OSD1] << 12; /* data32 |= HW_OSD_BLOCK_ENABLE_0; */ - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_CTRL_STAT, data32); -} - -static void osd1_update_disp_geometry(void) -{ - if ((osd_hw.block_mode[OSD1]) && - (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXBB)) { - /* multi block */ - /* - * osd_block_update_disp_geometry(OSD1); - * data32 = VSYNCOSD_RD_MPEG_REG(VIU_OSD1_CTRL_STAT); - * data32 &= 0xfffffff0; - * data32 |= (osd_hw.block_mode[OSD1] - * & HW_OSD_BLOCK_ENABLE_MASK); - * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_CTRL_STAT, data32); - */ - osd_log_info( - "osd1_update_disp_geometry: not support block mode\n"); - } else { - /* single block */ - osd1_basic_update_disp_geometry(); - } + VSYNCOSD_WR_MPEG_REG(hw_osd_reg_array[OSD1].osd_ctrl_stat, data32); remove_from_update_list(OSD1, DISP_GEOMETRY); } + static void osd2_update_disp_geometry(void) { u32 data32; data32 = (osd_hw.dispdata[OSD2].x_start & 0xfff) | (osd_hw.dispdata[OSD2].x_end & 0xfff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W3, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w3, data32); if ((osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE) && osd_hw.dispdata[OSD2].y_start > 0) data32 = (osd_hw.dispdata[OSD2].y_start & 0xfff) @@ -3800,24 +5500,29 @@ static void osd2_update_disp_geometry(void) else data32 = (osd_hw.dispdata[OSD2].y_start & 0xfff) | (osd_hw.dispdata[OSD2].y_end & 0xfff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W4, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w4, data32); if (osd_hw.scale[OSD2].h_enable || osd_hw.scale[OSD2].v_enable) { #if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) data32 = (osd_hw.pandata[OSD2].x_start & 0x1fff) | (osd_hw.pandata[OSD2].x_end & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W1, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w1, data32); data32 = (osd_hw.pandata[OSD2].y_start & 0x1fff) | (osd_hw.pandata[OSD2].y_end & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W2, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w2, data32); #else data32 = (osd_hw.scaledata[OSD2].x_start & 0x1fff) | (osd_hw.scaledata[OSD2].x_end & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W1, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w1, data32); data32 = ((osd_hw.scaledata[OSD2].y_start + osd_hw.pandata[OSD2].y_start) & 0x1fff) | ((osd_hw.scaledata[OSD2].y_end + osd_hw.pandata[OSD2].y_start) & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W2, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w2, data32); #endif } else if (osd_hw.free_scale_enable[OSD2] && (osd_hw.free_src_data[OSD2].x_end > 0) @@ -3825,98 +5530,86 @@ static void osd2_update_disp_geometry(void) /* enable osd free scale */ data32 = (osd_hw.free_src_data[OSD2].x_start & 0x1fff) | (osd_hw.free_src_data[OSD2].x_end & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W1, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w1, data32); data32 = ((osd_hw.free_src_data[OSD2].y_start + osd_hw.pandata[OSD2].y_start) & 0x1fff) | ((osd_hw.free_src_data[OSD2].y_end + osd_hw.pandata[OSD2].y_start) & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W2, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w2, data32); } else { data32 = (osd_hw.pandata[OSD2].x_start & 0x1fff) | (osd_hw.pandata[OSD2].x_end & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W1, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w1, data32); data32 = (osd_hw.pandata[OSD2].y_start & 0x1fff) | (osd_hw.pandata[OSD2].y_end & 0x1fff) << 16; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W2, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_blk0_cfg_w2, data32); } - data32 = VSYNCOSD_RD_MPEG_REG(VIU_OSD2_CTRL_STAT); + data32 = VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[OSD2].osd_ctrl_stat); data32 &= ~0x1ff000; data32 |= osd_hw.gbl_alpha[OSD2] << 12; /* data32 |= HW_OSD_BLOCK_ENABLE_0; */ - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_CTRL_STAT, data32); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[OSD2].osd_ctrl_stat, data32); remove_from_update_list(OSD2, DISP_GEOMETRY); } -static void osd1_update_disp_3d_mode(void) -{ - /*step 1 . set pan data */ - /* only called by vsync irq or rdma irq */ - u32 data32; - if (osd_hw.mode_3d[OSD1].left_right == OSD_LEFT) { - data32 = (osd_hw.mode_3d[OSD1].l_start & 0x1fff) - | (osd_hw.mode_3d[OSD1].l_end & 0x1fff) << 16; - VSYNCOSD_IRQ_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1, data32); +static void osd_update_disp_geometry(u32 index) +{ + if ((osd_hw.block_mode[index]) && + (osd_hw.osd_meson_dev.cpu_id <= __MESON_CPU_MAJOR_ID_GXBB)) { + osd_log_info( + "osd1_update_disp_geometry: not support block mode\n"); } else { - data32 = (osd_hw.mode_3d[OSD1].r_start & 0x1fff) - | (osd_hw.mode_3d[OSD1].r_end & 0x1fff) << 16; - VSYNCOSD_IRQ_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1, data32); + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + /* single block */ + if (index == OSD1) + osd1_basic_update_disp_geometry(); + else if (index == OSD2) + osd2_update_disp_geometry(); + } else { + osd_basic_update_disp_geometry(index); + } } - osd_hw.mode_3d[OSD1].left_right ^= 1; } -static void osd2_update_disp_3d_mode(void) + + +static void osd_update_disp_3d_mode(u32 index) { + /*step 1 . set pan data */ /* only called by vsync irq or rdma irq */ u32 data32; - if (osd_hw.mode_3d[OSD2].left_right == OSD_LEFT) { - data32 = (osd_hw.mode_3d[OSD2].l_start & 0x1fff) - | (osd_hw.mode_3d[OSD2].l_end & 0x1fff) << 16; - VSYNCOSD_IRQ_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W1, data32); + if (osd_hw.mode_3d[index].left_right == OSD_LEFT) { + data32 = (osd_hw.mode_3d[index].l_start & 0x1fff) + | (osd_hw.mode_3d[index].l_end & 0x1fff) << 16; + VSYNCOSD_IRQ_WR_MPEG_REG( + hw_osd_reg_array[index].osd_blk0_cfg_w1, data32); } else { - data32 = (osd_hw.mode_3d[OSD2].r_start & 0x1fff) - | (osd_hw.mode_3d[OSD2].r_end & 0x1fff) << 16; - VSYNCOSD_IRQ_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W1, data32); + data32 = (osd_hw.mode_3d[index].r_start & 0x1fff) + | (osd_hw.mode_3d[index].r_end & 0x1fff) << 16; + VSYNCOSD_IRQ_WR_MPEG_REG( + hw_osd_reg_array[index].osd_blk0_cfg_w1, data32); } - osd_hw.mode_3d[OSD2].left_right ^= 1; -} - -static void osd1_update_fifo(void) -{ - u32 data32; - - data32 = osd_hw.urgent[OSD1] & 1; - data32 |= 4 << 5; /* hold_fifo_lines */ - /* burst_len_sel: 3=64 */ - data32 |= 3 << 10; - /* fifo_depth_val: 32*8=256 */ - data32 |= (osd_hw.osd_fifo[OSD1] & 0xfffffff) << 12; - /* if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) */ - /* - * bit 23:22, fifo_ctrl - * 00 : for 1 word in 1 burst - * 01 : for 2 words in 1 burst - * 10 : for 4 words in 1 burst - * 11 : reserved - */ - data32 |= 2 << 22; - /* bit 28:24, fifo_lim */ - data32 |= 2 << 24; - VSYNCOSD_WR_MPEG_REG(VIU_OSD1_FIFO_CTRL_STAT, data32); - remove_from_update_list(OSD1, OSD_FIFO); + osd_hw.mode_3d[index].left_right ^= 1; } -static void osd2_update_fifo(void) +static void osd_update_fifo(u32 index) { u32 data32; - data32 = osd_hw.urgent[OSD2] & 1; + data32 = osd_hw.urgent[index] & 1; data32 |= 4 << 5; /* hold_fifo_lines */ /* burst_len_sel: 3=64 */ data32 |= 3 << 10; /* fifo_depth_val: 32*8=256 */ - data32 |= (osd_hw.osd_fifo[OSD2] & 0xfffffff) << 12; - /* if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) */ + data32 |= (osd_hw.osd_meson_dev.osd_fifo_len + & 0xfffffff) << 12; /* * bit 23:22, fifo_ctrl * 00 : for 1 word in 1 burst @@ -3927,8 +5620,9 @@ static void osd2_update_fifo(void) data32 |= 2 << 22; /* bit 28:24, fifo_lim */ data32 |= 2 << 24; - VSYNCOSD_WR_MPEG_REG(VIU_OSD2_FIFO_CTRL_STAT, data32); - remove_from_update_list(OSD2, OSD_FIFO); + VSYNCOSD_WR_MPEG_REG( + hw_osd_reg_array[index].osd_fifo_ctrl_stat, data32); + remove_from_update_list(index, OSD_FIFO); } void osd_init_scan_mode(void) @@ -3938,70 +5632,88 @@ void osd_init_scan_mode(void) output_type = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3; osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE; osd_hw.scan_mode[OSD2] = SCAN_MODE_PROGRESSIVE; + osd_hw.scan_mode[OSD3] = SCAN_MODE_PROGRESSIVE; switch (output_type) { case VOUT_ENCP: if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12)) { /* 1080i */ osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE; osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE; + osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE; } break; case VOUT_ENCI: if (osd_reg_read(ENCI_VIDEO_EN) & 1) { osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE; osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE; + osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE; } break; } } -void osd_init_hw(u32 logo_loaded, u32 osd_probe) +static int osd_extra_canvas_alloc(void) +{ + int osd_num = 2; + + if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) + osd_num = 6; + + if (canvas_pool_alloc_canvas_table("osd_extra", + &osd_extra_idx[0][0], osd_num, CANVAS_MAP_TYPE_1)) { + osd_log_info("allocate osd extra canvas error.\n"); + return -1; + } + return 0; +} + +void osd_init_hw(u32 logo_loaded, u32 osd_probe, + struct osd_device_data_s *osd_meson) { - u32 group, idx, data32, data2; + u32 idx, data32; int err_num = 0; osd_hw.fb_drvier_probe = osd_probe; osd_vpu_power_on(); - if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) + if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_GXTVBB) backup_regs_init(HW_RESET_AFBCD_REGS); - else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) + else if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_GXM) backup_regs_init(HW_RESET_OSD1_REGS); - else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) + else if ((osd_meson->cpu_id >= __MESON_CPU_MAJOR_ID_GXL) + && (osd_meson->cpu_id < __MESON_CPU_MAJOR_ID_TXL)) backup_regs_init(HW_RESET_OSD1_REGS); + else if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_G12A) + backup_regs_init(HW_RESET_MALI_AFBCD_REGS); else backup_regs_init(HW_RESET_NONE); recovery_regs_init(); - for (group = 0; group < HW_OSD_COUNT; group++) - for (idx = 0; idx < HW_REG_INDEX_MAX; idx++) - osd_hw.reg[group][idx].update_func = - hw_func_array[group][idx]; - osd_hw.updated[OSD1] = 0; - osd_hw.updated[OSD2] = 0; - osd_hw.urgent[OSD1] = 1; - osd_hw.urgent[OSD2] = 1; - osd_hw.osd_fifo[OSD1] = 32; - osd_hw.osd_fifo[OSD2] = 32; - - if ((get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX) - || (get_cpu_type() == MESON_CPU_MAJOR_ID_TXL) - || (get_cpu_type() == MESON_CPU_MAJOR_ID_TXHD)) - osd_hw.osd_fifo[OSD1] = 64; + for (idx = 0; idx < HW_REG_INDEX_MAX; idx++) + osd_hw.reg[idx].update_func = + hw_func_array[idx]; + memcpy(&osd_hw.osd_meson_dev, osd_meson, + sizeof(struct osd_device_data_s)); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM osd_hdr_on = false; #endif osd_hw.hw_reset_flag = HW_RESET_NONE; + osd_hw.hwc_enable = 0; + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + osd_hw.hw_cursor_en = 1; + osd_hw.hw_rdma_en = 1; + } else if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) { + osd_hw.hw_cursor_en = 0; + osd_hw.hw_rdma_en = 0; + } /* here we will init default value ,these value only set once . */ if (!logo_loaded) { /* init vpu fifo control register */ data32 = osd_reg_read(VPP_OFIFO_SIZE); - if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM)) - data32 |= 0xfff; - else if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) - data32 |= 0x400; - else - data32 |= 0x77f; + if (osd_hw.osd_meson_dev.osd_ver >= OSD_HIGH_ONE) { + data32 |= (osd_hw.osd_meson_dev.vpp_fifo_len) << 20; + data32 |= osd_hw.osd_meson_dev.vpp_fifo_len + 1; + } else + data32 |= osd_hw.osd_meson_dev.vpp_fifo_len; osd_reg_write(VPP_OFIFO_SIZE, data32); data32 = 0x08080808; osd_reg_write(VPP_HOLD_LINES, data32); @@ -4013,131 +5725,146 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe) data32 |= 4 << 5; /* hold_fifo_lines */ /* burst_len_sel: 3=64 */ data32 |= 3 << 10; - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { - /* - * bit 23:22, fifo_ctrl - * 00 : for 1 word in 1 burst - * 01 : for 2 words in 1 burst - * 10 : for 4 words in 1 burst - * 11 : reserved - */ - data32 |= 2 << 22; - /* bit 28:24, fifo_lim */ - data32 |= 2 << 24; - } - data2 = data32; - /* fifo_depth_val: 32*8=256 */ - data32 |= (osd_hw.osd_fifo[OSD1] & 0xfffffff) << 12; - data2 |= (osd_hw.osd_fifo[OSD2] & 0xfffffff) << 12; - osd_reg_write(VIU_OSD1_FIFO_CTRL_STAT, data32); - osd_reg_write(VIU_OSD2_FIFO_CTRL_STAT, data2); + /* + * bit 23:22, fifo_ctrl + * 00 : for 1 word in 1 burst + * 01 : for 2 words in 1 burst + * 10 : for 4 words in 1 burst + * 11 : reserved + */ + data32 |= 2 << 22; + /* bit 28:24, fifo_lim */ + data32 |= 2 << 24; + + /* data32_ = data32; */ + /* fifo_depth_val: 32 or 64 *8 = 256 or 512 */ + data32 |= (osd_hw.osd_meson_dev.osd_fifo_len + & 0xfffffff) << 12; + for (idx = 0; idx < osd_hw.osd_meson_dev.osd_count; idx++) + osd_reg_write( + hw_osd_reg_array[idx].osd_fifo_ctrl_stat, data32); + /* osd_reg_write(VIU_OSD2_FIFO_CTRL_STAT, data32_); */ osd_reg_set_mask(VPP_MISC, VPP_POSTBLEND_EN); osd_reg_clr_mask(VPP_MISC, VPP_PREBLEND_EN); - osd_vpp_misc = osd_reg_read(VPP_MISC) & OSD_RELATIVE_BITS; - osd_vpp_misc &= ~(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND); - notify_to_amvideo(); - osd_reg_clr_mask(VPP_MISC, - VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND); + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + osd_vpp_misc = + osd_reg_read(VPP_MISC) & OSD_RELATIVE_BITS; + osd_vpp_misc &= + ~(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND); + + notify_to_amvideo(); + osd_reg_clr_mask(VPP_MISC, + VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND); + } /* just disable osd to avoid booting hang up */ data32 = 0x1 << 0; data32 |= OSD_GLOBAL_ALPHA_DEF << 12; - osd_reg_write(VIU_OSD1_CTRL_STAT, data32); - osd_reg_write(VIU_OSD2_CTRL_STAT, data32); + for (idx = 0; idx < osd_hw.osd_meson_dev.osd_count; idx++) + osd_reg_write(hw_osd_reg_array[idx].osd_ctrl_stat, data32); + } + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + osd_vpp_misc = + osd_reg_read(VPP_MISC) & OSD_RELATIVE_BITS; + if (osd_hw.hw_cursor_en) { + osd_vpp_misc |= (VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); + notify_to_amvideo(); + osd_reg_set_mask(VPP_MISC, + VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); + osd_hw.order[OSD1] = OSD_ORDER_10; + } else { + osd_vpp_misc &= ~(VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); + notify_to_amvideo(); + osd_reg_clr_mask(VPP_MISC, + VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); + osd_hw.order[OSD1] = OSD_ORDER_01; + } + } else if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) { + osd_hw.order[OSD1] = LAYER_1; + osd_hw.order[OSD2] = LAYER_2; + osd_hw.order[OSD3] = LAYER_3; + osd_hw.osd_blend_mode = OSD_BLEND_NONE; + osd_hw.background_w = 1920; + osd_hw.background_h = 1080; + for (idx = 0; idx < osd_hw.osd_meson_dev.osd_count; idx++) { + osd_hw.premult_en[idx] = 0; + osd_hw.osd_afbcd[idx].format = COLOR_INDEX_32_ABGR; + osd_hw.osd_afbcd[idx].inter_format = + MALI_AFBC_16X16_PIXEL << 1 | + MALI_AFBC_SPLIT_ON; + osd_hw.osd_afbcd[idx].afbc_start = 0; + osd_hw.afbc_restart_in_vsync = 1; + #if 0 + /* enable for latch */ + osd_hw.osd_use_latch = 1; + data32 = 0; + data32 = osd_reg_read( + hw_osd_reg_array[idx].osd_ctrl_stat); + data32 |= 0x80000000; + osd_reg_write( + hw_osd_reg_array[idx].osd_ctrl_stat, data32); + #endif + } + osd_setting_default_hwc(); + } + for (idx = 0; idx < osd_hw.osd_meson_dev.osd_count; idx++) { + osd_hw.updated[idx] = 0; + osd_hw.urgent[idx] = 1; + osd_hw.enable[idx] = DISABLE; + osd_hw.fb_gem[idx].xres = 0; + osd_hw.fb_gem[idx].yres = 0; + osd_hw.gbl_alpha[idx] = OSD_GLOBAL_ALPHA_DEF; + osd_hw.color_info[idx] = NULL; + osd_hw.color_backup[idx] = NULL; + osd_hw.color_key[idx] = 0xffffffff; + osd_hw.color_key_enable[idx] = 0; + osd_hw.mode_3d[idx].enable = 0; + osd_hw.block_mode[idx] = 0; + osd_hw.osd_reverse[idx] = REVERSE_FALSE; + osd_hw.free_scale_enable[idx] = 0; + osd_hw.free_scale_enable_backup[idx] = 0; + osd_hw.scale[idx].h_enable = 0; + osd_hw.scale[idx].v_enable = 0; + osd_hw.free_scale[idx].h_enable = 0; + osd_hw.free_scale[idx].h_enable = 0; + osd_hw.free_scale_backup[idx].h_enable = 0; + osd_hw.free_scale_backup[idx].v_enable = 0; + osd_hw.free_src_data[idx].x_start = 0; + osd_hw.free_src_data[idx].x_end = 0; + osd_hw.free_src_data[idx].y_start = 0; + osd_hw.free_src_data[idx].y_end = 0; + osd_hw.free_src_data_backup[idx].x_start = 0; + osd_hw.free_src_data_backup[idx].x_end = 0; + osd_hw.free_src_data_backup[idx].y_start = 0; + osd_hw.free_src_data_backup[idx].y_end = 0; + osd_hw.free_scale_mode[idx] = 0; + osd_hw.buffer_alloc[idx] = 0; + osd_hw.osd_clear[idx] = 0; + osd_hw.osd_afbcd[idx].enable = 0; + osd_hw.use_h_filter_mode[idx] = -1; + osd_hw.use_v_filter_mode[idx] = -1; + osd_hw.premult_en[idx] = 0; + /* + * osd_hw.rotation_pandata[idx].x_start = 0; + * osd_hw.rotation_pandata[idx].y_start = 0; + */ + osd_set_dummy_data(idx, 0xff); } - osd_vpp_misc = - osd_reg_read(VPP_MISC) & OSD_RELATIVE_BITS; -#if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) - osd_vpp_misc |= (VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); - notify_to_amvideo(); - osd_reg_set_mask(VPP_MISC, VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); - osd_hw.order = OSD_ORDER_10; -#else - osd_vpp_misc &= ~(VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); - notify_to_amvideo(); - osd_reg_clr_mask(VPP_MISC, VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2); - osd_hw.order = OSD_ORDER_01; -#endif - osd_hw.enable[OSD2] = osd_hw.enable[OSD1] = DISABLE; osd_hw.fb_gem[OSD1].canvas_idx = OSD1_CANVAS_INDEX; osd_hw.fb_gem[OSD2].canvas_idx = OSD2_CANVAS_INDEX; - osd_hw.fb_gem[OSD1].xres = 0; - osd_hw.fb_gem[OSD1].yres = 0; - osd_hw.fb_gem[OSD2].xres = 0; - osd_hw.fb_gem[OSD2].yres = 0; - osd_hw.gbl_alpha[OSD1] = OSD_GLOBAL_ALPHA_DEF; - osd_hw.gbl_alpha[OSD2] = OSD_GLOBAL_ALPHA_DEF; - osd_hw.color_info[OSD1] = NULL; - osd_hw.color_info[OSD2] = NULL; - osd_hw.color_backup[OSD1] = NULL; - osd_hw.color_backup[OSD2] = NULL; - osd_hw.color_key[OSD1] = osd_hw.color_key[OSD2] = 0xffffffff; - osd_hw.free_scale_enable[OSD1] = osd_hw.free_scale_enable[OSD2] = 0; - osd_hw.scale[OSD1].h_enable = osd_hw.scale[OSD1].v_enable = 0; - osd_hw.scale[OSD2].h_enable = osd_hw.scale[OSD2].v_enable = 0; - osd_hw.free_scale_enable_backup[OSD1] = 0; - osd_hw.free_scale_enable_backup[OSD2] = 0; - osd_hw.mode_3d[OSD2].enable = osd_hw.mode_3d[OSD1].enable = 0; - osd_hw.block_mode[OSD1] = osd_hw.block_mode[OSD2] = 0; - osd_hw.free_scale[OSD1].h_enable = 0; - osd_hw.free_scale[OSD1].h_enable = 0; - osd_hw.free_scale[OSD2].v_enable = 0; - osd_hw.free_scale[OSD2].v_enable = 0; - osd_hw.free_scale_backup[OSD1].h_enable = 0; - osd_hw.free_scale_backup[OSD1].h_enable = 0; - osd_hw.free_scale_backup[OSD2].v_enable = 0; - osd_hw.free_scale_backup[OSD2].v_enable = 0; - osd_hw.osd_reverse[OSD1] = REVERSE_FALSE; - osd_hw.osd_reverse[OSD2] = REVERSE_FALSE; - /* - * osd_hw.rotation_pandata[OSD1].x_start = 0; - * osd_hw.rotation_pandata[OSD1].y_start = 0; - * osd_hw.rotation_pandata[OSD2].x_start = 0; - * osd_hw.rotation_pandata[OSD2].y_start = 0; - */ + if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) + osd_hw.fb_gem[OSD3].canvas_idx = OSD3_CANVAS_INDEX; + osd_extra_canvas_alloc(); osd_hw.antiflicker_mode = 0; osd_hw.osd_deband_enable = 1; - osd_hw.color_key_enable[OSD1] = 0; - osd_hw.color_key_enable[OSD2] = 0; - osd_hw.free_src_data[OSD1].x_start = 0; - osd_hw.free_src_data[OSD1].x_end = 0; - osd_hw.free_src_data[OSD1].y_start = 0; - osd_hw.free_src_data[OSD1].y_end = 0; - osd_hw.free_src_data[OSD2].x_start = 0; - osd_hw.free_src_data[OSD2].x_end = 0; - osd_hw.free_src_data[OSD2].y_start = 0; - osd_hw.free_src_data[OSD2].y_end = 0; - osd_hw.free_src_data_backup[OSD1].x_start = 0; - osd_hw.free_src_data_backup[OSD1].x_end = 0; - osd_hw.free_src_data_backup[OSD1].y_start = 0; - osd_hw.free_src_data_backup[OSD1].y_end = 0; - osd_hw.free_src_data_backup[OSD2].x_start = 0; - osd_hw.free_src_data_backup[OSD2].x_end = 0; - osd_hw.free_src_data_backup[OSD2].y_start = 0; - osd_hw.free_src_data_backup[OSD2].y_end = 0; - osd_hw.free_scale_mode[OSD1] = 0; - osd_hw.free_scale_mode[OSD2] = 1; - osd_hw.buffer_alloc[OSD1] = 0; - osd_hw.buffer_alloc[OSD2] = 0; - osd_hw.osd_clear[OSD1] = 0; - osd_hw.osd_clear[OSD2] = 0; - if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) - || (get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX)) - osd_reg_write(VPP_OSD_SC_DUMMY_DATA, 0x002020ff); - else if (get_cpu_type() == - MESON_CPU_MAJOR_ID_GXTVBB) - osd_reg_write(VPP_OSD_SC_DUMMY_DATA, 0xff); - else - osd_reg_write(VPP_OSD_SC_DUMMY_DATA, 0x008080ff); - if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) { - data32 = osd_reg_read(VIU_OSD1_FIFO_CTRL_STAT); + if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) { + data32 = osd_reg_read( + hw_osd_reg_array[OSD1].osd_fifo_ctrl_stat); data32 |= 0x18 << 5; - osd_reg_write(VIU_OSD1_FIFO_CTRL_STAT, data32); + osd_reg_write( + hw_osd_reg_array[OSD1].osd_fifo_ctrl_stat, data32); } osd_set_deband(osd_hw.osd_deband_enable); - /* osd_hw.osd_afbcd[OSD1].enable = 0; - * osd_hw.osd_afbcd[OSD2].enable = 0; - */ /* memset(osd_hw.rotate, 0, sizeof(struct osd_rotate_s)); */ #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE INIT_LIST_HEAD(&post_fence_list); @@ -4161,13 +5888,10 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe) request_fiq(INT_VIU_VSYNC, &osd_fiq_isr); #endif } -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.has_rdma && osd_hw.hw_rdma_en) osd_rdma_enable(1); -#endif } -#if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w, u32 osd_h) { @@ -4253,61 +5977,59 @@ void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w, add_to_update_list(OSD2, OSD_COLOR_MODE); add_to_update_list(OSD2, DISP_GEOMETRY); } -#endif /* CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR */ void osd_suspend_hw(void) { - osd_hw.reg_status_save = osd_reg_read(VPP_MISC) & OSD_RELATIVE_BITS; - osd_vpp_misc &= ~OSD_RELATIVE_BITS; - notify_to_amvideo(); - osd_reg_clr_mask(VPP_MISC, OSD_RELATIVE_BITS); - /* VSYNCOSD_CLR_MPEG_REG_MASK(VPP_MISC, OSD_RELATIVE_BITS); */ + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + osd_hw.reg_status_save = + osd_reg_read(VPP_MISC) & OSD_RELATIVE_BITS; + osd_vpp_misc &= ~OSD_RELATIVE_BITS; + notify_to_amvideo(); + osd_reg_clr_mask(VPP_MISC, OSD_RELATIVE_BITS); + /* VSYNCOSD_CLR_MPEG_REG_MASK(VPP_MISC, OSD_RELATIVE_BITS); */ + } osd_log_info("osd_suspended\n"); } void osd_resume_hw(void) { - if (osd_hw.reg_status_save & - (VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND)) - osd_hw.reg_status_save |= VPP_POSTBLEND_EN; - osd_vpp_misc = osd_hw.reg_status_save & OSD_RELATIVE_BITS; - notify_to_amvideo(); - osd_reg_set_mask(VPP_MISC, osd_hw.reg_status_save); - /* VSYNCOSD_SET_MPEG_REG_MASK(VPP_MISC, osd_hw.reg_status_save); */ - if (osd_hw.enable[OSD2] == ENABLE) { - osd_vpp_misc |= VPP_OSD2_POSTBLEND; - osd_reg_set_mask( - VIU_OSD2_CTRL_STAT, - 1 << 0); - osd_reg_set_mask( - VPP_MISC, - VPP_OSD2_POSTBLEND - | VPP_POSTBLEND_EN); - } else { - osd_vpp_misc &= ~VPP_OSD2_POSTBLEND; - osd_reg_clr_mask(VPP_MISC, - VPP_OSD2_POSTBLEND); - osd_reg_clr_mask( - VIU_OSD2_CTRL_STAT, - 1 << 0); - } - notify_to_amvideo(); + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + if (osd_hw.reg_status_save & + (VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND)) + osd_hw.reg_status_save |= VPP_POSTBLEND_EN; + osd_vpp_misc = osd_hw.reg_status_save & OSD_RELATIVE_BITS; + notify_to_amvideo(); + osd_reg_set_mask(VPP_MISC, osd_hw.reg_status_save); + if (osd_hw.enable[OSD2] == ENABLE) { + osd_vpp_misc |= VPP_OSD2_POSTBLEND; + osd_reg_set_mask( + VIU_OSD2_CTRL_STAT, + 1 << 0); + osd_reg_set_mask( + VPP_MISC, + VPP_OSD2_POSTBLEND + | VPP_POSTBLEND_EN); + } else { + osd_vpp_misc &= ~VPP_OSD2_POSTBLEND; + osd_reg_clr_mask(VPP_MISC, + VPP_OSD2_POSTBLEND); + osd_reg_clr_mask( + VIU_OSD2_CTRL_STAT, + 1 << 0); + } + notify_to_amvideo(); + } osd_log_info("osd_resumed\n"); } void osd_shutdown_hw(void) { - int cpu_type; - - cpu_type = get_cpu_type(); #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA - if (cpu_type != MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.has_rdma) enable_rdma(0); #endif -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - if (cpu_type != MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.has_rdma && osd_hw.hw_rdma_en) osd_rdma_enable(0); -#endif pr_info("osd_shutdown\n"); } @@ -4317,78 +6039,70 @@ static u32 __nosavedata free_scale_enable[HW_OSD_COUNT]; void osd_realdata_save_hw(void) { - free_scale_enable[OSD1] = osd_hw.free_scale_enable[OSD1]; - free_scale_enable[OSD2] = osd_hw.free_scale_enable[OSD2]; + int i; + + for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) + free_scale_enable[i] = osd_hw.free_scale_enable[i]; } void osd_realdata_restore_hw(void) { - osd_hw.free_scale_enable[OSD1] = free_scale_enable[OSD1]; - osd_hw.free_scale_enable[OSD2] = free_scale_enable[OSD2]; + int i; + + for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) + osd_hw.free_scale_enable[i] = free_scale_enable[i]; } void osd_freeze_hw(void) { - int cpu_type; - - cpu_type = get_cpu_type(); #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA - if (cpu_type != MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.has_rdma) enable_rdma(0); #endif -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - if (cpu_type != MESON_CPU_MAJOR_ID_AXG) { - osd_rdma_enable(0); - if (get_backup_reg(VIU_OSD1_BLK0_CFG_W0, - &fb0_cfg_w0_save) != 0) - fb0_cfg_w0_save = - osd_reg_read(VIU_OSD1_BLK0_CFG_W0); + if (osd_hw.hw_rdma_en) { + if (osd_hw.osd_meson_dev.has_rdma) { + osd_rdma_enable(0); + if (get_backup_reg(VIU_OSD1_BLK0_CFG_W0, + &fb0_cfg_w0_save) != 0) + fb0_cfg_w0_save = + osd_reg_read(VIU_OSD1_BLK0_CFG_W0); + } else + fb0_cfg_w0_save = osd_reg_read(VIU_OSD1_BLK0_CFG_W0); } else fb0_cfg_w0_save = osd_reg_read(VIU_OSD1_BLK0_CFG_W0); -#else - fb0_cfg_w0_save = osd_reg_read(VIU_OSD1_BLK0_CFG_W0); -#endif pr_debug("osd_freezed\n"); } void osd_thaw_hw(void) { - int cpu_type; - pr_debug("osd_thawed\n"); - cpu_type = get_cpu_type(); -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - if (cpu_type != MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.has_rdma && osd_hw.hw_rdma_en) osd_rdma_enable(2); -#endif #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA - if (cpu_type != MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.has_rdma) enable_rdma(1); #endif } void osd_restore_hw(void) { - int cpu_type; + int i; - cpu_type = get_cpu_type(); osd_reg_write(VIU_OSD1_BLK0_CFG_W0, fb0_cfg_w0_save); -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA - if (cpu_type != MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.has_rdma && osd_hw.hw_rdma_en) osd_rdma_enable(2); -#endif #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA - if (cpu_type != MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.has_rdma) enable_rdma(1); #endif - - if (cpu_type == MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) osd_update_phy_addr(0); #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS else { - canvas_config(osd_hw.fb_gem[0].canvas_idx, - osd_hw.fb_gem[0].addr, - osd_hw.fb_gem[0].width, - osd_hw.fb_gem[0].height, + for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) + canvas_config(osd_hw.fb_gem[i].canvas_idx, + osd_hw.fb_gem[i].addr, + osd_hw.fb_gem[i].width, + osd_hw.fb_gem[i].height, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); } #endif @@ -4493,6 +6207,8 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) memset(vaddr, 0x0, plane_map->byte_stride*plane_map->src_h); } + osd_log_dbg("canvas_id=%x, phy_addr=%x\n", + osd_hw.fb_gem[index].canvas_idx, phy_addr); canvas_config(osd_hw.fb_gem[index].canvas_idx, phy_addr, plane_map->byte_stride, @@ -4521,7 +6237,8 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) osd_hw.free_scale_mode[index] = 1; if (osd_hw.free_scale_enable[index] != osd_hw.free_scale_enable_backup[index]) { - osd_set_scan_mode(OSD1); + /* Todo: */ + osd_set_scan_mode(index); freescale_update = true; } @@ -4546,7 +6263,7 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) osd_hw.free_dst_data_backup[index].y_start + ((plane_map->dst_y + plane_map->dst_h) * height_dst) / height_src - 1; - if (osd_hw.osd_reverse[OSD1] == REVERSE_TRUE) { + if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { x_start = osd_hw.vinfo_width - freescale_dst[index].x_end - 1; y_start = osd_hw.vinfo_height @@ -4559,7 +6276,7 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) freescale_dst[index].y_start = y_start; freescale_dst[index].x_end = x_end; freescale_dst[index].y_end = y_end; - } else if (osd_hw.osd_reverse[OSD1] == REVERSE_X) { + } else if (osd_hw.osd_reverse[index] == REVERSE_X) { x_start = osd_hw.vinfo_width - freescale_dst[index].x_end - 1; x_end = osd_hw.vinfo_width @@ -4567,7 +6284,7 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) freescale_dst[index].x_start = x_start; freescale_dst[index].x_end = x_end; - } else if (osd_hw.osd_reverse[OSD1] == REVERSE_Y) { + } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { y_start = osd_hw.vinfo_height - freescale_dst[index].y_end - 1; y_end = osd_hw.vinfo_height @@ -4591,9 +6308,9 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) if ((height_dst != height_src) || (width_dst != width_src)) - osd_set_dummy_data(0); + osd_set_dummy_data(index, 0); else - osd_set_dummy_data(0xff); + osd_set_dummy_data(index, 0xff); } osd_log_dbg2("pandata x=%d,x_end=%d,y=%d,y_end=%d\n", osd_hw.pandata[index].x_start, @@ -4622,7 +6339,7 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) osd_hw.dispdata[index].y_start = plane_map->dst_y; osd_hw.dispdata[index].y_end = plane_map->dst_y + plane_map->dst_h - 1; - if (osd_hw.osd_reverse[OSD1] == REVERSE_TRUE) { + if (osd_hw.osd_reverse[index] == REVERSE_TRUE) { x_start = osd_hw.vinfo_width - osd_hw.dispdata[index].x_end - 1; y_start = osd_hw.vinfo_height @@ -4635,7 +6352,7 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) osd_hw.dispdata[index].y_start = y_start; osd_hw.dispdata[index].x_end = x_end; osd_hw.dispdata[index].y_end = y_end; - } else if (osd_hw.osd_reverse[OSD1] == REVERSE_X) { + } else if (osd_hw.osd_reverse[index] == REVERSE_X) { x_start = osd_hw.vinfo_width - osd_hw.dispdata[index].x_end - 1; x_end = osd_hw.vinfo_width @@ -4643,7 +6360,7 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) osd_hw.dispdata[index].x_start = x_start; osd_hw.dispdata[index].x_end = x_end; - } else if (osd_hw.osd_reverse[OSD1] == REVERSE_Y) { + } else if (osd_hw.osd_reverse[index] == REVERSE_Y) { y_start = osd_hw.vinfo_height - osd_hw.dispdata[index].y_end - 1; y_end = osd_hw.vinfo_height @@ -4827,8 +6544,13 @@ void osd_page_flip(struct osd_plane_map_s *plane_map) u32 osd_enable = 0; const struct vinfo_s *vinfo; - if (index >= 2) - return; + if (!osd_hw.hwc_enable) { + if (index >= OSD2) + return; + } else { + if (index >= OSD3) + return; + } osd_hw.buffer_alloc[index] = 1; if (osd_hw.osd_fps_start) @@ -4840,60 +6562,102 @@ void osd_page_flip(struct osd_plane_map_s *plane_map) osd_hw.vinfo_width = vinfo->width; osd_hw.vinfo_height = vinfo->height; } - if (plane_map->phy_addr && plane_map->src_w - && plane_map->src_h && index == OSD1) { - osd_hw.fb_gem[index].canvas_idx = - extern_canvas[ext_canvas_id]; - ext_canvas_id ^= 1; - color = convert_panel_format(plane_map->format); - if (color) { - osd_hw.color_info[index] = color; - } else - osd_log_err("fence color format error %d\n", - plane_map->format); - - freescale_update = osd_direct_render(plane_map); - - if (index == OSD1 && - osd_hw.osd_afbcd[index].enable == ENABLE) - osd_hw.osd_afbcd[index].phy_addr = - plane_map->phy_addr; - osd_hw.reg[index][OSD_COLOR_MODE].update_func(); - osd_hw.reg[index][DISP_GEOMETRY].update_func(); - if ((osd_hw.free_scale_enable[index] - && osd_update_window_axis) - || freescale_update) { - if (!osd_hw.osd_display_debug) - osd_hw.reg[index][DISP_FREESCALE_ENABLE] - .update_func(); - osd_update_window_axis = false; - } - if ((osd_hw.osd_afbcd[index].enable == DISABLE) - && (osd_enable != osd_hw.enable[index])) { - osd_hw.enable[index] = osd_enable; - if (!osd_hw.osd_display_debug) - osd_hw.reg[index][OSD_ENABLE] - .update_func(); - } - osd_wait_vsync_hw(); - } else if (plane_map->phy_addr && plane_map->src_w - && plane_map->src_h && index == OSD2) { - color = convert_panel_format(plane_map->format); - if (color) { - osd_hw.color_info[index] = color; - } else - osd_log_err("fence color format error %d\n", - plane_map->format); - osd_cursor_move(plane_map); - osd_hw.reg[index][OSD_COLOR_MODE].update_func(); - osd_hw.reg[index][DISP_GEOMETRY].update_func(); - if (osd_enable != osd_hw.enable[index]) { - osd_hw.enable[index] = osd_enable; - if (!osd_hw.osd_display_debug) - osd_hw.reg[index][OSD_ENABLE] - .update_func(); + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + if (plane_map->phy_addr && plane_map->src_w + && plane_map->src_h && index == OSD1) { + osd_hw.fb_gem[index].canvas_idx = + osd_extra_idx[index][ext_canvas_id]; + ext_canvas_id ^= 1; + color = convert_panel_format(plane_map->format); + if (color) { + osd_hw.color_info[index] = color; + } else + osd_log_err("fence color format error %d\n", + plane_map->format); + + freescale_update = osd_direct_render(plane_map); + + if (index == OSD1 && + osd_hw.osd_afbcd[index].enable == ENABLE) + osd_hw.osd_afbcd[index].phy_addr = + plane_map->phy_addr; + osd_hw.reg[OSD_COLOR_MODE].update_func(index); + osd_hw.reg[DISP_GEOMETRY].update_func(index); + if ((osd_hw.free_scale_enable[index] + && osd_update_window_axis) + || freescale_update) { + if (!osd_hw.osd_display_debug) + osd_hw.reg[DISP_FREESCALE_ENABLE] + .update_func(index); + osd_update_window_axis = false; + } + if ((osd_hw.osd_afbcd[index].enable == DISABLE) + && (osd_enable != osd_hw.enable[index])) { + osd_hw.enable[index] = osd_enable; + if (!osd_hw.osd_display_debug) + osd_hw.reg[OSD_ENABLE] + .update_func(index); + } + osd_wait_vsync_hw(); + } else if (plane_map->phy_addr && plane_map->src_w + && plane_map->src_h && index == OSD2) { + color = convert_panel_format(plane_map->format); + if (color) { + osd_hw.color_info[index] = color; + } else + osd_log_err("fence color format error %d\n", + plane_map->format); + if (osd_hw.hw_cursor_en) + osd_cursor_move(plane_map); + osd_hw.reg[OSD_COLOR_MODE].update_func(index); + osd_hw.reg[DISP_GEOMETRY].update_func(index); + if (osd_enable != osd_hw.enable[index]) { + osd_hw.enable[index] = osd_enable; + if (!osd_hw.osd_display_debug) + osd_hw.reg[OSD_ENABLE] + .update_func(index); + } + } + } else { + if (plane_map->phy_addr && plane_map->src_w + && plane_map->src_h) { + osd_hw.fb_gem[index].canvas_idx = + osd_extra_idx[index][ext_canvas_id]; + ext_canvas_id ^= 1; + color = convert_panel_format(plane_map->format); + if (color) { + osd_hw.color_info[index] = color; + } else + osd_log_err("fence color format error %d\n", + plane_map->format); + freescale_update = osd_direct_render(plane_map); + + if (osd_hw.osd_afbcd[index].enable == ENABLE) + osd_hw.osd_afbcd[index].phy_addr = + plane_map->phy_addr; + osd_hw.reg[OSD_COLOR_MODE].update_func(index); + if (!osd_hw.hwc_enable) { + osd_hw.reg[DISP_GEOMETRY].update_func(index); + if ((osd_hw.free_scale_enable[index] + && osd_update_window_axis) + || freescale_update) { + if (!osd_hw.osd_display_debug) + osd_hw.reg[DISP_FREESCALE_ENABLE] + .update_func(index); + osd_update_window_axis = false; + } + } + if ((osd_hw.osd_afbcd[index].enable == DISABLE) + && (osd_enable != osd_hw.enable[index])) { + osd_hw.enable[index] = osd_enable; + if (!osd_hw.osd_display_debug) + osd_hw.reg[OSD_ENABLE] + .update_func(index); + } + osd_wait_vsync_hw(); + } } } diff --git a/drivers/amlogic/media/osd/osd_hw.h b/drivers/amlogic/media/osd/osd_hw.h index 7378ac0a..bde8466 100644 --- a/drivers/amlogic/media/osd/osd_hw.h +++ b/drivers/amlogic/media/osd/osd_hw.h @@ -23,13 +23,12 @@ #include "osd_sync.h" #include "osd_drm.h" -#define REG_OFFSET (0x20) +//#define REG_OFFSET (0x20) #define OSD_RELATIVE_BITS 0x33330 -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA #include "osd_rdma.h" -#endif extern int int_viu_vsync; +extern struct hw_para_s osd_hw; #ifdef CONFIG_HIBERNATION extern void osd_freeze_hw(void); @@ -118,15 +117,14 @@ extern int osd_sync_request_render(u32 index, u32 yres, struct fb_sync_request_render_s *request, u32 phys_addr); extern s32 osd_wait_vsync_event(void); -#if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR) extern void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w, u32 osd_h); -#endif extern void osd_init_scan_mode(void); extern void osd_suspend_hw(void); extern void osd_resume_hw(void); extern void osd_shutdown_hw(void); -extern void osd_init_hw(u32 logo_loaded, u32 osd_probe); +extern void osd_init_hw(u32 logo_loaded, u32 osd_probe, + struct osd_device_data_s *osd_meson); extern void osd_init_scan_mode(void); extern void osd_set_logo_index(int index); extern int osd_get_logo_index(void); @@ -142,8 +140,8 @@ extern void enable_rdma(int enable_flag); extern void osd_ext_clone_pan(u32 index); #endif extern void osd_set_pxp_mode(u32 mode); -extern void osd_set_afbc(u32 enable); -extern u32 osd_get_afbc(void); +extern void osd_set_afbc(u32 index, u32 enable); +extern u32 osd_get_afbc(u32 index); extern u32 osd_get_reset_status(void); extern void osd_switch_free_scale( u32 pre_index, u32 pre_enable, u32 pre_scale, @@ -155,11 +153,27 @@ void osd_set_deband(u32 osd_deband_enable); void osd_get_fps(u32 *osd_fps); void osd_set_fps(u32 osd_fps_start); extern void osd_get_info(u32 index, u32 *addr, u32 *width, u32 *height); +void osd_update_scan_mode(void); +void osd_update_3d_mode(void); +void osd_update_vsync_hit(void); +void osd_hw_reset(void); +void osd_mali_afbc_restart(void); int logo_work_init(void); void set_logo_loaded(void); int set_osd_logo_freescaler(void); void osd_get_display_debug(u32 *osd_display_debug_enable); void osd_set_display_debug(u32 osd_display_debug_enable); +void osd_get_background_size(u32 *background_w, u32 *background_h); +void osd_set_background_size(u32 background_w, u32 background_h); +u32 osd_get_premult(u32 index); +void osd_set_premult(u32 index, u32 premult); +void osd_get_afbc_debug(u32 *val1, u32 *val2, u32 *val3, u32 *val4); +void osd_set_afbc_debug(u32 val1, u32 val2, u32 val3, u32 val4); +void osd_get_afbc_format(u32 index, u32 *format, u32 *inter_format); +void osd_set_afbc_format(u32 index, u32 format, u32 inter_format); +void osd_get_hwc_enable(u32 *hwc_enable); +void osd_set_hwc_enable(u32 hwc_enable); +void osd_do_hwc(void); void osd_backup_screen_info( u32 index, char __iomem *screen_base, @@ -171,5 +185,6 @@ void osd_restore_screen_info( void osd_set_clear(u32 index, u32 osd_clear); void osd_page_flip(struct osd_plane_map_s *plane_map); void walk_through_update_list(void); - +int osd_setting_blend(void); +void osd_set_hwc_enable(u32 hwc_enable); #endif diff --git a/drivers/amlogic/media/osd/osd_hw_def.h b/drivers/amlogic/media/osd/osd_hw_def.h index a561f26..a076695 100644 --- a/drivers/amlogic/media/osd/osd_hw_def.h +++ b/drivers/amlogic/media/osd/osd_hw_def.h @@ -21,35 +21,21 @@ #include #include "osd_hw.h" -static void osd1_update_color_mode(void); -static void osd1_update_enable(void); -static void osd1_update_color_key(void); -static void osd1_update_color_key_enable(void); -static void osd1_update_gbl_alpha(void); -static void osd1_update_order(void); -static void osd1_update_disp_geometry(void); -static void osd1_update_coef(void); -static void osd1_update_disp_freescale_enable(void); -static void osd1_update_disp_osd_reverse(void); -static void osd1_update_disp_osd_rotate(void); -static void osd1_update_disp_scale_enable(void); -static void osd1_update_disp_3d_mode(void); -static void osd1_update_fifo(void); +static void osd_update_color_mode(u32 index); +static void osd_update_enable(u32 index); +static void osd_update_color_key(u32 index); +static void osd_update_color_key_enable(u32 index); +static void osd_update_gbl_alpha(u32 index); +static void osd_update_order(u32 index); +static void osd_update_disp_geometry(u32 index); +static void osd_update_coef(u32 index); +static void osd_update_disp_freescale_enable(u32 index); +static void osd_update_disp_osd_reverse(u32 index); +static void osd_update_disp_osd_rotate(u32 index); +static void osd_update_disp_scale_enable(u32 index); +static void osd_update_disp_3d_mode(u32 index); +static void osd_update_fifo(u32 index); -static void osd2_update_color_mode(void); -static void osd2_update_enable(void); -static void osd2_update_color_key(void); -static void osd2_update_color_key_enable(void); -static void osd2_update_gbl_alpha(void); -static void osd2_update_order(void); -static void osd2_update_disp_geometry(void); -static void osd2_update_coef(void); -static void osd2_update_disp_freescale_enable(void); -static void osd2_update_disp_osd_reverse(void); -static void osd2_update_disp_osd_rotate(void); -static void osd2_update_disp_scale_enable(void); -static void osd2_update_disp_3d_mode(void); -static void osd2_update_fifo(void); LIST_HEAD(update_list); static DEFINE_SPINLOCK(osd_lock); @@ -57,39 +43,23 @@ static unsigned long lock_flags; #ifdef FIQ_VSYNC static unsigned long fiq_flag; #endif -static update_func_t hw_func_array[HW_OSD_COUNT][HW_REG_INDEX_MAX] = { - { - osd1_update_color_mode, - osd1_update_enable, - osd1_update_color_key, - osd1_update_color_key_enable, - osd1_update_gbl_alpha, - osd1_update_order, - osd1_update_coef, - osd1_update_disp_geometry, - osd1_update_disp_scale_enable, - osd1_update_disp_freescale_enable, - osd1_update_disp_osd_reverse, - osd1_update_disp_osd_rotate, - osd1_update_fifo, - }, - { - osd2_update_color_mode, - osd2_update_enable, - osd2_update_color_key, - osd2_update_color_key_enable, - osd2_update_gbl_alpha, - osd2_update_order, - osd2_update_coef, - osd2_update_disp_geometry, - osd2_update_disp_scale_enable, - osd2_update_disp_freescale_enable, - osd2_update_disp_osd_reverse, - osd2_update_disp_osd_rotate, - osd2_update_fifo, - }, +static update_func_t hw_func_array[HW_REG_INDEX_MAX] = { + osd_update_color_mode, + osd_update_enable, + osd_update_color_key, + osd_update_color_key_enable, + osd_update_gbl_alpha, + osd_update_order, + osd_update_coef, + osd_update_disp_geometry, + osd_update_disp_scale_enable, + osd_update_disp_freescale_enable, + osd_update_disp_osd_reverse, + osd_update_disp_osd_rotate, + osd_update_fifo, }; + #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA #ifdef FIQ_VSYNC #define add_to_update_list(osd_idx, cmd_idx) \ @@ -97,10 +67,11 @@ static update_func_t hw_func_array[HW_OSD_COUNT][HW_REG_INDEX_MAX] = { spin_lock_irqsave(&osd_lock, lock_flags); \ raw_local_save_flags(fiq_flag); \ local_fiq_disable(); \ - if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) \ + if (!osd_hw.osd_meson_dev.has_rdma || \ + !osd_hw.hw_rdma_en) \ osd_hw.updated[osd_idx] |= (1< #include -#include /* Local Headers */ #include "osd_log.h" #include "osd_backup.h" @@ -40,13 +39,11 @@ static struct reg_map_s osd_reg_map = { .size = 0x10000, }; -int osd_io_remap(void) +int osd_io_remap(int iomap) { int ret = 0; - u32 cpu_type; - cpu_type = get_cpu_type(); - if (cpu_type == MESON_CPU_MAJOR_ID_AXG) { + if (iomap) { if (osd_reg_map.flag) return 1; osd_reg_map.vir_addr = @@ -67,11 +64,9 @@ int osd_io_remap(void) uint32_t osd_cbus_read(uint32_t reg) { uint32_t ret = 0; - u32 cpu_type; unsigned int addr = 0; - cpu_type = get_cpu_type(); - if (cpu_type == MESON_CPU_MAJOR_ID_AXG) { + if (osd_reg_map.flag) { addr = OSDBUS_REG_ADDR(reg); ret = readl(osd_reg_map.vir_addr + addr); @@ -85,11 +80,9 @@ uint32_t osd_cbus_read(uint32_t reg) void osd_cbus_write(uint32_t reg, const uint32_t val) { - u32 cpu_type; unsigned int addr = 0; - cpu_type = get_cpu_type(); - if (cpu_type == MESON_CPU_MAJOR_ID_AXG) { + if (osd_reg_map.flag) { addr = OSDBUS_REG_ADDR(reg); writel(val, osd_reg_map.vir_addr + addr); } else @@ -101,13 +94,11 @@ void osd_cbus_write(uint32_t reg, uint32_t osd_reg_read(uint32_t reg) { uint32_t ret = 0; - u32 cpu_type; unsigned int addr = 0; /* if (get_backup_reg(reg, &ret) != 0) */ /* not read from bakcup */ - cpu_type = get_cpu_type(); - if (cpu_type == MESON_CPU_MAJOR_ID_AXG) { + if (osd_reg_map.flag) { addr = OSDBUS_REG_ADDR(reg); ret = readl(osd_reg_map.vir_addr + addr); @@ -121,11 +112,9 @@ uint32_t osd_reg_read(uint32_t reg) void osd_reg_write(uint32_t reg, const uint32_t val) { - u32 cpu_type; unsigned int addr = 0; - cpu_type = get_cpu_type(); - if (cpu_type == MESON_CPU_MAJOR_ID_AXG) { + if (osd_reg_map.flag) { addr = OSDBUS_REG_ADDR(reg); writel(val, osd_reg_map.vir_addr + addr); } else diff --git a/drivers/amlogic/media/osd/osd_io.h b/drivers/amlogic/media/osd/osd_io.h index 28e0017..e09c9a1 100644 --- a/drivers/amlogic/media/osd/osd_io.h +++ b/drivers/amlogic/media/osd/osd_io.h @@ -21,7 +21,7 @@ /* Local Headers */ #include "osd_log.h" -int osd_io_remap(void); +int osd_io_remap(int iomap); uint32_t osd_cbus_read(uint32_t reg); void osd_cbus_write(uint32_t reg, const uint32_t val); @@ -37,7 +37,6 @@ void osd_reg_set_bits(uint32_t reg, const uint32_t start, const uint32_t len); -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA u32 VSYNCOSD_RD_MPEG_REG(u32 reg); int VSYNCOSD_WR_MPEG_REG(u32 reg, u32 val); int VSYNCOSD_WR_MPEG_REG_BITS(u32 reg, u32 val, u32 start, u32 len); @@ -45,7 +44,7 @@ int VSYNCOSD_SET_MPEG_REG_MASK(u32 reg, u32 mask); int VSYNCOSD_CLR_MPEG_REG_MASK(u32 reg, u32 mask); int VSYNCOSD_IRQ_WR_MPEG_REG(u32 reg, u32 val); -#else +#if 0 #define VSYNCOSD_RD_MPEG_REG(reg) osd_reg_read(reg) #define VSYNCOSD_WR_MPEG_REG(reg, val) osd_reg_write(reg, val) #define VSYNCOSD_WR_MPEG_REG_BITS(reg, val, start, len) \ diff --git a/drivers/amlogic/media/osd/osd_logo.c b/drivers/amlogic/media/osd/osd_logo.c index e261c0d..22e7bf8 100644 --- a/drivers/amlogic/media/osd/osd_logo.c +++ b/drivers/amlogic/media/osd/osd_logo.c @@ -23,7 +23,6 @@ #include /* Amlogic Headers */ -#include #include #include @@ -171,11 +170,8 @@ int set_osd_logo_freescaler(void) pr_info("logo changed, return!\n"); return -1; } -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE - if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) - if (index >= 1) - return -1; -#endif + if ((osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) && (index >= 1)) + return -1; osd_set_free_scale_mode_hw(index, 1); osd_set_free_scale_enable_hw(index, 0); diff --git a/drivers/amlogic/media/osd/osd_progressbar.c b/drivers/amlogic/media/osd/osd_progressbar.c index 280fefc..23efa78 100644 --- a/drivers/amlogic/media/osd/osd_progressbar.c +++ b/drivers/amlogic/media/osd/osd_progressbar.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "osd_canvas.h" #include "osd_fb.h" @@ -165,7 +164,7 @@ int osd_init_progress_bar(void) struct ge2d_context_s *context = ge2d_context; u32 step = 1; - if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) + if (osd_hw.osd_meson_dev.has_ver == OSD_SIMPLE) return 0; memset(&progress_bar, 0, sizeof(struct osd_progress_bar_s)); diff --git a/drivers/amlogic/media/osd/osd_rdma.c b/drivers/amlogic/media/osd/osd_rdma.c index 84f5151..87d3325 100644 --- a/drivers/amlogic/media/osd/osd_rdma.c +++ b/drivers/amlogic/media/osd/osd_rdma.c @@ -35,7 +35,6 @@ #include /* Local Headers */ -#include #include "osd.h" #include "osd_io.h" #include "osd_reg.h" @@ -859,11 +858,14 @@ static void osd_reset_rdma_func(u32 reset_bit) rdma_write_reg(osd_reset_rdma_handle, VIU_SW_RESET, 0); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM - if ((rdma_hdr_delay == 0) || - (hdr_osd_reg.shadow_mode == 0)) - memcpy(&hdr_osd_shadow_reg, &hdr_osd_reg, - sizeof(struct hdr_osd_reg_s)); - hdr_restore_osd_csc(); + if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { + if ((rdma_hdr_delay == 0) || + (hdr_osd_reg.shadow_mode == 0)) + memcpy(&hdr_osd_shadow_reg, &hdr_osd_reg, + sizeof(struct hdr_osd_reg_s)); + hdr_restore_osd_csc(); + } + /* Todo: what about g12a */ #endif set_reset_rdma_trigger_line(); rdma_config(osd_reset_rdma_handle, 1 << 6); @@ -919,6 +921,7 @@ static void osd_rdma_irq(void *arg) osd_update_3d_mode(); osd_update_vsync_hit(); osd_hw_reset(); + osd_mali_afbc_restart(); rdma_irq_count++; { /*This is a memory barrier*/ @@ -1090,11 +1093,11 @@ int osd_rdma_reset_and_flush(u32 reset_bit) } /* same bit, but gxm only reset hardware, not top reg*/ - if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) + if (osd_hw.osd_meson_dev.cpu_id >= __MESON_CPU_MAJOR_ID_GXM) reset_bit &= ~HW_RESET_AFBCD_REGS; i = 0; - base = VIU_OSD1_CTRL_STAT; + base = hw_osd_reg_array[OSD1].osd_ctrl_stat; while ((reset_bit & HW_RESET_OSD1_REGS) && (i < OSD_REG_BACKUP_COUNT)) { addr = osd_reg_backup[i]; @@ -1114,6 +1117,17 @@ int osd_rdma_reset_and_flush(u32 reset_bit) addr, value); i++; } + i = 0; + base = VPU_MAFBC_COMMAND; + while ((reset_bit & HW_RESET_MALI_AFBCD_REGS) + && (i < MALI_AFBC_REG_BACKUP_COUNT)) { + addr = mali_afbc_reg_backup[i]; + value = mali_afbc_backup[addr - base]; + wrtie_reg_internal( + addr, value); + i++; + } + if (item_count < 500) osd_reg_write(END_ADDR, (table_paddr + item_count * 8 - 1)); else { @@ -1172,6 +1186,7 @@ static irqreturn_t osd_rdma_isr(int irq, void *dev_id) osd_update_3d_mode(); osd_update_vsync_hit(); osd_hw_reset(); + osd_mali_afbc_restart(); rdma_irq_count++; { /*This is a memory barrier*/ @@ -1258,8 +1273,8 @@ static int osd_rdma_init(void) osd_reg_write(OSD_RDMA_FLAG_REG, 0x0); #ifdef CONFIG_AMLOGIC_MEDIA_RDMA - if ((get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) - && (get_cpu_type() <= MESON_CPU_MAJOR_ID_TXL)) { + if ((osd_hw.osd_meson_dev.cpu_id >= __MESON_CPU_MAJOR_ID_GXL) + && (osd_hw.osd_meson_dev.cpu_id <= __MESON_CPU_MAJOR_ID_TXL)) { osd_reset_rdma_op.arg = osd_rdma_dev; osd_reset_rdma_handle = rdma_register(&osd_reset_rdma_op, diff --git a/drivers/amlogic/media/osd/osd_rdma.h b/drivers/amlogic/media/osd/osd_rdma.h index c061bd6..b489591 100644 --- a/drivers/amlogic/media/osd/osd_rdma.h +++ b/drivers/amlogic/media/osd/osd_rdma.h @@ -59,17 +59,12 @@ struct rdma_table_item { (osd_reg_read(OSD_RDMA_FLAG_REG) & \ ~OSD_RDMA_FLAG_REJECT))) -extern void osd_update_scan_mode(void); -extern void osd_update_3d_mode(void); -extern void osd_update_vsync_hit(void); -extern void osd_hw_reset(void); + extern int read_rdma_table(void); extern int osd_rdma_enable(u32 enable); extern int osd_rdma_reset_and_flush(u32 reset_bit); extern int rdma_reset_tigger_flag; extern int rdma_mgr_irq_request; -#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA extern void osd_rdma_interrupt_done_clear(void); -#endif extern int osd_rdma_uninit(void); #endif diff --git a/drivers/amlogic/media/osd/osd_reg.h b/drivers/amlogic/media/osd/osd_reg.h index 08885dc..bcb4ff7 100644 --- a/drivers/amlogic/media/osd/osd_reg.h +++ b/drivers/amlogic/media/osd/osd_reg.h @@ -176,6 +176,9 @@ #define VIU_OSD1_FIFO_CTRL_STAT 0x1a2b #define VIU_OSD1_TEST_RDDATA 0x1a2c #define VIU_OSD1_PROT_CTRL 0x1a2e +#define VIU_OSD1_MALI_UNPACK_CTRL 0x1a2f +#define VIU_OSD1_DIMM_CTRL 0x1adf + #define VIU_OSD2_CTRL_STAT 0x1a30 #define VIU_OSD2_CTRL_STAT2 0x1a4d #define VIU_OSD2_COLOR_ADDR 0x1a31 @@ -211,6 +214,29 @@ #define VIU_OSD2_FIFO_CTRL_STAT 0x1a4b #define VIU_OSD2_TEST_RDDATA 0x1a4c #define VIU_OSD2_PROT_CTRL 0x1a4e +#define VIU_OSD2_MALI_UNPACK_CTRL 0x1abd +#define VIU_OSD2_DIMM_CTRL 0x1acf + +#define VIU_OSD3_CTRL_STAT 0x3d80 +#define VIU_OSD3_CTRL_STAT2 0x3d81 +#define VIU_OSD3_COLOR_ADDR 0x3d82 +#define VIU_OSD3_COLOR 0x3d83 +#define VIU_OSD3_TCOLOR_AG0 0x3d84 +#define VIU_OSD3_TCOLOR_AG1 0x3d85 +#define VIU_OSD3_TCOLOR_AG2 0x3d86 +#define VIU_OSD3_TCOLOR_AG3 0x3d87 +#define VIU_OSD3_BLK0_CFG_W0 0x3d88 +#define VIU_OSD3_BLK0_CFG_W1 0x3d8c +#define VIU_OSD3_BLK0_CFG_W2 0x3d90 +#define VIU_OSD3_BLK0_CFG_W3 0x3d94 +#define VIU_OSD3_BLK0_CFG_W4 0x3d98 +#define VIU_OSD3_BLK1_CFG_W4 0x3d99 +#define VIU_OSD3_BLK2_CFG_W4 0x3d9a +#define VIU_OSD3_FIFO_CTRL_STAT 0x3d9c +#define VIU_OSD3_TEST_RDDATA 0x3d9d +#define VIU_OSD3_PROT_CTRL 0x3d9e +#define VIU_OSD3_MALI_UNPACK_CTRL 0x3d9f +#define VIU_OSD3_DIMM_CTRL 0x3da0 #define VD1_IF0_GEN_REG 0x1a50 #define VD1_IF0_CANVAS0 0x1a51 @@ -480,6 +506,37 @@ #define VPP_OSD_SCALE_COEF 0x1dcd #define VPP_INT_LINE_NUM 0x1dce +/* osd2 scaler */ +#define OSD2_VSC_PHASE_STEP 0x3d00 +#define OSD2_VSC_INI_PHASE 0x3d01 +#define OSD2_VSC_CTRL0 0x3d02 +#define OSD2_HSC_PHASE_STEP 0x3d03 +#define OSD2_HSC_INI_PHASE 0x3d04 +#define OSD2_HSC_CTRL0 0x3d05 +#define OSD2_HSC_INI_PAT_CTRL 0x3d06 +#define OSD2_SC_DUMMY_DATA 0x3d07 +#define OSD2_SC_CTRL0 0x3d08 +#define OSD2_SCI_WH_M1 0x3d09 +#define OSD2_SCO_H_START_END 0x3d0a +#define OSD2_SCO_V_START_END 0x3d0b +#define OSD2_SCALE_COEF_IDX 0x3d18 +#define OSD2_SCALE_COEF 0x3d19 + +/* osd34 scaler */ +#define OSD34_SCALE_COEF_IDX 0x3d1e +#define OSD34_SCALE_COEF 0x3d1f +#define OSD34_VSC_PHASE_STEP 0x3d20 +#define OSD34_VSC_INI_PHASE 0x3d21 +#define OSD34_VSC_CTRL0 0x3d22 +#define OSD34_HSC_PHASE_STEP 0x3d23 +#define OSD34_HSC_INI_PHASE 0x3d24 +#define OSD34_HSC_CTRL0 0x3d25 +#define OSD34_HSC_INI_PAT_CTRL 0x3d26 +#define OSD34_SC_DUMMY_DATA 0x3d27 +#define OSD34_SC_CTRL0 0x3d28 +#define OSD34_SCI_WH_M1 0x3d29 +#define OSD34_SCO_H_START_END 0x3d2a +#define OSD34_SCO_V_START_END 0x3d2b /* viu2 */ #define VIU2_ADDR_START 0x1e00 #define VIU2_ADDR_END 0x1eff @@ -550,6 +607,8 @@ #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 @@ -1411,7 +1470,118 @@ #define OSD1_AFBCD_PIXEL_VSCOPE 0x31aa #define VIU_MISC_CTRL1 0x1a07 + /* add for gxm and 962e dv core2 */ #define DOLBY_CORE2A_SWAP_CTRL1 0x3434 #define DOLBY_CORE2A_SWAP_CTRL2 0x3435 + +/* osd afbc on g12a */ +#define VPU_MAFBC_BLOCK_ID 0x3a00 +#define VPU_MAFBC_IRQ_RAW_STATUS 0x3a01 +#define VPU_MAFBC_IRQ_CLEAR 0x3a02 +#define VPU_MAFBC_IRQ_MASK 0x3a03 +#define VPU_MAFBC_IRQ_STATUS 0x3a04 +#define VPU_MAFBC_COMMAND 0x3a05 +#define VPU_MAFBC_STATUS 0x3a06 +#define VPU_MAFBC_SURFACE_CFG 0x3a07 + +/* osd afbc on g12a */ +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0 0x3a10 +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0 0x3a11 +#define VPU_MAFBC_FORMAT_SPECIFIER_S0 0x3a12 +#define VPU_MAFBC_BUFFER_WIDTH_S0 0x3a13 +#define VPU_MAFBC_BUFFER_HEIGHT_S0 0x3a14 +#define VPU_MAFBC_BOUNDING_BOX_X_START_S0 0x3a15 +#define VPU_MAFBC_BOUNDING_BOX_X_END_S0 0x3a16 +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S0 0x3a17 +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S0 0x3a18 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0 0x3a19 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0 0x3a1a +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S0 0x3a1b +#define VPU_MAFBC_PREFETCH_CFG_S0 0x3a1c + +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S1 0x3a30 +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S1 0x3a31 +#define VPU_MAFBC_FORMAT_SPECIFIER_S1 0x3a32 +#define VPU_MAFBC_BUFFER_WIDTH_S1 0x3a33 +#define VPU_MAFBC_BUFFER_HEIGHT_S1 0x3a34 +#define VPU_MAFBC_BOUNDING_BOX_X_START_S1 0x3a35 +#define VPU_MAFBC_BOUNDING_BOX_X_END_S1 0x3a36 +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S1 0x3a37 +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S1 0x3a38 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S1 0x3a39 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S1 0x3a3a +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S1 0x3a3b +#define VPU_MAFBC_PREFETCH_CFG_S1 0x3a3c + +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S2 0x3a50 +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S2 0x3a51 +#define VPU_MAFBC_FORMAT_SPECIFIER_S2 0x3a52 +#define VPU_MAFBC_BUFFER_WIDTH_S2 0x3a53 +#define VPU_MAFBC_BUFFER_HEIGHT_S2 0x3a54 +#define VPU_MAFBC_BOUNDING_BOX_X_START_S2 0x3a55 +#define VPU_MAFBC_BOUNDING_BOX_X_END_S2 0x3a56 +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S2 0x3a57 +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S2 0x3a58 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S2 0x3a59 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S2 0x3a5a +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S2 0x3a5b +#define VPU_MAFBC_PREFETCH_CFG_S2 0x3a5c + +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S3 0x3a70 +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S3 0x3a71 +#define VPU_MAFBC_FORMAT_SPECIFIER_S3 0x3a72 +#define VPU_MAFBC_BUFFER_WIDTH_S3 0x3a73 +#define VPU_MAFBC_BUFFER_HEIGHT_S3 0x3a74 +#define VPU_MAFBC_BOUNDING_BOX_X_START_S3 0x3a75 +#define VPU_MAFBC_BOUNDING_BOX_X_END_S3 0x3a76 +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S3 0x3a77 +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S3 0x3a78 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S3 0x3a79 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S3 0x3a7a +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S3 0x3a7b +#define VPU_MAFBC_PREFETCH_CFG_S3 0x3a7c + +#define VD1_AFBCD0_MISC_CTRL 0x1a0a +#define VD2_AFBCD1_MISC_CTRL 0x1a0b +#define DOLBY_PATH_CTRL 0x1a0c +#define WR_BACK_MISC_CTRL 0x1a0d +#define OSD_PATH_MISC_CTRL 0x1a0e +#define MALI_AFBCD_TOP_CTRL 0x1a0f + +#define VIU_OSD_BLEND_CTRL 0x39b0 +#define VIU_OSD_BLEND_CTRL1 0x39c0 +#define VIU_OSD_BLEND_DIN0_SCOPE_H 0x39b1 +#define VIU_OSD_BLEND_DIN0_SCOPE_V 0x39b2 +#define VIU_OSD_BLEND_DIN1_SCOPE_H 0x39b3 +#define VIU_OSD_BLEND_DIN1_SCOPE_V 0x39b4 +#define VIU_OSD_BLEND_DIN2_SCOPE_H 0x39b5 +#define VIU_OSD_BLEND_DIN2_SCOPE_V 0x39b6 +#define VIU_OSD_BLEND_DIN3_SCOPE_H 0x39b7 +#define VIU_OSD_BLEND_DIN3_SCOPE_V 0x39b8 +#define VIU_OSD_BLEND_DUMMY_DATA0 0x39b9 +#define VIU_OSD_BLEND_DUMMY_ALPHA 0x39ba +#define VIU_OSD_BLEND_BLEND0_SIZE 0x39bb +#define VIU_OSD_BLEND_BLEND1_SIZE 0x39bc +#define VIU_OSD_BLEND_RO_CURRENT_XY 0x39bf + +#define VPP_OUT_H_V_SIZE 0x1da5 + +#define VPP_VD2_HDR_IN_SIZE 0x1df0 +#define VPP_OSD1_IN_SIZE 0x1df1 +#define VPP_GCLK_CTRL2 0x1df2 +#define VD2_PPS_DUMMY_DATA 0x1df4 +#define VPP_OSD1_BLD_H_SCOPE 0x1df5 +#define VPP_OSD1_BLD_V_SCOPE 0x1df6 +#define VPP_OSD2_BLD_H_SCOPE 0x1df7 +#define VPP_OSD2_BLD_V_SCOPE 0x1df8 +#define VPP_WRBAK_CTRL 0x1df9 +#define VPP_SLEEP_CTRL 0x1dfa +#define VD1_BLEND_SRC_CTRL 0x1dfb +#define VD2_BLEND_SRC_CTRL 0x1dfc +#define OSD1_BLEND_SRC_CTRL 0x1dfd +#define OSD2_BLEND_SRC_CTRL 0x1dfe + +#define VPP_POST_BLEND_BLEND_DUMMY_DATA 0x3968 +#define VPP_POST_BLEND_DUMMY_ALPHA 0x3969 #endif -- 2.7.4