/*
 * drivers/osd/osd_fb.c
 *
 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
*/

/* System Headers */
#include <common.h>
#include <video_fb.h>
#include <stdio_dev.h>
#include <malloc.h>
#include <bmp_layout.h>
#include <asm/cpu_id.h>
#include <asm/arch/cpu.h>
#include <asm/arch/timer.h>

/* Local Headers */
#include <amlogic/fb.h>
#include <amlogic/color.h>
#include <amlogic/vinfo.h>
#include <amlogic/vout.h>

/* Local Headers */
#include "osd.h"
#include "osd_log.h"
#include "osd_hw.h"
#include "osd_fb.h"

#define INVALID_BPP_ITEM {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
static const struct color_bit_define_s default_color_format_array[] = {
	INVALID_BPP_ITEM,
	INVALID_BPP_ITEM,
	{
		COLOR_INDEX_02_PAL4, 0, 0,
		0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0,
		FB_VISUAL_PSEUDOCOLOR, 2,
	},
	INVALID_BPP_ITEM,
	{
		COLOR_INDEX_04_PAL16, 0, 1,
		0, 4, 0, 0, 4, 0, 0, 4, 0, 0, 0, 0,
		FB_VISUAL_PSEUDOCOLOR, 4,
	},
	INVALID_BPP_ITEM,
	INVALID_BPP_ITEM,
	INVALID_BPP_ITEM,
	{
		COLOR_INDEX_08_PAL256, 0, 2,
		0, 8, 0, 0, 8, 0, 0, 8, 0, 0, 0, 0,
		FB_VISUAL_PSEUDOCOLOR, 8,
	},
	/*16 bit color*/
	{
		COLOR_INDEX_16_655, 0, 4,
		10, 6, 0, 5, 5, 0, 0, 5, 0, 0, 0, 0,
		FB_VISUAL_TRUECOLOR, 16
	},
	{
		COLOR_INDEX_16_844, 1, 4,
		8, 8, 0, 4, 4, 0, 0, 4, 0, 0, 0, 0,
		FB_VISUAL_TRUECOLOR, 16
	},
	{
		COLOR_INDEX_16_6442, 2, 4,
		10, 6, 0, 6, 4, 0, 2, 4, 0, 0, 2, 0,
		FB_VISUAL_TRUECOLOR, 16
	},
	{
		COLOR_INDEX_16_4444_R, 3, 4,
		12, 4, 0, 8, 4, 0, 4, 4, 0, 0, 4, 0,
		FB_VISUAL_TRUECOLOR, 16
	},
	{
		COLOR_INDEX_16_4642_R, 7, 4,
		12, 4, 0, 6, 6, 0, 2, 4, 0, 0, 2, 0,
		FB_VISUAL_TRUECOLOR, 16
	},
	{
		COLOR_INDEX_16_1555_A, 6, 4,
		10, 5, 0, 5, 5, 0, 0, 5, 0, 15, 1, 0,
		FB_VISUAL_TRUECOLOR, 16
	},
	{
		COLOR_INDEX_16_4444_A, 5, 4,
		8, 4, 0, 4, 4, 0, 0, 4, 0, 12, 4, 0,
		FB_VISUAL_TRUECOLOR, 16
	},
	{
		COLOR_INDEX_16_565, 4, 4,
		11, 5, 0, 5, 6, 0, 0, 5, 0, 0, 0, 0,
		FB_VISUAL_TRUECOLOR, 16
	},
	/*24 bit color*/
	INVALID_BPP_ITEM,
	INVALID_BPP_ITEM,
	{
		COLOR_INDEX_24_6666_A, 4, 7,
		12, 6, 0, 6, 6, 0, 0, 6, 0, 18, 6, 0,
		FB_VISUAL_TRUECOLOR, 24
	},
	{
		COLOR_INDEX_24_6666_R, 3, 7,
		18, 6, 0, 12, 6, 0, 6, 6, 0, 0, 6, 0,
		FB_VISUAL_TRUECOLOR, 24
	},
	{
		COLOR_INDEX_24_8565, 2, 7,
		11, 5, 0, 5, 6, 0, 0, 5, 0, 16, 8, 0,
		FB_VISUAL_TRUECOLOR, 24
	},
	{
		COLOR_INDEX_24_5658, 1, 7,
		19, 5, 0, 13, 6, 0, 8, 5, 0, 0, 8, 0,
		FB_VISUAL_TRUECOLOR, 24
	},
	{
		COLOR_INDEX_24_888_B, 5, 7,
		0, 8, 0, 8, 8, 0, 16, 8, 0, 0, 0, 0,
		FB_VISUAL_TRUECOLOR, 24
	},
	{
		COLOR_INDEX_24_RGB, 0, 7,
		16, 8, 0, 8, 8, 0, 0, 8, 0, 0, 0, 0,
		FB_VISUAL_TRUECOLOR, 24
	},
	/*32 bit color*/
	INVALID_BPP_ITEM,
	INVALID_BPP_ITEM,
	INVALID_BPP_ITEM,
	INVALID_BPP_ITEM,
	{
		COLOR_INDEX_32_BGRA, 3, 5,
		8, 8, 0, 16, 8, 0, 24, 8, 0, 0, 8, 0,
		FB_VISUAL_TRUECOLOR, 32
	},
	{
		COLOR_INDEX_32_ABGR, 2, 5,
		0, 8, 0, 8, 8, 0, 16, 8, 0, 24, 8, 0,
		FB_VISUAL_TRUECOLOR, 32
	},
	{
		COLOR_INDEX_32_RGBA, 0, 5,
		24, 8, 0, 16, 8, 0, 8, 8, 0, 0, 8, 0,
		FB_VISUAL_TRUECOLOR, 32
	},
	{
		COLOR_INDEX_32_ARGB, 1, 5,
		16, 8, 0, 8, 8, 0, 0, 8, 0, 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},
};

GraphicDevice fb_gdev;
struct hw_para_s osd_hw;

typedef struct pic_info_t {
	unsigned int mode;
	unsigned int type;
	unsigned int pic_width;
	unsigned int pic_height;
	unsigned int bpp;
	ulong pic_image;
} pic_info_t;
static pic_info_t g_pic_info;
static int img_video_init = 0;

