Radix cross Linux

Radix Linux distribution for embedded systems.

637 Commits   4 Branches   3 Tags
author: Andrey V.Kosteltsev <kx@radix.pro> 2016-09-14 13:39:28 +0000 committer: Andrey V.Kosteltsev <kx@radix.pro> 2016-09-14 13:39:28 +0000 commit: 629f833e693c28e2a6c764a5c000d464a6c6220e parent: 4a7afd88fb539b1b15c243a47bdb622704b67f6c
Commit Summary:
Hardkernel-3.10.103: First step of OSD XRGB color mode backport from amlogic-3.14.29
Diffstat:
9 files changed, 4830 insertions, 1 deletion
diff --git a/boot/kernel/s805/3.10.103-20160830/Makefile b/boot/kernel/s805/3.10.103-20160830/Makefile
index 71d541c23..875148570 100644
--- a/boot/kernel/s805/3.10.103-20160830/Makefile
+++ b/boot/kernel/s805/3.10.103-20160830/Makefile
@@ -53,7 +53,6 @@ USE_TARGET_DEST_DIR_SYSROOT = no
 ifneq ($(filter $(HARDWARE),$(HARDWARE_M201) $(HARDWARE_MXQ)),)
 device_tree_names  = meson8b_m201_512M.dtb
 device_tree_names += meson8b_m201_1G.dtb
-device_tree_names += meson8b_odroidc.dtb
 device_tree_names += meson8b-mxq.dtb
 endif
 
diff --git a/boot/kernel/s805/3.10.103-20160830/PATCHES b/boot/kernel/s805/3.10.103-20160830/PATCHES
index 8ac16a0af..2da1b686a 100644
--- a/boot/kernel/s805/3.10.103-20160830/PATCHES
+++ b/boot/kernel/s805/3.10.103-20160830/PATCHES
@@ -1,2 +1,3 @@
 
 ../../../../sources/Linux/Hardkernel/S805/patches/linux-aml-3.10.103-20160830-m201-dtbs.patch -p0
+../../../../sources/Linux/Hardkernel/S805/patches/linux-aml-3.10.103-20160830-osd-xrgb.patch  -p0
diff --git a/sources/Linux/Hardkernel/S805/Makefile b/sources/Linux/Hardkernel/S805/Makefile
index f0d481787..b5fc4316c 100644
--- a/sources/Linux/Hardkernel/S805/Makefile
+++ b/sources/Linux/Hardkernel/S805/Makefile
@@ -13,6 +13,7 @@ tarballs    = $(addsuffix .tar.xz, $(addprefix linux-, $(versions)))
 sha1s       = $(addsuffix .sha1sum, $(tarballs))
 
 patches     = $(CURDIR)/patches/linux-aml-3.10.103-20160830-m201-dtbs.patch
+patches    += $(CURDIR)/patches/linux-aml-3.10.103-20160830-osd-xrgb.patch
 
 .NOTPARALLEL: $(patches)
 
@@ -48,6 +49,7 @@ $(sha1s): $(tarballs)
 $(patches): $(sha1s)
 	@echo -e "\n======= Create Patches =======\n" ; \
 	 ( cd create-3.10.103-20160830-m201-dtbs-patch ; ./create.patch.sh ) ; \
+	 ( cd create-3.10.103-20160830-osd-xrgb-patch  ; ./create.patch.sh ) ; \
 	 echo -e "\n"
 
 download_clean:
diff --git a/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/create.patch.sh b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/create.patch.sh
new file mode 100755
index 000000000..0b9827617
--- /dev/null
+++ b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/create.patch.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=3.10.103-20160830
+
+tar --files-from=file.list -xJvf ../linux-aml-$VERSION.tar.xz
+mv linux-aml-$VERSION linux-aml-$VERSION-orig
+
+cp -rf ./linux-aml-$VERSION-new ./linux-aml-$VERSION
+
+diff -b --unified -Nr  linux-aml-$VERSION-orig  linux-aml-$VERSION > linux-aml-$VERSION-osd-xrgb.patch
+
+mv linux-aml-$VERSION-osd-xrgb.patch ../patches
+
+rm -rf ./linux-aml-$VERSION
+rm -rf ./linux-aml-$VERSION-orig
diff --git a/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/file.list b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/file.list
new file mode 100644
index 000000000..9ad7468e4
--- /dev/null
+++ b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/file.list
@@ -0,0 +1,4 @@
+linux-aml-3.10.103-20160830/drivers/amlogic/display/osd/osd_hw.c
+linux-aml-3.10.103-20160830/drivers/amlogic/display/osd/osd_main.c
+linux-aml-3.10.103-20160830/include/linux/amlogic/osd/osd.h
+linux-aml-3.10.103-20160830/include/linux/amlogic/osd/osd_main.h
diff --git a/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/drivers/amlogic/display/osd/osd_hw.c b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/drivers/amlogic/display/osd/osd_hw.c
new file mode 100644
index 000000000..fcf6008c6
--- /dev/null
+++ b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/drivers/amlogic/display/osd/osd_hw.c
@@ -0,0 +1,2884 @@
+/*
+ * Amlogic Apollo
+ * frame buffer driver
+ *
+ * Copyright (C) 2009 Amlogic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Author:  Tim Yao <timyao@amlogic.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <plat/regops.h>
+#include <mach/am_regs.h>
+#include <linux/irqreturn.h>
+#include <linux/errno.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/amlogic/osd/osd.h>
+#include <linux/amlogic/vout/vout_notify.h>
+#include <linux/amlogic/amports/canvas.h>
+#include "osd_log.h"
+#include <linux/amlogic/amlog.h>
+#include <linux/amlogic/amports/vframe_receiver.h>
+#include "osd_hw_def.h"
+#include "osd_prot.h"
+#include "osd_antiflicker.h"
+#include "osd_clone.h"
+
+#ifdef CONFIG_AML_VSYNC_FIQ_ENABLE
+#define  FIQ_VSYNC
+#endif
+
+#ifdef CONFIG_VSYNC_RDMA
+int reset_rdma(void);
+int osd_rdma_enable(u32  enable);
+#endif
+
+static DEFINE_SPINLOCK(osd_onoff_lock);
+static DECLARE_WAIT_QUEUE_HEAD(osd_vsync_wq);
+
+static bool vsync_hit = false;
+static bool osd_vf_need_update = false;
+#ifdef CONFIG_AM_FB_EXT
+extern void osd_ext_clone_pan(u32 index);
+#endif
+extern void osd_clone_pan(u32 index, u32 yoffset, int debug_flag);
+
+static struct vframe_provider_s osd_vf_prov;
+static int  g_vf_visual_width;
+static int  g_vf_width;
+static int  g_vf_height;
+static int  g_rotation_width;
+static int  g_rotation_height;
+
+static int osd_h_filter_mode = 1;
+static int osd_v_filter_mode = 1;
+static int use_h_filter_mode = -1;
+static int use_v_filter_mode = -1;
+static unsigned int osd_filter_coefs_bicubic_sharp[] = {
+    0x01fa008c, 0x01fa0100, 0xff7f0200, 0xfe7f0300,
+    0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900,
+    0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
+    0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe,
+    0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd,
+    0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
+    0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa,
+    0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9,
+    0xf84848f8
+};
+
+static unsigned int osd_filter_coefs_bicubic[] =   //bicubic	coef0
+{
+    0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300, 0xfd7e0500, 0xfc7e0600,
+    0xfb7d0800, 0xfb7c0900, 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
+    0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe, 0xf76f1dfd, 0xf76d1ffd,
+    0xf76b21fd, 0xf76824fd, 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
+    0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa, 0xf8523cfa, 0xf8503ff9,
+    0xf84d42f9, 0xf84a45f9, 0xf84848f8
+};
+
+static unsigned int osd_filter_coefs_bilinear[] =  //2 point bilinear	coef1
+{
+    0x00800000, 0x007e0200, 0x007c0400, 0x007a0600, 0x00780800, 0x00760a00,
+    0x00740c00, 0x00720e00, 0x00701000, 0x006e1200, 0x006c1400, 0x006a1600,
+    0x00681800, 0x00661a00, 0x00641c00, 0x00621e00, 0x00602000, 0x005e2200,
+    0x005c2400, 0x005a2600, 0x00582800, 0x00562a00, 0x00542c00, 0x00522e00,
+    0x00503000, 0x004e3200, 0x004c3400, 0x004a3600, 0x00483800, 0x00463a00,
+    0x00443c00, 0x00423e00, 0x00404000
+};
+
+static unsigned int osd_filter_coefs_2point_binilear[] =  //2 point bilinear, bank_length == 2	coef2
+{
+    0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, 0x78080000, 0x760a0000,
+    0x740c0000, 0x720e0000, 0x70100000, 0x6e120000, 0x6c140000, 0x6a160000,
+    0x68180000, 0x661a0000, 0x641c0000, 0x621e0000, 0x60200000, 0x5e220000,
+    0x5c240000, 0x5a260000, 0x58280000, 0x562a0000, 0x542c0000, 0x522e0000,
+    0x50300000, 0x4e320000, 0x4c340000, 0x4a360000, 0x48380000, 0x463a0000,
+    0x443c0000, 0x423e0000, 0x40400000
+};
+
+//filt_triangle, point_num =3, filt_len =2.6, group_num = 64
+static unsigned int osd_filter_coefs_3point_triangle_sharp[] = {
+    0x40400000, 0x3e420000, 0x3d430000, 0x3b450000,
+    0x3a460000, 0x38480000, 0x37490000, 0x354b0000,
+    0x344c0000, 0x324e0000, 0x314f0000, 0x2f510000,
+    0x2e520000, 0x2c540000, 0x2b550000, 0x29570000,
+    0x28580000, 0x265a0000, 0x245c0000, 0x235d0000,
+    0x215f0000, 0x20600000, 0x1e620000, 0x1d620100,
+    0x1b620300, 0x19630400, 0x17630600, 0x15640700,
+    0x14640800, 0x12640a00, 0x11640b00, 0x0f650c00,
+    0x0d660d00
+};
+
+static unsigned int osd_filter_coefs_3point_triangle[] = {
+    0x40400000, 0x3f400100, 0x3d410200, 0x3c410300,
+    0x3a420400, 0x39420500, 0x37430600, 0x36430700,
+    0x35430800, 0x33450800, 0x32450900, 0x31450a00,
+    0x30450b00, 0x2e460c00, 0x2d460d00, 0x2c470d00,
+    0x2b470e00, 0x29480f00, 0x28481000, 0x27481100,
+    0x26491100, 0x25491200, 0x24491300, 0x234a1300,
+    0x224a1400, 0x214a1500, 0x204a1600, 0x1f4b1600,
+    0x1e4b1700, 0x1d4b1800, 0x1c4c1800, 0x1b4c1900,
+    0x1a4c1a00
+};
+
+static unsigned int osd_filter_coefs_4point_triangle[] = {
+    0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101,
+    0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303,
+    0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505,
+    0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707,
+    0x18382808, 0x18382808, 0x17372909, 0x17372909,
+    0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b,
+    0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d,
+    0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f,
+    0x10303010
+};
+
+// 4th order (cubic) b-spline
+//filt_cubic point_num =4, filt_len =4, group_num = 64
+static unsigned int vpp_filter_coefs_4point_bspline[] = {
+    0x15561500, 0x14561600, 0x13561700, 0x12561800,
+    0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00,
+    0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200,
+    0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700,
+    0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01,
+    0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201,
+    0x05473301, 0x05463401, 0x04453601, 0x04433702,
+    0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02,
+    0x033d3d03
+};
+
+//filt_quadratic, point_num =3, filt_len =3, group_num = 64
+static unsigned int osd_filter_coefs_3point_bspline[] = {
+    0x40400000, 0x3e420000, 0x3c440000, 0x3a460000,
+    0x38480000, 0x364a0000, 0x344b0100, 0x334c0100,
+    0x314e0100, 0x304f0100, 0x2e500200, 0x2c520200,
+    0x2a540200, 0x29540300, 0x27560300, 0x26570300,
+    0x24580400, 0x23590400, 0x215a0500, 0x205b0500,
+    0x1e5c0600, 0x1d5c0700, 0x1c5d0700, 0x1a5e0800,
+    0x195e0900, 0x185e0a00, 0x175f0a00, 0x15600b00,
+    0x14600c00, 0x13600d00, 0x12600e00, 0x11600f00,
+    0x10601000
+};
+
+ static unsigned int *filter_table[] = {
+     osd_filter_coefs_bicubic_sharp,
+     osd_filter_coefs_bicubic,
+     osd_filter_coefs_bilinear,
+     osd_filter_coefs_2point_binilear,
+     osd_filter_coefs_3point_triangle_sharp,
+     osd_filter_coefs_3point_triangle,
+     osd_filter_coefs_4point_triangle,
+     vpp_filter_coefs_4point_bspline,
+     osd_filter_coefs_3point_bspline
+ };
+
+#define OSD_TYPE_TOP_FIELD 0
+#define OSD_TYPE_BOT_FIELD 1
+/********************************************************************/
+/***********		osd psedu frame provider 			*****************/
+/********************************************************************/
+static vframe_t *osd_vf_peek(void *arg)
+{
+	return ((osd_vf_need_update && (vf.width > 0) && (vf.height > 0)) ? &vf : NULL);
+}
+
+static vframe_t *osd_vf_get(void *arg)
+{
+	if (osd_vf_need_update) {
+		vf_ext_light_unreg_provider(&osd_vf_prov);
+		osd_vf_need_update = false;
+		return &vf;
+	}
+	return NULL;
+}
+
+#define PROVIDER_NAME   "osd"
+static const struct vframe_operations_s osd_vf_provider =
+{
+	.peek = osd_vf_peek,
+	.get  = osd_vf_get,
+	.put  = NULL,
+};
+
+#ifdef CONFIG_AM_VIDEO
+static unsigned char osd_vf_prov_init = 0;
+#endif
+
+static inline void  osd_update_3d_mode(int enable_osd1,int enable_osd2)
+{
+	if(enable_osd1)
+	{
+		osd1_update_disp_3d_mode();
+	}
+	if(enable_osd2)
+	{
+		osd2_update_disp_3d_mode();
+	}
+}
+
+static inline void wait_vsync_wakeup(void)
+{
+	vsync_hit = true;
+	wake_up_interruptible(&osd_vsync_wq);
+}
+
+#ifdef CONFIG_VSYNC_RDMA
+static irqreturn_t osd_rdma_isr(int irq, void *dev_id)
+{
+#define  	VOUT_ENCI	1
+#define   	VOUT_ENCP	2
+#define	VOUT_ENCT	3
+	unsigned  int  fb0_cfg_w0,fb1_cfg_w0;
+	unsigned  int  odd_or_even_line;
+	unsigned  int  scan_line_number = 0;
+	unsigned  char output_type=0;
+
+	do{
+		if((aml_read_reg32(P_RDMA_STATUS)&0x0fffff0f) == 0){
+			break;
+		}
+	}while(1);
+
+#ifdef CONFIG_VSYNC_RDMA
+	reset_rdma();
+#endif
+
+	output_type=aml_read_reg32(P_VPU_VIU_VENC_MUX_CTRL)&0x3;
+	osd_hw.scan_mode= SCAN_MODE_PROGRESSIVE;
+	switch(output_type)
+	{
+		case VOUT_ENCP:
+			if (aml_read_reg32(P_ENCP_VIDEO_MODE) & (1 << 12)) //1080i
+				osd_hw.scan_mode= SCAN_MODE_INTERLACE;
+			break;
+		case VOUT_ENCI:
+			if (aml_read_reg32(P_ENCI_VIDEO_EN) & 1)
+				osd_hw.scan_mode= SCAN_MODE_INTERLACE;
+			break;
+	}
+
+	if(osd_hw.free_scale_enable[OSD1])
+	{
+		osd_hw.scan_mode= SCAN_MODE_PROGRESSIVE;
+	}
+
+	if (osd_hw.scan_mode == SCAN_MODE_INTERLACE)
+	{
+		fb0_cfg_w0=aml_read_reg32(P_VIU_OSD1_BLK0_CFG_W0);
+		fb1_cfg_w0=aml_read_reg32(P_VIU_OSD1_BLK0_CFG_W0+ REG_OFFSET);
+		if (aml_read_reg32(P_ENCP_VIDEO_MODE) & (1 << 12))
+		{
+			/* 1080I */
+			scan_line_number = ((aml_read_reg32(P_ENCP_INFO_READ))&0x1fff0000)>>16;
+			if ((osd_hw.pandata[OSD1].y_start%2) == 0)
+			{
+				if (scan_line_number >= 562){
+					/* bottom field, odd lines*/
+					odd_or_even_line = 0;	//vsync enable when the next vsync trigger
+				} else {
+					/* top field, even lines*/
+					odd_or_even_line = 1;
+				}
+			}else{
+				if (scan_line_number >= 562) {
+					/* top field, even lines*/
+					odd_or_even_line = 1;
+				} else {
+					/* bottom field, odd lines*/
+					odd_or_even_line = 0;
+				}
+			}
+		} else {
+			if ((osd_hw.pandata[OSD1].y_start%2) == 1){
+				odd_or_even_line = (aml_read_reg32(P_ENCI_INFO_READ) & (1<<29)) ?
+									OSD_TYPE_BOT_FIELD : OSD_TYPE_TOP_FIELD;
+			}else{
+				odd_or_even_line = (aml_read_reg32(P_ENCI_INFO_READ) & (1<<29)) ?
+									OSD_TYPE_TOP_FIELD : OSD_TYPE_BOT_FIELD;
+			}
+		}
+
+		fb0_cfg_w0 &=~1;
+		fb1_cfg_w0 &=~1;
+		fb0_cfg_w0 |=odd_or_even_line;
+		fb1_cfg_w0 |=odd_or_even_line;
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W0, fb0_cfg_w0);
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK1_CFG_W0, fb0_cfg_w0);
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK2_CFG_W0, fb0_cfg_w0);
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK3_CFG_W0, fb0_cfg_w0);
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W0+ REG_OFFSET, fb1_cfg_w0);
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK1_CFG_W0+ REG_OFFSET, fb1_cfg_w0);
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK2_CFG_W0+ REG_OFFSET, fb1_cfg_w0);
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK3_CFG_W0+ REG_OFFSET, fb1_cfg_w0);
+	}
+
+	osd_update_3d_mode(osd_hw.mode_3d[OSD1].enable,osd_hw.mode_3d[OSD2].enable);
+
+	if (!vsync_hit)
+	{
+#ifdef FIQ_VSYNC
+		fiq_bridge_pulse_trigger(&osd_hw.fiq_handle_item);
+#else
+		wait_vsync_wakeup();
+#endif
+	}
+
+	aml_write_reg32(P_RDMA_CTRL, 1<<24);
+
+	return IRQ_HANDLED;
+}
+#endif
+
+static inline void  walk_through_update_list(void)
+{
+	u32  i,j;
+	for(i=0;i<HW_OSD_COUNT;i++)
+	{
+		j=0;
+		while(osd_hw.updated[i] && j<32)
+		{
+			if(osd_hw.updated[i]&(1<<j))
+			{
+				osd_hw.reg[i][j].update_func();
+				remove_from_update_list(i,j);
+			}
+			j++;
+		}
+	}
+}
+
+/**********************************************************************/
+/**********          osd vsync irq handler              ***************/
+/**********************************************************************/
+#ifdef FIQ_VSYNC
+static irqreturn_t vsync_isr(int irq, void *dev_id)
+{
+	wait_vsync_wakeup();
+
+	return IRQ_HANDLED;
+}
+#endif
+
+#ifdef FIQ_VSYNC
+static void osd_fiq_isr(void)
+#else
+static irqreturn_t vsync_isr(int irq, void *dev_id)
+#endif
+{
+#ifndef CONFIG_VSYNC_RDMA
+#define  	VOUT_ENCI	1
+#define   	VOUT_ENCP	2
+#define	VOUT_ENCT	3
+
+	unsigned  int  fb0_cfg_w0,fb1_cfg_w0;
+	unsigned  int  odd_or_even_line;
+	unsigned  int  scan_line_number = 0;
+	unsigned  char output_type=0;
+
+	output_type=aml_read_reg32(P_VPU_VIU_VENC_MUX_CTRL)&0x3;
+	osd_hw.scan_mode= SCAN_MODE_PROGRESSIVE;
+	switch(output_type)
+	{
+		case VOUT_ENCP:
+			if (aml_read_reg32(P_ENCP_VIDEO_MODE) & (1 << 12)) //1080i
+				osd_hw.scan_mode= SCAN_MODE_INTERLACE;
+			break;
+		case VOUT_ENCI:
+			if (aml_read_reg32(P_ENCI_VIDEO_EN) & 1)
+				osd_hw.scan_mode= SCAN_MODE_INTERLACE;
+			break;
+	}
+
+	if(osd_hw.free_scale_enable[OSD1])
+	{
+		osd_hw.scan_mode= SCAN_MODE_PROGRESSIVE;
+	}
+
+	if (osd_hw.scan_mode == SCAN_MODE_INTERLACE)
+	{
+		fb0_cfg_w0=aml_read_reg32(P_VIU_OSD1_BLK0_CFG_W0);
+		fb1_cfg_w0=aml_read_reg32(P_VIU_OSD1_BLK0_CFG_W0+ REG_OFFSET);
+		if (aml_read_reg32(P_ENCP_VIDEO_MODE) & (1 << 12))
+		{
+			/* 1080I */
+			scan_line_number = ((aml_read_reg32(P_ENCP_INFO_READ))&0x1fff0000)>>16;
+			if ((osd_hw.pandata[OSD1].y_start%2) == 0)
+			{
+				if (scan_line_number >= 562){
+					/* bottom field, odd lines*/
+					odd_or_even_line = 1;
+				} else {
+					/* top field, even lines*/
+					odd_or_even_line = 0;
+				}
+			}else{
+				if (scan_line_number >= 562) {
+					/* top field, even lines*/
+					odd_or_even_line = 0;
+				} else {
+					/* bottom field, odd lines*/
+					odd_or_even_line = 1;
+				}
+			}
+		} else {
+			if ((osd_hw.pandata[OSD1].y_start%2) == 0){
+				odd_or_even_line = aml_read_reg32(P_ENCI_INFO_READ) & 1;
+			}else{
+				odd_or_even_line = !(aml_read_reg32(P_ENCI_INFO_READ) & 1);
+			}
+		}
+
+		fb0_cfg_w0 &=~1;
+		fb1_cfg_w0 &=~1;
+		fb0_cfg_w0 |=odd_or_even_line;
+		fb1_cfg_w0 |=odd_or_even_line;
+		aml_write_reg32(P_VIU_OSD1_BLK0_CFG_W0, fb0_cfg_w0);
+		aml_write_reg32(P_VIU_OSD1_BLK1_CFG_W0, fb0_cfg_w0);
+		aml_write_reg32(P_VIU_OSD1_BLK2_CFG_W0, fb0_cfg_w0);
+		aml_write_reg32(P_VIU_OSD1_BLK3_CFG_W0, fb0_cfg_w0);
+		aml_write_reg32(P_VIU_OSD1_BLK0_CFG_W0+ REG_OFFSET, fb1_cfg_w0);
+		aml_write_reg32(P_VIU_OSD1_BLK1_CFG_W0+ REG_OFFSET, fb1_cfg_w0);
+		aml_write_reg32(P_VIU_OSD1_BLK2_CFG_W0+ REG_OFFSET, fb1_cfg_w0);
+		aml_write_reg32(P_VIU_OSD1_BLK3_CFG_W0+ REG_OFFSET, fb1_cfg_w0);
+	}
+	//go through update list
+	walk_through_update_list();
+
+	osd_update_3d_mode(osd_hw.mode_3d[OSD1].enable,osd_hw.mode_3d[OSD2].enable);
+#endif
+
+#if 0
+#ifdef CONFIG_VSYNC_RDMA
+	reset_rdma();
+#endif
+#endif
+
+#ifndef CONFIG_VSYNC_RDMA
+	if (!vsync_hit)
+	{
+#ifdef FIQ_VSYNC
+		fiq_bridge_pulse_trigger(&osd_hw.fiq_handle_item);
+#else
+		wait_vsync_wakeup();
+#endif
+	}
+#endif
+
+#ifndef FIQ_VSYNC
+	return  IRQ_HANDLED;
+#endif
+}
+
+void osd_wait_vsync_hw(void)
+{
+	vsync_hit = false;
+
+	wait_event_interruptible_timeout(osd_vsync_wq, vsync_hit, HZ);
+}
+
+void osd_set_scan_mode(int index)
+{
+	const vinfo_t *vinfo;
+
+	osd_hw.scan_mode = SCAN_MODE_PROGRESSIVE;
+	vinfo = get_current_vinfo();
+	if (vinfo) {
+		osd_hw.scale_workaround = 0;
+		switch (vinfo->mode) {
+		case VMODE_480I:
+		case VMODE_480CVBS:
+		case VMODE_576I:
+		case VMODE_576CVBS:
+			if(osd_hw.free_scale_mode[index]){
+				osd_hw.field_out_en = 1;
+
+				if(osd_hw.free_scale_data[index].y_end == 719){
+					osd_hw.bot_type = 2;
+				}else if(osd_hw.free_scale_data[index].y_end == 1079){
+					osd_hw.bot_type = 3;
+				}else{
+					osd_hw.bot_type = 2;
+				}
+			}
+			osd_hw.scan_mode = SCAN_MODE_INTERLACE;
+		break;
+		case VMODE_1080I:
+		case VMODE_1080I_50HZ:
+#ifdef CONFIG_AML_VOUT_FRAMERATE_AUTOMATION
+		case VMODE_1080I_59HZ:
+#endif
+			if(osd_hw.free_scale_mode[index]){
+				osd_hw.field_out_en = 1;
+
+				if(osd_hw.free_scale_data[index].y_end == 719){
+					osd_hw.bot_type = 1;
+				}else if(osd_hw.free_scale_data[index].y_end == 1079){
+					osd_hw.bot_type = 2;
+				}else{
+					osd_hw.bot_type = 1;
+				}
+			}
+			osd_hw.scan_mode = SCAN_MODE_INTERLACE;
+		break;
+		case VMODE_4K2K_24HZ:
+		case VMODE_4K2K_25HZ:
+		case VMODE_4K2K_30HZ:
+		case VMODE_4K2K_SMPTE:
+			if(osd_hw.fb_for_4k2k){
+				if(osd_hw.free_scale_enable[index]){
+					osd_hw.scale_workaround = 1;
+				}
+			}
+			osd_hw.field_out_en = 0;
+		break;
+		default:
+			if(osd_hw.free_scale_mode[index]){
+				osd_hw.field_out_en = 0;
+			}
+		break;
+		}
+	}
+
+	if(osd_hw.free_scale_enable[OSD1] || osd_hw.free_scale_enable[OSD2]){
+		osd_hw.scan_mode= SCAN_MODE_PROGRESSIVE;
+	}
+}
+
+void  osd_set_gbl_alpha_hw(u32 index,u32 gbl_alpha)
+{
+	if(osd_hw.gbl_alpha[index] != gbl_alpha)
+	{
+
+		osd_hw.gbl_alpha[index]=gbl_alpha;
+		add_to_update_list(index,OSD_GBL_ALPHA);
+
+		osd_wait_vsync_hw();
+	}
+}
+u32  osd_get_gbl_alpha_hw(u32  index)
+{
+	return osd_hw.gbl_alpha[index];
+}
+void  osd_set_colorkey_hw(u32 index,u32 color_index,u32 colorkey )
+{
+	u8  r=0,g=0,b=0,a=(colorkey&0xff000000)>>24;
+	u32	data32;
+
+	colorkey&=0x00ffffff;
+	switch(color_index)
+	{
+		case COLOR_INDEX_16_655:
+			r=(colorkey>>10&0x3f)<<2;
+			g=(colorkey>>5&0x1f)<<3;
+			b=(colorkey&0x1f)<<3;
+			break;
+		case COLOR_INDEX_16_844:
+			r=colorkey>>8&0xff;
+			g=(colorkey>>4&0xf)<<4;
+			b=(colorkey&0xf)<<4;
+			break;
+		case COLOR_INDEX_16_565:
+			r=(colorkey>>11&0x1f)<<3;
+			g=(colorkey>>5&0x3f)<<2;
+			b=(colorkey&0x1f)<<3;
+			break;
+		case COLOR_INDEX_24_888_B:
+			b=colorkey>>16&0xff;
+			g=colorkey>>8&0xff;
+			r=colorkey&0xff;
+			break;
+		case COLOR_INDEX_24_RGB:
+		case COLOR_INDEX_YUV_422:
+			r=colorkey>>16&0xff;
+			g=colorkey>>8&0xff;
+			b=colorkey&0xff;
+			break;
+	}
+	data32=r<<24|g<<16|b<<8|a;
+	if( osd_hw.color_key[index]!=data32)
+	{
+		osd_hw.color_key[index]=data32;
+		amlog_mask_level(LOG_MASK_HARDWARE,LOG_LEVEL_LOW,"bpp:%d--r:0x%x g:0x%x b:0x%x ,a:0x%x\r\n",color_index,r,g,b,a);
+		add_to_update_list(index,OSD_COLOR_KEY);
+
+		osd_wait_vsync_hw();
+	}
+
+	return ;
+}
+void  osd_srckey_enable_hw(u32  index,u8 enable)
+{
+	if(enable != osd_hw.color_key_enable[index])
+	{
+		osd_hw.color_key_enable[index]=enable;
+		add_to_update_list(index,OSD_COLOR_KEY_ENABLE);
+
+		osd_wait_vsync_hw();
+	}
+
+}
+
+void osd_set_color_mode(int index, const color_bit_define_t *color) {
+    if(color != osd_hw.color_info[index]) {
+        osd_hw.color_info[index] = color;
+        add_to_update_list(index, OSD_COLOR_MODE);
+    }
+}
+
+void osddev_update_disp_axis_hw(
+		u32 display_h_start,
+		u32 display_h_end,
+		u32 display_v_start,
+		u32 display_v_end,
+		u32 xoffset,
+		u32 yoffset,
+		u32 mode_change,
+		u32 index)
+{
+	dispdata_t   disp_data;
+	pandata_t    pan_data;
+
+	if(NULL==osd_hw.color_info[index]) return ;
+	if(mode_change)  //modify pandata .
+	{
+		add_to_update_list(index,OSD_COLOR_MODE);
+	}
+	disp_data.x_start=display_h_start;
+	disp_data.y_start=display_v_start;
+	disp_data.x_end=display_h_end;
+	disp_data.y_end=display_v_end;
+
+	pan_data.x_start=xoffset;
+	pan_data.x_end=xoffset + (display_h_end - display_h_start);
+	pan_data.y_start=yoffset;
+	pan_data.y_end=yoffset + (display_v_end-display_v_start);
+
+	//if output mode change then reset pan ofFfset.
+	memcpy(&osd_hw.pandata[index],&pan_data,sizeof(pandata_t));
+	memcpy(&osd_hw.dispdata[index],&disp_data,sizeof(dispdata_t));
+	add_to_update_list(index,DISP_GEOMETRY);
+	osd_wait_vsync_hw();
+
+}
+void osd_setup(struct osd_ctl_s *osd_ctl,
+		u32 xoffset,
+		u32 yoffset,
+		u32 xres,
+		u32 yres,
+		u32 xres_virtual,
+		u32 yres_virtual,
+		u32 disp_start_x,
+		u32 disp_start_y,
+		u32 disp_end_x,
+		u32 disp_end_y,
+		u32 fbmem,
+		const color_bit_define_t *color,
+		int index
+	      )
+{
+	u32  w=(color->bpp * xres_virtual + 7) >> 3;
+	dispdata_t   disp_data;
+	pandata_t    pan_data;
+#ifdef CONFIG_AM_LOGO
+	static u32	    logo_setup_ok=0;
+#endif
+
+	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]){
+			pan_data.x_end=xoffset + g_vf_visual_width;
+			pan_data.y_end=yoffset + g_vf_height;
+			disp_data.x_end=disp_start_x + g_vf_width;
+			disp_data.y_end=disp_start_y + g_vf_height;
+		}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);
+		if (likely(osd_hw.rotate[index].on_off && osd_hw.rotate[index].on_off > 0)){
+			disp_data.x_end = disp_start_x + g_rotation_height;
+			disp_data.y_end = disp_start_y + g_rotation_width;
+		}else{
+			disp_data.x_end=disp_end_x;
+			disp_data.y_end=disp_end_y;
+		}
+	}
+
+	if( osd_hw.fb_gem[index].addr!=fbmem || osd_hw.fb_gem[index].width !=w ||  osd_hw.fb_gem[index].height !=yres_virtual)
+	{
+		osd_hw.fb_gem[index].addr=fbmem;
+		osd_hw.fb_gem[index].width=w;
+		osd_hw.fb_gem[index].height=yres_virtual;
+		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);
+	}
+
+	if(color != osd_hw.color_info[index])
+	{
+		osd_hw.color_info[index]=color;
+		add_to_update_list(index,OSD_COLOR_MODE);
+	}
+	//osd blank only control by /sys/class/graphcis/fbx/blank
+	/*
+	   if(osd_hw.enable[index] == DISABLE)
+	   {
+	   osd_hw.enable[index]=ENABLE;
+	   add_to_update_list(index,OSD_ENABLE);
+
+	   }*/
+	if(memcmp(&pan_data,&osd_hw.pandata[index],sizeof(pandata_t))!= 0 ||
+			memcmp(&disp_data,&osd_hw.dispdata[index],sizeof(dispdata_t))!=0)
+	{
+		//if(!osd_hw.free_scale_enable[OSD1]) //in free scale mode ,adjust geometry para is abandoned.
+		{
+			memcpy(&osd_hw.pandata[index],&pan_data,sizeof(pandata_t));
+			memcpy(&osd_hw.dispdata[index],&disp_data,sizeof(dispdata_t));
+			add_to_update_list(index,DISP_GEOMETRY);
+		}
+	}
+
+#ifdef CONFIG_AM_LOGO
+	if(!logo_setup_ok)
+	{
+#ifdef FIQ_VSYNC
+		osd_fiq_isr();
+#else
+		vsync_isr(INT_VIU_VSYNC,NULL);
+#endif
+		logo_setup_ok++;
+	}
+#endif
+
+	if(osd_hw.antiflicker_mode){
+		osd_antiflicker_update_pan(yoffset, yres);
+	}
+
+	if(osd_hw.clone){
+		osd_clone_pan(index, yoffset, 0);
+	}
+
+#ifdef CONFIG_AM_FB_EXT
+	osd_ext_clone_pan(index);
+#endif
+
+	osd_wait_vsync_hw();
+}
+
+void osd_setpal_hw(unsigned regno,
+		unsigned red,
+		unsigned green,
+		unsigned blue,
+		unsigned transp,
+		int index
+		)
+{
+
+	if (regno < 256) {
+		u32 pal;
+		pal = ((red   & 0xff) << 24) |
+			((green & 0xff) << 16) |
+			((blue  & 0xff) <<  8) |
+			(transp & 0xff);
+
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_COLOR_ADDR+REG_OFFSET*index, regno);
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_COLOR+REG_OFFSET*index, pal);
+	}
+}
+u32 osd_get_osd_order_hw(u32 index)
+{
+	return  osd_hw.osd_order&0x3;
+}
+void osd_change_osd_order_hw(u32 index,u32 order)
+{
+	if((order != OSD_ORDER_01)&&(order != OSD_ORDER_10))
+		return ;
+	osd_hw.osd_order=order;
+	add_to_update_list(index,OSD_CHANGE_ORDER);
+	osd_wait_vsync_hw();
+}
+
+void osd_free_scale_enable_hw(u32 index,u32 enable)
+{
+	if (osd_hw.free_scale_mode[index]){
+		unsigned int hfs_enable = 0;
+		unsigned int vfs_enable = 0;
+
+		hfs_enable = (enable&0xffff0000?1:0);
+		vfs_enable = (enable&0xffff?1:0);
+		osd_hw.free_scale[index].hfs_enable = hfs_enable;
+		osd_hw.free_scale[index].vfs_enable = vfs_enable;
+
+		if (hfs_enable ||vfs_enable){
+			osd_hw.free_scale_enable[index] = 1;
+		}else if (!hfs_enable && !vfs_enable){
+			osd_hw.free_scale_enable[index] = 0;
+		}
+
+		if (osd_hw.free_scale_enable[index])
+		{
+			if ((osd_hw.free_scale_data[index].x_end > 0) && hfs_enable){
+				osd_hw.free_scale_width[index] = osd_hw.free_scale_data[index].x_end - \
+								osd_hw.free_scale_data[index].x_start;
+			}
+
+			if ((osd_hw.free_scale_data[index].y_end > 0) && vfs_enable){
+				osd_hw.free_scale_height[index] = osd_hw.free_scale_data[index].y_end -\
+								 osd_hw.free_scale_data[index].y_start;
+			}
+			osd_set_scan_mode(index);
+			add_to_update_list(index,OSD_COLOR_MODE);
+			add_to_update_list(index,OSD_FREESCALE_COEF);
+			add_to_update_list(index,DISP_GEOMETRY);
+			add_to_update_list(index,DISP_FREESCALE_ENABLE);
+		}else{
+			osd_set_scan_mode(index);
+			add_to_update_list(index,OSD_COLOR_MODE);
+			add_to_update_list(index,DISP_GEOMETRY);
+			add_to_update_list(index,DISP_FREESCALE_ENABLE);
+		}
+
+		osd_enable_hw(osd_hw.enable[index],index);
+	}else{
+		static  dispdata_t	save_disp_data={0,0,0,0};
+#ifdef CONFIG_AM_VIDEO
+#ifdef CONFIG_POST_PROCESS_MANAGER
+		int mode_changed = 0;
+		if((index==OSD1)&&(osd_hw.free_scale_enable[index]!=enable))
+			mode_changed = 1;
+#endif
+#endif
+
+		amlog_level(LOG_LEVEL_HIGH,"osd%d free scale %s\r\n",index,enable?"ENABLE":"DISABLE");
+		enable = (enable&0xffff?1:0);
+		osd_hw.free_scale_enable[index]=enable;
+		if (index==OSD1)
+		{
+			if(enable)
+			{
+				osd_vf_need_update = true;
+				if ((osd_hw.free_scale_data[OSD1].x_end > 0) && (osd_hw.free_scale_data[OSD1].x_end > 0)) {
+					vf.width = osd_hw.free_scale_data[index].x_end - osd_hw.free_scale_data[index].x_start + 1;
+					vf.height = osd_hw.free_scale_data[index].y_end - osd_hw.free_scale_data[index].y_start + 1;
+				} else {
+					vf.width=osd_hw.free_scale_width[OSD1];
+					vf.height=osd_hw.free_scale_height[OSD1];
+				}
+				//				vf.type = (osd_hw.scan_mode==SCAN_MODE_INTERLACE ?VIDTYPE_INTERLACE:VIDTYPE_PROGRESSIVE) | VIDTYPE_VIU_FIELD;
+				vf.type = (VIDTYPE_NO_VIDEO_ENABLE | VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | VIDTYPE_VSCALE_DISABLE);
+				vf.ratio_control=DISP_RATIO_FORCECONFIG|DISP_RATIO_NO_KEEPRATIO;
+#ifdef CONFIG_AM_VIDEO
+				if(osd_vf_prov_init==0){
+					vf_provider_init(&osd_vf_prov, PROVIDER_NAME, &osd_vf_provider, NULL);
+					osd_vf_prov_init = 1;
+				}
+				vf_reg_provider(&osd_vf_prov);
+#endif
+				memcpy(&save_disp_data,&osd_hw.dispdata[OSD1],sizeof(dispdata_t));
+				g_vf_visual_width=vf.width-1-osd_hw.dispdata[OSD1].x_start ;
+				g_vf_width=vf.width-1;
+				g_vf_height=vf.height-1;
+
+				osd_hw.dispdata[OSD1].x_end =osd_hw.dispdata[OSD1].x_start + vf.width-1;
+				osd_hw.dispdata[OSD1].y_end =osd_hw.dispdata[OSD1].y_start + vf.height-1;
+
+				osd_set_scan_mode(index);
+				add_to_update_list(OSD1,DISP_GEOMETRY);
+				add_to_update_list(OSD1,OSD_COLOR_MODE);
+			}
+			else
+			{
+				osd_vf_need_update = false;
+				osd_set_scan_mode(index);
+				if(save_disp_data.x_end <= save_disp_data.x_start ||
+						save_disp_data.y_end <= save_disp_data.y_start)
+				{
+					return ;
+				}
+				memcpy(&osd_hw.dispdata[OSD1],&save_disp_data,sizeof(dispdata_t));
+
+				add_to_update_list(OSD1,DISP_GEOMETRY);
+				add_to_update_list(OSD1,OSD_COLOR_MODE);
+#ifdef CONFIG_AM_VIDEO
+				vf_unreg_provider(&osd_vf_prov);
+#endif
+			}
+		}
+		else
+		{
+			add_to_update_list(OSD2,DISP_GEOMETRY);
+			add_to_update_list(OSD2,OSD_COLOR_MODE);
+		}
+		osd_enable_hw(osd_hw.enable[index],index);
+#ifdef CONFIG_AM_VIDEO
+#ifdef CONFIG_POST_PROCESS_MANAGER
+		if(mode_changed){
+			//vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_RESET,NULL);
+			extern void vf_ppmgr_reset(int type);
+			vf_ppmgr_reset(1);
+		}
+#endif
+#endif
+	}
+}
+
+void osd_get_free_scale_enable_hw(u32 index, u32 *free_scale_enable)
+{
+	*free_scale_enable = osd_hw.free_scale_enable[index];
+}
+
+void osd_free_scale_mode_hw(u32 index,u32 freescale_mode)
+{
+	osd_hw.free_scale_mode[index] = freescale_mode;
+}
+
+void osd_get_free_scale_mode_hw(u32 index, u32 *freescale_mode)
+{
+	*freescale_mode = osd_hw.free_scale_mode[index];
+}
+
+void osd_4k2k_fb_mode_hw(u32 fb_for_4k2k)
+{
+	osd_hw.fb_for_4k2k = fb_for_4k2k;
+}
+
+void osd_free_scale_width_hw(u32 index,u32 width)
+{
+	osd_hw.free_scale_width[index]=width;
+	if (osd_hw.free_scale_enable[index] &&
+			(!osd_hw.free_scale_mode[index])) {
+		osd_vf_need_update = true;
+		vf.width = osd_hw.free_scale_width[index];
+	}
+}
+
+void osd_get_free_scale_width_hw(u32 index, u32 *free_scale_width)
+{
+	*free_scale_width = osd_hw.free_scale_width[index];
+}
+
+void osd_free_scale_height_hw(u32 index,u32 height)
+{
+	osd_hw.free_scale_height[index]=height;
+	if (osd_hw.free_scale_enable[index] &&
+			(!osd_hw.free_scale_mode[index])) {
+		osd_vf_need_update = true;
+		vf.height = osd_hw.free_scale_height[index];
+	}
+}
+
+void osd_get_free_scale_height_hw(u32 index, u32 *free_scale_height)
+{
+	*free_scale_height = osd_hw.free_scale_height[index];
+}
+
+void osd_get_free_scale_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1)
+{
+	*x0 = osd_hw.free_scale_data[index].x_start;
+	*y0 = osd_hw.free_scale_data[index].y_start;
+	*x1 = osd_hw.free_scale_data[index].x_end;
+	*y1 = osd_hw.free_scale_data[index].y_end;
+}
+
+void osd_set_free_scale_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1)
+{
+	osd_hw.free_scale_data[index].x_start = x0;
+	osd_hw.free_scale_data[index].y_start = y0;
+	osd_hw.free_scale_data[index].x_end = x1;
+	osd_hw.free_scale_data[index].y_end = y1;
+}
+
+void osd_get_scale_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1)
+{
+	*x0 = osd_hw.scaledata[index].x_start;
+	*x1 = osd_hw.scaledata[index].x_end;
+	*y0 = osd_hw.scaledata[index].y_start;
+	*y1 = osd_hw.scaledata[index].y_end;
+}
+
+void osd_set_scale_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1)
+{
+	osd_hw.scaledata[index].x_start = x0;
+	osd_hw.scaledata[index].x_end = x1;
+	osd_hw.scaledata[index].y_start = y0;
+	osd_hw.scaledata[index].y_end = y1;
+}
+
+void osd_get_window_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1)
+{
+    const vinfo_t *vinfo;
+    vinfo = get_current_vinfo();
+    if (vinfo) {
+        switch (vinfo->mode) {
+ 		        case VMODE_480I:
+ 		        case VMODE_480CVBS:
+ 		        case VMODE_576I:
+ 		        case VMODE_576CVBS:
+ 		        case VMODE_1080I:
+ 		        case VMODE_1080I_50HZ:
+#ifdef CONFIG_AML_VOUT_FRAMERATE_AUTOMATION
+				case VMODE_1080I_59HZ:
+#endif
+
+ 		        	  *y0 = osd_hw.free_dst_data[index].y_start*2;
+ 			          *y1 = osd_hw.free_dst_data[index].y_end*2;
+ 		        break;
+ 		        default:
+ 		        	  *y0 = osd_hw.free_dst_data[index].y_start;
+ 			          *y1 = osd_hw.free_dst_data[index].y_end;
+ 		        break;
+        }
+    }
+
+	  *x0 = osd_hw.free_dst_data[index].x_start;
+	  *x1 = osd_hw.free_dst_data[index].x_end;
+}
+
+void osd_set_window_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1)
+{
+	const vinfo_t *vinfo;
+	vinfo = get_current_vinfo();
+	if (vinfo) {
+	switch (vinfo->mode) {
+		case VMODE_480I:
+		case VMODE_480CVBS:
+		case VMODE_576I:
+		case VMODE_576CVBS:
+		case VMODE_1080I:
+		case VMODE_1080I_50HZ:
+#ifdef CONFIG_AML_VOUT_FRAMERATE_AUTOMATION
+		case VMODE_1080I_59HZ:
+#endif
+		osd_hw.free_dst_data[index].y_start = y0/2;
+		osd_hw.free_dst_data[index].y_end = y1/2;
+		break;
+		default:
+		osd_hw.free_dst_data[index].y_start = y0;
+		osd_hw.free_dst_data[index].y_end = y1;
+		break;
+	}
+	}
+	osd_hw.free_dst_data[index].x_start = x0;
+	osd_hw.free_dst_data[index].x_end = x1;
+#if 0
+	osd_hw.free_dst_data[index].y_start = y0;
+	osd_hw.free_dst_data[index].y_end = y1/2;
+#endif
+
+#if defined(CONFIG_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 = y0;
+	osd_hw.cursor_dispdata[index].y_end = y1;
+#endif
+}
+
+
+void osd_get_osd_info_hw(u32 index, s32 (*posdval)[4], u32(*posdreg)[5], s32 info_flag)
+{
+	if(info_flag == 0){
+		posdval[0][0] = osd_hw.pandata[index].x_start;
+		posdval[0][1] = osd_hw.pandata[index].x_end;
+		posdval[0][2] = osd_hw.pandata[index].y_start;
+		posdval[0][3] = osd_hw.pandata[index].y_end;
+
+		posdval[1][0] = osd_hw.dispdata[index].x_start;
+		posdval[1][1] = osd_hw.dispdata[index].x_end;
+		posdval[1][2] = osd_hw.dispdata[index].y_start;
+		posdval[1][3] = osd_hw.dispdata[index].y_end;
+
+		posdval[2][0] = osd_hw.scaledata[index].x_start;
+		posdval[2][1] = osd_hw.scaledata[index].x_end;
+		posdval[2][2] = osd_hw.scaledata[index].y_start;
+		posdval[2][3] = osd_hw.scaledata[index].y_end;
+	}else if(info_flag == 1){
+		posdreg[0][0] = aml_read_reg32(P_VIU_OSD1_BLK0_CFG_W0);
+		posdreg[0][1] = aml_read_reg32(P_VIU_OSD1_BLK0_CFG_W1);
+		posdreg[0][2] = aml_read_reg32(P_VIU_OSD1_BLK0_CFG_W2);
+		posdreg[0][3] = aml_read_reg32(P_VIU_OSD1_BLK0_CFG_W3);
+		posdreg[0][4] = aml_read_reg32(P_VIU_OSD1_BLK0_CFG_W4);
+
+		posdreg[1][0] = aml_read_reg32(P_VIU_OSD2_BLK0_CFG_W0);
+		posdreg[1][1] = aml_read_reg32(P_VIU_OSD2_BLK0_CFG_W1);
+		posdreg[1][2] = aml_read_reg32(P_VIU_OSD2_BLK0_CFG_W2);
+		posdreg[1][3] = aml_read_reg32(P_VIU_OSD2_BLK0_CFG_W3);
+		posdreg[1][4] = aml_read_reg32(P_VIU_OSD2_BLK0_CFG_W4);
+	}else{
+		;//ToDo
+	}
+}
+
+void osd_get_block_windows_hw(u32 index, u32 *windows)
+{
+	memcpy(windows, osd_hw.block_windows[index], sizeof(osd_hw.block_windows[index]));
+}
+
+void osd_set_block_windows_hw(u32 index, u32 *windows)
+{
+	memcpy(osd_hw.block_windows[index], windows, sizeof(osd_hw.block_windows[index]));
+	add_to_update_list(index, DISP_GEOMETRY);
+	osd_wait_vsync_hw();
+}
+
+void osd_get_block_mode_hw(u32 index, u32 *mode)
+{
+	*mode = osd_hw.block_mode[index];
+}
+
+void osd_set_block_mode_hw(u32 index, u32 mode)
+{
+	osd_hw.block_mode[index] = mode;
+	add_to_update_list(index, DISP_GEOMETRY);
+	osd_wait_vsync_hw();
+}
+
+void osd_enable_3d_mode_hw(int index,int enable)
+{
+	spin_lock_irqsave(&osd_lock, lock_flags);
+	osd_hw.mode_3d[index].enable=enable;
+	spin_unlock_irqrestore(&osd_lock, lock_flags);
+	if(enable)  //when disable 3d mode ,we should return to stardard state.
+	{
+		osd_hw.mode_3d[index].left_right=LEFT;
+		osd_hw.mode_3d[index].l_start=osd_hw.pandata[index].x_start;
+		osd_hw.mode_3d[index].l_end= (osd_hw.pandata[index].x_end +  osd_hw.pandata[index].x_start)>>1;
+		osd_hw.mode_3d[index].r_start=osd_hw.mode_3d[index].l_end + 1;
+		osd_hw.mode_3d[index].r_end=osd_hw.pandata[index].x_end;
+		osd_hw.mode_3d[index].origin_scale.h_enable=osd_hw.scale[index].h_enable;
+		osd_hw.mode_3d[index].origin_scale.v_enable=osd_hw.scale[index].v_enable;
+		osd_set_2x_scale_hw(index,1,0);
+	}
+	else
+	{
+
+		osd_set_2x_scale_hw(index,osd_hw.mode_3d[index].origin_scale.h_enable,
+				osd_hw.mode_3d[index].origin_scale.v_enable);
+	}
+}
+void osd_enable_hw(int enable ,int index )
+{
+	osd_hw.enable[index]=enable;
+	add_to_update_list(index,OSD_ENABLE);
+
+	osd_wait_vsync_hw();
+}
+
+void osd_set_2x_scale_hw(u32 index,u16 h_scale_enable,u16 v_scale_enable)
+{
+	amlog_level(LOG_LEVEL_HIGH, "osd[%d] set scale, h_scale: %s, v_scale: %s\r\n",
+			index, h_scale_enable ? "ENABLE" : "DISABLE", v_scale_enable ? "ENABLE" : "DISABLE");
+	amlog_level(LOG_LEVEL_HIGH, "osd[%d].scaledata: %d %d %d %d\n",
+			index,
+			osd_hw.scaledata[index].x_start,
+			osd_hw.scaledata[index].x_end,
+			osd_hw.scaledata[index].y_start,
+			osd_hw.scaledata[index].y_end);
+	amlog_level(LOG_LEVEL_HIGH, "osd[%d].pandata: %d %d %d %d\n",
+			index,
+			osd_hw.pandata[index].x_start,
+			osd_hw.pandata[index].x_end,
+			osd_hw.pandata[index].y_start,
+			osd_hw.pandata[index].y_end);
+
+	osd_hw.scale[index].h_enable = h_scale_enable;
+	osd_hw.scale[index].v_enable = v_scale_enable;
+	add_to_update_list(index, DISP_SCALE_ENABLE);
+	add_to_update_list(index, DISP_GEOMETRY);
+
+	osd_wait_vsync_hw();
+}
+
+void osd_get_flush_rate(u32 *break_rate)
+{
+	const vinfo_t *vinfo;
+	vinfo = get_current_vinfo();
+	*break_rate = vinfo->sync_duration_num /vinfo->sync_duration_den;
+}
+
+void osd_set_osd_rotate_angle_hw(u32 index, u32 angle)
+{
+	osd_hw.rotate[index].angle = angle;
+	add_to_update_list(index, DISP_OSD_ROTATE);
+	osd_wait_vsync_hw();
+}
+
+void osd_get_osd_rotate_angle_hw(u32 index,u32 *angle)
+{
+	*angle = osd_hw.rotate[index].angle;
+}
+void osd_set_osd_rotate_on_hw(u32 index, u32 on_off)
+{
+	//static dispdata_t save_disp_data={0,0,0,0};
+	//static dispdata_t save_disp_data2={0,0,0,0};
+	osd_hw.rotate[index].on_off = on_off;
+
+	if(on_off)
+	{
+		if(index == OSD1){
+			//memcpy(&save_disp_data,&osd_hw.dispdata[index],sizeof(dispdata_t));
+		}else if(index == OSD2){
+			//memcpy(&save_disp_data2,&osd_hw.dispdata[index],sizeof(dispdata_t));
+		}
+		g_rotation_width = osd_hw.rotation_pandata[index].x_end-osd_hw.rotation_pandata[index].x_start;
+		g_rotation_height = osd_hw.rotation_pandata[index].y_end-osd_hw.rotation_pandata[index].y_start;
+		osd_hw.dispdata[index].x_end = osd_hw.dispdata[OSD1].x_start+g_rotation_height;
+		osd_hw.dispdata[index].y_end = osd_hw.dispdata[OSD1].y_start+g_rotation_width;
+	}
+	else
+	{
+#if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8)
+	{
+		if(IS_MESON_M8_CPU){
+			VSYNCOSD_SET_MPEG_REG_MASK(VPU_SW_RESET, 1<<8);
+			VSYNCOSD_CLR_MPEG_REG_MASK(VPU_SW_RESET, 1<<8);
+		}
+	}
+#endif
+		if(index == OSD1){
+#if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8)
+	{
+		if(IS_MESON_M8_CPU){
+			VSYNCOSD_SET_MPEG_REG_MASK(VIU_SW_RESET, 1<<0);
+			VSYNCOSD_CLR_MPEG_REG_MASK(VIU_SW_RESET, 1<<0);
+		}
+	}
+#endif
+			VSYNCOSD_SET_MPEG_REG_MASK(VIU_OSD1_FIFO_CTRL_STAT, 1<<0);
+			//memcpy(&osd_hw.dispdata[index],&save_disp_data,sizeof(dispdata_t));
+		}else{
+			VSYNCOSD_SET_MPEG_REG_MASK(VIU_SW_RESET, 1<<1);
+			VSYNCOSD_CLR_MPEG_REG_MASK(VIU_SW_RESET, 1<<1);
+			VSYNCOSD_SET_MPEG_REG_MASK(VIU_OSD2_FIFO_CTRL_STAT, 1<<0);
+			//memcpy(&osd_hw.dispdata[index],&save_disp_data2,sizeof(dispdata_t));
+		}
+	}
+	add_to_update_list(index,OSD_COLOR_MODE);
+	add_to_update_list(index, DISP_GEOMETRY);
+	add_to_update_list(index, DISP_OSD_ROTATE);
+	osd_wait_vsync_hw();
+}
+
+void osd_get_osd_rotate_on_hw(u32 index,u32 *on_off)
+{
+	*on_off = osd_hw.rotate[index].on_off;
+}
+
+void osd_set_osd_antiflicker_hw(u32 index, u32 vmode, u32 yres)
+{
+	bool osd_need_antiflicker = false;
+
+	switch (vmode) {
+		case VMODE_480I:
+		case VMODE_480CVBS:
+		case VMODE_576I:
+		case VMODE_576CVBS:
+		case VMODE_1080I:
+		case VMODE_1080I_50HZ:
+#ifdef CONFIG_AML_VOUT_FRAMERATE_AUTOMATION
+		case VMODE_1080I_59HZ:
+#endif
+			osd_need_antiflicker = false;
+		break;
+		default:
+		break;
+	}
+
+	if (osd_need_antiflicker){
+		osd_hw.antiflicker_mode = 1;
+		osd_antiflicker_task_start();
+		osd_antiflicker_enable(1);
+		osd_antiflicker_update_pan(osd_hw.pandata[index].y_start, yres);
+	}else{
+		if(osd_hw.antiflicker_mode){
+			osd_antiflicker_task_stop();
+		}
+		osd_hw.antiflicker_mode = 0;
+	}
+}
+
+void osd_get_osd_antiflicker_hw(u32 index, u32 *on_off)
+{
+	*on_off = osd_hw.antiflicker_mode;
+}
+
+void osd_clone_pan(u32 index, u32 yoffset, int debug_flag)
+{
+	s32 offset = 0;
+	u32 index_buffer = 0;
+	s32 osd0_buffer_number = 0;
+	s32 height_osd1 = 0;
+
+	if(yoffset != 0){
+		index_buffer = osd_hw.fb_gem[index].height/yoffset;
+		if ( index_buffer == 3){
+			osd0_buffer_number = 1;
+		}else if (index_buffer == 1){
+			osd0_buffer_number = 2;
+		}
+	}else{
+		osd0_buffer_number = 0;
+	}
+
+	osd_clone_get_virtual_yres(&height_osd1);
+	if (osd_hw.clone) {
+		offset = osd0_buffer_number*height_osd1;
+
+		osd_hw.pandata[OSD2].y_start = offset;
+		osd_hw.pandata[OSD2].y_end = offset+height_osd1-1;
+		if (osd_hw.angle[OSD2]) {
+			if(debug_flag){
+				printk("++ osd_clone_pan start when enable clone\n");
+			}
+			osd_clone_update_pan(osd0_buffer_number);
+		}
+		add_to_update_list(OSD2, DISP_GEOMETRY);
+		osd_wait_vsync_hw();
+	}
+}
+
+void osd_set_osd_angle_hw(u32 index, u32 angle, u32  virtual_osd1_yres, u32 virtual_osd2_yres)
+{
+#ifndef OSD_GE2D_CLONE_SUPPORT
+	printk("++ osd_clone depends on GE2D module!\n");
+	return;
+#endif
+
+	if(angle > 4) {
+		printk("++ invalid angle: %d\n", angle);
+		return;
+	}
+
+	printk("++ virtual_osd1_yres is %d, virtual_osd2_yres is %d!\n", virtual_osd1_yres, virtual_osd2_yres);
+	osd_clone_set_virtual_yres(virtual_osd1_yres, virtual_osd2_yres);
+	if (osd_hw.clone == 0) {
+		printk("++ set osd[%d]->angle: %d->%d\n", index, osd_hw.angle[index], angle);
+		osd_clone_set_angle(angle);
+		osd_hw.angle[index] = angle;
+	} else if (!((osd_hw.angle[index] == 0) || (angle == 0))) {
+		printk("++ set osd[%d]->angle: %d->%d\n", index, osd_hw.angle[index], angle);
+		osd_clone_set_angle(angle);
+		osd_hw.angle[index] = angle;
+		osd_clone_pan(index, osd_hw.pandata[OSD1].y_start, 1);
+	}
+}
+
+void osd_get_osd_angle_hw(u32 index, u32 *angle)
+{
+	*angle = osd_hw.angle[index];
+}
+
+void osd_set_osd_clone_hw(u32 index, u32 clone)
+{
+	int ret = -1;
+
+	printk("++ set osd[%d]->clone: %d->%d\n", index, osd_hw.clone, clone);
+	osd_hw.clone = clone;
+
+	if (osd_hw.clone) {
+		if (osd_hw.angle[index]) {
+			osd_hw.color_info[index] = osd_hw.color_info[OSD1];
+			ret = osd_clone_task_start();
+			if(ret){
+				osd_clone_pan(index, osd_hw.pandata[OSD1].y_start, 1);
+			}else{
+				printk("++ start clone error\n");
+			}
+		}
+	} else {
+		if (osd_hw.angle[index]) {
+			osd_clone_task_stop();
+		}
+	}
+	add_to_update_list(index, OSD_COLOR_MODE);
+}
+
+void osd_set_osd_update_pan_hw(u32 index)
+{
+	osd_clone_pan(index, osd_hw.pandata[OSD1].y_start, 1);
+}
+
+void osd_get_osd_clone_hw(u32 index, u32 *clone)
+{
+	*clone = osd_hw.clone;
+}
+
+void osd_set_osd_reverse_hw(u32 index, u32 reverse)
+{
+	osd_hw.osd_reverse[index] = reverse;
+	add_to_update_list(index, DISP_OSD_REVERSE);
+	osd_wait_vsync_hw();
+}
+
+void osd_get_osd_reverse_hw(u32 index,u32 *reverse)
+{
+	*reverse = osd_hw.osd_reverse[index];
+}
+
+void osd_set_prot_canvas_hw(u32 index, s32 x_start, s32 y_start, s32 x_end, s32 y_end)
+{
+	osd_hw.rotation_pandata[index].x_start = x_start;
+	osd_hw.rotation_pandata[index].y_start = y_start;
+	osd_hw.rotation_pandata[index].x_end = x_end;
+	osd_hw.rotation_pandata[index].y_end = y_end;
+
+	if (osd_hw.rotate[index].on_off && osd_hw.rotate[index].angle > 0) {
+		g_rotation_width = osd_hw.rotation_pandata[index].x_end-osd_hw.rotation_pandata[index].x_start;
+		g_rotation_height = osd_hw.rotation_pandata[index].y_end-osd_hw.rotation_pandata[index].y_start;
+		osd_hw.dispdata[index].x_end = osd_hw.dispdata[OSD1].x_start+g_rotation_height;
+		osd_hw.dispdata[index].y_end = osd_hw.dispdata[OSD1].y_start+g_rotation_width;
+
+		add_to_update_list(index, DISP_GEOMETRY);
+		add_to_update_list(index, OSD_COLOR_MODE);
+	}
+}
+
+void osd_get_prot_canvas_hw(u32 index, s32 *x_start, s32 *y_start, s32 *x_end, s32 *y_end)
+{
+	*x_start = osd_hw.rotation_pandata[index].x_start;
+	*y_start = osd_hw.rotation_pandata[index].y_start;
+	*x_end = osd_hw.rotation_pandata[index].x_end;
+	*y_end = osd_hw.rotation_pandata[index].y_end;
+}
+
+void osd_pan_display_hw(unsigned int xoffset, unsigned int yoffset,int index )
+{
+	long diff_x, diff_y;
+
+#if defined(CONFIG_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 0
+
+#ifdef CONFIG_AM_FB_EXT
+		osd_ext_clone_pan(index);
+#endif
+		osd_wait_vsync_hw();
+#endif
+		amlog_mask_level(LOG_MASK_HARDWARE,LOG_LEVEL_LOW,"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_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 != SCAN_MODE_INTERLACE)
+	{
+		if(osd_hw.scale[OSD1].v_enable)
+		{
+			VSYNCOSD_SET_MPEG_REG_MASK(VIU_OSD1_BLK0_CFG_W0, 1<<14);
+		}
+		else
+		{
+			VSYNCOSD_CLR_MPEG_REG_MASK(VIU_OSD1_BLK0_CFG_W0, 1<<14);
+		}
+	}
+}
+static  void  osd2_update_disp_scale_enable(void)
+{
+	if(osd_hw.scale[OSD2].h_enable)
+	{
+#if defined(CONFIG_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 != SCAN_MODE_INTERLACE)
+	{
+		if(osd_hw.scale[OSD2].v_enable)
+		{
+#if defined(CONFIG_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);
+		}
+	}
+}
+
+static  void  osd1_update_disp_freescale_enable(void)
+{
+	int hf_phase_step, vf_phase_step;
+	int 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;
+
+	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) > 0 ?  (hf_bank_len/2 - 1): 0;
+	vsc_ini_rpt_p0_num = (vf_bank_len/2 - 1) > 0 ?  (vf_bank_len/2 - 1): 0;
+
+	dst_w = osd_hw.free_dst_data[OSD1].x_end -osd_hw.free_dst_data[OSD1].x_start+1;
+	hf_phase_step = ((osd_hw.free_scale_width[OSD1]+1)<< 18) / dst_w;
+	hf_phase_step = (hf_phase_step << 6);
+
+	dst_h = osd_hw.free_dst_data[OSD1].y_end - osd_hw.free_dst_data[OSD1].y_start+1;
+	vf_phase_step = ((osd_hw.free_scale_height[OSD1]+1) << 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);
+
+	VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SC_DUMMY_DATA, 0x00808000, 0, 32);
+
+	if (osd_hw.free_scale_enable[OSD1]){
+		VSYNCOSD_WR_MPEG_REG_BITS (VPP_OSD_SC_CTRL0, 1, 3, 1);
+		VSYNCOSD_WR_MPEG_REG_BITS (VPP_OSD_SC_CTRL0, OSD1, 0, 2);
+		VSYNCOSD_WR_MPEG_REG_BITS (VPP_OSD_SC_CTRL0, 0, 4, 8);
+	}else{
+		VSYNCOSD_CLR_MPEG_REG_MASK (VPP_OSD_SC_CTRL0, 1<<3);
+	}
+
+	if (osd_hw.free_scale_enable[OSD1]){
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCI_WH_M1, osd_hw.free_scale_width[OSD1], 16, 13);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCI_WH_M1, osd_hw.free_scale_height[OSD1], 0,  13);
+
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCO_H_START_END, osd_hw.free_dst_data[OSD1].x_start, 16, 12);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCO_H_START_END, osd_hw.free_dst_data[OSD1].x_end, 0, 12);
+
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCO_V_START_END, osd_hw.free_dst_data[OSD1].y_start, 16, 12);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCO_V_START_END, osd_hw.free_dst_data[OSD1].y_end, 0, 12);
+	}
+
+	if (osd_hw.free_scale[OSD1].vfs_enable){
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, vf_bank_len, 0, 3);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, vsc_ini_rcv_num, 3, 4);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, vsc_ini_rpt_p0_num, 8, 2);
+		if (osd_hw.field_out_en){  //interface output
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, vsc_bot_rcv_num, 11, 4);
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, vsc_bot_rpt_p0_num, 16, 2);
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 1, 23, 1);
+		}else{
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 0, 11, 4);
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 0, 16, 2);
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 0, 23, 1);
+		}
+
+		if(osd_hw.scale_workaround){
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 0x1, 21, 1);
+		} else {
+			VSYNCOSD_CLR_MPEG_REG_MASK(VPP_OSD_VSC_CTRL0, 1<<21);
+		}
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 1, 24, 1);
+	}else{
+		VSYNCOSD_CLR_MPEG_REG_MASK(VPP_OSD_VSC_CTRL0, 1<<24);
+	}
+
+	if (osd_hw.free_scale[OSD1].hfs_enable){
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_CTRL0, hf_bank_len, 0, 3);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_CTRL0, hsc_ini_rcv_num, 3, 3);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_CTRL0, hsc_ini_rpt_p0_num, 8, 2);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_CTRL0, 1, 22, 1);
+	}else{
+		VSYNCOSD_CLR_MPEG_REG_MASK(VPP_OSD_HSC_CTRL0, 1<<22);
+	}
+
+	if (osd_hw.free_scale_enable[OSD1]){
+		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_BITS(VPP_OSD_VSC_INI_PHASE, 0, 0, 16);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_INI_PHASE, bot_ini_phase, 16, 16);
+	}
+
+	remove_from_update_list(OSD1,DISP_FREESCALE_ENABLE);
+}
+
+static void osd1_update_coef(void)
+{
+	int i;
+	int hf_coef_wren = 1;
+	int vf_coef_wren = 1;
+
+	int *hf_coef, *vf_coef;
+
+	if(osd_hw.scale_workaround){
+		osd_v_filter_mode = 3;
+	}
+
+	vf_coef = filter_table[osd_v_filter_mode];
+
+	if (vf_coef_wren) {
+		VSYNCOSD_WR_MPEG_REG_BITS (VPP_OSD_SCALE_COEF_IDX, 0x0000, 0, 9);
+		for (i = 0; i < 33; i++)
+		{
+			VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCALE_COEF, vf_coef[i]);
+		}
+	}
+
+	hf_coef = filter_table[osd_h_filter_mode];
+
+	if (hf_coef_wren) {
+		VSYNCOSD_WR_MPEG_REG_BITS (VPP_OSD_SCALE_COEF_IDX, 0x0100, 0, 9);
+		for (i = 0; i < 33; i++)
+		{
+			VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCALE_COEF, hf_coef[i]);
+		}
+	}
+	remove_from_update_list(OSD1,OSD_FREESCALE_COEF);
+}
+
+static  void  osd2_update_disp_freescale_enable(void)
+{
+	int hf_phase_step, vf_phase_step;
+	int 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 hsc_ini_rcv_num, hsc_ini_rpt_p0_num;
+
+	int hf_bank_len = 4;
+	int vf_bank_len = 4;
+
+	if(osd_hw.scale_workaround){
+		vf_bank_len = 2;
+	}
+    
+	hsc_ini_rcv_num = hf_bank_len;
+	vsc_ini_rcv_num = vf_bank_len;
+	hsc_ini_rpt_p0_num = (hf_bank_len/2 - 1) > 0 ?  (hf_bank_len/2 - 1): 0;
+	vsc_ini_rpt_p0_num = (vf_bank_len/2 - 1) > 0 ?  (vf_bank_len/2 - 1): 0;
+
+	dst_w = osd_hw.free_dst_data[OSD2].x_end -osd_hw.free_dst_data[OSD2].x_start+1;
+	hf_phase_step = ((osd_hw.free_scale_width[OSD2]+1)<< 18) / dst_w;
+	hf_phase_step = (hf_phase_step << 6);
+
+	dst_h = osd_hw.free_dst_data[OSD2].y_end - osd_hw.free_dst_data[OSD2].y_start+1;
+	vf_phase_step = ((osd_hw.free_scale_height[OSD2]+1) << 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);
+
+	VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SC_DUMMY_DATA, 0x00808000, 0, 32);
+
+	if (osd_hw.free_scale_enable[OSD2]){
+		VSYNCOSD_WR_MPEG_REG_BITS (VPP_OSD_SC_CTRL0, 1, 3, 1);
+		VSYNCOSD_WR_MPEG_REG_BITS (VPP_OSD_SC_CTRL0, OSD2, 0, 2);
+		VSYNCOSD_WR_MPEG_REG_BITS (VPP_OSD_SC_CTRL0, 0, 4, 8);
+	}else{
+		if (!osd_hw.free_scale_enable[OSD1]){
+		    VSYNCOSD_CLR_MPEG_REG_MASK (VPP_OSD_SC_CTRL0, 1<<3);
+		}
+	}
+
+	if (osd_hw.free_scale_enable[OSD2]){
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCI_WH_M1, osd_hw.free_scale_width[OSD2], 16, 13);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCI_WH_M1, osd_hw.free_scale_height[OSD2], 0, 13);
+
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCO_H_START_END, osd_hw.free_dst_data[OSD2].x_start, 16, 12);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCO_H_START_END, osd_hw.free_dst_data[OSD2].x_end, 0, 12);
+
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCO_V_START_END, osd_hw.free_dst_data[OSD2].y_start, 16, 12);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_SCO_V_START_END, osd_hw.free_dst_data[OSD2].y_end, 0, 12);
+	}
+
+	if (osd_hw.free_scale[OSD2].hfs_enable){
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_CTRL0, hf_bank_len, 0, 3);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_CTRL0, hsc_ini_rcv_num, 3, 3);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_CTRL0, hsc_ini_rpt_p0_num, 8, 2);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_HSC_CTRL0, 1, 22, 1);
+	}else{
+		if (!osd_hw.free_scale[OSD1].hfs_enable){
+		    VSYNCOSD_CLR_MPEG_REG_MASK(VPP_OSD_HSC_CTRL0, 1<<22);
+		}
+	}
+
+	if (osd_hw.free_scale[OSD2].vfs_enable){
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, vf_bank_len, 0, 3);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, vsc_ini_rcv_num, 3, 3);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, vsc_ini_rpt_p0_num, 8, 2);
+		if (osd_hw.field_out_en){  //interface output
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, vsc_bot_rcv_num, 11, 4);
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, vsc_bot_rpt_p0_num, 16, 2);
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 1, 23, 1);
+		}else{
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 0, 11, 4);
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 0, 16, 2);
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 0, 23, 1);
+		}
+
+		if(osd_hw.scale_workaround){
+			VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 0x1, 21, 1);
+		} else {
+			VSYNCOSD_CLR_MPEG_REG_MASK(VPP_OSD_VSC_CTRL0, 1<<21);
+		}
+        
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_CTRL0, 1, 24, 1);
+	}else{
+		if (!osd_hw.free_scale[OSD1].vfs_enable){
+		    VSYNCOSD_CLR_MPEG_REG_MASK(VPP_OSD_VSC_CTRL0, 1<<24);
+		}
+	}
+
+	if (osd_hw.free_scale_enable[OSD2]){
+		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_BITS(VPP_OSD_VSC_INI_PHASE, 0, 0, 16);
+		VSYNCOSD_WR_MPEG_REG_BITS(VPP_OSD_VSC_INI_PHASE, bot_ini_phase, 16, 16);
+	}
+	remove_from_update_list(OSD2,DISP_FREESCALE_ENABLE);
+}
+
+static void osd2_update_coef(void)
+{
+	int i;
+	int hf_coef_wren = 1;
+
+	int vf_coef_wren = 1;
+	int *hf_coef, *vf_coef;
+
+	if(osd_hw.scale_workaround){
+		osd_v_filter_mode = 3;
+	}
+
+	vf_coef = filter_table[osd_v_filter_mode];
+
+	if (vf_coef_wren) {
+		VSYNCOSD_WR_MPEG_REG_BITS (VPP_OSD_SCALE_COEF_IDX, 0x0000, 0, 9);
+		for (i = 0; i < 33; i++)
+		{
+			VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCALE_COEF, vf_coef[i]);
+		}
+	}
+
+	hf_coef = filter_table[osd_h_filter_mode];
+
+	if (hf_coef_wren) {
+		VSYNCOSD_WR_MPEG_REG_BITS (VPP_OSD_SCALE_COEF_IDX, 0x0100, 0, 9);
+		for (i = 0; i < 33; i++)
+		{
+			VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCALE_COEF, hf_coef[i]);
+		}
+	}
+	remove_from_update_list(OSD2,OSD_FREESCALE_COEF);
+}
+
+static   void  osd1_update_color_mode(void)
+{
+	u32  data32=0;
+
+	if (osd_hw.color_info[OSD1] != NULL) {
+		data32= (osd_hw.scan_mode== SCAN_MODE_INTERLACE) ? 2 : 0;
+		data32 |= VSYNCOSD_RD_MPEG_REG(VIU_OSD1_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(osd_hw.color_info[OSD1]->color_index < COLOR_INDEX_YUV_422)
+			data32 |= 1                      << 7; /* rgb enable */
+		data32 |=  osd_hw.color_info[OSD1]->hw_blkmode<< 8; /* osd_blk_mode */
+		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);
+		{
+			u32 idx = osd_hw.color_info[OSD1]->color_index;
+
+			if (idx >= COLOR_INDEX_32_BGRX && idx <= COLOR_INDEX_32_XRGB)
+			{
+				printk("OSD1 set XRGB idx=%d\n", idx);
+				/* This code works for get_cpu_type() >= MESON_CPU_MAJOR_GXBB !!!
+				 * What we have to do here for M201 board with S805 ?????????????
+				   VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD1_CTRL_STAT2, 0x1ff, 6, 9);
+				 */
+			}
+			else
+			{
+				printk("OSD1 set ARGB idx=%d\n", idx);
+				/* This code works for get_cpu_type() >= MESON_CPU_MAJOR_GXBB !!!
+				 * What we have to do here for M201 board with S805 ?????????????
+				   VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD1_CTRL_STAT2, 0, 6, 9);
+				 */
+			}
+		}
+	}
+	remove_from_update_list(OSD1,OSD_COLOR_MODE);
+}
+static   void  osd2_update_color_mode(void)
+{
+	u32  data32=0;
+	if (osd_hw.color_info[OSD2] != NULL) {
+		data32= (osd_hw.scan_mode== 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[OSD1].on_off)
+		data32 |= OSD_DATA_LITTLE_ENDIAN	 <<15 ;
+
+		data32 |= osd_hw.color_info[OSD2]->hw_colormat<< 2;
+		if(osd_hw.color_info[OSD2]->color_index < COLOR_INDEX_YUV_422)
+			data32 |= 1                      << 7; /* rgb enable */
+		data32 |=  osd_hw.color_info[OSD2]->hw_blkmode<< 8; /* osd_blk_mode */
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W0, data32);
+		{
+			u32 idx = osd_hw.color_info[OSD2]->color_index;
+
+			if (idx >= COLOR_INDEX_32_BGRX && idx <= COLOR_INDEX_32_XRGB)
+			{
+				printk("OSD2 set XRGB idx=%d\n", idx);
+				/* This code works for get_cpu_type() >= MESON_CPU_MAJOR_GXBB !!!
+				 * What we have to do here for M201 board with S805 ?????????????
+				   VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD2_CTRL_STAT2, 0x1ff, 6, 9);
+				 */
+			}
+			else
+			{
+				printk("OSD2 set ARGB idx=%d\n", idx);
+				/* This code works for get_cpu_type() >= MESON_CPU_MAJOR_GXBB !!!
+				 * What we have to do here for M201 board with S805 ?????????????
+				   VSYNCOSD_WR_MPEG_REG_BITS(VIU_OSD2_CTRL_STAT2, 0, 6, 9);
+				 */
+			}
+		}
+	}
+	remove_from_update_list(OSD2,OSD_COLOR_MODE);
+}
+
+static   void  osd1_update_enable(void)
+{
+    unsigned long flags;
+    if (osd_hw.free_scale_mode[OSD1]){
+        spin_lock_irqsave(&osd_onoff_lock, flags);
+        if (osd_hw.enable[OSD1] == ENABLE){
+            aml_set_reg32_mask(P_VPP_MISC,VPP_OSD1_POSTBLEND);
+            aml_set_reg32_mask(P_VPP_MISC,VPP_POSTBLEND_EN);
+        }else{
+            aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD1_POSTBLEND);
+        }
+        spin_unlock_irqrestore(&osd_onoff_lock, flags);
+    }else{
+        u32  video_enable=0;
+        spin_lock_irqsave(&osd_onoff_lock, flags);
+        video_enable |=aml_read_reg32(P_VPP_MISC)&VPP_VD1_PREBLEND;
+
+        if(osd_hw.enable[OSD1]==ENABLE)
+        {
+            if(osd_hw.free_scale_enable[OSD1])
+            {
+                aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD1_POSTBLEND);
+                aml_set_reg32_mask(P_VPP_MISC,VPP_OSD1_PREBLEND);
+                aml_set_reg32_mask(P_VPP_MISC,VPP_VD1_POSTBLEND);
+                aml_set_reg32_mask(P_VPP_MISC,VPP_PREBLEND_EN);
+            }
+            else
+            {
+                aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD1_PREBLEND);
+                if(!video_enable)
+                {
+                    aml_clr_reg32_mask(P_VPP_MISC,VPP_VD1_POSTBLEND);
+                }
+                aml_set_reg32_mask(P_VPP_MISC,VPP_OSD1_POSTBLEND);
+            }
+
+        }
+        else
+        {
+            if(osd_hw.free_scale_enable[OSD1])
+            {
+                aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD1_PREBLEND);
+            }
+            else
+            {
+                aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD1_POSTBLEND);
+            }
+        }
+        spin_unlock_irqrestore(&osd_onoff_lock, flags);
+    }
+    remove_from_update_list(OSD1,OSD_ENABLE);
+}
+static   void  osd2_update_enable(void)
+{
+    unsigned long flags;
+    if (osd_hw.free_scale_mode[OSD2]){
+        spin_lock_irqsave(&osd_onoff_lock, flags);
+        if (osd_hw.enable[OSD2] == ENABLE){
+            // osd1 and osd2 share the only one freescale, so set  VPP_OSD1_POSTBLEND here.
+            if(osd_hw.free_scale_enable[OSD2]){
+                aml_set_reg32_mask(P_VPP_MISC,VPP_OSD1_POSTBLEND);
+                aml_set_reg32_mask(P_VPP_MISC,VPP_POSTBLEND_EN);
+            }else{
+				#ifndef CONFIG_FB_OSD2_CURSOR
+                aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD1_POSTBLEND);
+				#endif
+                aml_set_reg32_mask(P_VPP_MISC,VPP_OSD2_POSTBLEND);
+                aml_set_reg32_mask(P_VPP_MISC,VPP_POSTBLEND_EN);
+            }
+        }else{
+            if (osd_hw.enable[OSD1] == ENABLE){
+                aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD2_POSTBLEND);
+            } else {
+                aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD1_POSTBLEND|VPP_OSD2_POSTBLEND);
+            }
+        }
+        spin_unlock_irqrestore(&osd_onoff_lock, flags);
+    }else{
+        u32  video_enable=0;
+        video_enable |=VSYNCOSD_RD_MPEG_REG(VPP_MISC)&VPP_VD1_PREBLEND;
+        spin_lock_irqsave(&osd_onoff_lock, flags);
+        if(osd_hw.enable[OSD2]==ENABLE)
+        {
+            if(osd_hw.free_scale_enable[OSD2])
+            {
+                aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD2_POSTBLEND);
+                aml_set_reg32_mask(P_VPP_MISC,VPP_OSD2_PREBLEND);
+                aml_set_reg32_mask(P_VPP_MISC,VPP_VD1_POSTBLEND);
+            }
+            else
+            {
+                aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD2_PREBLEND);
+                if(!video_enable)
+                {
+                    aml_clr_reg32_mask(P_VPP_MISC,VPP_VD1_POSTBLEND);
+                }
+                aml_set_reg32_mask(P_VPP_MISC,VPP_OSD2_POSTBLEND);
+            }
+
+        }
+        else
+        {
+            if(osd_hw.free_scale_enable[OSD2])
+            {
+                aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD2_PREBLEND);
+            }
+            else
+            {
+                aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD2_POSTBLEND);
+            }
+        }
+         spin_unlock_irqrestore(&osd_onoff_lock, flags);
+    }
+    remove_from_update_list(OSD2,OSD_ENABLE);
+}
+
+static void osd1_update_disp_osd_reverse(void)
+{
+	if (osd_hw.osd_reverse[OSD1]){
+		VSYNCOSD_WR_MPEG_REG_BITS (VIU_OSD1_BLK0_CFG_W0, 3, 28, 2);
+	}else{
+		VSYNCOSD_CLR_MPEG_REG_MASK (VIU_OSD1_BLK0_CFG_W0, 3<<28);
+	}
+	remove_from_update_list(OSD1, DISP_OSD_REVERSE);
+}
+
+static void osd2_update_disp_osd_reverse(void)
+{
+	if (osd_hw.osd_reverse[OSD2]){
+		VSYNCOSD_WR_MPEG_REG_BITS (VIU_OSD2_BLK0_CFG_W0, 3, 28, 2);
+	}else{
+		VSYNCOSD_CLR_MPEG_REG_MASK (VIU_OSD2_BLK0_CFG_W0, 3<<28);
+	}
+	remove_from_update_list(OSD2, DISP_OSD_REVERSE);
+}
+static void osd1_update_disp_osd_rotate(void)
+{
+	unsigned char 	x_rev=0,y_rev=0;
+	unsigned char 	bpp=32;
+	unsigned int	x_start;
+	unsigned int	x_end;
+	unsigned int	y_start;
+	unsigned int	y_end;
+	unsigned int	y_len_m1;
+
+	if( osd_hw.color_info[OSD1]->color_index <=COLOR_INDEX_08_PAL256){
+		bpp=8;
+	}else if( osd_hw.color_info[OSD1]->color_index <= COLOR_INDEX_16_565){
+		bpp=16;
+	}else if( osd_hw.color_info[OSD1]->color_index <= COLOR_INDEX_24_RGB){
+		bpp=24;
+	}else if( osd_hw.color_info[OSD1]->color_index <= COLOR_INDEX_32_ARGB){
+		bpp=32;
+	}
+
+	switch(osd_hw.rotate[OSD1].angle)
+	{
+	  case 0://clockwise H flip (dst )
+	  x_rev=0;
+	  y_rev=0;
+	  break;//clockwise
+	  case 1:
+	  y_rev=1;
+	  break;
+	  case 2://anti-clockwise
+	  x_rev=1;
+	  break;
+	  case 3://anti-clockwise H flip(dst)
+	  x_rev=1;
+	  y_rev=1;
+	  break;
+	}
+
+	x_start = osd_hw.rotation_pandata[OSD1].x_start;
+	x_end = osd_hw.rotation_pandata[OSD1].x_end;
+	y_start = osd_hw.rotation_pandata[OSD1].y_start;
+	y_end = osd_hw.rotation_pandata[OSD1].y_end;
+	y_len_m1 = y_end-y_start;
+
+#if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8)
+	{
+		if(IS_MESON_M8_CPU){
+			osd_set_prot(
+				x_rev,
+				y_rev,
+				(bpp>>3)-1,				//unsigned char   bytes_per_pixel,
+				0,				//unsigned char   conv_422to444,
+				OSD_DATA_LITTLE_ENDIAN,		//unsigned char   little_endian,
+				HOLD_LINES,			//unsigned int    hold_lines,
+				x_start,
+				x_end,
+				y_start,
+				y_end,
+				y_len_m1,
+				Y_STEP,
+				PAT_START_PTR,
+				PAT_END_PTR,
+				PAT_VAL,
+				osd_hw.fb_gem[OSD1].canvas_idx,
+				CID_VALUE,
+				CID_MODE,
+				CUGT,				//urgent bit
+				REQ_ONOFF_EN,
+				REQ_ON_MAX,
+				REQ_OFF_MIN,
+				OSD1,
+				osd_hw.rotate[OSD1].on_off);
+		}
+	}
+#endif
+	remove_from_update_list(OSD1, DISP_OSD_ROTATE);
+}
+static void osd2_update_disp_osd_rotate(void)
+{
+	unsigned char 	x_rev=0,y_rev=0;
+	unsigned char 	bpp=32;
+	unsigned int	x_start;
+	unsigned int	x_end;
+	unsigned int	y_start;
+	unsigned int	y_end;
+	unsigned int	y_len_m1;
+
+	if( osd_hw.color_info[OSD2]->color_index <=COLOR_INDEX_08_PAL256){
+		bpp=8;
+	}else if( osd_hw.color_info[OSD2]->color_index <= COLOR_INDEX_16_565){
+		bpp=16;
+	}else if( osd_hw.color_info[OSD2]->color_index <= COLOR_INDEX_24_RGB){
+		bpp=24;
+	}else if( osd_hw.color_info[OSD2]->color_index <= COLOR_INDEX_32_ARGB){
+		bpp=32;
+	}
+	switch(osd_hw.rotate[OSD2].angle)
+	{
+	  case 0://clockwise H flip (dst )
+	  x_rev=0;
+	  y_rev=0;
+	  break;//clockwise
+	  case 1:
+	  y_rev=1;
+	  break;
+	  case 2://anti-clockwise
+	  x_rev=1;
+          break;
+	  case 3://anti-clockwise H flip(dst)
+	  x_rev=1;
+	  y_rev=1;
+	  break;
+	}
+
+	x_start = osd_hw.rotation_pandata[OSD2].x_start;
+	x_end = osd_hw.rotation_pandata[OSD2].x_end;
+	y_start = osd_hw.rotation_pandata[OSD2].y_start;
+	y_end = osd_hw.rotation_pandata[OSD2].y_end;
+	y_len_m1 = y_end-y_start;
+
+#if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8)
+	{
+		if(IS_MESON_M8_CPU){
+			osd_set_prot(
+				x_rev,
+				y_rev,
+				(bpp>>3)-1,				//unsigned char   bytes_per_pixel,
+				0,				//unsigned char   conv_422to444,
+				OSD_DATA_LITTLE_ENDIAN,		//unsigned char   little_endian,
+				HOLD_LINES,			//unsigned int    hold_lines,
+				x_start,
+				x_end,
+				y_start,
+				y_end,
+				y_len_m1,
+				Y_STEP,
+				PAT_START_PTR,
+				PAT_END_PTR,
+				PAT_VAL,
+				osd_hw.fb_gem[OSD2].canvas_idx,
+				CID_VALUE,
+				CID_MODE,
+				CUGT,				//urgent bit
+				REQ_ONOFF_EN,
+				REQ_ON_MAX,
+				REQ_OFF_MIN,
+				OSD2,
+				osd_hw.rotate[OSD2].on_off);
+		}
+	}
+#endif
+    remove_from_update_list(OSD2, DISP_OSD_ROTATE);
+}
+
+
+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)
+{
+	VSYNCOSD_WR_MPEG_REG(VIU_OSD2_TCOLOR_AG0,osd_hw.color_key[OSD2]);
+	remove_from_update_list(OSD2,OSD_COLOR_KEY);
+}
+static  void  osd1_update_color_key_enable(void)
+{
+	u32  data32;
+	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);
+}
+static  void  osd2_update_color_key_enable(void)
+{
+	u32  data32;
+	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);
+}
+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)
+{
+	u32  data32;
+
+	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)
+{
+    unsigned long flags;
+    spin_lock_irqsave(&osd_onoff_lock, flags);
+    switch(osd_hw.osd_order)
+    {
+        case  OSD_ORDER_01:
+        aml_clr_reg32_mask(P_VPP_MISC,VPP_POST_FG_OSD2|VPP_PRE_FG_OSD2);
+        break;
+        case  OSD_ORDER_10:
+        aml_clr_reg32_mask(P_VPP_MISC,VPP_POST_FG_OSD2|VPP_PRE_FG_OSD2);
+        break;
+        default:
+        break;
+    }
+    spin_unlock_irqrestore(&osd_onoff_lock, flags);
+    remove_from_update_list(OSD2,OSD_CHANGE_ORDER);
+}
+static   void  osd1_update_order(void)
+{
+    unsigned long flags;
+    spin_lock_irqsave(&osd_onoff_lock, flags);
+    switch(osd_hw.osd_order)
+    {
+        case  OSD_ORDER_01:
+        aml_clr_reg32_mask(P_VPP_MISC,VPP_POST_FG_OSD2|VPP_PRE_FG_OSD2);
+        break;
+        case  OSD_ORDER_10:
+        aml_clr_reg32_mask(P_VPP_MISC,VPP_POST_FG_OSD2|VPP_PRE_FG_OSD2);
+        break;
+        default:
+        break;
+    }
+    spin_unlock_irqrestore(&osd_onoff_lock, flags);
+    remove_from_update_list(OSD1,OSD_CHANGE_ORDER);
+}
+
+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;
+
+	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 < 4; 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;
+				}
+				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;
+			}
+			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);
+			}
+			for (i = 0; i < 4; 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;
+			}
+			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 < 4; 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;
+			}
+			break;
+		case HW_OSD_BLOCK_LAYOUT_CUSTOMER:
+			for (i = 0; i < 4; 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);
+				}
+				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);
+				}
+				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:
+			amlog_level(LOG_LEVEL_HIGH, "ERROR block_mode: 0x%x\n", osd_hw.block_mode[index]);
+			break;
+	}
+}
+
+static void osd1_update_disp_geometry(void)
+{
+	u32 data32;
+	/* enable osd multi block */
+	if (osd_hw.block_mode[OSD1]) {
+		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);
+	} else {
+		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);
+		if (osd_hw.scan_mode == SCAN_MODE_INTERLACE) {
+			data32 = ((osd_hw.dispdata[OSD1].y_start >> 1) & 0xfff) | ((((osd_hw.dispdata[OSD1].y_end+1) >> 1) - 1) & 0xfff) << 16 ;
+		} else {
+			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);
+
+		/* enable osd 2x scale */
+		if (osd_hw.scale[OSD1].h_enable || osd_hw.scale[OSD1].v_enable) {
+			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.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);
+			}
+
+			/* adjust display y-axis */
+			if (osd_hw.scale[OSD1].v_enable) {
+				if (osd_hw.scan_mode == 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(VIU_OSD1_BLK0_CFG_W4, data32);
+			}
+		} else if (osd_hw.free_scale_enable[OSD1]
+				&& (osd_hw.free_scale_data[OSD1].x_end > 0)
+				&& (osd_hw.free_scale_data[OSD1].y_end > 0)
+				&& (!osd_hw.rotate[OSD1].on_off)) {
+			/* enable osd free scale */
+			data32 = (osd_hw.free_scale_data[OSD1].x_start & 0x1fff) | (osd_hw.free_scale_data[OSD1].x_end & 0x1fff) << 16;
+			VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1,data32);
+			data32 = ((osd_hw.free_scale_data[OSD1].y_start + osd_hw.pandata[OSD1].y_start) & 0x1fff)
+					| ((osd_hw.free_scale_data[OSD1].y_end  + osd_hw.pandata[OSD1].y_start) & 0x1fff) << 16 ;
+			VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W2, data32);
+		} else if (osd_hw.free_scale_enable[OSD1]
+				&& (osd_hw.free_scale_data[OSD1].x_end > 0)
+				&& (osd_hw.free_scale_data[OSD1].y_end > 0)
+				&& (osd_hw.rotate[OSD1].on_off
+				&& osd_hw.rotate[OSD1].angle > 0)){
+			data32 = (osd_hw.rotation_pandata[OSD1].x_start & 0x1fff) | (osd_hw.rotation_pandata[OSD1].x_end & 0x1fff) << 16;
+			VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1,data32);
+			data32 = ((osd_hw.rotation_pandata[OSD1].y_start + osd_hw.pandata[OSD1].y_start) & 0x1fff)
+					| ((osd_hw.rotation_pandata[OSD1].y_end  + osd_hw.pandata[OSD1].y_start) & 0x1fff) << 16 ;
+			VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W2,data32);
+#if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8)
+			{
+				if(IS_MESON_M8_CPU){
+					VSYNCOSD_WR_MPEG_REG(VPU_PROT1_Y_START_END,data32);
+				}
+			}
+#endif
+		}else if (osd_hw.rotate[OSD1].on_off
+				&& osd_hw.rotate[OSD1].angle > 0){
+			/* enable osd rotation */
+			data32 = (osd_hw.rotation_pandata[OSD1].x_start & 0x1fff) | (osd_hw.rotation_pandata[OSD1].x_end & 0x1fff) << 16;
+			VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1,data32);
+			data32 = ((osd_hw.rotation_pandata[OSD1].y_start + osd_hw.pandata[OSD1].y_start) & 0x1fff)
+					| ((osd_hw.rotation_pandata[OSD1].y_end  + osd_hw.pandata[OSD1].y_start) & 0x1fff) << 16 ;
+			VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W2,data32);
+#if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8)
+			{
+				if(IS_MESON_M8_CPU){
+					VSYNCOSD_WR_MPEG_REG(VPU_PROT1_Y_START_END,data32);
+				}
+			}
+#endif
+		}else {
+			/* norma/l 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);
+			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);
+		}
+
+		data32=VSYNCOSD_RD_MPEG_REG(VIU_OSD1_CTRL_STAT);
+		data32 &= 0xfffffff0;
+		data32 |= HW_OSD_BLOCK_ENABLE_0;
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_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);
+	if(osd_hw.scan_mode== SCAN_MODE_INTERLACE)
+	{
+		data32=((osd_hw.dispdata[OSD2].y_start >>1) & 0xfff) | ((((osd_hw.dispdata[OSD2].y_end+1)>>1)-1) & 0xfff) <<16 ;
+	}
+	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);
+
+	if (osd_hw.scale[OSD2].h_enable || osd_hw.scale[OSD2].v_enable) {
+#if defined(CONFIG_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);
+		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);
+#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);
+		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);
+#endif
+	} else if (osd_hw.free_scale_enable[OSD2]
+				&& (osd_hw.free_scale_data[OSD2].x_end > 0)
+				&& (osd_hw.free_scale_data[OSD2].y_end > 0)) {
+			/* enable osd free scale */
+			data32 = (osd_hw.free_scale_data[OSD2].x_start & 0x1fff) | (osd_hw.free_scale_data[OSD2].x_end & 0x1fff) << 16;
+			VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W1, data32);
+			data32 = ((osd_hw.free_scale_data[OSD2].y_start + osd_hw.pandata[OSD2].y_start) & 0x1fff)
+					| ((osd_hw.free_scale_data[OSD2].y_end  + osd_hw.pandata[OSD2].y_start) & 0x1fff) << 16 ;
+			VSYNCOSD_WR_MPEG_REG(VIU_OSD2_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);
+		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);
+	}
+	remove_from_update_list(OSD2,DISP_GEOMETRY);
+}
+static  void  osd1_update_disp_3d_mode(void)
+{
+	/*step 1 . set pan data */
+	u32  data32;
+
+	if(osd_hw.mode_3d[OSD1].left_right==LEFT)
+	{
+		data32=(osd_hw.mode_3d[OSD1].l_start& 0x1fff) | (osd_hw.mode_3d[OSD1].l_end& 0x1fff) << 16;
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1,data32);
+	}
+	else
+	{
+		data32=(osd_hw.mode_3d[OSD1].r_start& 0x1fff) | (osd_hw.mode_3d[OSD1].r_end& 0x1fff) << 16;
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1,data32);
+	}
+	osd_hw.mode_3d[OSD1].left_right^=1;
+}
+static  void  osd2_update_disp_3d_mode(void)
+{
+	u32  data32;
+
+	if(osd_hw.mode_3d[OSD2].left_right==LEFT)
+	{
+		data32=(osd_hw.mode_3d[OSD2].l_start& 0x1fff) | (osd_hw.mode_3d[OSD2].l_end& 0x1fff) << 16;
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W1,data32);
+	}
+	else
+	{
+		data32=(osd_hw.mode_3d[OSD2].r_start& 0x1fff) | (osd_hw.mode_3d[OSD2].r_end& 0x1fff) << 16;
+		VSYNCOSD_WR_MPEG_REG(VIU_OSD2_BLK0_CFG_W1,data32);
+	}
+	osd_hw.mode_3d[OSD2].left_right^=1;
+}
+
+#if MESON_CPU_TYPE < MESON_CPU_TYPE_MESON8
+void osd_init_scan_mode(void)
+{
+#define  	VOUT_ENCI	1
+#define   	VOUT_ENCP	2
+#define	VOUT_ENCT	3
+	unsigned  char output_type=0;
+	output_type=aml_read_reg32(P_VPU_VIU_VENC_MUX_CTRL)&0x3;
+	osd_hw.scan_mode= SCAN_MODE_PROGRESSIVE;
+	switch(output_type)
+	{
+		case VOUT_ENCP:
+			if (aml_read_reg32(P_ENCP_VIDEO_MODE) & (1 << 12)) //1080i
+				osd_hw.scan_mode= SCAN_MODE_INTERLACE;
+			break;
+		case VOUT_ENCI:
+			if (aml_read_reg32(P_ENCI_VIDEO_EN) & 1)
+				osd_hw.scan_mode= SCAN_MODE_INTERLACE;
+			break;
+	}
+}
+#endif
+
+void osd_init_hw(u32  logo_loaded)
+{
+	u32 group,idx,data32;
+
+	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;
+	//here we will init default value ,these value only set once .
+#if defined(CONFIG_ARCH_MESON6TVD)||(defined(CONFIG_ARCH_MESON6TV))
+	aml_set_reg32_mask(P_VPU_OSD1_MMC_CTRL, 1<<12); // set OSD to vdisp2
+#endif
+	if(!logo_loaded)
+	{
+		data32 = 1;          // Set DDR request priority to be urgent
+#if defined(CONFIG_ARCH_MESON6TVD)||(defined(CONFIG_ARCH_MESON6TV))
+		data32 |= 18  << 5;  // hold_fifo_lines
+		#else
+		data32 |= 4   << 5;  // hold_fifo_lines
+		#endif
+		data32 |= 3   << 10; // burst_len_sel: 3=64
+		data32 |= 32  << 12; // fifo_depth_val: 32*8=256
+
+		aml_write_reg32(P_VIU_OSD1_FIFO_CTRL_STAT, data32);
+		aml_write_reg32(P_VIU_OSD2_FIFO_CTRL_STAT, data32);
+
+		aml_set_reg32_mask(P_VPP_MISC,VPP_POSTBLEND_EN);
+		aml_clr_reg32_mask(P_VPP_MISC, VPP_PREBLEND_EN);
+		aml_clr_reg32_mask(P_VPP_MISC,VPP_OSD1_POSTBLEND|VPP_OSD2_POSTBLEND );
+		// just disable osd to avoid booting hang up
+		#if defined(CONFIG_ARCH_MESON6TVD)||(defined(CONFIG_ARCH_MESON6TV))
+		data32 = 0x0 << 0; // osd_blk_enable
+		#else
+		data32 = 0x1 << 0;
+		#endif
+	    	data32 |= OSD_GLOBAL_ALPHA_DEF<< 12;
+		data32 |= (1<<21);
+	    	aml_write_reg32(P_VIU_OSD1_CTRL_STAT , data32);
+		aml_write_reg32(P_VIU_OSD2_CTRL_STAT , data32);
+	}
+
+#if defined(CONFIG_FB_OSD2_CURSOR)
+	aml_set_reg32_mask(P_VPP_MISC, VPP_POST_FG_OSD2|VPP_PRE_FG_OSD2);
+	osd_hw.osd_order=OSD_ORDER_10;
+#else
+	aml_clr_reg32_mask(P_VPP_MISC,VPP_POST_FG_OSD2|VPP_PRE_FG_OSD2);
+	osd_hw.osd_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.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;
+	vf.width =vf.height=0;
+	osd_hw.color_key[OSD1]=osd_hw.color_key[OSD2]=0xffffffff;
+	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.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].hfs_enable=0;
+	osd_hw.free_scale[OSD1].hfs_enable=0;
+	osd_hw.free_scale[OSD2].vfs_enable=0;
+	osd_hw.free_scale[OSD2].vfs_enable=0;
+	osd_hw.osd_reverse[OSD1] = osd_hw.osd_reverse[OSD2] = 0;
+	osd_hw.rotation_pandata[OSD1].x_start = osd_hw.rotation_pandata[OSD1].y_start = 0;
+	osd_hw.rotation_pandata[OSD2].x_start = osd_hw.rotation_pandata[OSD2].y_start = 0;
+	osd_hw.antiflicker_mode = 0;
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
+	osd_hw.free_scale_mode[OSD1] = osd_hw.free_scale_mode[OSD2] = 1;
+#else
+	osd_hw.free_scale_mode[OSD1] = osd_hw.free_scale_mode[OSD2] = 0;
+#endif
+
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
+    osd_hw.free_scale_mode[OSD1] = osd_hw.free_scale_mode[OSD2] = 1;
+#else
+    osd_hw.free_scale_mode[OSD1] = osd_hw.free_scale_mode[OSD2] = 0;
+#endif
+
+	memset(osd_hw.rotate,0,sizeof(osd_rotate_t));
+
+#ifdef FIQ_VSYNC
+	osd_hw.fiq_handle_item.handle=vsync_isr;
+	osd_hw.fiq_handle_item.key=(u32)vsync_isr;
+	osd_hw.fiq_handle_item.name="osd_vsync";
+	if(register_fiq_bridge_handle(&osd_hw.fiq_handle_item))
+#else
+	if ( request_irq(INT_VIU_VSYNC, &vsync_isr,
+		IRQF_SHARED , "am_osd_vsync", osd_setup))
+#endif
+	{
+		amlog_level(LOG_LEVEL_HIGH,"can't request irq for vsync\r\n");
+	}
+
+#ifdef FIQ_VSYNC
+    request_fiq(INT_VIU_VSYNC, &osd_fiq_isr);
+#endif
+
+#ifdef CONFIG_VSYNC_RDMA
+	osd_rdma_enable(1);
+#endif
+
+#ifdef CONFIG_VSYNC_RDMA
+
+	if (request_irq(INT_RDMA, &osd_rdma_isr,
+                    IRQF_SHARED, "osd_rdma", (void *)"osd_rdma"))
+	{
+		amlog_level(LOG_LEVEL_HIGH,"can't request irq for rdma\r\n");
+	}
+#endif
+	return ;
+}
+
+
+#if defined(CONFIG_FB_OSD2_CURSOR)
+void osd_cursor_hw(s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w, u32 osd_h, int index)
+{
+	dispdata_t disp_tmp;
+
+	if (index != 1)
+		return;
+
+	if(osd_hw.free_scale_mode[OSD1]){
+		if(osd_hw.free_scale_enable[OSD1]){
+			memcpy(&disp_tmp, &osd_hw.cursor_dispdata[OSD1], sizeof(dispdata_t));
+		}else{
+			memcpy(&disp_tmp, &osd_hw.dispdata[OSD1], sizeof(dispdata_t));
+		}
+	}else{
+		memcpy(&disp_tmp, &osd_hw.dispdata[OSD1], sizeof(dispdata_t));
+	}
+	
+	if (osd_hw.scale[OSD2].h_enable && (osd_hw.scaledata[OSD2].x_start > 0)
+			&& (osd_hw.scaledata[OSD2].x_end > 0)) {
+		x = x * osd_hw.scaledata[OSD2].x_end / osd_hw.scaledata[OSD2].x_start;
+		if (osd_hw.scaledata[OSD2].x_end > osd_hw.scaledata[OSD2].x_start) {
+			disp_tmp.x_start=osd_hw.dispdata[OSD1].x_start * osd_hw.scaledata[OSD2].x_end / osd_hw.scaledata[OSD2].x_start;
+			disp_tmp.x_end=osd_hw.dispdata[OSD1].x_end * osd_hw.scaledata[OSD2].x_end / osd_hw.scaledata[OSD2].x_start;
+		}
+	}
+
+	if (osd_hw.scale[OSD2].v_enable && (osd_hw.scaledata[OSD2].y_start > 0)
+			&& (osd_hw.scaledata[OSD2].y_end > 0)) {
+		y = y * osd_hw.scaledata[OSD2].y_end / osd_hw.scaledata[OSD2].y_start;
+		if (osd_hw.scaledata[OSD2].y_end > osd_hw.scaledata[OSD2].y_start) {
+			disp_tmp.y_start = osd_hw.dispdata[OSD1].y_start * osd_hw.scaledata[OSD2].y_end / osd_hw.scaledata[OSD2].y_start;
+			disp_tmp.y_end = osd_hw.dispdata[OSD1].y_end * osd_hw.scaledata[OSD2].y_end / osd_hw.scaledata[OSD2].y_start;
+		}
+	}
+
+	x += xstart;
+	y += ystart;
+	/**
+	 * Use pandata to show a partial cursor when it is at the edge because the
+	 * registers can't have negative values and because we need to manually
+	 * clip the cursor when it is past the edge.  The edge is hardcoded
+	 * to the OSD0 area.
+	 */
+	osd_hw.dispdata[OSD2].x_start = x;
+	osd_hw.dispdata[OSD2].y_start = y;
+	if (x <  disp_tmp.x_start) {
+		// if negative position, set osd to 0,y and pan.
+		if (( disp_tmp.x_start - x) < osd_w) {
+			osd_hw.pandata[OSD2].x_start = disp_tmp.x_start - x;
+			osd_hw.pandata[OSD2].x_end = osd_w - 1;
+		}
+		osd_hw.dispdata[OSD2].x_start = 0;
+	} else {
+		osd_hw.pandata[OSD2].x_start = 0;
+		if (x + osd_w > disp_tmp.x_end) {
+			// if past positive edge, set osd to inside of the edge and pan.
+			if (x < disp_tmp.x_end)
+				osd_hw.pandata[OSD2].x_end = disp_tmp.x_end - x;
+		} else {
+			osd_hw.pandata[OSD2].x_end = osd_w - 1;
+		}
+	}
+	if (y < disp_tmp.y_start) {
+		if ((disp_tmp.y_start- y) < osd_h) {
+			osd_hw.pandata[OSD2].y_start =disp_tmp.y_start - y;
+			osd_hw.pandata[OSD2].y_end = osd_h - 1;
+		}
+		osd_hw.dispdata[OSD2].y_start = 0;
+	} else {
+		osd_hw.pandata[OSD2].y_start = 0;
+		if (y + osd_h > disp_tmp.y_end) {
+			if (y < disp_tmp.y_end)
+				osd_hw.pandata[OSD2].y_end = disp_tmp.y_end - y;
+		} else {
+			osd_hw.pandata[OSD2].y_end = osd_h - 1;
+		}
+	}
+	osd_hw.dispdata[OSD2].x_end = osd_hw.dispdata[OSD2].x_start + osd_hw.pandata[OSD2].x_end - osd_hw.pandata[OSD2].x_start;
+	osd_hw.dispdata[OSD2].y_end = osd_hw.dispdata[OSD2].y_start + osd_hw.pandata[OSD2].y_end - osd_hw.pandata[OSD2].y_start;
+	add_to_update_list(OSD2,DISP_GEOMETRY);
+}
+#endif //CONFIG_FB_OSD2_CURSOR
+
+void osddev_copy_data_tocursor_hw(u32 cursor_mem_vaddr, aml_hwc_addr_t *hwc_mem)
+{
+	u32 tmp;
+	u32 i;
+	u32 value_pixel = 0;
+	u32 size = 32*32*4;
+
+	if (hwc_mem->addr & 0x3) { /* Address not 32bit aligned */
+		for (i = 0; i < size; i += 4) {
+			tmp = readb(hwc_mem->addr + i);
+			value_pixel = tmp;
+			tmp = readb(hwc_mem->addr + i + 1);
+			value_pixel |= (tmp << 8);
+			tmp = readb(hwc_mem->addr + i + 2);
+			value_pixel |= (tmp << 16);
+			tmp = readb(hwc_mem->addr + i + 3);
+			value_pixel |= (tmp << 24);
+			writel(value_pixel, cursor_mem_vaddr+ i);
+		}
+	} else {
+		for (i = 0; i < size; i += 4) {
+			tmp = readl(hwc_mem->addr + i);
+			writel(tmp, cursor_mem_vaddr+ i);
+		}
+	}
+}
+
+void  osd_suspend_hw(void)
+{
+	osd_hw.reg_status_save = aml_read_reg32(P_VPP_MISC) & OSD_RELATIVE_BITS;
+
+	aml_clr_reg32_mask(P_VPP_MISC, OSD_RELATIVE_BITS);
+
+    printk("osd_suspended\n");
+
+	return ;
+
+}
+void osd_resume_hw(void)
+{
+    aml_set_reg32_mask(P_VPP_MISC, osd_hw.reg_status_save);
+
+    printk("osd_resumed\n");
+
+	return ;
+}
+
+MODULE_PARM_DESC(osd_h_filter_mode, "\n osd_h_filter_mode \n");
+module_param(osd_h_filter_mode, int, 0664);
+
+MODULE_PARM_DESC(osd_v_filter_mode, "\n osd_v_filter_mode \n");
+module_param(osd_v_filter_mode, int, 0664);
+
diff --git a/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/drivers/amlogic/display/osd/osd_main.c b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/drivers/amlogic/display/osd/osd_main.c
new file mode 100644
index 000000000..3831b3906
--- /dev/null
+++ b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/drivers/amlogic/display/osd/osd_main.c
@@ -0,0 +1,2111 @@
+/*
+ * Amlogic osd
+ * frame buffer driver
+ *
+ * Copyright (C) 2009 Amlogic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Author:  Tim Yao <timyao@amlogic.com>
+ *		   
+ *		    jianfeng_wang : add ge2d support 09/05/21	
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/spinlock.h>
+#include <asm/cacheflush.h>
+#include <mach/am_regs.h>
+#include <linux/fs.h>
+#include <linux/sysfs.h>
+#include <linux/file.h>
+#include <linux/fdtable.h>
+#include <linux/console.h>
+#include <linux/amlogic/osd/osd_main.h>
+#include <linux/amlogic/osd/osd_dev.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include "osd_log.h"
+#include <linux/amlogic/amlog.h>
+#include <linux/amlogic/logo/logo_dev.h>
+#include <linux/amlogic/logo/logo_dev_osd.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+
+// This is not in osd_hw.h private or public header
+void osd_wait_vsync_hw(void);
+
+#if defined(CONFIG_MACH_MESON8B_ODROIDC)
+static int monitor_onoff_flag;
+#endif
+
+static struct early_suspend early_suspend;
+static int early_suspend_flag = 0;
+#endif
+#ifdef CONFIG_SCREEN_ON_EARLY
+static int early_resume_flag = 0;
+#endif
+
+osd_info_t  osd_info={
+	.index = 0,
+	.osd_reverse = 0,
+};
+
+MODULE_AMLOG(AMLOG_DEFAULT_LEVEL, 0x0, LOG_LEVEL_DESC, LOG_MASK_DESC);
+
+static myfb_dev_t  *gp_fbdev_list[OSD_COUNT]={NULL,NULL};
+
+static DEFINE_MUTEX(dbg_mutex);
+static char request2XScaleValue[32];
+static char videohole[32];
+
+
+const color_bit_define_t*	
+_find_color_format(struct fb_var_screeninfo * var)
+{
+	u32	upper_margin,lower_margin,i,level;
+	const color_bit_define_t *ret=NULL;
+	
+	level=(var->bits_per_pixel -1)/8; 
+	switch(level)
+	{
+		case 0:
+		upper_margin=COLOR_INDEX_08_PAL256;
+		lower_margin=COLOR_INDEX_02_PAL4;
+		break;
+		case 1:
+		upper_margin=COLOR_INDEX_16_565;
+		lower_margin=COLOR_INDEX_16_655;
+		break;	
+		case 2:
+		upper_margin=COLOR_INDEX_24_RGB;
+		lower_margin=COLOR_INDEX_24_6666_A;
+		break;		
+		case 3:
+		if ((var->nonstd != 0)
+		    && (var->transp.length == 0)) {
+			/* RGBX Mode */
+#ifdef CONFIG_FB_AMLOGIC_UMP
+			upper_margin = COLOR_INDEX_32_XRGB;
+#else
+			upper_margin = COLOR_INDEX_32_XBGR;
+#endif
+			lower_margin = COLOR_INDEX_32_BGRX;
+		} else {
+#ifdef CONFIG_FB_AMLOGIC_UMP
+			upper_margin = COLOR_INDEX_32_ARGB;
+#else
+			upper_margin = COLOR_INDEX_32_ABGR;
+#endif
+			lower_margin = COLOR_INDEX_32_BGRA;
+		}
+		break;
+		case 4:
+		upper_margin=COLOR_INDEX_YUV_422;
+		lower_margin=COLOR_INDEX_YUV_422;	
+		break;
+		default :
+		return NULL;
+	}
+
+	/*
+	 * if not provide color component length
+	 * then we find the first depth match.
+	 */
+	if ((var->nonstd != 0) && (level == 3)
+	    && (var->transp.length == 0)) {
+		/* RGBX Mode */
+		for (i = upper_margin; i >= lower_margin; i--) {
+			if ((default_color_format_array[i].red_length == var->red.length) &&
+			    (default_color_format_array[i].green_length == var->green.length) &&
+			    (default_color_format_array[i].blue_length == var->blue.length) &&
+			    (default_color_format_array[i].transp_offset == var->transp.offset) &&
+			    (default_color_format_array[i].green_offset == var->green.offset) &&
+			    (default_color_format_array[i].blue_offset == var->blue.offset) &&
+			    (default_color_format_array[i].red_offset == var->red.offset)) {
+				 ret = &default_color_format_array[i];
+				break;
+			}
+		}
+	} else 	if((var->red.length==0)||(var->green.length==0)||(var->blue.length==0)||
+		var->bits_per_pixel != (var->red.length+var->green.length+var->blue.length+var->transp.length))
+	{
+		amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"not provide color component length,use default color \n");
+		ret =&default_color_format_array[upper_margin];
+	}
+	else
+	{
+		for ( i=upper_margin;i>=lower_margin;i--)
+		{
+			if( (default_color_format_array[i].red_length==var->red.length)&&
+			(default_color_format_array[i].green_length==var->green.length)&&
+			(default_color_format_array[i].blue_length==var->blue.length)&&
+			(default_color_format_array[i].transp_length ==var->transp.length)&&
+			(default_color_format_array[i].transp_offset==var->transp.offset)&&
+			(default_color_format_array[i].green_offset==var->green.offset)&&
+			(default_color_format_array[i].blue_offset==var->blue.offset)&&
+			(default_color_format_array[i].red_offset==var->red.offset))
+			{
+				 ret = &default_color_format_array[i];
+				 break;
+			}
+		}
+	}
+	return ret;
+}
+static void __init
+_fbdev_set_default(struct myfb_dev *fbdev,int index )
+{
+    	/* setup default value */
+	fbdev->fb_info->var = mydef_var[index];
+	fbdev->fb_info->fix = mydef_fix;
+	fbdev->color=_find_color_format(&fbdev->fb_info->var);
+}
+
+static int
+osd_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	struct fb_fix_screeninfo *fix;
+    	struct myfb_dev *fbdev=( struct myfb_dev*)info->par;
+	const color_bit_define_t   *color_format_pt;
+
+	fix = &info->fix;
+	
+	color_format_pt=_find_color_format(var);
+	if (color_format_pt == NULL || color_format_pt->color_index==0)
+	{
+		return -EFAULT ;
+	}
+	amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"select color format :index%d,bpp %d\r\n",color_format_pt->color_index, \
+												color_format_pt->bpp) ;
+	fbdev->color=color_format_pt;
+	var->red.offset = color_format_pt->red_offset;
+	var->red.length = color_format_pt->red_length;
+	var->red.msb_right= color_format_pt->red_msb_right ;
+	var->green.offset  = color_format_pt->green_offset;
+	var->green.length  = color_format_pt->green_length;
+	var->green.msb_right = color_format_pt->green_msb_right;
+	var->blue.offset   = color_format_pt->blue_offset;
+	var->blue.length   = color_format_pt->blue_length;
+	var->blue.msb_right = color_format_pt->blue_msb_right;
+	var->transp.offset= color_format_pt->transp_offset ;
+	var->transp.length = color_format_pt->transp_length ;
+	var->transp.msb_right = color_format_pt->transp_msb_right ;
+	var->bits_per_pixel=color_format_pt->bpp ;
+	amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"rgba(L/O):%d/%d-%d/%d-%d/%d-%d/%d\n",
+					var->red.length,var->red.offset,
+					var->green.length,var->green.offset,
+					var->blue.length,var->blue.offset,
+					var->transp.length,var->transp.offset);
+	fix->visual=color_format_pt->color_type ;
+	//adjust memory length.	
+ 	fix->line_length = var->xres_virtual*var->bits_per_pixel/8;
+	amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"xvirtual=%d,bpp:%d,kernel_line_length=%d\r\n",var->xres_virtual,var->bits_per_pixel,fix->line_length);
+	if(var->xres_virtual*var->yres_virtual*var->bits_per_pixel/8> fbdev->fb_len )
+	{
+		amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"no enough memory for %d*%d*%d\r\n",var->xres,var->yres,var->bits_per_pixel);
+		return  -ENOMEM;
+	}
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+
+    	var->left_margin = var->right_margin = var->upper_margin = var->lower_margin = 0;
+    
+	if (var->xres + var->xoffset > var->xres_virtual)
+		var->xoffset = var->xres_virtual - var->xres;
+	if (var->yres + var->yoffset > var->yres_virtual)
+		var->yoffset = var->yres_virtual - var->yres;
+    
+    	return 0;
+}
+
+static int
+osd_set_par(struct fb_info *info)
+{
+	const vinfo_t *vinfo;
+	struct myfb_dev *fbdev = (struct myfb_dev *)info->par;
+	osd_ctl_t *osd_ctrl=&fbdev->osd_ctl; 
+	u32  virt_end_x,virt_end_y;
+	
+	vinfo = get_current_vinfo();
+	virt_end_x=osd_ctrl->disp_start_x+info->var.xres;
+	virt_end_y=osd_ctrl->disp_start_y+info->var.yres;
+	
+	if(virt_end_x > vinfo->width)
+	{
+		osd_ctrl->disp_end_x=vinfo->width - 1 ;
+	}
+	else
+	{
+		osd_ctrl->disp_end_x=virt_end_x -1;
+	}
+	if(virt_end_y  >vinfo->height)
+	{
+		osd_ctrl->disp_end_y=vinfo->height - 1;
+	}
+	else
+	{     
+		osd_ctrl->disp_end_y=virt_end_y - 1; 
+	}
+	osddev_set((struct myfb_dev *)info->par);
+	return  0;
+}
+
+static int
+osd_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+        unsigned transp, struct fb_info *info)
+{
+    return osddev_setcolreg(regno, red, green, blue,
+                        transp, (struct myfb_dev *)info->par);
+}
+
+static int
+osd_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+	int count, index, r;
+	u16 *red, *green, *blue, *transp;
+	u16 trans = 0xffff;
+
+	red     = cmap->red;
+	green   = cmap->green;
+	blue    = cmap->blue;
+	transp  = cmap->transp;
+	index   = cmap->start;
+
+	for (count = 0; count < cmap->len; count++) {
+		if (transp)
+			trans = *transp++;
+		r = osddev_setcolreg(index++, *red++, *green++, *blue++, trans,
+				(struct myfb_dev *)info->par);
+		if (r != 0)
+			return r;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_FB_AMLOGIC_UMP
+int (*disp_get_ump_secure_id) (struct fb_info *info, myfb_dev_t *g_fbi,
+					unsigned long arg, int buf);
+EXPORT_SYMBOL(disp_get_ump_secure_id);
+#endif
+
+static int
+osd_ioctl(struct fb_info *info, unsigned int cmd,
+               unsigned long arg)
+{
+	 struct myfb_dev *fbdev = (struct myfb_dev *)info->par;
+	 void __user *argp = (void __user *)arg;
+   	 u32  src_colorkey;//16 bit or 24 bit 
+   	 u32  srckey_enable;
+	 u32  gbl_alpha;
+	 u32  osd_order;
+	 s32  osd_axis[4] = {0};
+	 s32  osd_dst_axis[4] = {0};
+	 u32  block_windows[8] = {0};
+	 u32  block_mode;
+        unsigned long  ret;
+	 u32  flush_rate;
+
+	unsigned int karg = 0;
+#ifdef CONFIG_FB_AMLOGIC_UMP
+	int secure_id_buf_num = 0;
+#endif
+
+    	switch (cmd)
+  	{
+   		case  FBIOPUT_OSD_SRCKEY_ENABLE:
+			ret=copy_from_user(&srckey_enable,argp,sizeof(u32));
+			break;
+   		case  FBIOPUT_OSD_SRCCOLORKEY:
+			ret=copy_from_user(&src_colorkey,argp,sizeof(u32));
+			break ;
+		case FBIOPUT_OSD_SET_GBL_ALPHA:
+			ret=copy_from_user(&gbl_alpha,argp,sizeof(u32));
+			break;
+		case FBIOPUT_OSD_SCALE_AXIS:
+			ret=copy_from_user(&osd_axis, argp, 4 * sizeof(s32));
+			break;
+		case FBIOGET_OSD_SCALE_AXIS:
+		case FBIOPUT_OSD_ORDER:
+		case FBIOGET_OSD_ORDER:
+		case FBIOGET_OSD_GET_GBL_ALPHA:
+		case FBIOPUT_OSD_2X_SCALE:	
+		case FBIOPUT_OSD_ENABLE_3D_MODE:
+		case FBIOPUT_OSD_FREE_SCALE_ENABLE:
+		case FBIOPUT_OSD_FREE_SCALE_MODE:
+		case FBIOPUT_OSD_FREE_SCALE_WIDTH:
+		case FBIOPUT_OSD_FREE_SCALE_HEIGHT:
+		case FBIOGET_OSD_BLOCK_WINDOWS:
+		case FBIOGET_OSD_BLOCK_MODE:
+		case FBIOGET_OSD_FREE_SCALE_AXIS:
+		case FBIOGET_OSD_WINDOW_AXIS:
+		case FBIOPUT_OSD_REVERSE:
+		case FBIOPUT_OSD_ROTATE_ON:
+		case FBIOPUT_OSD_ROTATE_ANGLE:
+			break;
+		case FBIOPUT_OSD_BLOCK_MODE:
+			block_mode = (u32)argp;
+			break;
+		case FBIOPUT_OSD_BLOCK_WINDOWS:
+			ret=copy_from_user(&block_windows, argp, 8 * sizeof(u32));
+			break;
+		case FBIOPUT_OSD_FREE_SCALE_AXIS:
+			ret=copy_from_user(&osd_axis, argp, 4 * sizeof(s32));
+			break;
+		case FBIOPUT_OSD_WINDOW_AXIS:
+			ret=copy_from_user(&osd_dst_axis, argp, 4 * sizeof(s32));
+			break;
+#ifdef CONFIG_FB_AMLOGIC_UMP
+		case GET_UMP_SECURE_ID_BUF2:	/* flow trough */
+		{
+			secure_id_buf_num = 1;
+			if (!disp_get_ump_secure_id)
+				request_module("osd_ump");
+			if (disp_get_ump_secure_id)
+				return disp_get_ump_secure_id(info, fbdev, arg,
+							      secure_id_buf_num);
+			else
+				return -ENOTSUPP;
+		}
+		break;
+		case GET_UMP_SECURE_ID_BUF1:	/* flow trough */
+		{
+			secure_id_buf_num = 0;
+			if (!disp_get_ump_secure_id)
+				request_module("osd_ump");
+			if (disp_get_ump_secure_id)
+				return disp_get_ump_secure_id(info, fbdev, arg,
+							      secure_id_buf_num);
+			else
+				return -ENOTSUPP;
+		}
+		break;
+#endif
+		case FBIOPUT_OSD2_CURSOR_DATA:
+		{
+			if (copy_from_user(&karg, argp, sizeof(unsigned int))) {
+				return -EFAULT;
+			}
+			aml_hwc_addr_t para;
+			if (copy_from_user(&para, (void __user *)karg, sizeof(aml_hwc_addr_t))) {
+				return -EFAULT;
+			}
+			ret = osddev_copy_data_tocursor(fbdev, &para);
+		}
+		break;
+		
+		case FBIO_WAITFORVSYNC:
+		{
+        		osd_wait_vsync_hw();
+         		ret = 0;
+      		}
+      		break;
+
+		default :
+			amlog_mask_level(LOG_MASK_IOCTL,LOG_LEVEL_HIGH,"command not supported\r\n ");
+			return -1;
+	}
+	mutex_lock(&fbdev->lock);
+
+  	switch (cmd)
+    	{
+    		case FBIOPUT_OSD_ORDER:
+		osddev_change_osd_order(info->node,arg);	
+		break;
+		case FBIOGET_OSD_ORDER:
+		osd_order=osddev_get_osd_order(info->node);
+		ret=copy_to_user(argp, &osd_order, sizeof(u32));
+		break;	
+		case FBIOPUT_OSD_FREE_SCALE_WIDTH:
+		osddev_free_scale_width(info->node,arg);
+		break;
+		case FBIOPUT_OSD_FREE_SCALE_HEIGHT:
+		osddev_free_scale_height(info->node,arg);
+		break;
+    		case FBIOPUT_OSD_FREE_SCALE_ENABLE:
+		osddev_free_scale_enable(info->node,arg);
+		break;
+		case FBIOPUT_OSD_FREE_SCALE_MODE:
+		osddev_free_scale_mode(info->node, arg);
+		break;
+    		case FBIOPUT_OSD_ENABLE_3D_MODE:
+		osddev_enable_3d_mode(info->node,arg);
+		break;
+    		case FBIOPUT_OSD_2X_SCALE: //arg :higher 16 bit h_scale_enable, lower 16 bit v_scale_enable
+		osddev_set_2x_scale(info->node,arg&0xffff0000?1:0,arg&0xffff?1:0);
+		break;
+		case FBIOGET_OSD_FLUSH_RATE:
+		osddev_get_flush_rate(&flush_rate);
+		if(copy_to_user(argp, &flush_rate, sizeof(u32)))
+			return -EFAULT;
+		break;
+		case FBIOPUT_OSD_REVERSE:
+		osddev_set_osd_reverse(info->node, arg);
+		break;
+		case FBIOPUT_OSD_ROTATE_ON:
+		osddev_set_osd_rotate_on(info->node, arg);
+		break;
+		case FBIOPUT_OSD_ROTATE_ANGLE:
+		osddev_set_osd_rotate_angle(info->node, arg);
+		break;
+		case FBIOPUT_OSD_SRCCOLORKEY:
+		switch(fbdev->color->color_index)
+	  	{
+	 		case COLOR_INDEX_16_655:
+			case COLOR_INDEX_16_844:
+			case COLOR_INDEX_16_565:
+			case COLOR_INDEX_24_888_B:
+			case COLOR_INDEX_24_RGB:
+			case COLOR_INDEX_YUV_422:
+	  	   	amlog_mask_level(LOG_MASK_IOCTL,LOG_LEVEL_LOW,"set osd color key 0x%x\r\n",src_colorkey);
+            fbdev->color_key = src_colorkey;
+	  	 	osddev_set_colorkey(info->node,fbdev->color->color_index,src_colorkey);
+			break;
+			default: break;
+	  	}
+	   	break ;
+	  	case FBIOPUT_OSD_SRCKEY_ENABLE:
+	   	switch(fbdev->color->color_index)
+	  	{
+	 		case COLOR_INDEX_16_655:
+			case COLOR_INDEX_16_844:
+			case COLOR_INDEX_16_565:
+			case COLOR_INDEX_24_888_B:
+			case COLOR_INDEX_24_RGB:
+			case COLOR_INDEX_YUV_422:	
+			amlog_mask_level(LOG_MASK_IOCTL,LOG_LEVEL_LOW,"set osd color key %s\r\n",srckey_enable?"enable":"disable");
+			if (srckey_enable != 0) {
+				fbdev->enable_key_flag |= KEYCOLOR_FLAG_TARGET;
+				if (!(fbdev->enable_key_flag & KEYCOLOR_FLAG_ONHOLD)) {
+					osddev_srckey_enable(info->node, 1);
+					fbdev->enable_key_flag |= KEYCOLOR_FLAG_CURRENT;
+				}
+			} else {
+				osddev_srckey_enable(info->node, 0);
+				fbdev->enable_key_flag &= ~(KEYCOLOR_FLAG_TARGET | KEYCOLOR_FLAG_CURRENT);
+			}
+			break;
+			default:break;
+	 	}
+	   	break;
+	 	case FBIOPUT_OSD_SET_GBL_ALPHA:
+	 	osddev_set_gbl_alpha(info->node,gbl_alpha);
+	 	break;
+	 	case  FBIOGET_OSD_GET_GBL_ALPHA:
+	 	gbl_alpha=osddev_get_gbl_alpha(info->node);
+	 	ret=copy_to_user(argp, &gbl_alpha, sizeof(u32));
+	  	break;
+
+		case FBIOGET_OSD_SCALE_AXIS:
+			osddev_get_scale_axis(info->node, &osd_axis[0], &osd_axis[1], &osd_axis[2], &osd_axis[3]);
+			ret=copy_to_user(argp, &osd_axis, 4 * sizeof(s32));
+			break;
+		case FBIOPUT_OSD_SCALE_AXIS:
+			osddev_set_scale_axis(info->node, osd_axis[0], osd_axis[1], osd_axis[2], osd_axis[3]);
+			break;
+		case FBIOGET_OSD_BLOCK_WINDOWS:
+			osddev_get_block_windows(info->node, block_windows);
+			ret=copy_to_user(argp, &block_windows, 8 * sizeof(u32));
+			break;
+		case FBIOPUT_OSD_BLOCK_WINDOWS:
+			osddev_set_block_windows(info->node, block_windows);
+			break;
+		case FBIOPUT_OSD_BLOCK_MODE:
+			osddev_set_block_mode(info->node, block_mode);
+			break;
+		case FBIOGET_OSD_BLOCK_MODE:
+			osddev_get_block_mode(info->node, &block_mode);
+			ret=copy_to_user(argp, &block_mode, sizeof(u32));
+			break;
+		case FBIOGET_OSD_FREE_SCALE_AXIS:
+			osddev_get_free_scale_axis(info->node, &osd_axis[0], &osd_axis[1], &osd_axis[2], &osd_axis[3]);
+			ret=copy_to_user(argp, &osd_axis, 4 * sizeof(s32));
+			break;
+		case FBIOGET_OSD_WINDOW_AXIS:
+			osddev_get_window_axis(info->node, &osd_dst_axis[0], &osd_dst_axis[1], &osd_dst_axis[2], &osd_dst_axis[3]);
+			ret=copy_to_user(argp, &osd_dst_axis, 4 * sizeof(s32));
+			break;
+		case FBIOPUT_OSD_FREE_SCALE_AXIS:
+			osddev_set_free_scale_axis(info->node, osd_axis[0], osd_axis[1], osd_axis[2], osd_axis[3]);
+			break;
+		case FBIOPUT_OSD_WINDOW_AXIS:
+			osddev_set_window_axis(info->node, osd_dst_axis[0], osd_dst_axis[1], osd_dst_axis[2], osd_dst_axis[3]);
+			break;
+		default:
+			break;
+    	}
+
+   	mutex_unlock(&fbdev->lock);
+	
+	return  0;
+}
+static int osd_open(struct fb_info *info, int arg)
+{
+	return 0;
+	
+}
+
+/* Blank Mode */
+extern void control_hdmiphy(int on);
+
+static int
+osd_blank(int blank_mode, struct fb_info *info)
+{
+ 	osddev_enable((blank_mode != 0) ? 0 : 1,info->node);
+
+#if defined(CONFIG_MACH_MESON8B_ODROIDC)
+	if (!monitor_onoff_flag)
+		return 0;
+
+	switch (blank_mode) {
+	case FB_BLANK_UNBLANK: /* Display: On; HSync: On, VSync: On */
+		control_hdmiphy(1); /* HDMI PHY ON */
+		break;
+	case FB_BLANK_NORMAL: /* Display: Off; HSync: On, VSync: On */
+	case FB_BLANK_HSYNC_SUSPEND: /* Display: Off; HSync: Off, VSync: On */
+	case FB_BLANK_VSYNC_SUSPEND: /* Display: Off; HSync: On, VSync: Off */
+		break;
+	case FB_BLANK_POWERDOWN: /* Display: Off; HSync: Off, VSync: Off */
+		control_hdmiphy(0); /* HDMI PHY OFF*/
+		break;
+	}
+#endif
+    	return 0;
+}
+
+static int osd_pan_display(struct fb_var_screeninfo *var,
+                        struct fb_info *fbi)
+{
+	osddev_pan_display(var,fbi);
+	amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"osd_pan_display:=>osd%d\r\n",fbi->node);
+	return 0;
+}
+
+#if defined(CONFIG_FB_OSD2_CURSOR)
+static int osd_cursor(struct fb_info *fbi, struct fb_cursor *var)
+{
+	s16 startx = 0, starty = 0;
+	myfb_dev_t *fb_dev = gp_fbdev_list[1];
+	if (fb_dev) {
+		startx = fb_dev->osd_ctl.disp_start_x;
+		starty = fb_dev->osd_ctl.disp_start_y;
+	}
+	osddev_cursor((struct myfb_dev *)fbi->par,
+                  (s16)var->hot.x, (s16)var->hot.y,
+                  startx, starty,
+                  fbi->var.xres, fbi->var.yres);
+	return 0;
+}
+#endif
+
+static int osd_sync(struct fb_info *info)
+{
+	return 0;
+}
+
+
+/* fb_ops structures */
+static struct fb_ops osd_ops = {
+	.owner          = THIS_MODULE,
+	.fb_check_var   = osd_check_var,
+	.fb_set_par     = osd_set_par,
+	.fb_setcolreg   = osd_setcolreg,
+	.fb_setcmap     = osd_setcmap,
+	.fb_fillrect    = cfb_fillrect,
+	.fb_copyarea    = cfb_copyarea,
+	.fb_imageblit   = cfb_imageblit,
+#ifdef CONFIG_FB_SOFT_CURSOR
+	.fb_cursor      = soft_cursor,
+#elif defined(CONFIG_FB_OSD2_CURSOR)
+	.fb_cursor      = osd_cursor,
+#endif
+	.fb_ioctl       = osd_ioctl,
+	.fb_open        = osd_open,
+	.fb_blank       = osd_blank,
+	.fb_pan_display = osd_pan_display,
+	.fb_sync        = osd_sync,
+};
+
+static  void  set_default_display_axis(struct fb_var_screeninfo *var,osd_ctl_t *osd_ctrl,const vinfo_t *vinfo)
+{
+	u32  virt_end_x=osd_ctrl->disp_start_x + var->xres;
+	u32  virt_end_y=osd_ctrl->disp_start_y+var->yres;
+
+	if(virt_end_x > vinfo->width)
+	{
+		osd_ctrl->disp_end_x=vinfo->width- 1 ;//screen axis 
+	}
+	else
+	{
+		osd_ctrl->disp_end_x=virt_end_x- 1 ;//screen axis 
+	}
+	if(virt_end_y > vinfo->height)
+	{
+		osd_ctrl->disp_end_y=vinfo->height- 1 ;
+	}
+	else
+	{
+		osd_ctrl->disp_end_y=virt_end_y- 1 ;//screen axis 
+	}
+	return ;
+}
+
+int osd_notify_callback(struct notifier_block *block, unsigned long cmd , void *para)
+{
+	const vinfo_t *vinfo;
+	myfb_dev_t *fb_dev;
+	int  i,blank;
+	disp_rect_t  *disp_rect;
+	
+	vinfo = get_current_vinfo();
+	amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"tv_server:vmode=%s\r\n", vinfo->name);
+	
+	switch(cmd)
+	{
+		case  VOUT_EVENT_MODE_CHANGE:
+		amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"recevie change mode  message \r\n");
+		for(i=0;i<OSD_COUNT;i++)
+		{
+			if(NULL==(fb_dev=gp_fbdev_list[i])) continue;
+			set_default_display_axis(&fb_dev->fb_info->var,&fb_dev->osd_ctl,vinfo);
+			console_lock();
+			osddev_update_disp_axis(fb_dev,1);
+			osddev_set_osd_antiflicker(OSD1, vinfo->mode, gp_fbdev_list[OSD1]->fb_info->var.yres);
+			console_unlock();
+		}
+		break;
+
+		case VOUT_EVENT_OSD_BLANK:
+		blank=*(int*)para ;	
+		for(i=0;i<OSD_COUNT;i++)
+		{
+			if(NULL==(fb_dev=gp_fbdev_list[i])) continue;
+			console_lock();
+			osd_blank(blank,fb_dev->fb_info);
+			console_unlock();
+		}
+		break;
+		case   VOUT_EVENT_OSD_DISP_AXIS:
+		disp_rect=(disp_rect_t*)para;	
+		
+		for(i=0;i<OSD_COUNT;i++)
+		{	
+			if(!disp_rect)  break;
+			fb_dev=gp_fbdev_list[i];
+			if(fb_dev->preblend_enable) break;  //if osd layer preblend ,it's position is controled by vpp.
+			fb_dev->osd_ctl.disp_start_x=disp_rect->x  ;
+			fb_dev->osd_ctl.disp_start_y=disp_rect->y  ;
+			amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"set disp axis: x:%d y:%d w:%d h:%d\r\n"  , \
+					disp_rect->x, disp_rect->y,\
+					disp_rect->w, disp_rect->h );
+			if(disp_rect->x+disp_rect->w > vinfo->width)
+			{
+				fb_dev->osd_ctl.disp_end_x=vinfo->width - 1;
+			}
+			else
+			{
+				fb_dev->osd_ctl.disp_end_x=fb_dev->osd_ctl.disp_start_x+disp_rect->w -1 ; 
+			}
+			if(disp_rect->y+ disp_rect->h>vinfo->height)
+			{
+				fb_dev->osd_ctl.disp_end_y=vinfo->height- 1;
+			}
+			else
+			{
+				fb_dev->osd_ctl.disp_end_y=fb_dev->osd_ctl.disp_start_y + disp_rect->h - 1 ;
+			}
+			disp_rect ++;
+			amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"new disp axis: startx:%d starty:%d endx:%d endy:%d\r\n"  , \
+					fb_dev->osd_ctl.disp_start_x, fb_dev->osd_ctl.disp_start_y,\
+					fb_dev->osd_ctl.disp_end_x,fb_dev->osd_ctl.disp_end_y);
+			console_lock();
+			osddev_update_disp_axis(fb_dev,0);
+			console_unlock();
+		}
+		
+		break;
+	}
+	return 0;
+}
+
+static struct notifier_block osd_notifier_nb = {
+	.notifier_call	= osd_notify_callback,
+};
+static ssize_t store_preblend_enable(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+	fbdev->preblend_enable= simple_strtoul(buf, NULL, 0);
+	vout_notifier_call_chain(VOUT_EVENT_OSD_PREBLEND_ENABLE,&fbdev->preblend_enable) ;
+	return count;
+}
+
+static ssize_t show_preblend_enable(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+	return snprintf(buf, PAGE_SIZE, "preblend[%s]\n",fbdev->preblend_enable?"enable":"disable");
+}
+
+static ssize_t store_enable_3d(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+	fbdev->enable_3d= simple_strtoul(buf, NULL, 0);
+	osddev_enable_3d_mode(fb_info->node, fbdev->enable_3d);
+	return count;
+}
+
+static ssize_t show_enable_3d(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+	return snprintf(buf, PAGE_SIZE, "3d_enable:[0x%x]\n",fbdev->enable_3d);
+}
+
+static ssize_t store_color_key(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+	int r = simple_strtoul(buf, NULL, 16);
+	switch(fbdev->color->color_index)
+	  	{
+	 		case COLOR_INDEX_16_655:
+			case COLOR_INDEX_16_844:
+			case COLOR_INDEX_16_565:
+			case COLOR_INDEX_24_888_B:
+			case COLOR_INDEX_24_RGB:
+			case COLOR_INDEX_YUV_422:
+            fbdev->color_key = r;
+	  	 	osddev_set_colorkey(fb_info->node, fbdev->color->color_index, fbdev->color_key);
+			break;
+			default: break;
+	  	}
+	return count;
+}
+
+static ssize_t show_color_key(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+	return snprintf(buf, PAGE_SIZE, "0x%x\n", fbdev->color_key);
+}
+
+static ssize_t store_enable_key(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+	int r = simple_strtoul(buf, NULL, 0);
+
+	mutex_lock(&fbdev->lock);
+
+	if (r != 0) {
+		fbdev->enable_key_flag |= KEYCOLOR_FLAG_TARGET;
+		if (!(fbdev->enable_key_flag & KEYCOLOR_FLAG_ONHOLD)) {
+			osddev_srckey_enable(fb_info->node, 1);
+			fbdev->enable_key_flag |= KEYCOLOR_FLAG_CURRENT;
+		}
+	} else {
+		fbdev->enable_key_flag &= ~(KEYCOLOR_FLAG_TARGET | KEYCOLOR_FLAG_CURRENT);
+		osddev_srckey_enable(fb_info->node, 0);
+	}
+
+	mutex_unlock(&fbdev->lock);
+
+	return count;
+}
+
+static ssize_t show_enable_key(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+	return snprintf(buf, PAGE_SIZE, (fbdev->enable_key_flag & KEYCOLOR_FLAG_TARGET) ? "1\n" : "0\n");
+}
+
+static ssize_t store_enable_key_onhold(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+	int r = simple_strtoul(buf, NULL, 0);
+
+	mutex_lock(&fbdev->lock);
+
+	if (r != 0) {
+		/* hold all the calls to enable color key */
+		fbdev->enable_key_flag |= KEYCOLOR_FLAG_ONHOLD;
+		fbdev->enable_key_flag &= ~KEYCOLOR_FLAG_CURRENT;
+		osddev_srckey_enable(fb_info->node, 0);
+
+	} else {
+		fbdev->enable_key_flag &= ~KEYCOLOR_FLAG_ONHOLD;
+
+		/* if target and current mistach then recover the pending key settings */
+		if (fbdev->enable_key_flag & KEYCOLOR_FLAG_TARGET) {
+			if ((fbdev->enable_key_flag & KEYCOLOR_FLAG_CURRENT) == 0) {
+				fbdev->enable_key_flag |= KEYCOLOR_FLAG_CURRENT;
+				osddev_srckey_enable(fb_info->node, 1);
+			}
+		} else {
+			if (fbdev->enable_key_flag & KEYCOLOR_FLAG_CURRENT) {
+				fbdev->enable_key_flag &= ~KEYCOLOR_FLAG_CURRENT;
+				osddev_srckey_enable(fb_info->node, 0);
+			}
+		}
+	}
+
+	mutex_unlock(&fbdev->lock);
+
+	return count;
+}
+
+static ssize_t show_enable_key_onhold(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+	return snprintf(buf, PAGE_SIZE, (fbdev->enable_key_flag & KEYCOLOR_FLAG_ONHOLD) ? "1\n" : "0\n");
+}
+
+
+static int parse_para(const char *para, int para_num, int *result)
+{
+	char *endp;
+	const char *startp = para;
+	int *out = result;
+	int len = 0, count = 0;
+
+	if (!startp)
+		return 0;
+
+	len = strlen(startp);
+
+	do {
+		while (startp && (isspace(*startp) || !isgraph(*startp)) && len) {
+			startp++;
+			len--;
+		}
+
+		if (len == 0)
+			break;
+
+		*out++ = simple_strtol(startp, &endp, 0);
+
+		len -= endp - startp;
+		startp = endp;
+		count++;
+
+	} while ((endp) && (count < para_num) && (len > 0));
+
+	return count;
+}
+static ssize_t show_request_2xscale(struct device *device, struct device_attribute *attr,
+			 char *buf)
+{
+	memcpy(buf,request2XScaleValue,32);
+    return 32;
+}
+
+static ssize_t store__request_2xscale(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	memset(request2XScaleValue,0,32);
+	memcpy(request2XScaleValue,buf,count);
+    return count;
+}
+
+static ssize_t  show_video_hole(struct device *device, struct device_attribute *attr,
+			 char *buf)
+{
+	memcpy(buf,videohole,32);
+    return 32;
+}
+
+static ssize_t store__video_hole(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	memset(videohole,0,32);
+	memcpy(videohole,buf,count);
+    return count;
+}
+
+
+static ssize_t show_free_scale_axis(struct device *device, struct device_attribute *attr,
+			 char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	int x, y, w, h;
+
+	osddev_get_free_scale_axis(fb_info->node, &x, &y, &w, &h);
+
+    return snprintf(buf, PAGE_SIZE, "%d %d %d %d\n", x, y, w, h);
+}
+
+static ssize_t store_free_scale_axis(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	int parsed[4];
+
+	if (likely(parse_para(buf, 4, parsed) == 4)) {
+		osddev_set_free_scale_axis(fb_info->node, parsed[0], parsed[1], parsed[2], parsed[3]);
+	} else {
+		amlog_level(LOG_LEVEL_HIGH, "set free scale axis error\n");
+	}
+
+	return count;
+}
+
+static ssize_t show_scale_axis(struct device *device, struct device_attribute *attr,
+			 char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	int x0, y0, x1, y1;
+
+	osddev_get_scale_axis(fb_info->node, &x0, &y0, &x1, &y1);
+
+    return snprintf(buf, PAGE_SIZE, "%d %d %d %d\n", x0, y0, x1, y1);
+}
+
+static ssize_t store_scale_axis(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	int parsed[4];
+
+	if (likely(parse_para(buf, 4, parsed) == 4)) {
+		osddev_set_scale_axis(fb_info->node, parsed[0], parsed[1], parsed[2], parsed[3]);
+	} else {
+		amlog_level(LOG_LEVEL_HIGH, "set scale axis error\n");
+	}
+
+	return count;
+}
+
+static ssize_t store_scale_width(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	unsigned int free_scale_width=0;
+    
+	free_scale_width= simple_strtoul(buf, NULL, 0);
+	osddev_free_scale_width(fb_info->node, free_scale_width);
+
+	return count;
+}
+
+static ssize_t show_scale_width(struct device *device, struct device_attribute *attr,
+			  char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	unsigned int free_scale_width=0;
+
+	osddev_get_free_scale_width(fb_info->node, &free_scale_width);
+	return snprintf(buf, PAGE_SIZE, "free_scale_width:%d\n",free_scale_width);
+	
+}
+
+static ssize_t store_scale_height(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	unsigned int free_scale_height=0;
+
+	free_scale_height= simple_strtoul(buf, NULL, 0);
+	osddev_free_scale_height(fb_info->node, free_scale_height);
+
+	return count;
+}
+
+static ssize_t show_scale_height(struct device *device, struct device_attribute *attr,
+			  char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	unsigned int free_scale_height=0;
+
+	osddev_get_free_scale_height(fb_info->node, &free_scale_height);
+	return snprintf(buf, PAGE_SIZE, "free_scale_height:%d\n",free_scale_height);
+}
+
+static ssize_t store_free_scale(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	unsigned int free_scale_enable=0;
+
+	free_scale_enable= simple_strtoul(buf, NULL, 0);
+	osddev_free_scale_enable(fb_info->node, free_scale_enable);
+
+	return count;
+}
+
+static ssize_t show_free_scale(struct device *device, struct device_attribute *attr,
+			 char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	unsigned int free_scale_enable=0;
+
+	osddev_get_free_scale_enable(fb_info->node, &free_scale_enable);
+	return snprintf(buf, PAGE_SIZE, "free_scale_enable:[0x%x]\n",free_scale_enable);
+}
+
+static ssize_t store_freescale_mode(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	unsigned int free_scale_mode=0;
+    
+	free_scale_mode= simple_strtoul(buf, NULL, 0);
+	osddev_free_scale_mode(fb_info->node, free_scale_mode);
+
+	return count;
+}
+
+static ssize_t show_freescale_mode(struct device *device, struct device_attribute *attr,
+			 char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	unsigned int free_scale_mode=0;
+
+	osddev_get_free_scale_mode(fb_info->node, &free_scale_mode);
+
+	return snprintf(buf, PAGE_SIZE, "free_scale_mode:%s\n",free_scale_mode?"new":"default");
+}
+
+static ssize_t store_scale(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+
+	fbdev->scale = simple_strtoul(buf, NULL, 0);
+	osddev_set_2x_scale(fb_info->node,fbdev->scale&0xffff0000?1:0,fbdev->scale&0xffff?1:0);
+
+	return count;
+}
+
+static ssize_t show_scale(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+	return snprintf(buf, PAGE_SIZE, "scale:[0x%x]\n",fbdev->scale);
+}
+
+static ssize_t show_window_axis(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	int x0, y0, x1, y1;
+
+	osddev_get_window_axis(fb_info->node, &x0, &y0, &x1, &y1);
+
+	return snprintf(buf, PAGE_SIZE, "window axis is [%d %d %d %d]\n", x0, y0, x1, y1);
+}
+
+static ssize_t store_window_axis(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	s32 parsed[4];
+
+	if (likely(parse_para(buf, 4, parsed) == 4)) {
+		osddev_set_window_axis(fb_info->node, parsed[0], parsed[1], parsed[2], parsed[3]);
+	} else {
+		amlog_level(LOG_LEVEL_HIGH, "set window axis error\n");
+	}
+
+	return count;
+}
+
+
+static ssize_t store_osd_info(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	int osd_val[3][4] = {}; unsigned int osd_reg[2][5] = {}; int osd_info_flag = 0;
+
+	if (NULL != buf) {
+		if(strncmp(buf, "val", 3) == 0){
+			osd_info_flag = 0;
+		}else if(strncmp(buf, "reg", 3) == 0){
+			osd_info_flag = 1;
+		}else{
+			osd_info_flag = 2;
+		}
+		osddev_get_osd_info(fb_info->node, osd_val, osd_reg, osd_info_flag);
+	} else {
+		amlog_level(LOG_LEVEL_HIGH, "set store_osd_info *buf* is NULL error\n");
+	}
+	
+	if (osd_info_flag == 0){
+		amlog_level(LOG_LEVEL_HIGH, "pandata[%d].x_start :  %d\n"
+									  "pandata[%d].x_end   :  %d\n"
+									  "pandata[%d].y_start :  %d\n"
+									  "pandata[%d].y_end   :  %d\n",
+									fb_info->node, osd_val[0][0], fb_info->node, 
+									osd_val[0][1], fb_info->node, osd_val[0][2],
+									fb_info->node, osd_val[0][3]);
+		amlog_level(LOG_LEVEL_HIGH, "dispdata[%d].x_start :  %d\n"
+									  "dispdata[%d].x_end   :  %d\n"
+									  "dispdata[%d].y_start :  %d\n"
+									  "dispdata[%d].y_end   :  %d\n",
+									fb_info->node, osd_val[1][0], fb_info->node,
+									osd_val[1][1], fb_info->node, osd_val[1][2],
+									fb_info->node, osd_val[1][3]);
+		amlog_level(LOG_LEVEL_HIGH, "scaledata[%d].x_start :  %d\n"
+									  "scaledata[%d].x_end   :  %d\n"
+									  "scaledata[%d].y_start :  %d\n"
+									  "scaledata[%d].y_end   :  %d\n",
+									fb_info->node, osd_val[2][0], fb_info->node,
+									osd_val[2][1], fb_info->node, osd_val[2][2],
+									fb_info->node, osd_val[2][3]);
+	}else if(osd_info_flag == 1){
+		amlog_level(LOG_LEVEL_HIGH,  " [0x1a1b] : *0x%x*\n"
+									  " [0x1a1c] : *0x%x*\n"
+									  " [0x1a1d] : *0x%x*\n"
+									  " [0x1a1e] : *0x%x*\n"
+									  " [0x1a13] : *0x%x*\n",
+									osd_reg[0][0], osd_reg[0][1], osd_reg[0][2], osd_reg[0][3], osd_reg[0][4]);
+		amlog_level(LOG_LEVEL_HIGH, "  [0x1a3b] : *0x%x*\n"
+									 "  [0x1a3c] : *0x%x*\n"
+									 "  [0x1a3d] : *0x%x*\n"
+									 "  [0x1a3e] : *0x%x*\n"
+									 "  [0x1a64] : *0x%x*\n",
+									osd_reg[1][0], osd_reg[1][1], osd_reg[1][2], osd_reg[1][3], osd_reg[1][4]);
+	}else if(osd_info_flag == 2){
+		amlog_level(LOG_LEVEL_HIGH, "set store_osd_info osd_info_flag is error\n");
+	}
+	
+	return count;
+}
+
+static ssize_t store_order(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+
+	fbdev->order = simple_strtoul(buf, NULL, 0);
+	osddev_change_osd_order(fb_info->node, fbdev->order);
+
+	return count;
+}
+
+static ssize_t show_order(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct myfb_dev *fbdev = (struct myfb_dev *)fb_info->par;
+
+	fbdev->order = osddev_get_osd_order(fb_info->node);
+
+	return snprintf(buf, PAGE_SIZE, "order:[0x%x]\n",fbdev->order);
+}
+
+static ssize_t show_block_windows(struct device *device, struct device_attribute *attr,
+			 char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	u32 wins[8];
+
+	osddev_get_block_windows(fb_info->node, wins);
+
+    return snprintf(buf, PAGE_SIZE, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", 
+			wins[0], wins[1], wins[2], wins[3], wins[4], wins[5], wins[6], wins[7]);
+}
+
+static ssize_t store_block_windows(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	int parsed[8];
+
+	if (likely(parse_para(buf, 8, parsed) == 8)) {
+		osddev_set_block_windows(fb_info->node, parsed);
+	} else {
+		amlog_level(LOG_LEVEL_HIGH, "set block windows error\n");
+	}
+
+	return count;
+}
+
+static ssize_t show_block_mode(struct device *device, struct device_attribute *attr,
+			 char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	u32 mode;
+
+	osddev_get_block_mode(fb_info->node, &mode);
+
+    return snprintf(buf, PAGE_SIZE, "0x%x\n", mode);
+}
+
+static ssize_t store_block_mode(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	u32 mode;
+
+	mode = simple_strtoul(buf, NULL, 0);
+	osddev_set_block_mode(fb_info->node, mode);
+
+	return count;
+}
+
+static ssize_t show_flush_rate(struct device *device, struct device_attribute *attr,
+			 char *buf)
+{
+	u32 flush_rate = 0;
+	osddev_get_flush_rate(&flush_rate);
+	return snprintf(buf, PAGE_SIZE, "flush_rate:[%d]\n", flush_rate);
+}
+
+static ssize_t show_osd_reverse(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	unsigned int osd_reverse = 0;
+
+	osddev_get_osd_reverse(fb_info->node, &osd_reverse);
+	return snprintf(buf, PAGE_SIZE, "osd_reverse:[%s]\n", osd_reverse?"TRUE":"FALSE");
+}
+
+static ssize_t store_osd_reverse(struct device *device, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	unsigned int osd_reverse = 0;
+
+	osd_reverse = simple_strtoul(buf, NULL, 0);
+	osddev_set_osd_reverse(fb_info->node, osd_reverse);
+
+	return count;
+}
+static ssize_t show_rotate_on(struct device *device, struct device_attribute *attr,
+                        char *buf)
+{
+        struct fb_info *fb_info = dev_get_drvdata(device);
+        unsigned int osd_rotate = 0;
+
+        osddev_get_osd_rotate_on(fb_info->node, &osd_rotate);
+        return snprintf(buf, PAGE_SIZE, "osd_rotate:[%s]\n", osd_rotate?"ON":"OFF");
+}
+
+static ssize_t store_rotate_on(struct device *device, struct device_attribute *attr,
+                         const char *buf, size_t count)
+{
+        struct fb_info *fb_info = dev_get_drvdata(device);
+        unsigned int osd_rotate = 0;
+
+        osd_rotate = simple_strtoul(buf, NULL, 0);
+        osddev_set_osd_rotate_on(fb_info->node, osd_rotate);
+
+        return count;
+}
+
+static ssize_t show_prot_state(struct device *device, struct device_attribute *attr,
+                        char *buf)
+{
+	int pos=0;
+	unsigned int osd_rotate = 0;
+	struct fb_info *fb_info = dev_get_drvdata(device);
+
+	osddev_get_osd_rotate_on(fb_info->node, &osd_rotate);
+	pos += snprintf(buf+pos, PAGE_SIZE, "%d", osd_rotate);
+	return pos;
+}
+
+static ssize_t show_rotate_angle(struct device *device, struct device_attribute *attr,
+                        char *buf)
+{
+        struct fb_info *fb_info = dev_get_drvdata(device);
+        unsigned int osd_rotate_angle = 0;
+                
+        osddev_get_osd_rotate_angle(fb_info->node, &osd_rotate_angle);
+        return snprintf(buf, PAGE_SIZE, "osd_rotate:%d\n", osd_rotate_angle);
+}
+
+static ssize_t store_rotate_angle(struct device *device, struct device_attribute *attr,
+                         const char *buf, size_t count)
+{
+        struct fb_info *fb_info = dev_get_drvdata(device);
+        unsigned int osd_rotate_angle = 0;
+
+        osd_rotate_angle = simple_strtoul(buf, NULL, 0);
+        osddev_set_osd_rotate_angle(fb_info->node, osd_rotate_angle);
+
+        return count;
+}
+
+static ssize_t show_prot_canvas(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	int x_start, y_start, x_end, y_end;
+
+	osddev_get_prot_canvas(fb_info->node, &x_start, &y_start, &x_end, &y_end);
+
+	return snprintf(buf, PAGE_SIZE, "%d %d %d %d\n", x_start, y_start, x_end, y_end);
+}
+
+static ssize_t store_prot_canvas(struct device *device, struct device_attribute *attr,
+                         const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	int parsed[4];
+
+	if (likely(parse_para(buf, 4, parsed) == 4)) {
+		osddev_set_prot_canvas(fb_info->node, parsed[0], parsed[1], parsed[2], parsed[3]);
+	} else {
+		amlog_level(LOG_LEVEL_HIGH, "set prot canvas error\n");
+	}
+
+	return count;
+}
+
+static ssize_t show_antiflicker(struct device *device, struct device_attribute *attr,
+                        char *buf)
+{
+	unsigned int osd_antiflicker = 0;
+	struct fb_info *fb_info = dev_get_drvdata(device);
+
+	osddev_get_osd_antiflicker(fb_info->node, &osd_antiflicker);
+	return snprintf(buf, PAGE_SIZE, "osd_antifliter:[%s]\n", osd_antiflicker?"ON":"OFF");
+}
+
+static ssize_t store_antiflicker(struct device *device, struct device_attribute *attr,
+                         const char *buf, size_t count)
+{
+	const vinfo_t *vinfo;
+	unsigned int osd_antiflicker = 0;
+	struct fb_info *fb_info = dev_get_drvdata(device);
+
+	osd_antiflicker = simple_strtoul(buf, NULL, 0);
+	vinfo = get_current_vinfo();
+
+	if(osd_antiflicker == 2){
+		osddev_set_osd_antiflicker(fb_info->node, osd_antiflicker, fb_info->var.yres);
+	}else{
+		osddev_set_osd_antiflicker(fb_info->node, vinfo->mode, fb_info->var.yres);
+	}
+
+	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);
+
+	osddev_get_osd_angle(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);
+
+	osd_angle = simple_strtoul(buf, NULL, 0);
+
+	memset((char*)fb_info->screen_base, 0x80, fb_info->screen_size);
+	osddev_set_osd_angle(fb_info->node, osd_angle, mydef_var[OSD1].yres, fb_info->var.yres);
+
+	return count;
+}
+
+static ssize_t show_ver_clone(struct device *device, struct device_attribute *attr,
+                        char *buf)
+{
+	unsigned int osd_clone = 0;
+	struct fb_info *fb_info = dev_get_drvdata(device);
+
+	osddev_get_osd_clone(fb_info->node, &osd_clone);
+	return snprintf(buf, PAGE_SIZE, "osd_clone:[%s]\n", osd_clone?"ON":"OFF");
+}
+
+static ssize_t store_ver_clone(struct device *device, struct device_attribute *attr,
+                         const char *buf, size_t count)
+{
+	unsigned int osd_clone = 0;
+	struct fb_info *fb_info = dev_get_drvdata(device);
+
+	osd_clone = simple_strtoul(buf, NULL, 0);
+
+	osddev_set_osd_clone(fb_info->node, osd_clone);
+
+	return count;
+}
+
+static ssize_t store_ver_update_pan(struct device *device, struct device_attribute *attr,
+                         const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+
+	osddev_set_osd_update_pan(fb_info->node);
+
+	return count;
+}
+
+static inline  int str2lower(char *str)
+{
+	while(*str != '\0')
+	{
+		*str= TOLOWER(*str);
+		str++;
+	}
+	return 0;
+}
+
+static inline int install_osd_reverse_info(osd_info_t *init_osd_info,char *para)
+{
+	static  para_osd_info_t para_osd_info[OSD_END+2]={
+//head
+	{"head",	OSD_INVALID_INFO,	OSD_END+1,						1,								0,								OSD_END+1},
+//dev
+	{"osd0",	DEV_OSD0,			OSD_FIRST_GROUP_START-1,	OSD_FIRST_GROUP_START+1,	OSD_FIRST_GROUP_START,		OSD_SECOND_GROUP_START-1},
+	{"osd1",	DEV_OSD1,			OSD_FIRST_GROUP_START,		OSD_FIRST_GROUP_START+2,	OSD_FIRST_GROUP_START,		OSD_SECOND_GROUP_START-1},
+	{"all",	DEV_ALL,			OSD_FIRST_GROUP_START+1,	OSD_FIRST_GROUP_START+3,	OSD_FIRST_GROUP_START,		OSD_SECOND_GROUP_START-1},
+//reverse_mode
+	{"true",	REVERSE_TRUE,		OSD_SECOND_GROUP_START-1,	OSD_SECOND_GROUP_START+1,	OSD_SECOND_GROUP_START,	OSD_END},
+	{"false",	REVERSE_FALSE,	OSD_SECOND_GROUP_START,	OSD_SECOND_GROUP_START+2,	OSD_SECOND_GROUP_START,	OSD_END},
+	{"tail",	OSD_INVALID_INFO,	OSD_END,						0,								0,								OSD_END+1},
+	};
+
+	u32 i = 0;
+	static u32 tail = OSD_END+1;
+	u32 first = para_osd_info[0].next_idx;
+
+	for(i=first; i<tail; i=para_osd_info[i].next_idx)
+	{
+		if(strcmp(para_osd_info[i].name,para)==0)
+		{
+			u32 group_start = para_osd_info[i].cur_group_start ;
+			u32 group_end = para_osd_info[i].cur_group_end;
+			u32	prev = para_osd_info[group_start].prev_idx;
+			u32  next = para_osd_info[group_end].next_idx;
+			switch(para_osd_info[i].cur_group_start)
+			{
+				case OSD_FIRST_GROUP_START:
+				init_osd_info->index = (osd_dev_t)para_osd_info[i].info;
+				break;
+				case OSD_SECOND_GROUP_START:
+				init_osd_info->osd_reverse = (reverse_info_t)para_osd_info[i].info;
+				break;
+			}
+			para_osd_info[prev].next_idx=next;
+			para_osd_info[next].prev_idx=prev;
+			return 0;
+		}
+	}
+
+	return 0;
+}
+
+#if defined(CONFIG_MACH_MESON8B_ODROIDC)
+static int __init osd_setup_monitor_onoff(char *str)
+{
+	if (!strcmp(str, "true") || !strcmp(str, "1"))
+		monitor_onoff_flag = 1;
+	else
+		monitor_onoff_flag = 0;
+
+	return 0;
+}
+__setup("monitor_onoff=", osd_setup_monitor_onoff);
+#endif
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief  set_osd_reverse
+ *
+ * @param  str
+ *
+ * @return
+ */
+/* --------------------------------------------------------------------------*/
+static int __init osd_info_setup(char *str)
+{
+	char	*ptr=str;
+	char	sep[2];
+	char	*option;
+	int count=2;
+	char find=0;
+	osd_info_t *init_osd_info;
+
+	if(NULL==str){
+		return -EINVAL;
+	}
+
+	init_osd_info = &osd_info;
+	memset(init_osd_info,0,sizeof(osd_info_t));
+
+	do
+	{
+		if(!isalpha(*ptr)&&!isdigit(*ptr))
+		{
+			find=1;
+			break;
+		}
+	}while(*++ptr != '\0');
+
+	if(!find){
+		return -EINVAL;
+	}
+
+	sep[0]=*ptr; sep[1]='\0';
+
+	while((count--) && (option=strsep(&str, sep)))
+	{
+		str2lower(option);
+		install_osd_reverse_info(init_osd_info, option);
+	}
+
+	return 0;
+}
+
+__setup("osd_reverse=", osd_info_setup);
+
+static struct device_attribute osd_attrs[] = {
+	__ATTR(scale, S_IRUGO|S_IWUSR|S_IWGRP, show_scale, store_scale),
+	__ATTR(order, S_IRUGO|S_IWUSR|S_IWGRP, show_order, store_order),
+	__ATTR(enable_3d, S_IRUGO|S_IWUSR, show_enable_3d, store_enable_3d),
+	__ATTR(preblend_enable,S_IRUGO|S_IWUSR, show_preblend_enable, store_preblend_enable),
+	__ATTR(free_scale, S_IRUGO|S_IWUSR|S_IWGRP, show_free_scale, store_free_scale),
+	__ATTR(scale_axis, S_IRUGO|S_IWUSR, show_scale_axis, store_scale_axis),
+	__ATTR(scale_width, S_IRUGO|S_IWUSR|S_IWGRP, show_scale_width, store_scale_width),
+	__ATTR(scale_height, S_IRUGO|S_IWUSR|S_IWGRP, show_scale_height, store_scale_height),
+    __ATTR(color_key, S_IRUGO|S_IWUSR, show_color_key, store_color_key),
+    __ATTR(enable_key, S_IRUGO|S_IWUSR|S_IWGRP, show_enable_key, store_enable_key),
+    __ATTR(enable_key_onhold, S_IRUGO|S_IWUSR|S_IWGRP, show_enable_key_onhold, store_enable_key_onhold),
+	__ATTR(block_windows, S_IRUGO|S_IWUSR, show_block_windows, store_block_windows),
+	__ATTR(block_mode, S_IRUGO|S_IWUSR|S_IWGRP, show_block_mode, store_block_mode),
+	__ATTR(free_scale_axis, S_IRUGO|S_IWUSR|S_IWGRP, show_free_scale_axis, store_free_scale_axis),
+	__ATTR(request2XScale, S_IRUGO|S_IWUSR|S_IWGRP, show_request_2xscale, store__request_2xscale),
+	__ATTR(osd_info_msg, S_IRUGO|S_IWUSR, NULL, store_osd_info),
+	__ATTR(video_hole, S_IRUGO|S_IWUSR, show_video_hole, store__video_hole),
+	__ATTR(window_axis, S_IRUGO|S_IWUSR|S_IWGRP, show_window_axis, store_window_axis),
+	__ATTR(freescale_mode, S_IRUGO|S_IWUSR|S_IWGRP, show_freescale_mode, store_freescale_mode),
+	__ATTR(flush_rate, S_IRUGO|S_IWUSR, show_flush_rate, NULL),
+	__ATTR(prot_on, S_IRUGO|S_IWUSR|S_IWGRP, show_rotate_on, store_rotate_on),
+	__ATTR(prot_angle, S_IRUGO|S_IWUSR|S_IWGRP, show_rotate_angle, store_rotate_angle),
+	__ATTR(prot_canvas, S_IRUGO|S_IWUSR|S_IWGRP, show_prot_canvas, store_prot_canvas),
+	__ATTR(osd_reverse, S_IRUGO|S_IWUSR, show_osd_reverse, store_osd_reverse),
+	__ATTR(prot_state, S_IRUGO|S_IWUSR, show_prot_state, NULL),
+	__ATTR(osd_antiflicker, S_IRUGO|S_IWUSR, show_antiflicker, store_antiflicker),
+	__ATTR(ver_angle, S_IRUGO|S_IWUSR, show_ver_angle, store_ver_angle),
+	__ATTR(ver_clone, S_IRUGO|S_IWUSR, show_ver_clone, store_ver_clone),
+	__ATTR(ver_update_pan, S_IRUGO|S_IWUSR, NULL, store_ver_update_pan),
+};		
+
+#ifdef  CONFIG_PM
+static int osd_suspend(struct platform_device *dev, pm_message_t state)
+{
+#ifdef CONFIG_HAS_EARLYSUSPEND
+    if (early_suspend_flag)
+        return 0;
+#endif
+       osddev_suspend();
+       return 0;
+}
+
+static int osd_resume(struct platform_device * dev)
+{
+#ifdef CONFIG_SCREEN_ON_EARLY
+	if (early_resume_flag) {
+		early_resume_flag = 0;
+		return 0;
+	}
+#endif
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+    if (early_suspend_flag)
+        return 0;
+#endif
+       osddev_resume();
+       return 0;
+}
+#endif 
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void osd_early_suspend(struct early_suspend *h)
+{
+    if (early_suspend_flag)
+        return;
+    //osd_suspend(NULL,PMSG_SUSPEND);
+    osddev_suspend();
+    early_suspend_flag = 1;
+}
+
+static void osd_late_resume(struct early_suspend *h)
+{
+    if (!early_suspend_flag)
+        return;
+    early_suspend_flag = 0;
+    //osd_resume(NULL);
+    osddev_resume();
+}
+#endif
+
+#ifdef CONFIG_SCREEN_ON_EARLY
+void osd_resume_early(void)
+{
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	osddev_resume();
+	early_suspend_flag = 0;
+#endif
+	early_resume_flag = 1;
+	return ;
+}
+EXPORT_SYMBOL(osd_resume_early);
+#endif
+
+static struct resource memobj;
+static int 
+osd_probe(struct platform_device *pdev)
+{
+#ifdef CONFIG_AM_HDMI_ONLY
+	extern int read_hpd_gpio(void);
+#endif
+	int r;
+	int ret;
+    struct fb_info *fbi=NULL;
+	const vinfo_t *vinfo;
+    struct fb_var_screeninfo *var;
+  	struct fb_fix_screeninfo *fix;
+	struct resource *mem;
+	int  index,Bpp;
+	logo_object_t  *init_logo_obj=NULL;
+	int  logo_osd_index=0,i;
+	myfb_dev_t 	*fbdev = NULL;
+	vmode_t current_mode = VMODE_MASK;
+#ifdef CONFIG_AM_HDMI_ONLY
+	vmode_t cvbs_mode = VMODE_MASK;
+	int hpd_state = 0;
+#endif
+	const void *prop;
+	int prop_idx=0;
+	int rotation = 0;
+	
+	vout_register_client(&osd_notifier_nb);
+
+#ifdef CONFIG_AM_LOGO
+	init_logo_obj = get_current_logo_obj();
+	if( init_logo_obj )
+	{
+		if(init_logo_obj->para.output_dev_type<LOGO_DEV_VID) //osd0 or osd1
+		{
+			logo_osd_index = init_logo_obj->para.output_dev_type;
+		}else{
+			if(init_logo_obj->para.output_dev_type==LOGO_DEV_VID)
+			init_logo_obj=NULL; //if logo device on video layer ,
+		}					 //we cant use it .
+	}
+#endif
+
+	{
+		prop = of_get_property(pdev->dev.of_node, "scale_mode", NULL);
+		if(prop){
+			prop_idx = of_read_ulong(prop, 1);
+		}
+		osddev_free_scale_mode(OSD0, prop_idx);
+
+		prop = of_get_property(pdev->dev.of_node, "4k2k_fb", NULL);
+		if(prop){
+			prop_idx = of_read_ulong(prop, 1);
+		}
+		osddev_4k2k_fb_mode(prop_idx);
+	}
+
+	if (NULL==init_logo_obj )
+	{
+    		prop = of_get_property(pdev->dev.of_node, "vmode", NULL);
+		if(prop){
+			prop_idx = of_read_ulong(prop,1);
+		}
+
+		if(prop_idx == 3){
+			if(get_current_mode_state() == VMODE_SETTED){
+				amlog_level(LOG_LEVEL_HIGH,"vmode has setted in aml logo module\r\n");
+			}else{
+				DisableVideoLayer();
+				#ifdef CONFIG_AM_HDMI_ONLY
+					hpd_state = read_hpd_gpio();
+					cvbs_mode = get_current_cvbs_vmode();
+					current_mode = get_current_hdmi_vmode();
+
+					if (hpd_state == 0)
+						set_current_vmode(cvbs_mode);
+					else
+						set_current_vmode(current_mode);
+				#else
+					current_mode = get_resolution_vmode();
+					set_current_vmode(current_mode);
+				#endif
+			}
+		}
+		else if(prop_idx == 1){
+			current_mode = VMODE_LCD;
+			set_current_vmode(VMODE_LCD);
+		}
+		else if(prop_idx == 2){
+			current_mode = VMODE_LVDS_1080P;
+			set_current_vmode(VMODE_LVDS_1080P);
+		}
+		osddev_init();
+    	}
+	vinfo = get_current_vinfo();
+	printk("%s, vinfo:%p\n", __func__, vinfo);
+
+    	for (index=0;index<OSD_COUNT;index++)
+    	{
+#if 0
+    		//platform resource 
+		if (!(mem = platform_get_resource(pdev, IORESOURCE_MEM, index)))
+		{
+			amlog_level(LOG_LEVEL_HIGH,"No frame buffer memory define.\n");
+			r = -EFAULT;
+			goto failed2;
+		}
+
+		//if we have no resource then no need to create this device.
+		amlog_level(LOG_LEVEL_HIGH,"[osd%d] 0x%x-0x%x\n",index,mem->start,mem->end);
+		if (!mem || mem->start== 0 || mem->end==0 || mem->start==mem->end)
+		{
+			continue ;
+		}
+#else
+		mem = &memobj;
+		ret = find_reserve_block(pdev->dev.of_node->name,index);
+		if(ret < 0){
+			amlog_level(LOG_LEVEL_HIGH,"can not find %s%d reserve block\n",pdev->dev.of_node->name,index);
+			r = -EFAULT;
+			goto failed2;
+		}
+
+		mem->start = (phys_addr_t)get_reserve_block_addr(ret);
+		mem->end = mem->start+ (phys_addr_t)get_reserve_block_size(ret)-1;
+#endif
+		fbi = framebuffer_alloc(sizeof(struct myfb_dev), &pdev->dev);
+		if(!fbi){
+			r = -ENOMEM;
+			goto failed1;
+		}
+
+		fbdev = (struct myfb_dev *)fbi->par;
+		fbdev->fb_info = fbi;
+		fbdev->dev = pdev;
+
+		mutex_init(&fbdev->lock);
+
+    		var = &fbi->var;
+    		fix = &fbi->fix;
+
+		gp_fbdev_list[index]=fbdev;
+		fbdev->fb_mem_paddr = mem->start;
+		fbdev->fb_len = mem->end - mem->start + 1;
+		fbdev->fb_mem_vaddr = ioremap_wc(fbdev->fb_mem_paddr, fbdev->fb_len);
+
+		if (!fbdev->fb_mem_vaddr)
+		{
+			amlog_level(LOG_LEVEL_HIGH,"failed to ioremap framebuffer\n");
+			r = -ENOMEM;
+			goto failed1;
+		}
+	
+		//clear framebuffer memory
+		amlog_level(LOG_LEVEL_HIGH,"Frame buffer memory assigned at phy:0x%08x, vir:0x%p, size=%dK\n",
+	    	fbdev->fb_mem_paddr, fbdev->fb_mem_vaddr, fbdev->fb_len >> 10);
+		printk("%s, mydef_var:%p, vinfo:%p\n", __func__, mydef_var, vinfo);
+
+		mydef_var[index].width=vinfo->screen_real_width;
+		mydef_var[index].height=vinfo->screen_real_height;
+		if( init_logo_obj && index==logo_osd_index ) //adjust default var info
+		{
+			int  bpp=init_logo_obj->dev->output_dev.osd.color_depth;//bytes per pixel
+			printk("don't find to display_size_default from mesonfb-dts\n");
+			mydef_var[index].xres=init_logo_obj->dev->vinfo->width;
+			mydef_var[index].yres=init_logo_obj->dev->vinfo->height;	
+			mydef_var[index].xres_virtual=init_logo_obj->dev->vinfo->width;
+			mydef_var[index].yres_virtual=init_logo_obj->dev->vinfo->height<<1;//logo always use double buffer
+			mydef_var[index].bits_per_pixel=bpp;
+			
+			amlog_level(LOG_LEVEL_HIGH,"init fbdev bpp is :%d\r\n",mydef_var[index].bits_per_pixel);
+			if(mydef_var[index].bits_per_pixel>32){
+				mydef_var[index].bits_per_pixel=32;
+			}
+		} else {
+			if (index == OSD0){
+				ret = of_property_read_u32_array(pdev->dev.of_node, "display_size_default", &var_screeninfo[0], 5);
+				if(ret){
+					printk("don't find to display_size_default from mesonfb-dts\n");
+				}
+				else {			
+					int  bpp=var_screeninfo[4];//bytes per pixel
+					mydef_var[index].xres=var_screeninfo[0];
+					mydef_var[index].yres=var_screeninfo[1];	
+					mydef_var[index].xres_virtual=var_screeninfo[2];
+					mydef_var[index].yres_virtual=var_screeninfo[3];//logo always use double buffer
+					mydef_var[index].bits_per_pixel=bpp;
+				
+					amlog_level(LOG_LEVEL_HIGH,"init fbdev bpp is :%d\r\n",mydef_var[index].bits_per_pixel);
+					if(mydef_var[index].bits_per_pixel>32) 
+					{
+						mydef_var[index].bits_per_pixel=32;
+					}
+				}
+			}
+			amlog_level(LOG_LEVEL_HIGH,"---------------clear framebuffer%d memory  \r\n",index);
+			memset((char*)fbdev->fb_mem_vaddr, 0x80, fbdev->fb_len);
+		}
+
+		if (index == OSD0){
+			prop = of_get_property(pdev->dev.of_node, "rotation", NULL);
+			if(prop)
+				prop_idx = of_read_ulong(prop,1);
+
+			rotation = prop_idx;
+		}
+		_fbdev_set_default(fbdev,index);
+		if(NULL==fbdev->color)
+		{
+			r = -ENOENT;
+			goto failed1;
+		}
+
+		Bpp=(fbdev->color->color_index >8?(fbdev->color->color_index>16?(fbdev->color->color_index>24?4:3):2):1);
+		fix->line_length=var->xres_virtual*Bpp;
+		fix->smem_start = fbdev->fb_mem_paddr;
+		fix->smem_len = fbdev->fb_len;
+		if (fb_alloc_cmap(&fbi->cmap, 16, 0) != 0) {
+			amlog_level(LOG_LEVEL_HIGH,"unable to allocate color map memory\n");
+			r = -ENOMEM;
+			goto failed2;
+    		}
+
+		if (!(fbi->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL))) {
+			amlog_level(LOG_LEVEL_HIGH,"unable to allocate pseudo palette memory\n");
+			r = -ENOMEM;
+			goto failed2;
+		}
+		memset(fbi->pseudo_palette, 0, sizeof(u32) * 16);
+
+	   	fbi->fbops = &osd_ops;
+    		fbi->screen_base = (char __iomem *)fbdev->fb_mem_vaddr ;
+		fbi->screen_size = fix->smem_len;
+		set_default_display_axis(&fbdev->fb_info->var,&fbdev->osd_ctl,vinfo);
+		osd_check_var(var, fbi);
+    		register_framebuffer(fbi);
+		if(NULL==init_logo_obj )//if we have init a logo object ,then no need to setup hardware . 
+		{
+			osddev_set(fbdev);
+		}
+
+		if(index == OSD0 && (rotation == 90 || rotation == 270)){
+			osddev_set(fbdev);
+		}
+		for(i=0;i<ARRAY_SIZE(osd_attrs);i++)
+		r=device_create_file(fbi->dev, &osd_attrs[i]);
+		
+   	}	
+
+	index=0;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	early_suspend.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING;
+	early_suspend.suspend = osd_early_suspend;
+	early_suspend.resume = osd_late_resume;
+	register_early_suspend(&early_suspend);
+#endif
+	if (rotation == 90 || rotation == 270){
+		osddev_set_prot_canvas(0, 0,0,var_screeninfo[0]-1,var_screeninfo[1]-1);
+		if(rotation == 90){
+			osddev_set_osd_rotate_angle(0, 1);
+		}
+		else{
+			osddev_set_osd_rotate_angle(0, 2);
+			osddev_set_osd_rotate_on(0, 1);
+		}
+	}
+
+	if (osd_info.index == DEV_ALL){
+		osddev_set_osd_reverse(0, osd_info.osd_reverse);
+		osddev_set_osd_reverse(1, osd_info.osd_reverse);
+	}else{
+		osddev_set_osd_reverse(osd_info.index, osd_info.osd_reverse);
+	}
+	amlog_level(LOG_LEVEL_HIGH,"osd probe ok  \r\n");
+	vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE, NULL);
+	osddev_free_scale_enable(osd_info.index, 0);
+	return 0;
+
+failed2:
+	fb_dealloc_cmap(&fbi->cmap);
+failed1:
+    	amlog_level(LOG_LEVEL_HIGH,"Driver module insert failed.\n");
+   	return r;
+}
+
+static int
+osd_remove(struct platform_device *pdev)
+{
+   	struct fb_info *fbi;
+	int i=0;
+
+    	amlog_level(LOG_LEVEL_HIGH,"osd_remove.\n");
+	if (!pdev)
+		return -ENODEV;
+
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+    unregister_early_suspend(&early_suspend);
+#endif
+	
+	vout_unregister_client(&osd_notifier_nb);
+	
+	
+	for(i=0;i<OSD_COUNT;i++)
+	{
+		int j;
+		
+		if(gp_fbdev_list[i])
+		{
+			myfb_dev_t * fbdev=gp_fbdev_list[i];
+
+			fbi = fbdev->fb_info;
+			for(j=0;j<ARRAY_SIZE(osd_attrs);j++)
+			device_remove_file(fbi->dev, &osd_attrs[j]);
+			iounmap(fbdev->fb_mem_vaddr);
+      			kfree(fbi->pseudo_palette);
+     			fb_dealloc_cmap(&fbi->cmap);
+         		unregister_framebuffer(fbi);
+			framebuffer_release(fbi);
+		}
+	}
+	return 0;
+}
+
+#ifndef MODULE
+
+/* Process kernel command line parameters */
+static int __init
+osd_setup_attribute(char *options)
+{
+    char *this_opt = NULL;
+    int r = 0;
+
+    if (!options || !*options)
+        goto exit;
+
+    while (!r && (this_opt = strsep(&options, ",")) != NULL) {
+        if (!strncmp(this_opt, "xres:", 5))
+            mydef_var[0].xres = mydef_var[0].xres_virtual = simple_strtoul(this_opt + 5, NULL, 0);
+        else if (!strncmp(this_opt, "yres:", 5))
+            mydef_var[0].yres = mydef_var[0].yres_virtual = simple_strtoul(this_opt + 5, NULL, 0);
+        else {
+            amlog_level(LOG_LEVEL_HIGH,"invalid option\n");
+            r = -1;
+        }
+    }
+exit:
+    return r;
+}
+
+#endif
+
+/****************************************/
+static const struct of_device_id meson_fb_dt_match[]={
+	{	.compatible 	= "amlogic,mesonfb",
+	},
+	{},
+};
+
+static struct platform_driver
+osd_driver = {
+    .probe      = osd_probe,
+    .remove     = osd_remove,
+#ifdef  CONFIG_PM      
+    .suspend  =osd_suspend,
+    .resume    =osd_resume,
+#endif    
+    .driver     = {
+        .name   = "mesonfb",
+        .of_match_table=meson_fb_dt_match,
+    }
+};
+
+static int __init
+osd_init_module(void)
+{
+	amlog_level(LOG_LEVEL_HIGH,"osd_init\n");
+
+#ifndef MODULE
+    {
+      	char *option;
+      if (fb_get_options("mesonfb", &option)) {
+           return -ENODEV;
+   	}
+	  
+   	osd_setup_attribute(option);
+    }
+#endif
+
+    if (platform_driver_register(&osd_driver)) {
+        amlog_level(LOG_LEVEL_HIGH,"failed to register osd driver\n");
+        return -ENODEV;
+    }
+
+    return 0;
+}
+
+static void __exit
+osd_remove_module(void)
+{
+    amlog_level(LOG_LEVEL_HIGH,"osd_remove_module.\n");
+
+    platform_driver_unregister(&osd_driver);
+}
+
+/****************************************/
+module_init(osd_init_module);
+module_exit(osd_remove_module);
+
+MODULE_DESCRIPTION("AMLOGIC framebuffer driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");
diff --git a/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/include/linux/amlogic/osd/osd.h b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/include/linux/amlogic/osd/osd.h
new file mode 100644
index 000000000..4257a5081
--- /dev/null
+++ b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/include/linux/amlogic/osd/osd.h
@@ -0,0 +1,169 @@
+/*
+ * Amlogic OSD
+ * frame buffer driver
+ *
+ * Copyright (C) 2009 Amlogic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Author:	Tim Yao <timyao@amlogic.com>
+ *
+ */
+
+#ifndef OSD_H
+#define OSD_H
+#include  <linux/fb.h>
+
+typedef  enum {
+	COLOR_INDEX_02_PAL4    = 2,  // 0
+    	COLOR_INDEX_04_PAL16   = 4, // 0
+	COLOR_INDEX_08_PAL256=8,
+	COLOR_INDEX_16_655 =9,
+	COLOR_INDEX_16_844 =10,
+	COLOR_INDEX_16_6442 =11 ,
+	COLOR_INDEX_16_4444_R = 12,
+	COLOR_INDEX_16_4642_R = 13,
+	COLOR_INDEX_16_1555_A=14,
+	COLOR_INDEX_16_4444_A = 15,
+	COLOR_INDEX_16_565 =16,
+	
+	COLOR_INDEX_24_6666_A=19,
+	COLOR_INDEX_24_6666_R=20,
+	COLOR_INDEX_24_8565 =21,
+	COLOR_INDEX_24_5658 = 22,
+	COLOR_INDEX_24_888_B = 23,
+	COLOR_INDEX_24_RGB = 24,
+
+	COLOR_INDEX_32_BGRX = 25,
+	COLOR_INDEX_32_XBGR = 26,
+	COLOR_INDEX_32_RGBX = 27,
+	COLOR_INDEX_32_XRGB = 28,
+
+	COLOR_INDEX_32_BGRA=29,
+	COLOR_INDEX_32_ABGR = 30,
+	COLOR_INDEX_32_RGBA=31,
+	COLOR_INDEX_32_ARGB=32,
+
+	COLOR_INDEX_YUV_422=33,
+	
+}color_index_t;
+
+typedef struct {
+	unsigned int addr;
+} aml_hwc_addr_t;
+
+
+typedef  struct {
+	color_index_t	color_index;
+	u8	hw_colormat;
+	u8	hw_blkmode;
+
+	u8	red_offset ;
+	u8	red_length;
+	u8	red_msb_right;
+	
+	u8	green_offset;
+	u8	green_length;
+	u8	green_msb_right;
+
+	u8	blue_offset;
+	u8	blue_length;
+	u8	blue_msb_right;
+
+	u8	transp_offset;
+	u8	transp_length;
+	u8	transp_msb_right;
+
+	u8	color_type;
+	u8	bpp;
+
+		
+	
+}color_bit_define_t;
+typedef struct osd_ctl_s {
+    u32  xres_virtual;
+    u32  yres_virtual;
+    u32  xres;
+    u32  yres;
+    u32  disp_start_x; //coordinate of screen 
+    u32  disp_start_y;
+    u32  disp_end_x;
+    u32  disp_end_y;
+    u32  addr;
+    u32  index;
+} osd_ctl_t;
+#define  INVALID_BPP_ITEM    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
+
+static const  color_bit_define_t   default_color_format_array[]={
+	INVALID_BPP_ITEM,
+	INVALID_BPP_ITEM,
+	{COLOR_INDEX_02_PAL4,0,0,/*red*/ 0,2,0,/*green*/0,2,0,/*blue*/0,2,0,/*trans*/0,0,0,FB_VISUAL_PSEUDOCOLOR,2},
+	INVALID_BPP_ITEM,	
+	{COLOR_INDEX_04_PAL16,0,1,/*red*/ 0,4,0,/*green*/0,4,0,/*blue*/0,4,0,/*trans*/0,0,0,FB_VISUAL_PSEUDOCOLOR,4},
+	INVALID_BPP_ITEM,	
+	INVALID_BPP_ITEM,	
+	INVALID_BPP_ITEM,	
+	{COLOR_INDEX_08_PAL256,0,2,/*red*/ 0,8,0,/*green*/0,8,0,/*blue*/0,8,0,/*trans*/0,0,0,FB_VISUAL_PSEUDOCOLOR,8},
+/*16 bit color*/
+	{COLOR_INDEX_16_655,0,4,/*red*/ 10,6,0,/*green*/5,5,0,/*blue*/0,5,0,/*trans*/0,0,0,FB_VISUAL_TRUECOLOR,16},
+	{COLOR_INDEX_16_844,1,4,/*red*/ 8,8,0,/*green*/4,4,0,/*blue*/0,4,0,/*trans*/0,0,0,FB_VISUAL_TRUECOLOR,16},
+	{COLOR_INDEX_16_6442,2,4,/*red*/ 10,6,0,/*green*/6,4,0,/*blue*/2,4,0,/*trans*/0,2,0,FB_VISUAL_TRUECOLOR,16},
+	{COLOR_INDEX_16_4444_R,3,4,/*red*/ 12,4,0,/*green*/8,4,0,/*blue*/4,4,0,/*trans*/0,4,0,FB_VISUAL_TRUECOLOR,16,},
+	{COLOR_INDEX_16_4642_R,7,4,/*red*/ 12,4,0,/*green*/6,6,0,/*blue*/2,4,0,/*trans*/0,2,0,FB_VISUAL_TRUECOLOR,16},
+	{COLOR_INDEX_16_1555_A,6,4,/*red*/ 10,5,0,/*green*/5,5,0,/*blue*/0,5,0,/*trans*/15,1,0,FB_VISUAL_TRUECOLOR,16},
+	{COLOR_INDEX_16_4444_A,5,4,/*red*/ 8,4,0,/*green*/4,4,0,/*blue*/0,4,0,/*trans*/12,4,0,FB_VISUAL_TRUECOLOR,16},
+	{COLOR_INDEX_16_565,4,4,/*red*/ 11,5,0,/*green*/5,6,0,/*blue*/0,5,0,/*trans*/0,0,0,FB_VISUAL_TRUECOLOR,16},
+/*24 bit color*/
+	INVALID_BPP_ITEM,
+	INVALID_BPP_ITEM,
+	{COLOR_INDEX_24_6666_A,4,7,/*red*/ 12,6,0,/*green*/6,6,0,/*blue*/0,6,0,/*trans*/18,6,0,FB_VISUAL_TRUECOLOR,24},
+	{COLOR_INDEX_24_6666_R,3,7,/*red*/ 18,6,0,/*green*/12,6,0,/*blue*/6,6,0,/*trans*/0,6,0,FB_VISUAL_TRUECOLOR,24},
+	{COLOR_INDEX_24_8565,2,7,/*red*/ 11,5,0,/*green*/5,6,0,/*blue*/0,5,0,/*trans*/16,8,0,FB_VISUAL_TRUECOLOR,24},
+	{COLOR_INDEX_24_5658,1,7,/*red*/ 19,5,0,/*green*/13,6,0,/*blue*/8,5,0,/*trans*/0,8,0,FB_VISUAL_TRUECOLOR,24},
+	{COLOR_INDEX_24_888_B,5,7,/*red*/ 0,8,0,/*green*/8,8,0,/*blue*/16,8,0,/*trans*/0,0,0,FB_VISUAL_TRUECOLOR,24},
+	{COLOR_INDEX_24_RGB,0,7,/*red*/ 16,8,0,/*green*/8,8,0,/*blue*/0,8,0,/*trans*/0,0,0,FB_VISUAL_TRUECOLOR,24},
+/*32 bit color RGBX*/
+	{COLOR_INDEX_32_BGRX,3,5,/*red*/ 8,8,0,/*green*/16,8,0,/*blue*/24,8,0,/*trans*/0,0,0,FB_VISUAL_TRUECOLOR,32},
+	{COLOR_INDEX_32_XBGR,2,5,/*red*/ 0,8,0,/*green*/8,8,0,/*blue*/16,8,0,/*trans*/24,0,0,FB_VISUAL_TRUECOLOR,32},
+	{COLOR_INDEX_32_RGBX,0,5,/*red*/ 24,8,0,/*green*/16,8,0,/*blue*/8,8,0,/*trans*/0,0,0,FB_VISUAL_TRUECOLOR,32},
+	{COLOR_INDEX_32_XRGB,1,5,/*red*/ 16,8,0,/*green*/8,8,0,/*blue*/0,8,0,/*trans*/24,0,0,FB_VISUAL_TRUECOLOR,32},
+/*32 bit color RGBA*/
+	{COLOR_INDEX_32_BGRA,3,5,/*red*/ 8,8,0,/*green*/16,8,0,/*blue*/24,8,0,/*trans*/0,8,0,FB_VISUAL_TRUECOLOR,32},
+	{COLOR_INDEX_32_ABGR,2,5,/*red*/ 0,8,0,/*green*/8,8,0,/*blue*/16,8,0,/*trans*/24,8,0,FB_VISUAL_TRUECOLOR,32},
+	{COLOR_INDEX_32_RGBA,0,5,/*red*/ 24,8,0,/*green*/16,8,0,/*blue*/8,8,0,/*trans*/0,8,0,FB_VISUAL_TRUECOLOR,32},
+	{COLOR_INDEX_32_ARGB,1,5,/*red*/ 16,8,0,/*green*/8,8,0,/*blue*/0,8,0,/*trans*/24,8,0,FB_VISUAL_TRUECOLOR,32},
+/*YUV color*/
+	{COLOR_INDEX_YUV_422,0,3,0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,16},
+};
+
+typedef struct reg_val_pair{
+    uint reg;
+    uint val;
+} reg_val_pair_t;	
+
+#ifdef CONFIG_VSYNC_RDMA
+int VSYNCOSD_WR_MPEG_REG(unsigned long adr, unsigned long val);
+int VSYNCOSD_WR_MPEG_REG_BITS(unsigned long adr, unsigned long val, unsigned long start, unsigned long len);
+u32  VSYNCOSD_RD_MPEG_REG(unsigned long addr);
+int VSYNCOSD_SET_MPEG_REG_MASK(unsigned long adr, unsigned long _mask);
+int VSYNCOSD_CLR_MPEG_REG_MASK(unsigned long adr, unsigned long _mask);
+#else
+#define VSYNCOSD_WR_MPEG_REG(adr,val) aml_write_reg32(P_##adr, val)
+#define VSYNCOSD_WR_MPEG_REG_BITS(adr, val, start, len)  aml_set_reg32_bits(P_##adr, val, start, len)
+#define VSYNCOSD_RD_MPEG_REG(adr) aml_read_reg32(P_##adr)
+#define VSYNCOSD_SET_MPEG_REG_MASK(adr, _mask) aml_set_reg32_mask(P_##adr, _mask)
+#define VSYNCOSD_CLR_MPEG_REG_MASK(adr,  _mask) aml_clr_reg32_mask(P_##adr, _mask)
+#endif
+#endif /* OSD1_H */
diff --git a/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/include/linux/amlogic/osd/osd_main.h b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/include/linux/amlogic/osd/osd_main.h
new file mode 100644
index 000000000..6cb050a4f
--- /dev/null
+++ b/sources/Linux/Hardkernel/S805/create-3.10.103-20160830-osd-xrgb-patch/linux-aml-3.10.103-20160830-new/include/linux/amlogic/osd/osd_main.h
@@ -0,0 +1,207 @@
+/*
+ * Amlogic osd
+ * frame buffer driver
+ *
+ * Copyright (C) 2009 Amlogic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Author:  Tim Yao <timyao@amlogic.com>
+ *
+ */
+
+#ifndef OSD_MAIN_H
+#define OSD_MAIN_H
+#include  <linux/list.h>
+#include  <linux/amlogic/vout/vout_notify.h>
+#include  <linux/amlogic/osd/osd_dev.h>
+#include  <linux/fb.h>
+
+static __u32 var_screeninfo[5];
+
+static struct fb_var_screeninfo mydef_var[] = {
+{
+	.xres            = 1200,
+	.yres            = 690,
+	.xres_virtual    = 1200,
+	.yres_virtual    = 1380,
+	.xoffset         = 0,
+	.yoffset         = 0,
+	.bits_per_pixel = 16,
+	.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,
+	
+}
+
+#ifdef  CONFIG_FB_OSD2_ENABLE
+,
+{
+#if defined(CONFIG_FB_OSD2_DEFAULT_WIDTH)
+	.xres            = CONFIG_FB_OSD2_DEFAULT_WIDTH,
+#else
+	.xres            = 32,
+#endif
+#if defined(CONFIG_FB_OSD2_DEFAULT_HEIGHT)
+	.yres            = CONFIG_FB_OSD2_DEFAULT_HEIGHT,
+#else
+	.yres            = 32,
+#endif
+#if defined(CONFIG_FB_OSD2_DEFAULT_WIDTH_VIRTUAL)
+	.xres_virtual    = CONFIG_FB_OSD2_DEFAULT_WIDTH_VIRTUAL,
+#else
+	.xres_virtual    = 32,
+#endif
+#if defined(CONFIG_FB_OSD2_DEFAULT_HEIGHT_VIRTUAL)
+	.yres_virtual    = CONFIG_FB_OSD2_DEFAULT_HEIGHT_VIRTUAL,
+#else
+	.yres_virtual    = 32,
+#endif
+	.xoffset         = 0,
+	.yoffset         = 0,
+#if defined(CONFIG_FB_OSD2_DEFAULT_BITS_PER_PIXEL)
+	.bits_per_pixel  = CONFIG_FB_OSD2_DEFAULT_BITS_PER_PIXEL,
+#else
+	.bits_per_pixel = 32,
+#endif
+	.grayscale       = 0,
+	.red             = {0, 0, 0},  //leave as it is ,set by system.
+	.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 mydef_fix = {
+	.id		    = "OSD FB",
+	.xpanstep 	= 1,
+	.ypanstep 	= 1,
+	.type		= FB_TYPE_PACKED_PIXELS,
+	.visual		= FB_VISUAL_TRUECOLOR,
+	.accel		= FB_ACCEL_NONE,
+};
+
+typedef  struct {
+	int x ;
+	int y ;
+	int w ;
+	int h ;
+}disp_rect_t;
+#define DRIVER_NAME "osdfb"
+#define MODULE_NAME "osdfb"
+#define  FBIOPUT_OSD_SRCCOLORKEY	0x46fb
+#define  FBIOPUT_OSD_SRCKEY_ENABLE	0x46fa
+#define  FBIOPUT_OSD_SET_GBL_ALPHA	0x4500
+#define  FBIOGET_OSD_GET_GBL_ALPHA	0x4501
+#define  FBIOPUT_OSD_2X_SCALE		0x4502
+#define  FBIOPUT_OSD_ENABLE_3D_MODE	0x4503
+#define  FBIOPUT_OSD_FREE_SCALE_ENABLE	0x4504
+#define  FBIOPUT_OSD_FREE_SCALE_WIDTH	0x4505
+#define  FBIOPUT_OSD_FREE_SCALE_HEIGHT	0x4506
+#define  FBIOPUT_OSD_ORDER  		0x4507
+#define  FBIOGET_OSD_ORDER  		0x4508
+#define  FBIOGET_OSD_SCALE_AXIS		0x4509
+#define  FBIOPUT_OSD_SCALE_AXIS		0x450a
+#define  FBIOGET_OSD_BLOCK_WINDOWS	0x450b
+#define  FBIOPUT_OSD_BLOCK_WINDOWS	0x450c
+#define  FBIOGET_OSD_BLOCK_MODE		0x450d
+#define  FBIOPUT_OSD_BLOCK_MODE		0x450e
+#define  FBIOGET_OSD_FREE_SCALE_AXIS 0x450f
+#define  FBIOPUT_OSD_FREE_SCALE_AXIS  0x4510
+#define  FBIOPUT_OSD_FREE_SCALE_MODE  0x4511
+#define  FBIOGET_OSD_WINDOW_AXIS  	0x4512
+#define  FBIOPUT_OSD_WINDOW_AXIS  	0x4513
+#define  FBIOGET_OSD_FLUSH_RATE	0x4514
+#define  FBIOPUT_OSD_REVERSE		0x4515
+#define  FBIOPUT_OSD_ROTATE_ON   	0x4516
+#define  FBIOPUT_OSD_ROTATE_ANGLE	0x4517
+
+#define GET_UMP_SECURE_ID_BUF1 _IOWR('m', 311, unsigned int)
+#define GET_UMP_SECURE_ID_BUF2 _IOWR('m', 312, unsigned int)
+#define FBIOPUT_OSD2_CURSOR_DATA _IOWR('m', 313, unsigned int)
+
+#define  OSD_INVALID_INFO   		0xffffffff
+
+#define  OSD_FIRST_GROUP_START   	1
+#define  OSD_SECOND_GROUP_START 	4
+#define  OSD_END			5
+
+typedef  struct {
+	u32 index;
+	u32 osd_reverse;
+}osd_info_t;
+
+typedef  struct {
+	char *name;
+	u32   info;
+	u32   prev_idx;
+	u32   next_idx;
+	u32   cur_group_start;
+	u32   cur_group_end;
+}para_osd_info_t;
+
+typedef enum{
+	DEV_OSD0 = 0,
+	DEV_OSD1,
+	DEV_ALL,
+	DEV_MAX
+}osd_dev_t;
+
+typedef enum{
+	REVERSE_FALSE = 0,
+	REVERSE_TRUE,
+	REVERSE_MAX
+}reverse_info_t;
+
+#ifdef CONFIG_FB_AMLOGIC_UMP
+extern int (*disp_get_ump_secure_id) (struct fb_info *info, myfb_dev_t *g_fbi,
+                                       unsigned long arg, int buf);
+#endif
+
+#endif /* OSD_MAIN_H */