#if defined(CONFIG_AML_MINUI)
extern int in_fastboot_mode;
#endif

static void osd_layer_init(GraphicDevice *gdev, int layer)
{
	u32 index = layer;
	u32 xoffset = 0;
	u32 yoffset = 0;
	u32 xres = 0;
	u32 yres = 0;
	u32 xres_virtual = 0;
	u32 yres_virtual = 0;
	u32 disp_start_x = 0;
	u32 disp_start_y = 0;
	u32 disp_end_x = 0;
	u32 disp_end_y = 0;
	u32 fbmem = gdev->frameAdrs;
	const struct color_bit_define_s *color =
			&default_color_format_array[gdev->gdfIndex];

	if (index >= VIU2_OSD1) {
		xres = gdev->winSizeX;
		yres = gdev->winSizeY;
		xres_virtual = gdev->winSizeX;
		yres_virtual = gdev->winSizeY * 2;
		disp_end_x = gdev->winSizeX - 1;
		disp_end_y = gdev->winSizeY - 1;
	} else {
		xres = gdev->fb_width;
		yres = gdev->fb_height;
		xres_virtual = gdev->fb_width;
		yres_virtual = gdev->fb_height * 2;
		disp_end_x = gdev->fb_width - 1;
		disp_end_y = gdev->fb_height - 1;
	}

#ifdef CONFIG_AML_MESON_G12A
	if (index >= VIU2_OSD1)
		osd_init_hw_viu2();
	else
#endif
	osd_init_hw();
	osd_setup_hw(index,
		     xoffset,
		     yoffset,
		     xres,
		     yres,
		     xres_virtual ,
		     yres_virtual,
		     disp_start_x,
		     disp_start_y,
		     disp_end_x,
		     disp_end_y,
		     fbmem,
		     color);
}

static unsigned long env_strtoul(const char *name, int base)
{
	unsigned long ret = 0;

	ret = getenv_ulong(name, base, 0);

	if (base == 16)
		osd_logd("%s: 0x%lx\n", name, ret);
	else if (base == 10)
		osd_logd("%s: %ld\n", name, ret);

	return ret;
}

static int get_dts_node(char *dt_addr, char *dtb_node)
{
#ifdef CONFIG_OF_LIBFDT
	int parent_offset = 0;
	char *propdata = NULL;

	parent_offset = fdt_path_offset(dt_addr, dtb_node);
	if (parent_offset < 0) {
		/* not found */
		return -1;
	} else {
		propdata = (char *)fdt_getprop(dt_addr, parent_offset, "status", NULL);
		if (propdata == NULL) {
			osd_logi("not find status, default to disabled\n");
			return -1;
		} else {
			if (strncmp(propdata, "okay", 2)) {
				osd_logi("status disabled\n");
				return -1;
			}
		}
	}
	return parent_offset;
#else
	return -1;
#endif
}

unsigned long get_fb_addr(void)
{
	char *dt_addr = NULL;
	unsigned long fb_addr = 0;
	static int initrd_set = 0;
	char str_fb_addr[32];
	char fdt_node[32];
#ifdef CONFIG_OF_LIBFDT
	int parent_offset = 0;
	char *propdata = NULL;
#endif

	fb_addr = env_strtoul("fb_addr", 16);
#ifdef CONFIG_OF_LIBFDT
#ifdef CONFIG_DTB_MEM_ADDR
	dt_addr = (char *)CONFIG_DTB_MEM_ADDR;
#else
	dt_addr = (char *)0x01000000;
#endif

#if defined(CONFIG_AML_MINUI)
	if (in_fastboot_mode == 1) {
		osd_logi("in fastboot mode, load default fb_addr parameters \n");
	} else
#endif
	{
		if (fdt_check_header(dt_addr) < 0) {
			osd_logi("check dts: %s, load default fb_addr parameters\n",
				fdt_strerror(fdt_check_header(dt_addr)));
		} else {
			strcpy(fdt_node, "/meson-fb");
			osd_logi("load fb addr from dts:%s\n", fdt_node);
			parent_offset = get_dts_node(dt_addr, fdt_node);
			if (parent_offset < 0) {
				strcpy(fdt_node, "/fb");
				osd_logi("load fb addr from dts:%s\n", fdt_node);
				parent_offset = get_dts_node(dt_addr, fdt_node);
				if (parent_offset < 0) {
					strcpy(fdt_node, "/drm-vpu");
					osd_logi("load fb addr from dts:%s\n", fdt_node);
					parent_offset = get_dts_node(dt_addr, fdt_node);
					if (parent_offset < 0) {
						osd_logi("not find node: %s\n",fdt_strerror(parent_offset));
						osd_logi("use default fb_addr parameters\n");
					} else {
						/* check fb_addr */
						propdata = (char *)fdt_getprop(dt_addr, parent_offset, "logo_addr", NULL);
						if (propdata == NULL) {
							osd_logi("failed to get fb addr for logo\n");
							osd_logi("use default fb_addr parameters\n");
						} else {
							fb_addr = simple_strtoul(propdata, NULL, 16);
						}
					}
				} else {
					/* check fb_addr */
					propdata = (char *)fdt_getprop(dt_addr, parent_offset, "logo_addr", NULL);
					if (propdata == NULL) {
						osd_logi("failed to get fb addr for logo\n");
						osd_logi("use default fb_addr parameters\n");
					} else {
						fb_addr = simple_strtoul(propdata, NULL, 16);
					}
				}
			} else {
				/* check fb_addr */
				propdata = (char *)fdt_getprop(dt_addr, parent_offset, "logo_addr", NULL);
				if (propdata == NULL) {
					osd_logi("failed to get fb addr for logo\n");
					osd_logi("use default fb_addr parameters\n");
				} else {
					fb_addr = simple_strtoul(propdata, NULL, 16);
				}
			}
		}
	}
#endif
	if ((!initrd_set) && (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_AXG)) {
		sprintf(str_fb_addr,"%lx",fb_addr);
		setenv("initrd_high", str_fb_addr);
		initrd_set = 1;
		osd_logi("set initrd_high: 0x%s\n", str_fb_addr);
	}

	osd_logi("fb_addr for logo: 0x%lx\n", fb_addr);
	return fb_addr;
}

static void get_osd_version(void)
{
	u32 family_id = get_cpu_id().family_id;

	if (family_id == MESON_CPU_MAJOR_ID_AXG)
		osd_hw.osd_ver = OSD_SIMPLE;
	else if ((family_id == MESON_CPU_MAJOR_ID_G12A) ||
			(family_id == MESON_CPU_MAJOR_ID_G12B) ||
			(family_id >= MESON_CPU_MAJOR_ID_SM1))
		osd_hw.osd_ver = OSD_HIGH_ONE;
	else
		osd_hw.osd_ver = OSD_NORMAL;
}

int get_osd_layer(void)
{
	char *layer_str;
	int osd_index = -1;

	layer_str = getenv("display_layer");
	if (strcmp(layer_str, "osd0") == 0)
		osd_index = OSD1;
	else if (strcmp(layer_str, "osd1") == 0)
		osd_index = OSD2;
	else if (strcmp(layer_str, "viu2_osd0") == 0)
		osd_index = VIU2_OSD1;
	else
		osd_loge("%s, error found\n", __func__);

	return osd_index;
}
static void *osd_hw_init(void)
{
	int osd_index = -1;
	u32 color_index = 0;

	color_index = env_strtoul("display_color_index", 10);

	if ((color_index < ARRAY_SIZE(default_color_format_array))
	    && (default_color_format_array[color_index].color_index !=
		COLOR_INDEX_NULL))
		fb_gdev.gdfIndex = color_index;
	else {
		osd_loge("color_index %d invalid\n", color_index);
		return NULL;
	}

	osd_index = get_osd_layer();
	if (osd_index < 0) {
		osd_loge("osd_hw_init: invalid osd_index\n");
		return NULL;
	}

	if (osd_index == OSD1)
		osd_layer_init(&fb_gdev, OSD1);
	else if (osd_index == OSD2) {
		if (osd_hw.osd_ver == OSD_SIMPLE) {
			osd_loge("AXG not support osd2\n");
			return NULL;
		}
		osd_layer_init(&fb_gdev, OSD2);
	} else if (osd_index == VIU2_OSD1) {
		if (osd_hw.osd_ver == OSD_SIMPLE) {
			osd_loge("AXG not support viu2 osd0\n");
			return NULL;
		}
		osd_layer_init(&fb_gdev, VIU2_OSD1);
	} else {
		osd_loge("display_layer(%d) invalid\n", osd_index);
		return NULL;
	}
	return (void *)&fb_gdev;
}

void *video_hw_init(int display_mode)
{
	u32 fb_addr = 0;
	u32 display_width = 0;
	u32 display_height = 0;
	u32 display_bpp = 0;
	u32 fg = 0;
	u32 bg = 0;
	u32 fb_width = 0;
	u32 fb_height = 0;

	get_osd_version();

	vout_init();

	fb_addr = get_fb_addr();
	switch (display_mode) {
	case MIDDLE_MODE:
	case RECT_MODE:
#ifdef CONFIG_OSD_SCALE_ENABLE
		fb_width = env_strtoul("fb_width", 10);
		fb_height = env_strtoul("fb_height", 10);
#endif
		display_bpp = env_strtoul("display_bpp", 10);
		break;
	case FULL_SCREEN_MODE:
		fb_width = g_pic_info.pic_width;
		fb_height = g_pic_info.pic_height;
		display_bpp = g_pic_info.bpp;
		break;
	}
	display_width = env_strtoul("display_width", 10);
	display_height = env_strtoul("display_height", 10);
	fg = env_strtoul("display_color_fg", 10);
	bg = env_strtoul("display_color_bg", 10);

	/* fill in Graphic Device */
	fb_gdev.frameAdrs = fb_addr;
	fb_gdev.fb_width = fb_width;
	fb_gdev.fb_height = fb_height;
	fb_gdev.winSizeX = display_width;
	fb_gdev.winSizeY = display_height;
	fb_gdev.gdfBytesPP = display_bpp / 8;
	fb_gdev.fg = fg;
	fb_gdev.bg = bg;
	fb_gdev.mode = display_mode;
	return osd_hw_init();
}

int rle8_decode(uchar *ptr, bmp_image_t *bmap_rle8, ulong width_bmp, ulong height_bmp) {
	uchar a;
	uchar cnt, runlen;
	int i;
	int decode;
	int pixels;
	uchar *pic;
	int limit;

	a = 0xFF;
	decode = 1;
	pixels = 0;
	limit = width_bmp * height_bmp;
	pic = (uchar *)bmap_rle8 + le32_to_cpu(bmap_rle8->header.data_offset);

	while (decode) {
		switch (pic[0]) {
		case 0:
			switch (pic[1]) {
			case 0:
				/* end of row */
				pic += 2;
				continue;
			case 1:
				/* end of bmp */
				decode = 0;
				break;
			case 2:
				/* 00 02 mode */
				pic += 4;
				break;

			default:
				/* 00 (03~FF) mode */
				cnt = pic[1];
				runlen = cnt;
				pixels += cnt;
				if (pixels > limit)
				{
					osd_loge("Error: Too much encoded pixel data, validate your bitmap\n");
					decode = 0;
					return -1;
				}
				pic += 2;
				for (i = 0; i < cnt; i++) {

					*ptr = bmap_rle8->color_table[*pic].blue;
					ptr += 1;
					*ptr = bmap_rle8->color_table[*pic].green;
					ptr += 1;
					*ptr = bmap_rle8->color_table[*pic].red;
					ptr += 1;
					*ptr = a;
					ptr += 1;
					pic += 1;
				}
				if (runlen & 1)
					pic += 1;	/* 0 padding if length is odd */
				break;
			}
			break;

		default:
			/* normal mode */
			cnt = pic[0];
			runlen = cnt;
			pixels += cnt;
			if (pixels > limit) {
				osd_loge("Error: Too much encoded pixel data, validate your bitmap\n");
				return -1;
			}
			pic += 1;
			for (i = 0; i < cnt; i++) {

				*ptr = bmap_rle8->color_table[*pic].blue;
				ptr += 1;
				*ptr = bmap_rle8->color_table[*pic].green;
				ptr += 1;
				*ptr = bmap_rle8->color_table[*pic].red;
				ptr += 1;
				*ptr = a;
				ptr += 1;
			}
			pic += 1;
			break;
		}
	}
	return (0);
}

static int parse_bmp_info(ulong bmp_image)
{
	bmp_image_t *bmp = (bmp_image_t *)bmp_image;

	if (!((bmp->header.signature[0] == 'B') &&
		  (bmp->header.signature[1] == 'M'))) {
		osd_loge("no valid bmp image at 0x%lx\n", bmp_image);
		return 1;
	}
	g_pic_info.pic_width = le32_to_cpu(bmp->header.width);
	g_pic_info.pic_height = le32_to_cpu(bmp->header.height);
	g_pic_info.bpp = le16_to_cpu(bmp->header.bit_count);
	return 0;
}

int video_display_bitmap(ulong bmp_image, int x, int y)
{
	struct vinfo_s *info = NULL;
#if defined CONFIG_AML_VOUT
	info = vout_get_current_vinfo();
#endif
	// ushort *cmap_base = NULL;
	unsigned long byte_width;
	ushort i, j;
	uchar *fb;
	bmp_image_t *bmp = (bmp_image_t *)bmp_image;
	uchar *bmap;
	ushort padded_line;
	unsigned long width, height;
	unsigned long pheight;
	unsigned long pwidth;
	unsigned colors, bpix, bmp_bpix;
	uint lcd_line_length;
	int osd_index = -1;

	osd_index = get_osd_layer();
	if (osd_index < 0) {
		osd_loge("video_display_bitmap: invalid osd_index\n");
		return (-1);
	}

	/* viu1 has scaler, viu2 has no scaler */
	if (osd_index >= VIU2_OSD1) {
		pwidth = info->width;
		pheight = info->height;
	} else {
		pheight = fb_gdev.fb_height;
		pwidth = fb_gdev.fb_width;
	}

	lcd_line_length = CANVAS_ALIGNED((pwidth * NBITS(info->vl_bpix)) / 8);
	if (fb_gdev.mode != FULL_SCREEN_MODE)
		if (parse_bmp_info(bmp_image))
			return -1;
	width = g_pic_info.pic_width;
	height = g_pic_info.pic_height;
	bmp_bpix = g_pic_info.bpp;
	colors = 1 << bmp_bpix;
	uchar *buffer_rgb = NULL;
	bpix = NBITS(info->vl_bpix);
	if ((bpix != 1) && (bpix != 8) && (bpix != 16) && (bpix != 24) &&
	    (bpix != 32)) {
		osd_loge("%d bit/pixel mode1, but BMP has %d bit/pixel\n",
			 bpix, bmp_bpix);
		return 1;
	}
	/* We support displaying 8bpp BMPs on 16bpp LCDs */
	/*if (bpix != bmp_bpix && (bmp_bpix != 8 || bpix != 16)) {
		osd_loge("%d bit/pixel mode2, but BMP has %d bit/pixel\n",
			 bpix,
			 le16_to_cpu(bmp->header.bit_count));
		return 1;
	}*/

	osd_logd("Display-bmp: %d x %d  with %d colors\n",
		 (int)width, (int)height, (int)colors);

	if ((x == -1) && (y == -1)) {
		/* use MIDDLE_MODE */
		if ((width > pwidth) || (height > pheight)) {
			x = 0;
			y = 0;
		} else {
			x = (pwidth - width) / 2;
			y = (pheight - height) / 2;
		}
	} else {
		switch (fb_gdev.mode) {
		case MIDDLE_MODE:
			if ((width > pwidth) || (height > pheight)) {
				x = 0;
				y = 0;
			} else {
				x = (pwidth - width) / 2;
				y = (pheight - height) / 2;
			}
			break;
		case RECT_MODE:
			break;
		case FULL_SCREEN_MODE:
			x = 0;
			y = 0;
			break;
		}
	}
	/*
	 *  BMP format for Monochrome assumes that the state of a
	 * pixel is described on a per Bit basis, not per Byte.
	 *  So, in case of Monochrome BMP we should align widths
	 * on a byte boundary and convert them from Bit to Byte
	 * units.
	 *  Probably, PXA250 and MPC823 process 1bpp BMP images in
	 * their own ways, so make the converting to be MCC200
	 * specific.
	 */
	padded_line = (width & 0x3) ? ((width & ~0x3) + 4) : (width);

	if ((x + width) > pwidth)
		width = pwidth - x;
	if ((y + height) > pheight)
		height = pheight - y;

	bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset);
	fb   = (uchar *)(osd_hw.fb_gem[osd_index].addr +
			 (y + height - 1) * lcd_line_length + x * fb_gdev.gdfBytesPP);

	osd_logd("fb=0x%p; bmap=0x%p, width=%ld, height= %ld, lcd_line_length=%d, padded_line=%d, fb_gdev.fb_width=%d, fb_gdev.fb_height=%d \n",
		 fb, bmap, width, height, lcd_line_length, padded_line,fb_gdev.fb_width,fb_gdev.fb_height);

	if (bmp_bpix == 8) {
		/* decode of RLE8 */
		buffer_rgb = (uchar *)malloc(height * width * 4 * sizeof(uchar) + 1);
		if (buffer_rgb == NULL) {
			printf("Error:fail to malloc the memory!");
			return (-1);
		}
	}
	uchar *ptr_rgb = buffer_rgb;
	switch (bmp_bpix) {
	case 8:
		if (bpix != 16)
			byte_width = width;
		else
			byte_width = width * 2;
		rle8_decode(ptr_rgb, bmp, width, height);
		for (i = 0; i < height; ++i) {
			for (j = 0; j < width; j++) {
				if (bpix != 16) {
					*(fb++) = *buffer_rgb;
					buffer_rgb += 1;
					*(fb++) = *buffer_rgb;
					buffer_rgb += 1;
					*(fb++) = *buffer_rgb;
					buffer_rgb += 1;
					*(fb++) = *buffer_rgb;
					buffer_rgb += 1;
				}
				// else {
				// 	*(uint16_t *)fb = cmap_base[*buffer_rgb++];
				// 	fb += sizeof(uint16_t) / sizeof(*fb);
				// }
			}
			buffer_rgb += (padded_line - width);
			fb -= (byte_width * 4 + lcd_line_length);
		}
		buffer_rgb -= width*height*4;
		free(buffer_rgb);
		break;
	case 16:
		for (i = 0; i < height; ++i) {
			for (j = 0; j < width; j++) {

				*(fb++) = *(bmap++);
				*(fb++) = *(bmap++);
			}
			bmap += (padded_line - width) * 2;
			fb   -= (width * 2 + lcd_line_length);
		}
		break;
	case 24:
		if (bpix == 32) {
			for (i = 0; i < height; ++i) {
				for (j = 0; j < width; j++) {

					*(fb++) = *(bmap++);
					*(fb++) = *(bmap++);
					*(fb++) = *(bmap++);
					*(fb++) = 0xff;
				}
				bmap += (padded_line - width);
				fb   -= (width * 4 + lcd_line_length);
			}
		} else {
			for (i = 0; i < height; ++i) {
				for (j = 0; j < width; j++) {

					*(fb++) = *(bmap++);
					*(fb++) = *(bmap++);
					*(fb++) = *(bmap++);
				}
				bmap += (padded_line - width);
				fb   -= (width * 3 + lcd_line_length);
			}
		}
		break;
	case 32:
		for (i = 0; i < height; ++i) {
			for (j = 0; j < width; j++) {

				*(fb++) = *(bmap++);
				*(fb++) = *(bmap++);
				*(fb++) = *(bmap++);
				*(fb++) = *(bmap++);
			}
			bmap += (padded_line - width);
			fb   -= (width * 4 + lcd_line_length);
		}
		break;
	default:
		osd_loge("error: gdev.bpp %d, but bmp.bpp %d\n", fb_gdev.gdfBytesPP, bmp_bpix);
		return (-1);
	}
	buffer_rgb = NULL;
	ptr_rgb = NULL;

	flush_cache((unsigned long)osd_hw.fb_gem[osd_index].addr,
		    pheight * CANVAS_ALIGNED(pwidth * info->vl_bpix / 8));
	return (0);
}

int video_display_raw(ulong raw_image, int x, int y)
{
	struct vinfo_s *info = NULL;
#if defined CONFIG_AML_VOUT
	info = vout_get_current_vinfo();
#endif
	ushort i, j;
	uchar *fb;
	uchar *bmap = (uchar *)raw_image;
	ushort padded_line;
	unsigned long width, height;
#ifdef CONFIG_OSD_SCALE_ENABLE
	unsigned long pheight = fb_gdev.fb_height;
	unsigned long pwidth = fb_gdev.fb_width;
#else
	unsigned long pheight = info->width;
	unsigned long pwidth = info->height;
#endif
	unsigned colors, bpix, bmp_bpix;
	int lcd_line_length = (pwidth * NBITS(info->vl_bpix)) / 8;
	int osd_index = -1;

	osd_index = get_osd_layer();
	if (osd_index < 0) {
		osd_loge("video_display_raw: invalid osd_index\n");
		return (-1);
	}

	width = g_pic_info.pic_width;
	height = g_pic_info.pic_height;
	bmp_bpix = g_pic_info.bpp;
	colors = 1 << bmp_bpix;
	bpix = NBITS(info->vl_bpix);
	if ((bpix != 1) && (bpix != 8) && (bpix != 16) && (bpix != 24) &&
	    (bpix != 32)) {
		osd_loge("%d bit/pixel mode1, but BMP has %d bit/pixel\n",
			 bpix, bmp_bpix);
		return 1;
	}
	/* We support displaying 8bpp BMPs on 16bpp LCDs */
	/*if (bpix != bmp_bpix && (bmp_bpix != 8 || bpix != 16)) {
		osd_loge("%d bit/pixel mode2, but BMP has %d bit/pixel\n",
			 bpix,
			 le16_to_cpu(bmp->header.bit_count));
		return 1;
	}*/

	osd_logd("Display-bmp: %d x %d  with %d colors\n",
		 (int)width, (int)height, (int)colors);

	if ((x == -1) && (y == -1)) {
		/* use MIDDLE_MODE */
		if ((width > pwidth) || (height > pheight)) {
			x = 0;
			y = 0;
		} else {
			x = (pwidth - width) / 2;
			y = (pheight - height) / 2;
		}
	} else {
		switch (fb_gdev.mode) {
		case MIDDLE_MODE:
			if ((width > pwidth) || (height > pheight)) {
				x = 0;
				y = 0;
			} else {
				x = (pwidth - width) / 2;
				y = (pheight - height) / 2;
			}
			break;
		case RECT_MODE:
			break;
		case FULL_SCREEN_MODE:
			x = 0;
			y = 0;
			break;
		}
	}
	/*
	 *  BMP format for Monochrome assumes that the state of a
	 * pixel is described on a per Bit basis, not per Byte.
	 *  So, in case of Monochrome BMP we should align widths
	 * on a byte boundary and convert them from Bit to Byte
	 * units.
	 *  Probably, PXA250 and MPC823 process 1bpp BMP images in
	 * their own ways, so make the converting to be MCC200
	 * specific.
	 */
	padded_line = (width & 0x3) ? ((width & ~0x3) + 4) : (width);

	if ((x + width) > pwidth)
		width = pwidth - x;
	if ((y + height) > pheight)
		height = pheight - y;

	osd_enable_hw(osd_index, 1);

	fb   = (uchar *)(info->vd_base + y * lcd_line_length + x * fb_gdev.gdfBytesPP);

	osd_logd("fb=0x%p; bmap=0x%p, width=%ld, height= %ld, lcd_line_length=%d, padded_line=%d, fb_gdev.fb_width=%d, fb_gdev.fb_height=%d \n",
		 fb, bmap, width, height, lcd_line_length, padded_line,fb_gdev.fb_width,fb_gdev.fb_height);

	if (FULL_SCREEN_MODE == fb_gdev.mode) {
		memcpy(fb, bmap, height * width * bmp_bpix / 8);
	} else {
		switch (bmp_bpix) {
		case 16:
			for (i = 0; i < height; ++i) {
				for (j = 0; j < width; j++) {

					*(fb++) = *(bmap++);
					*(fb++) = *(bmap++);
				}
				bmap += (padded_line - width) * 2;
				fb   += (lcd_line_length - width * 2);
			}
			break;
		case 24:
			if (bpix == 32) {
				for (i = 0; i < height; ++i) {
					for (j = 0; j < width; j++) {

						*(fb++) = *(bmap++);
						*(fb++) = *(bmap++);
						*(fb++) = *(bmap++);
						*(fb++) = 0xff;
					}
					bmap += (padded_line - width) * 4;
					fb   += (lcd_line_length - width * 4);
				}
			} else {
				for (i = 0; i < height; ++i) {
					for (j = 0; j < width; j++) {

						*(fb++) = *(bmap++);
						*(fb++) = *(bmap++);
						*(fb++) = *(bmap++);
					}
					bmap += (padded_line - width) * 3;
					fb   += (lcd_line_length - width * 3);
				}
			}
			break;
		case 32:
			for (i = 0; i < height; ++i) {
				for (j = 0; j < width; j++) {

					*(fb++) = *(bmap++);
					*(fb++) = *(bmap++);
					*(fb++) = *(bmap++);
					*(fb++) = *(bmap++);
				}
				bmap += (padded_line - width) * 4;
				fb   += (lcd_line_length - width * 4);
			}
			break;
		default:
			osd_loge("error: gdev.bpp %d, but raw.bpp %d\n", fb_gdev.gdfBytesPP, bmp_bpix);
			return (-1);
		}
	}
	flush_cache((unsigned long)info->vd_base,
		    pheight * pwidth * info->vl_bpix / 8);
	return (0);
}

#ifdef CONFIG_OSD_SCALE_ENABLE
int video_scale_bitmap(void)
{
	char *layer_str = NULL;
	int osd_index = -1;
	int axis[4] = {};
#ifdef CONFIG_AML_MESON_G12A
	struct pandata_s disp_data;
#endif

	osd_logd2("video_scale_bitmap src w=%d, h=%d, dst w=%d, dst h=%d\n",
		fb_gdev.fb_width, fb_gdev.fb_height, fb_gdev.winSizeX, fb_gdev.winSizeY);

	vout_get_current_axis(axis);
	layer_str = getenv("display_layer");
	if (strcmp(layer_str, "osd0") == 0)
		osd_index = OSD1;
	else if (strcmp(layer_str, "osd1") == 0)
		osd_index = OSD2;
	else if (strcmp(layer_str, "viu2_osd0") == 0) {
		osd_index = VIU2_OSD1;
		goto no_scale;
	} else {
		osd_logd2("video_scale_bitmap: invalid display_layer\n");
		return (-1);
	}

#ifdef CONFIG_OSD_SUPERSCALE_ENABLE
	if ((fb_gdev.fb_width * 2 != fb_gdev.winSizeX) ||
	    (fb_gdev.fb_height * 2 != fb_gdev.winSizeY)) {
		osd_enable_hw(osd_index, 1);
		return (-1);
	}
	osd_set_free_scale_mode_hw(osd_index, 2);
#else
	osd_set_free_scale_mode_hw(osd_index, 1);
#endif
	osd_set_free_scale_axis_hw(osd_index, 0, 0, fb_gdev.fb_width - 1,
				   fb_gdev.fb_height - 1);
	osd_set_window_axis_hw(osd_index, axis[0], axis[1], axis[0] + axis[2] - 1,
			       axis[1] + axis[3] - 1);
	osd_set_free_scale_enable_hw(osd_index, 0x10001);

no_scale:
#ifdef CONFIG_AML_MESON_G12A
	disp_data.x_start = axis[0];
	disp_data.y_start = axis[1];
	disp_data.x_end = axis[0] + axis[2] - 1;
	disp_data.y_end = axis[1] + axis[3] - 1;
	if (osd_hw.osd_ver == OSD_HIGH_ONE && osd_index < VIU2_OSD1)
		osd_update_blend(&disp_data);
#endif

	osd_enable_hw(osd_index, 1);

	return (1);
}
#endif

/*
MIDDLE_MODE,RECT_MODE:
	fixed framebuffer size get from uboot env.
	bmp_image can be 0.
FULL_SCREEN_MODE:
	usd bmp size as framebuffer size;
	 must set bmp_image;
*/
void img_mode_set(u32 display_mode)
{
	fb_gdev.mode = display_mode;
}

void img_addr_set(ulong pic_image)
{
	g_pic_info.pic_image = pic_image;
}

void img_type_set(u32 type)
{
	g_pic_info.type = type;
}

void img_raw_size_set(u32 raw_width, u32 raw_height, u32 raw_bpp)
{
		g_pic_info.pic_width = raw_width;
		g_pic_info.pic_height = raw_height;
		g_pic_info.bpp = raw_bpp;
}

static int img_raw_init(void)
{
	unsigned int display_mode;

	if (img_video_init)
		return 0;

	display_mode = fb_gdev.mode;
#if 0
	if (display_mode == FULL_SCREEN_MODE) {
		g_pic_info.pic_width = env_strtoul("pic_width", 10);
		g_pic_info.pic_height = env_strtoul("pic_height", 10);
		g_pic_info.bpp = env_strtoul("pic_bpp", 10);
	}
#endif
	if (NULL == video_hw_init(display_mode)) {
		printf("Initialize video device failed!\n");
		return -1;
	}
	osd_logd2("raw_width=%d, raw_height=%d, raw_bpp=%d\n", g_pic_info.pic_width, g_pic_info.pic_height, g_pic_info.bpp);
	img_video_init = 1;
	return 0;
}

static int img_bmp_init(void)
{
	unsigned int display_mode;

	if (img_video_init)
		return 0;
	display_mode = fb_gdev.mode;
	if (display_mode == FULL_SCREEN_MODE) {
		if (g_pic_info.pic_image != 0)
			if (parse_bmp_info(g_pic_info.pic_image))
				return -1;
	}
	if (NULL == video_hw_init(display_mode)) {
		printf("Initialize video device failed!\n");
		return -1;
	}
	img_video_init = 1;
	return 0;
}

int img_osd_init(void)
{
	int ret = -1;

	if (g_pic_info.type == BMP_PIC)
		ret = img_bmp_init();
	else if(g_pic_info.type == RAW_PIC)
		ret = img_raw_init();
	return ret;
}

int img_bmp_display(ulong bmp_image, int x, int y)
{
	return video_display_bitmap(bmp_image, x, y);
}

int img_raw_display(ulong raw_image, int x, int y)
{
	return video_display_raw(raw_image, x, y);
}

int img_display(ulong bmp_image, int x, int y)
{
	int ret = -1;
	if (g_pic_info.type == BMP_PIC)
		ret = img_bmp_display(bmp_image, x, y);
	else if(g_pic_info.type == RAW_PIC)
		ret = img_raw_display(bmp_image, x, y);
	return ret;
}

int img_scale(void)
{
	int ret = -1;

	if (!img_video_init) {
		printf("fastboot osd not enabled!\n");
	}
#ifdef CONFIG_OSD_SCALE_ENABLE
	ret = video_scale_bitmap();
#endif
	return ret;
}

int img_osd_clear(void)
{
	if (!img_video_init) {
		printf("Please enable osd device first!\n");
		return 1;
	}

#ifdef CONFIG_OSD_SCALE_ENABLE
	memset((void *)(long long)(fb_gdev.frameAdrs), 0,
	       (fb_gdev.fb_width * fb_gdev.fb_height)*fb_gdev.gdfBytesPP);

	flush_cache(fb_gdev.frameAdrs,
		    ((fb_gdev.fb_width * fb_gdev.fb_height)*fb_gdev.gdfBytesPP));
#else
	memset((void *)(long long)(fb_gdev.frameAdrs), 0,
	       (fb_gdev.winSizeX * fb_gdev.winSizeY)*fb_gdev.gdfBytesPP);

	flush_cache(fb_gdev.frameAdrs,
		    ((fb_gdev.winSizeX * fb_gdev.winSizeY)*fb_gdev.gdfBytesPP));
#endif
	return 0;
}

void img_osd_uninit(void)
{
	img_video_init = 0;
}

static int _osd_hw_init(void)
{
	u32 fb_addr = 0;
	u32 display_width = 0;
	u32 display_height = 0;
	u32 display_bpp = 0;
	u32 color_index = 0;
	u32 fg = 0;
	u32 bg = 0;
	u32 fb_width = 0;
	u32 fb_height = 0;;

	get_osd_version();

	vout_init();
	fb_addr = get_fb_addr();
#ifdef CONFIG_OSD_SCALE_ENABLE
	fb_width = env_strtoul("fb_width", 10);
	fb_height = env_strtoul("fb_height", 10);
#endif
	display_width = env_strtoul("display_width", 10);
	display_height = env_strtoul("display_height", 10);
	display_bpp = env_strtoul("display_bpp", 10);
	color_index = env_strtoul("display_color_index", 10);
	fg = env_strtoul("display_color_fg", 10);
	bg = env_strtoul("display_color_bg", 10);

	/* fill in Graphic Device */
	fb_gdev.frameAdrs = fb_addr;
	fb_gdev.fb_width = fb_width;
	fb_gdev.fb_height = fb_height;
	fb_gdev.winSizeX = display_width;
	fb_gdev.winSizeY = display_height;
	fb_gdev.gdfBytesPP = display_bpp / 8;
	fb_gdev.fg = fg;
	fb_gdev.bg = bg;
	if ((color_index < ARRAY_SIZE(default_color_format_array))
	    && (default_color_format_array[color_index].color_index !=
		COLOR_INDEX_NULL))
		fb_gdev.gdfIndex = color_index;
	else {
		osd_loge("color_index %d invalid\n", color_index);
		return -1;
	}
	return 0;
}

static int osd_hw_init_by_index(u32 osd_index)
{
	if (_osd_hw_init() < 0)
		return -1;
	if (osd_index == OSD1)
		osd_layer_init(&fb_gdev, OSD1);
	else if ( osd_index == OSD2) {
		if (osd_hw.osd_ver == OSD_SIMPLE) {
			osd_loge("AXG not support osd2\n");
			return -1;
		}
		osd_layer_init(&fb_gdev, OSD2);
	}
	else {
		osd_loge("display_layer(%d) invalid\n", osd_index);
		return -1;
	}

	return 0;
}





static int video_display_osd(u32 osd_index)
{
	struct vinfo_s *info = NULL;
#if defined CONFIG_AML_VOUT
	info = vout_get_current_vinfo();
#endif
	ushort i, j;
	uchar *fb;
	unsigned long width, height;
#ifdef CONFIG_OSD_SCALE_ENABLE
	unsigned long pheight = fb_gdev.fb_height;
	unsigned long pwidth = fb_gdev.fb_width;
#else
	unsigned long pheight = info->width;
	unsigned long pwidth = info->height;
#endif
	int bpp;

	if (fb_gdev.gdfBytesPP != 2) {
		osd_loge("%d bit/pixel mode1, not support now\n",
			fb_gdev.gdfBytesPP);
		return -1;
	}
	bpp = fb_gdev.gdfBytesPP;
	width = fb_gdev.fb_width;
	height = fb_gdev.fb_height;
	osd_set_free_scale_enable_hw(osd_index, 0x0);  // disable free_scale
	osd_enable_hw(osd_index, 1);

	fb   = (uchar *)(info->vd_base);
	osd_logd("fb=0x%p; width=%ld, height= %ld, bpp=%d\n",
		 fb, width, height, bpp);

	for (j = 0; j < height; j++) {
		for (i = 0; i < width; i++ ) {
			*(fb++) = 0x0;
			*(fb++) = 0xf8;
		}
	}

	flush_cache((unsigned long)info->vd_base, pheight * pwidth * bpp);

	return (0);
}

u32 hist_max_min[3][100], hist_spl_val[3][100],
	hist_spl_pix_cnt[3][100], hist_cheoma_sum[3][100];

void hist_set_golden_data(void)
{
	u32 i = 0;
	u32 family_id = get_cpu_id().family_id;
	char *str = NULL;
	char *hist_env_key[12] =
			{"hist_max_min_osd0","hist_spl_val_osd0","hist_spl_pix_cnt_osd0","hist_cheoma_sum_osd0",
			"hist_max_min_osd1","hist_spl_val_osd1","hist_spl_pix_cnt_osd1","hist_cheoma_sum_osd1",
			"hist_max_min_osd2","hist_spl_val_osd2","hist_spl_pix_cnt_osd2","hist_cheoma_sum_osd2"};
	// GXL
	hist_max_min[OSD1][MESON_CPU_MAJOR_ID_GXL] = 0x3d3d;
	hist_spl_val[OSD1][MESON_CPU_MAJOR_ID_GXL] = 0xc4dad1;
	hist_spl_pix_cnt[OSD1][MESON_CPU_MAJOR_ID_GXL] = 0x33a25;
	hist_cheoma_sum[OSD1][MESON_CPU_MAJOR_ID_GXL] = 0xd4fd8a;

	hist_max_min[OSD2][MESON_CPU_MAJOR_ID_GXL] = 0x4f4f;
	hist_spl_val[OSD2][MESON_CPU_MAJOR_ID_GXL] = 0xfef16b;
	hist_spl_pix_cnt[OSD2][MESON_CPU_MAJOR_ID_GXL] = 0x33a25;
	hist_cheoma_sum[OSD2][MESON_CPU_MAJOR_ID_GXL] = 0xe85a68;

	// TXL
	hist_max_min[OSD1][MESON_CPU_MAJOR_ID_TXL] = 0x3d3d;
	hist_spl_val[OSD1][MESON_CPU_MAJOR_ID_TXL] = 0x78a1400;
	hist_spl_pix_cnt[OSD1][MESON_CPU_MAJOR_ID_TXL] = 0x1fa400;
	hist_cheoma_sum[OSD1][MESON_CPU_MAJOR_ID_TXL] = 0x8284800;

	hist_max_min[OSD2][MESON_CPU_MAJOR_ID_TXL] = 0x4f4f;
	hist_spl_val[OSD2][MESON_CPU_MAJOR_ID_TXL] = 0x9c39c00;
	hist_spl_pix_cnt[OSD2][MESON_CPU_MAJOR_ID_TXL] = 0x1fa400;
	hist_cheoma_sum[OSD2][MESON_CPU_MAJOR_ID_TXL] = 0x8e62000;

	// G12A
	hist_max_min[OSD1][MESON_CPU_MAJOR_ID_G12A]
						= hist_max_min[OSD2][MESON_CPU_MAJOR_ID_G12A]
						= 0x3d3d;
	hist_spl_val[OSD1][MESON_CPU_MAJOR_ID_G12A]
						= hist_spl_val[OSD2][MESON_CPU_MAJOR_ID_G12A]
						= 0xc4dcf6;
	hist_spl_pix_cnt[OSD1][MESON_CPU_MAJOR_ID_G12A]
						= hist_spl_pix_cnt[OSD2][MESON_CPU_MAJOR_ID_G12A]
						= 0x33a2e;
	hist_cheoma_sum[OSD1][MESON_CPU_MAJOR_ID_G12A]
						= hist_cheoma_sum[OSD2][MESON_CPU_MAJOR_ID_G12A]
						= 0xd4ffdc;

	for (i = 0; i < 12; i++) {
		str = getenv(hist_env_key[i]);
		if (str) {
			switch (i%4) {
				case 0:
					hist_max_min[i/4][family_id] = env_strtoul(str, 16);
					break;
				case 1:
					hist_spl_val[i/4][family_id] = env_strtoul(str, 16);
					break;
				case 2:
					hist_spl_pix_cnt[i/4][family_id] = env_strtoul(str, 16);
					break;
				case 3:
					hist_cheoma_sum[i/4][family_id] = env_strtoul(str, 16);
					break;
			}
		}
	}
}

int osd_rma_test(u32 osd_index)
{
	u32 i = osd_index, osd_max = 1;
	u32 hist_result[4];
	u32 family_id = get_cpu_id().family_id;

	if (osd_hw.osd_ver == OSD_SIMPLE) {
		osd_max = 0;
	} else if (osd_hw.osd_ver == OSD_HIGH_ONE) {
		osd_max = 1; // osd3 not supported now
	}
	if (osd_index > osd_max) {
		osd_loge("=== osd%d is not supported, osd_max is %d ===\n", osd_index, osd_max);
		return (-1);
	}

	hist_set_golden_data();
	osd_logi("=== osd_rma_test for osd%d ===\n", i);
	osd_hw_init_by_index(i);
	if (-1 == video_display_osd(i)) {
		return (-1);
	}
	osd_hist_enable(osd_index);
	_udelay(50000);
	osd_get_hist_stat(hist_result);
	_udelay(50000);
	osd_get_hist_stat(hist_result);

	if ((hist_result[0] == hist_max_min[osd_index][family_id]) && (hist_result[1] == hist_spl_val[osd_index][family_id]) &&
	    (hist_result[2] == hist_spl_pix_cnt[osd_index][family_id]) && (hist_result[3] == hist_cheoma_sum[osd_index][family_id])) {
			osd_logi("=== osd%d, osd_rma_test pass. ===\n", osd_index);
			return (0);
	} else {
			osd_loge("osd hist stat result:0x%x, 0x%x, 0x%x, 0x%x\n",
					hist_result[0], hist_result[1], hist_result[2], hist_result[3]);
			osd_loge("osd hist golden data:0x%x, 0x%x, 0x%x, 0x%x\n",
					hist_max_min[osd_index][family_id], hist_spl_val[osd_index][family_id],
					hist_spl_pix_cnt[osd_index][family_id], hist_cheoma_sum[osd_index][family_id]);
			osd_loge("=== osd%d, osd_rma_test failed. ===\n", osd_index);
			return (-1);
	}
}
