summaryrefslogtreecommitdiff
path: root/common/wmt_display
diff options
context:
space:
mode:
authorKevin2014-11-15 11:48:36 +0800
committerKevin2014-11-15 11:48:36 +0800
commitd04075478d378d9e15f3e1abfd14b0bd124077d4 (patch)
tree733dd964582f388b9e3e367c249946cd32a2851f /common/wmt_display
downloadFOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.tar.gz
FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.tar.bz2
FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.zip
init commit via android 4.4 uboot
Diffstat (limited to 'common/wmt_display')
-rwxr-xr-xcommon/wmt_display/animation/charge_animation.c1262
-rwxr-xr-xcommon/wmt_display/cmd_mbit.c107
-rwxr-xr-xcommon/wmt_display/cmd_textout.c161
-rwxr-xr-xcommon/wmt_display/com-fb.h143
-rwxr-xr-xcommon/wmt_display/com-video.h103
-rwxr-xr-xcommon/wmt_display/com-vpp.h455
-rwxr-xr-xcommon/wmt_display/devices/cs8556.c400
-rwxr-xr-xcommon/wmt_display/devices/lcd-AUO-A080SN01.c95
-rwxr-xr-xcommon/wmt_display/devices/lcd-CHILIN-LW700at9003.c104
-rwxr-xr-xcommon/wmt_display/devices/lcd-EKING-EK08009-70135.c103
-rwxr-xr-xcommon/wmt_display/devices/lcd-HANNSTAR-HSD101PFW2.c103
-rwxr-xr-xcommon/wmt_display/devices/lcd-INNOLUX-AT070TN83.c118
-rwxr-xr-xcommon/wmt_display/devices/lcd-lvds-1024x600.c94
-rwxr-xr-xcommon/wmt_display/devices/lcd-mipi-ssd2828.c375
-rwxr-xr-xcommon/wmt_display/devices/lcd-oem.c408
-rwxr-xr-xcommon/wmt_display/devices/lcd-setup.c212
-rwxr-xr-xcommon/wmt_display/devices/lcd.c448
-rwxr-xr-xcommon/wmt_display/devices/sil902x.c74
-rwxr-xr-xcommon/wmt_display/devices/sil902x.h71
-rwxr-xr-xcommon/wmt_display/devices/ts8224b.h446
-rwxr-xr-xcommon/wmt_display/devices/vt1625.c949
-rwxr-xr-xcommon/wmt_display/devices/vt1632.c157
-rwxr-xr-xcommon/wmt_display/display_aligment.S482
-rwxr-xr-xcommon/wmt_display/edid.h168
-rwxr-xr-xcommon/wmt_display/env_parse.c398
-rwxr-xr-xcommon/wmt_display/govrh.c1932
-rwxr-xr-xcommon/wmt_display/govrh.h184
-rwxr-xr-xcommon/wmt_display/hdmi.c1457
-rwxr-xr-xcommon/wmt_display/hdmi.h352
-rwxr-xr-xcommon/wmt_display/hw/wmt-govrh-reg.h366
-rwxr-xr-xcommon/wmt_display/hw/wmt-hdmi-reg.h379
-rwxr-xr-xcommon/wmt_display/hw/wmt-lvds-reg.h129
-rwxr-xr-xcommon/wmt_display/hw/wmt-ost.h37
-rwxr-xr-xcommon/wmt_display/hw/wmt-pwm.h110
-rwxr-xr-xcommon/wmt_display/hw/wmt-scl-reg.h543
-rwxr-xr-xcommon/wmt_display/hw/wmt-vpp-hw.h137
-rwxr-xr-xcommon/wmt_display/hw/wmt-vpp-reg.h132
-rwxr-xr-xcommon/wmt_display/hw/wmt_gpio.h791
-rwxr-xr-xcommon/wmt_display/hw/wmt_i2c.h316
-rwxr-xr-xcommon/wmt_display/hw/wmt_mmap.h190
-rwxr-xr-xcommon/wmt_display/hw_devices.h38
-rwxr-xr-xcommon/wmt_display/lcd.h105
-rwxr-xr-xcommon/wmt_display/lvds.c202
-rwxr-xr-xcommon/wmt_display/lvds.h73
-rwxr-xr-xcommon/wmt_display/minivgui.c1949
-rwxr-xr-xcommon/wmt_display/minivgui.h116
-rwxr-xr-xcommon/wmt_display/parse-edid.c1069
-rwxr-xr-xcommon/wmt_display/pwm.c306
-rwxr-xr-xcommon/wmt_display/scl.c1556
-rwxr-xr-xcommon/wmt_display/scl.h128
-rwxr-xr-xcommon/wmt_display/sw_i2c.c436
-rwxr-xr-xcommon/wmt_display/sw_i2c.h63
-rwxr-xr-xcommon/wmt_display/uboot-vpp.c298
-rwxr-xr-xcommon/wmt_display/vout-wmt.c1344
-rwxr-xr-xcommon/wmt_display/vout.c941
-rwxr-xr-xcommon/wmt_display/vout.h391
-rwxr-xr-xcommon/wmt_display/vpp-osif.c912
-rwxr-xr-xcommon/wmt_display/vpp-osif.h266
-rwxr-xr-xcommon/wmt_display/vpp.c1413
-rwxr-xr-xcommon/wmt_display/vpp.h679
-rwxr-xr-xcommon/wmt_display/wmt-ost.c107
-rwxr-xr-xcommon/wmt_display/wmt_cmd_display.c357
-rwxr-xr-xcommon/wmt_display/wmt_display.h170
63 files changed, 27410 insertions, 0 deletions
diff --git a/common/wmt_display/animation/charge_animation.c b/common/wmt_display/animation/charge_animation.c
new file mode 100755
index 0000000..7728002
--- /dev/null
+++ b/common/wmt_display/animation/charge_animation.c
@@ -0,0 +1,1262 @@
+/*******************************************************************************
+* Copyright (c) 2013 WonderMedia Technologies, Inc.
+*
+* Abstract:
+* This program is designed to show the charge animation
+*
+******************************Release History ***********************************
+*
+* Version 1.0 , HowayHuo, 2013/5/8
+* First version: Created by Howayhuo
+*
+**********************************************************************************/
+#include <common.h>
+#include <command.h>
+#include <asm/arch/common_def.h>
+#include <asm/byteorder.h>
+#include <bmp_layout.h>
+#include "../../../board/wmt/include/wmt_pmc.h"
+#include "../../../board/wmt/wmt_battery/wmt_battery.h"
+#include "../minivgui.h"
+#include "../wmt_display.h"
+
+#define HSP3_STATUS (0xD8130000 + 0x3C)
+#define REBOOT_BIT 0x10
+
+#define POWERUP_SOURCE_STATUS (0xD8130000 + 0xD0)
+#define PWRBTN_BIT 0x01
+#define VBAT_RISING_BIT 0x02
+#define DCDET_RISING_BIT 0x04
+#define DCDET_FALLING_BIT 0x08
+#define DCDET_BIT 0x10
+
+#define ENV_MPTOOL_DETECT "wmt.mptool.detect"
+#define ENV_MPTOOL_TIMEOUT "wmt.mptool.timeout"
+#define ENV_USBPC_TIMEOUT "wmt.usbpc.timeout"
+
+static unsigned char *sp_mem_addr = (unsigned char *)0x3000000;
+
+static int s_usb_to_pc;
+static int s_pwm_duty_decreased;
+static int s_battery_init_ok = -1;
+static int s_animation_init_ok = -1;
+static int s_lcd_first_light = 1;
+
+/*
+s_step_by_step_light value:
+1: the backlight is light step by setp.
+0: the backlight is light right now
+*/
+static int s_step_by_step_light = 1;
+
+extern int g_tf_boot;
+
+//extern char* CMD_LOAD_SCRIPT;
+extern int g_show_logo;
+extern int udc_fastboot_init(void);
+extern void udc_fastboot_transfer(void);
+extern void udc_fastboot_exit(void);
+extern int wmt_udc_connected(void);
+extern int udc_fastboot_is_init(void);
+extern void do_wmt_poweroff(void);
+extern int wmt_mptool_ready(void);
+extern int usb_plugin(void);
+extern void run_fastboot(int backlight_on);
+
+extern struct nand_chip *get_current_nand_chip(void);
+extern int WMTAccessNandEarier(unsigned long long naddr, unsigned int maddr,
+ unsigned int size, int write);
+
+extern unsigned int pwm_get_enable(int no);
+extern void lcd_blt_enable(int no, int enable);
+extern void lcd_set_power_down(int enable);
+//extern void hint_battery_checking(void);
+
+static int sleep_sec(int sec)
+{
+ ulong start = get_timer(0);
+ ulong delay;
+
+ delay = sec * CFG_HZ;
+
+ while (get_timer(start) < delay) {
+ if (ctrlc ()) {
+ return (-1);
+ }
+ udelay (100);
+ }
+
+ return 0;
+}
+
+//return level ( 0 ~ 5 ), level < 0 is error
+static int get_battery_level(int *p_percent)
+{
+ int capacity, level = 0;
+
+ if (wmt_battery_is_charging_full() == 1) {
+ printf("power is full\n");
+ capacity = 100;
+ } else
+ capacity = wmt_battery_get_capacity();
+
+ *p_percent = capacity;
+
+ if (capacity >= 0 && capacity <= 100)
+ level = capacity / 20;
+
+ return level;
+}
+
+static void decrease_pwm_duty(int duty_percent)
+{
+ int duty;
+
+ if(!(g_display_vaild & DISPLAY_ENABLE))
+ return;
+
+ //if(s_pwm_duty_decreased == 1)
+ // return;
+
+ if (g_display_param.vout == VPP_VOUT_LCD) {
+ if ((g_display_vaild & PWMDEFMASK) == PWMDEFTP) {
+ if(duty_percent <= g_pwm_setting.duty) {
+ lcd_blt_set_pwm(g_pwm_setting.pwm_no,
+ duty_percent, g_pwm_setting.period);
+
+ s_pwm_duty_decreased = 1;
+
+ mdelay(10);
+ }
+ } else {
+ duty = (duty_percent * g_pwm_setting.period) / 100;
+ if(duty <= g_pwm_setting.duty) {
+ pwm_set_duty(g_pwm_setting.pwm_no, duty - 1);
+
+ s_pwm_duty_decreased = 1;
+
+ mdelay(10);
+ }
+ }
+ }
+}
+
+static void restore_pwm_duty(void)
+{
+ if(s_pwm_duty_decreased == 0)
+ return;
+
+ if(!(g_display_vaild & DISPLAY_ENABLE))
+ return;
+
+ if (g_display_param.vout == VPP_VOUT_LCD) {
+ if ((g_display_vaild & PWMDEFMASK) == PWMDEFTP) {
+ lcd_blt_set_pwm(g_pwm_setting.pwm_no,
+ g_pwm_setting.duty, g_pwm_setting.period);
+ } else {
+ pwm_set_duty(g_pwm_setting.pwm_no,
+ g_pwm_setting.duty - 1);
+ }
+ }
+
+ s_pwm_duty_decreased = 0;
+}
+
+static void set_lcd_backlight(int on)
+{
+ int duty, i = 0;
+ int charger_type;
+
+ if(on) {
+ charger_type = wmt_charger_cable_type();
+ if((charger_type == CABLE_TYPE_USB) && s_usb_to_pc && !wmt_charger_pc_charging()) {
+ if(wmt_battery_is_lowlevel() > 0)
+ decrease_pwm_duty(30);
+ else
+ restore_pwm_duty();
+ }
+
+ if(s_lcd_first_light) {
+ if(!(REG32_VAL(HSP3_STATUS) & REBOOT_BIT)
+ && !wmt_is_dc_plugin()
+ && !(REG8_VAL(POWERUP_SOURCE_STATUS) & PWRBTN_BIT)) {
+ printf("Adapter is removed when open lcd backlight.\nPower off\n");
+ do_wmt_poweroff();
+ }
+ s_lcd_first_light = 0;
+ }
+
+ if(s_step_by_step_light) {
+ decrease_pwm_duty(30);
+ duty = 30;
+ lcd_blt_enable(g_pwm_setting.pwm_no, 1);
+ while(duty < g_pwm_setting.duty) {
+ mdelay(20);
+ duty = 40 + 5 * i;
+ i++;
+ decrease_pwm_duty(duty);
+ }
+ } else
+ lcd_blt_enable(g_pwm_setting.pwm_no, 1);
+ } else
+ lcd_blt_enable(g_pwm_setting.pwm_no, 0);
+}
+
+static void low_battery_picture_show(void)
+{
+ //clear_charge_percent(sp_mem_addr);
+ mv_clearFB();
+ show_charge_picture(sp_mem_addr, 6);
+}
+
+static void update_current_battery_picture(void)
+{
+ int index, percent;
+
+ if(wmt_battery_is_lowlevel() > 0)
+ low_battery_picture_show();
+ else {
+ index = get_battery_level(&percent);
+ if(index >= 0) {
+ display_charge_percent(sp_mem_addr, percent);
+ show_charge_picture(sp_mem_addr, index);
+ }
+ }
+}
+
+static int charge_animation_init(void)
+{
+ int ret;
+ unsigned int nand_addr;
+ char *s, *s_logosize_uboot, *s_logosize_charge;
+ unsigned int logo_size, total_size;
+
+ //printf("charging animation init\n");
+
+ if(s_animation_init_ok == 0)
+ return -1;
+ else if(s_animation_init_ok == 1)
+ return 0;
+
+ if(!g_tf_boot) {
+ //1: check nand flash env
+ s = getenv("wmt.nfc.mtd.u-boot-logo");
+ if(s == NULL) {
+ printf("wmt.nfc.mtd.u-boot-logo isn't set\n");
+ s_animation_init_ok = 0;
+ return -1;
+ } else {
+ nand_addr = simple_strtoul (s, NULL, 16);
+
+ total_size = 0;
+ s_logosize_uboot = getenv("wmt.logosize.uboot");
+ if(s_logosize_uboot) {
+ s_logosize_charge = getenv("wmt.logosize.charge");
+ if(s_logosize_charge)
+ total_size = simple_strtoul(s_logosize_uboot, NULL, 0)
+ + simple_strtoul(s_logosize_charge, NULL, 0);
+ }
+
+ if(total_size == 0)
+ total_size = 0x380000;
+
+ printf("anim init: nand_addr = 0x%x, mem_addr = 0x%x, read_size = 0x%x\n",
+ nand_addr, (unsigned int)sp_mem_addr, total_size);
+
+ REG32_VAL(GPIO_BASE_ADDR + 0x200) &= ~(1 << 11); //PIN_SHARE_SDMMC1_NAND
+ ret = WMTAccessNandEarier(nand_addr, (unsigned int)sp_mem_addr, total_size, 0);
+ if(ret) {
+ printf("load charge-anim fail\n");
+ s_animation_init_ok = 0;
+ return -1;
+ }
+ }
+
+ //2: check bmp header
+ if(*sp_mem_addr != 'B') {
+ printf("logo isn't BMP format\n");
+ s_animation_init_ok = 0;
+ return -1;
+ }
+
+ logo_size = (*(unsigned short *)(sp_mem_addr + 4) << 16) + (*(unsigned short *)(sp_mem_addr + 2));
+
+ if(*(sp_mem_addr + logo_size) != 'B') {
+ printf("charge-anim isn't BMP format\n");
+ s_animation_init_ok = 0;
+ return -1;
+ }
+ } else {
+ ret = run_command("mmcinit 1", 0);
+ if(ret == -1) {
+ printf("TF: run \"mmcinit 1\" failed\n");
+ s_animation_init_ok = 0;
+ return -1;
+ } else {
+ char tmp[100] = {0};
+ sprintf(tmp, "fatload mmc 1 0x%x charge-logo.bmp", (unsigned int)sp_mem_addr);
+ ret = run_command(tmp, 0);
+ if(ret == -1) {
+ printf("TF: fatload charge-logo.bmp failed\n");
+ s_animation_init_ok = 0;
+ return -1;
+ }
+ }
+
+ if(*sp_mem_addr != 'B') {
+ printf("TF: charge-anim isn't BMP format\n");
+ s_animation_init_ok = 0;
+ return -1;
+ }
+ }
+
+ s_animation_init_ok = 1;
+
+ printf("load charge-animation ok\n");
+
+ return 0;
+}
+
+/*
+static int need_battery_adjust(void)
+{
+ char *s;
+
+ s = getenv("wmt.battery.adjust");
+ if((s != NULL) && !strcmp(s, "0")) {
+ return 0;
+ }
+
+ return 1;
+
+}
+*/
+
+static int battery_init(void)
+{
+ int ret;
+
+ if(s_battery_init_ok == 0)
+ return -1;
+ else if(s_battery_init_ok == 1)
+ return 0;
+
+ ret = wmt_power_supply_init();
+ if(ret) {
+ printf("battery init error\n");
+ s_battery_init_ok = 0;
+ return -1;
+ }
+
+ s_battery_init_ok = 1;
+
+ return 0;
+}
+
+int low_power_detect(void)
+{
+ int ret;
+ int delay;
+
+ if(wmt_is_dc_plugin())
+ return 0;
+
+ ret = battery_init();
+ if(ret) {
+ printf("battery init error. Skip Low power detect\n");
+ return -1;
+ }
+
+ printf("check whether low power or not\n");
+
+ ret = wmt_battery_is_lowlevel();
+ if(ret < 0) {
+ printf("check battery low failed\n");
+ return -1;
+ } else if(ret == 0) {
+ //printf("battery power enough\n");
+ return 0;
+ } else {
+ printf("low power detected\n");
+ }
+
+ if(wmt_battery_is_gauge() == 1)
+ delay = 3;
+ else
+ delay = 60;
+
+ while(delay) {
+ if(delay % 10 == 0) {
+ if (tstc()) {
+ if (getc() == 0xd) {
+ printf("Got 'Enter' key. Cancel Low power detect\n");
+ g_show_logo = 1;
+ return 0;
+ }
+ }
+ }
+
+ if(wmt_is_dc_plugin()) {
+ printf("Detected adapter plugin. Cancel Low power detect\n");
+ break;
+ }
+
+ mdelay(50);
+
+ ret = wmt_battery_is_lowlevel();
+ if(ret < 0) {
+ restore_pwm_duty();
+ printf("check battery low failed\n");
+ break;
+ } else if(ret == 0) {
+ restore_pwm_duty();
+ printf("battery power enough\n");
+ break;
+ }
+
+ delay--;
+ }
+
+ //printf("low power detect complete\n");
+
+ //display low power picture
+ if(delay == 0) {
+ if (!(g_display_vaild & DISPLAY_ENABLE)) {
+ ret = display_init(0, 0);
+ if(ret == -1) {
+ printf("Display init fail. Skip Low power detect\n");
+ return -1;
+ }
+ }
+ charge_animation_init();
+ low_battery_picture_show();
+ decrease_pwm_duty(30);
+ set_lcd_backlight(1);
+
+ delay = 500;
+ while(delay) {
+ if(delay % 100 == 0) {
+ if (tstc()) {
+ if (getc() == 0xd) {
+ printf("Got 'Enter' key. Cancel Low power picture display\n");
+ g_show_logo = 1;
+ return 0;
+ }
+ }
+ }
+
+ if(wmt_is_dc_plugin()) {
+ printf("Detected adapter plugin. Cancel Low power picture display\n");
+ return 0;
+ }
+
+ mdelay(10);
+ delay--;
+ }
+
+ set_lcd_backlight(0);
+ lcd_set_power_down(1);
+ mdelay(500); //delay for avoiding lcd blink
+ printf("----> low power. power off\n");
+ do_wmt_poweroff();
+ }
+
+ return 0;
+}
+
+#define TIMEOUT_USBPC_CHECK 400 // 400 ms
+#define TIMEOUT_MPTOOL_CHECK 3000 // 3 s
+
+/*
+* Function: check_udc_to_pc
+*
+* Return:
+* 1: usb device connect to pc
+* 0: udc device doesn't connect to pc
+* <0: error
+*/
+int check_udc_to_pc(int force)
+{
+ int ret, delay_check_connected;
+ static int udc_had_check;
+ static int check_result;
+ unsigned int timeout;
+ char *s;
+
+ if(force)
+ udc_had_check = 0;
+
+ if(udc_had_check == 1)
+ return check_result;
+
+ udc_had_check = 1;
+
+ if(!usb_plugin()) {
+ printf("check_udc_to_pc: usb plugout\n");
+ s_usb_to_pc = 0;
+ check_result = 0;
+ return 0;
+ } else
+ printf("check_udc_to_pc: usb plugin\n");
+
+ s = getenv(ENV_USBPC_TIMEOUT);
+ if(s) {
+ timeout = simple_strtoul(s, NULL, 0);
+ printf("Manually set usbpc timeout: %u ms\n", timeout);
+ } else
+ timeout = TIMEOUT_USBPC_CHECK;
+
+ if(timeout > 300000) {
+ printf("usbpc timeout force change to 300000 ms\n");
+ timeout = 300000;
+ }
+
+ if(!udc_fastboot_is_init()) {
+ ret = udc_fastboot_init();
+ if(ret) {
+ printf("udc_fastboot_init error. check_udc_to_pc fail\n");
+ s_usb_to_pc = 0;
+ check_result = -1;
+ return -1;
+ }
+ }
+
+ delay_check_connected = 0;
+
+ while(1) {
+ udc_fastboot_transfer();
+ if(wmt_udc_connected()) {
+ printf("usb connect to pc, detect_time = %d ms\n", delay_check_connected);
+ s_usb_to_pc = 1;
+ check_result = 1;
+ return 1;
+ }
+
+ if(delay_check_connected >= timeout)
+ break;
+
+ delay_check_connected++;
+
+ if (tstc()) {
+ if(getc() == 0x0d) {
+ printf("Got 'Enter'. Cancel usbpc check. check time: %d ms\n", delay_check_connected);
+ break;
+ }
+ }
+
+ mdelay(1);
+ }
+
+ if(delay_check_connected >= timeout)
+ printf("usb doesn't connect to pc\n");
+
+ s_usb_to_pc = 0;
+ check_result = 0;
+ return 0;
+}
+
+/*
+* Function: check_mptool
+*
+* Return:
+* 1: mptool is detected
+* 0: mptool is NOT detected
+* <0: mptool checking is cancel
+*/
+int check_mptool(void)
+{
+ char *s;
+ int ret, delay_check_mptool;
+ unsigned int timeout;
+
+ if((s = getenv(ENV_MPTOOL_DETECT)) != NULL && !strcmp(s, "0"))
+ return 0;
+
+ if(s_usb_to_pc == 0)
+ return 0;
+
+ s = getenv(ENV_MPTOOL_TIMEOUT);
+ if(s) {
+ timeout = simple_strtoul(s, NULL, 0);
+ printf("Manually set mptool timeout: %u ms\n", timeout);
+ } else
+ timeout = TIMEOUT_MPTOOL_CHECK;
+
+ if(timeout > 600000) {
+ printf("mptool timeout force change to 600000 ms\n");
+ timeout = 600000;
+ }
+
+ if(!udc_fastboot_is_init()) {
+ ret = udc_fastboot_init();
+ if(ret) {
+ printf("udc_fastboot_init error. check mptool fail\n");
+ return 0;
+ }
+ }
+
+ delay_check_mptool = 0;
+
+ printf("Hint: Press 'Enter' key to Cancel MPTool detection\n");
+ while(1) {
+ udc_fastboot_transfer();
+ if(wmt_mptool_ready()) {
+ printf("MPTool is detected\n");
+ return 1;
+ }
+
+ if(delay_check_mptool >= timeout)
+ break;
+
+ delay_check_mptool++;
+
+ if (tstc()) {
+ switch(getc()) {
+ case 0x03:
+ printf("Got 'Ctrl+C'. Cancel mptool check. check time: %d ms\n", delay_check_mptool);
+ return -1;
+
+ // we think the mptool is not found when pressing 'Enter' key
+ case 0x0d:
+ printf("Got 'Enter'. Cancel mptool check. check time: %d ms\n", delay_check_mptool);
+ return 0;
+
+ default:
+ break;
+ }
+ }
+
+ mdelay(1);
+ }
+
+ if(delay_check_mptool >= timeout)
+ printf("MPTool is NOT detected\n");
+
+ return 0;
+}
+
+int set_charge_current(void)
+{
+ int ret, usb_to_pc;
+
+ ret = battery_init();
+ if(ret) {
+ printf("battery_init error. set_charge_current fail\n");
+ return -1;
+ }
+
+ if(wmt_is_dc_plugin()) {
+ if(wmt_charger_cable_type() == CABLE_TYPE_USB) {
+ usb_to_pc = check_udc_to_pc(0);
+ if(usb_to_pc == 0) {
+ printf("usb_adapter plugin. set large current charge\n");
+ wmt_charger_event_callback(POWER_EVENT_DCDET_ADAPTER);
+ } else if(usb_to_pc == 1)
+ printf("usb connect to pc. default small current charge\n");
+ else {
+ printf("check usb_to_pc fail. set large current charge");
+ wmt_charger_event_callback(POWER_EVENT_DCDET_ADAPTER);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void check_pmc_busy(void)
+{
+ while (PMCS2_VAL & 0x3F0038)
+ ;
+}
+
+static void set_arm_freq(int freq)
+{
+ auto_pll_divisor(DEV_ARM, CLK_ENABLE, 0, 0);
+ auto_pll_divisor(DEV_ARM, SET_PLLDIV, 2, freq);
+ check_pmc_busy();
+}
+
+#define PERIOD_CHECK 10 // 10 ms //how long time to check
+#define PERIOD_PLAY 250 // 250 ms //the play speed
+#define PERIOD_PAUSE 700 // 700 ms //the pause time after a play peroid complete
+#define PERIOD_DETECTADAPT 50 // 50 ms //check if the power adapter is unplug
+#define PERIOD_READBATT 1 * 1000 // 1 s //how long time to read battery
+#define PERIOD_READPWRKEY 10 // 10ms //how long time to detect power key
+#define PERIOD_LONGPRESS 500 // 500 ms //how long time is regarded as long press
+#define PERIOD_BLTIMEOUT 10 * 1000 // 10 s //how long time to close backlight
+#define PERIOD_USBDETECT 50 // 50 ms //how long time to detect usb
+#define PERIOD_GAUGE_READBATT 10 * 1000 // 10 s //how long time to read battery
+
+/*
+* play_charge_animation()
+* return:
+* 0: play charging animation success
+* 1: fail to play charging animation. need detect low power
+* <0: fail to play charging animation. needn't detect low power
+*/
+int play_charge_animation(void)
+{
+ const int max_play_count = (PERIOD_PLAY) / (PERIOD_CHECK);
+ const int max_pause_count = (PERIOD_PAUSE - PERIOD_PLAY) / (PERIOD_CHECK);
+ const int max_detectAdapter_count = (PERIOD_DETECTADAPT) / (PERIOD_CHECK);
+ int max_readBatt_count = (PERIOD_READBATT) / (PERIOD_CHECK);
+ const int max_readPwrKey_count = (PERIOD_READPWRKEY) / (PERIOD_CHECK);
+ const int max_longPress_count = (PERIOD_LONGPRESS) / (PERIOD_CHECK);
+ const int max_blTimeout_count = (PERIOD_BLTIMEOUT) / (PERIOD_CHECK);
+ const int max_usbDetect_count = (PERIOD_USBDETECT) / (PERIOD_CHECK);
+
+ int play_count; //play period
+ int pause_count; //pause time after a play period complete
+ int detectAdapter_count; //check if the adapter is unpluged
+ int readBatt_count; //how long time to read battery
+ int readPwrKey_count; //how long time to detect power key
+ int longPress_count; //how long time is regarded as long press
+ int blTimeout_count; //how long time to close backlight
+ int usbDetect_count; //how long time to detect usb
+
+ int frame_num, frame_index, start_index, backup_start_index;
+ int is_powerKey_press, backup_pwm_status;
+
+ int battery_is_full = 0, udc_is_init;
+ int ret;
+ char *s;
+ int charger_type = CABLE_TYPE_UNKNOWN;
+ int percent;
+ int delay;
+ int saved_arm_freq;
+ int full_event_sended = 0;
+ int is_charging = 1;
+ int is_usb_plugin = 0;
+ int need_check_mptool;
+ //int current_arm_freq;
+ //printf("play charging animation\n");
+
+ //1: detect "enter key"
+ if (tstc()) {
+ if (getc() == 0xd) { // "Enter" key
+ puts("Got 'Enter' key. Cancel charge animation play\n");
+ return 0;
+ }
+ }
+
+ // 2: check power source
+ if(!wmt_is_dc_plugin() && !(REG8_VAL(POWERUP_SOURCE_STATUS) & PWRBTN_BIT)) {
+ printf("Adatper is removed when init charging-animation.\nPower off\n");
+ do_wmt_poweroff();
+ }
+
+ //3: detect power key press
+ if(PMPB_VAL & BIT24) {
+ printf("Power key detected. Skip charge-anim play\n");
+ return 1;
+ }
+
+ //4: check power on by reset
+ if((REG32_VAL(HSP3_STATUS) & REBOOT_BIT) == REBOOT_BIT) {
+ printf("system Reboot. Skip charge-anim play\n");
+ return 1;
+ }
+
+ //5: check charge animation env
+ s = getenv(ENV_CHARGE_ANIMATION);
+ if((s != NULL) && !strcmp(s, "0")) //if wmt.display.chargeanim is set to 0
+ return 1;
+
+ //6: check dircect boot env
+ if(((s = getenv("wmt_sys_directboot")) != NULL && !strcmp(s, "1")) \
+ || ((s = getenv("wmt_sys_restore")) != NULL && !strcmp(s, "1")))
+ return 1;
+
+
+ //7: battery init
+ ret = battery_init();
+ if(ret) {
+ printf("battery init error. Don't play charge-anim\n");
+ return -1;
+ }
+
+ if(wmt_battery_is_gauge() == 1) {
+ printf("battery is gauge\n");
+ max_readBatt_count = (PERIOD_GAUGE_READBATT) / (PERIOD_CHECK);
+ }
+
+ //printf("REG32_VAL(PM_CTRL_BASE_ADDR + 0x00D0) = 0x%x\n", REG8_VAL(PM_CTRL_BASE_ADDR + 0xd0));
+
+ //8: lcd init. but don't open backlight
+ s = getenv("wmt.backlight.stepbystep"); //if wmt.backlight.stepbystep is set to 0
+ if((s != NULL) && !strcmp(s, "0"))
+ s_step_by_step_light = 0;
+
+ if (!(g_display_vaild & DISPLAY_ENABLE)) {
+ ret = display_init(0, 0);
+ if(ret == -1) {
+ printf("Display init fail. Don't play charge-anim\n");
+ return -1;
+ }
+ }
+ mv_clearFB();
+
+ //9: check adapter
+ charger_type = wmt_charger_cable_type();
+
+ if(wmt_is_dc_plugin()) {
+ if(charger_type == CABLE_TYPE_DC)
+ printf("AC charger plugin\n");
+ else if(charger_type == CABLE_TYPE_USB) {
+ printf("usb plugin\n");
+ } else {
+ printf("charger type error. Don't play charge-anim\n");
+ return -1;
+ }
+ } else {
+ printf("Battery power supply\n");
+ if((REG8_VAL(POWERUP_SOURCE_STATUS) & PWRBTN_BIT) == 0) {
+ printf("POWERUP_SOURCE_STATUS = 0x%x\n", REG8_VAL(POWERUP_SOURCE_STATUS));
+ printf("Adatper is removed when start play charging-animation.\nPower off\n");
+ do_wmt_poweroff();
+ }
+ low_power_detect();
+ if(!wmt_is_dc_plugin())
+ return -1;
+
+ // when using usb charge, if plugin adapter during low_power_detect, re-check udc to pc
+ if(charger_type == CABLE_TYPE_USB) {
+ printf("check if usb connect to pc\n");
+ if(!udc_fastboot_is_init()) {
+ ret = udc_fastboot_init();
+ if(ret) {
+ printf("udc_fastboot_init error. Don't play charge-anim\n");
+ return -1;
+ }
+ }
+ check_udc_to_pc(1);
+ set_charge_current();
+ if(s_usb_to_pc == 0)
+ restore_pwm_duty();
+ }
+ }
+
+ //10: charge animation init
+ ret = charge_animation_init();
+ if(ret) {
+ printf("charge-anim init fail. Don't play charge-anim\n");
+ return -1;
+ }
+
+ //11: get battery level
+ start_index = get_battery_level(&percent);
+ if(start_index < 0) {
+ printf("Battery level error(%d). Don't play charge-anim\n", start_index);
+ return -1;
+ }
+
+ printf("Hit 'Enter' key to stop animation\n");
+
+ //12: show the first charge picture
+ frame_num = 6;
+ play_count = -1;
+ pause_count = 0;
+ detectAdapter_count = 0;
+ readBatt_count = 0;
+ readPwrKey_count = 0;
+ longPress_count = -1;
+ is_powerKey_press = 0;
+ backup_pwm_status = 0;
+ blTimeout_count = 0;
+ usbDetect_count = 0;
+
+ frame_index = start_index;
+
+ init_charge_percent();
+ //display_charge_percent(sp_mem_addr, percent);
+ show_charge_picture(sp_mem_addr, frame_index);
+
+ if(start_index != frame_num - 1) //not last frame
+ frame_index++;
+
+ //13: when using usb charge, detect low power if usb connect to pc
+ if((charger_type == CABLE_TYPE_USB) && s_usb_to_pc && !wmt_charger_pc_charging()) {
+ ret = wmt_battery_is_lowlevel();
+ if(ret > 0) {
+ printf("USB connect to PC. Low power\n");
+
+ if(wmt_battery_is_gauge() == 1)
+ delay = 3;
+ else
+ delay = 60;
+
+ while(delay) {
+ if (tstc()) {
+ if (getc() == 0xd) {
+ printf("Got 'Enter' key. Cancel Low power detect during USB connect to PC\n");
+ return 0;
+ }
+ }
+
+ if(!wmt_is_dc_plugin()) {
+ low_battery_picture_show();
+ decrease_pwm_duty(30);
+ set_lcd_backlight(1);
+ sleep_sec(5);
+ set_lcd_backlight(0);
+ lcd_set_power_down(1);
+ mdelay(500); //delay for avoiding lcd blink
+ printf("----> USB connect to PC. Low power. power off\n");
+ do_wmt_poweroff();
+ }
+
+ mdelay(50);
+
+ ret = wmt_battery_is_lowlevel();
+ if(ret < 0) {
+ printf("Low power detect failed during USB connect to PC\n");
+ return -1;
+ } else if(ret == 0) {
+ printf("battery power enough during USB connect to PC\n");
+ break;
+ }
+
+ delay--;
+ }
+
+ if(delay == 0)
+ low_battery_picture_show();
+
+ } else if(ret < 0) {
+ printf("Low power detect failed during USB connect to PC\n");
+ return -1;
+ } else
+ printf("USB connect to PC. Power enough\n");
+
+ set_lcd_backlight(1);
+ } else
+ set_lcd_backlight(1);
+
+ //14: set cpu freq to 300MHz
+ saved_arm_freq = auto_pll_divisor(DEV_ARM, GET_FREQ, 0, 0);
+ //printf("save cpu freq = %d\n", saved_arm_freq);
+ set_arm_freq(300);
+ //current_arm_freq = auto_pll_divisor(DEV_ARM, GET_FREQ, 0, 0);
+ //printf("set cpu freq = %d\n", current_arm_freq);
+
+ //15: set charge current and control led
+ if (charger_type == CABLE_TYPE_DC) {
+ wmt_charger_event_callback(POWER_EVENT_DCDET_ADAPTER);
+ } else if (charger_type == CABLE_TYPE_USB) {
+ if (s_usb_to_pc == 1)
+ wmt_charger_event_callback(POWER_EVENT_DCDET_USBPC);
+ else
+ wmt_charger_event_callback(POWER_EVENT_DCDET_ADAPTER);
+ }
+
+ if(usb_plugin()) {
+ printf("usb plugin before charging\n");
+ is_usb_plugin = 1;
+ } else {
+ printf("usb plugout before charging\n");
+ is_usb_plugin = 0;
+ }
+
+ //16: check whether detect mptool or not
+ if((s = getenv(ENV_MPTOOL_DETECT)) != NULL && !strcmp(s, "0"))
+ need_check_mptool = 0;
+ else
+ need_check_mptool = 1;
+
+ //17: enter the animation loop
+ while(1) {
+ if (tstc()) {//we got a key press
+ printf("we got a key press\n");
+ //Check if the key is 'Enter' which ascii code is 13
+ // If the key is 'Enter', exit
+ if (getc() == 13)
+ break;
+ }
+
+ //check if usb connect to pc. And check mptool when usb connect to pc
+ if(need_check_mptool) {
+ if(usbDetect_count >= 0)
+ usbDetect_count++;
+
+ if(usbDetect_count > max_usbDetect_count) {
+ if(usb_plugin()) {
+ if(is_usb_plugin == 0) {
+ is_usb_plugin = 1;
+ printf("usb plugin during charging\n");
+ }
+
+ if(!udc_fastboot_is_init()) {
+ ret = udc_fastboot_init();
+ if(ret) {
+ printf("udc_fastboot_init error during playing charge-anim\n");
+ udc_is_init = 0;
+ } else
+ udc_is_init = 1;
+ } else
+ udc_is_init = 1;
+ } else {
+ if(is_usb_plugin == 1) {
+ is_usb_plugin = 0;
+ printf("usb plugout during charging\n");
+ }
+ udc_fastboot_exit();
+ udc_is_init = 0;
+ if(s_usb_to_pc) {
+ s_usb_to_pc = 0;
+ if(charger_type == CABLE_TYPE_USB && wmt_is_dc_plugin())
+ wmt_charger_event_callback(POWER_EVENT_DCDET_ADAPTER);
+ }
+ }
+
+ if(udc_is_init) {
+ udc_fastboot_transfer();
+ if(s_usb_to_pc == 0) {
+ if(wmt_udc_connected()) {
+ printf("usb connect to pc\n");
+ s_usb_to_pc = 1;
+ if(charger_type == CABLE_TYPE_USB) {
+ wmt_charger_event_callback(POWER_EVENT_DCDET_USBPC);
+ if(!wmt_charger_pc_charging())
+ update_current_battery_picture();
+ }
+ }
+ } else {
+ if(wmt_mptool_ready()) {
+ set_arm_freq(saved_arm_freq / 1000000);
+ udc_fastboot_exit();
+ run_fastboot(1);
+ break;
+ }
+ }
+ }
+
+ usbDetect_count = 0;
+ }
+ }
+
+ if((charger_type == CABLE_TYPE_USB) && s_usb_to_pc && !wmt_charger_pc_charging())
+ is_charging = 0;
+ else
+ is_charging = 1;
+
+ readBatt_count++;
+ readPwrKey_count++;
+ detectAdapter_count++;
+
+ if(longPress_count >= 0)
+ longPress_count++;
+
+ if(blTimeout_count >= 0)
+ blTimeout_count++;
+
+ if(detectAdapter_count > max_detectAdapter_count) {
+ detectAdapter_count = 0;
+ if(!wmt_is_dc_plugin()) {
+ if(is_charging) {
+ display_charge_percent(sp_mem_addr, percent);
+ show_charge_picture(sp_mem_addr, start_index);
+ }
+
+ printf("unplug power adapter\n");
+ if(!pwm_get_enable(g_pwm_setting.pwm_no)) {
+ set_lcd_backlight(1);
+ if(is_charging == 0)
+ update_current_battery_picture();
+ }
+
+ wmt_charger_event_callback(POWER_EVENT_DCDET_PLUGOUT);
+ sleep_sec(3);
+ set_lcd_backlight(0);
+ lcd_set_power_down(1);
+ mdelay(500); //delay for avoiding lcd blink
+ printf("power off\n");
+ do_wmt_poweroff();
+ }
+ }
+
+ if(readBatt_count > max_readBatt_count) {
+ readBatt_count = 0;
+ backup_start_index = start_index;
+ start_index = get_battery_level(&percent);
+
+ if (percent == 100 && is_charging) {
+ if (!full_event_sended) {
+ wmt_charger_event_callback(POWER_EVENT_CHARGING_FULL);
+ full_event_sended = 1;
+ }
+ } else
+ full_event_sended = 0;
+
+ if(start_index < 0 || start_index >= frame_num) {
+ if(is_charging) {
+ display_charge_percent(sp_mem_addr, percent);
+ show_charge_picture(sp_mem_addr, backup_start_index);
+ }
+ printf("read battery error\n");
+ if(!pwm_get_enable(g_pwm_setting.pwm_no)) {
+ set_lcd_backlight(1);
+ if(is_charging == 0)
+ update_current_battery_picture();
+ }
+
+ sleep_sec(2);
+ set_lcd_backlight(0);
+ lcd_set_power_down(1);
+ mdelay(500); //delay for avoiding lcd blink
+ printf("power off\n");
+ do_wmt_poweroff();
+ }
+
+ if(is_charging == 0)
+ update_current_battery_picture();
+ else
+ display_charge_percent(sp_mem_addr, percent);
+ }
+
+ if(blTimeout_count > max_blTimeout_count) {
+ blTimeout_count = -1;
+ if(pwm_get_enable(g_pwm_setting.pwm_no)) {
+ printf("close backlight during charging\n");
+ set_lcd_backlight(0);
+ }
+ }
+
+ if(readPwrKey_count > max_readPwrKey_count) {
+ readPwrKey_count = 0;
+ if((PMPB_VAL & BIT24) || (PMWS_VAL & BIT14)) {
+ if(PMWS_VAL & BIT14)
+ PMWS_VAL |= BIT14;
+ if(is_powerKey_press == 0) {
+ backup_pwm_status = pwm_get_enable(g_pwm_setting.pwm_no);
+ printf("press pwr key, backup_pwm_status = %d\n", backup_pwm_status);
+ if(!backup_pwm_status) {
+ set_lcd_backlight(1);
+ if(is_charging == 0)
+ update_current_battery_picture();
+ }
+
+ is_powerKey_press = 1;
+ blTimeout_count = -1;
+ longPress_count = 0;
+ }
+ } else {
+ if(is_powerKey_press == 1) {
+ printf("release pwr key, backup_pwm_status = %d\n", backup_pwm_status);
+ is_powerKey_press = 0;
+ if(backup_pwm_status) {
+ if(pwm_get_enable(g_pwm_setting.pwm_no))
+ set_lcd_backlight(0);
+ blTimeout_count = -1;
+ } else {
+ if(!pwm_get_enable(g_pwm_setting.pwm_no)) {
+ set_lcd_backlight(1);
+ if(is_charging == 0)
+ update_current_battery_picture();
+ }
+ blTimeout_count = 0;
+ }
+ }
+ longPress_count = -1;
+ }
+ }
+
+ if(longPress_count > max_longPress_count) {
+ printf("charge_animation: long press key detected\n");
+ // if is_charging = 0 and detect battery low, don't startup system
+ if(is_charging == 0 && wmt_battery_is_lowlevel() > 0) {
+ printf("USB connect to PC and low power. skip long press\n");
+ } else
+ break;
+ }
+
+ udelay(PERIOD_CHECK * 1000);
+
+ //if is_charging = 0, don't play animation
+ if(is_charging == 0)
+ continue;
+
+ if(play_count >= 0)
+ play_count++;
+
+ if(pause_count >= 0)
+ pause_count++;
+
+ if(play_count > max_play_count) {
+ show_charge_picture(sp_mem_addr, frame_index);
+
+ if((frame_index == start_index) || (frame_index == frame_num - 1)) { //a play period complete
+ pause_count = 0; //enable pause
+ play_count = -1; //disable play
+ } else {
+ play_count = 0; //restart play period
+ pause_count = -1;
+ }
+
+ frame_index++;
+ if(frame_index >= frame_num)
+ frame_index = start_index;
+ }
+
+ if(pause_count > max_pause_count) {
+ if((start_index == frame_num - 1) && (frame_index == start_index)) { //the battery is full, always pause, don't play
+ if(battery_is_full == 0) {
+ display_charge_percent(sp_mem_addr, percent);
+ show_charge_picture(sp_mem_addr, frame_index);
+ battery_is_full = 1;
+ }
+ play_count = -1; //disable play
+ pause_count = 0; //enable pause
+ } else {
+ play_count = 0; //enable play
+ pause_count = -1; //disable pause
+ battery_is_full = 0;
+ }
+ }
+ }
+
+ //restore cpu freq
+ set_arm_freq(saved_arm_freq / 1000000);
+ //current_arm_freq = auto_pll_divisor(DEV_ARM, GET_FREQ, 0, 0);
+ //printf("restore cpu freq = %d\n", current_arm_freq);
+
+ return 0;
+}
+
+static int do_check_usbtopc(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int ret;
+ int delay = 0;
+ int max_delay = 300;
+ int exit_flag = 0;
+
+ ret = udc_fastboot_init();
+ if(ret)
+ return -1;
+
+ while (++delay <= max_delay) {
+ udc_fastboot_transfer();
+ if(wmt_udc_connected()) {
+ printf("usb connetct = 1, delay = %d\n", delay);
+ break;
+ }
+ exit_flag |= ctrlc();
+ if(exit_flag)
+ break;
+ mdelay(1);
+ }
+
+ if(delay > max_delay)
+ printf("usb connetct = 0\n");
+
+ udc_fastboot_exit();
+
+ return 0;
+}
+
+
+U_BOOT_CMD(
+ isusbtopc, 1, 0, do_check_usbtopc,
+ "isusbtopc - check if usb connect to pc\n",
+ "- check if usb connect to pc\n"
+);
+
diff --git a/common/wmt_display/cmd_mbit.c b/common/wmt_display/cmd_mbit.c
new file mode 100755
index 0000000..89c307d
--- /dev/null
+++ b/common/wmt_display/cmd_mbit.c
@@ -0,0 +1,107 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+should have received a copy of the GNU General Public License along with this
+program. If not, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <version.h>
+#include <stdarg.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <linux/stddef.h>
+#include <asm/byteorder.h>
+
+#include "wmt_display.h"
+#include "com-vpp.h"
+
+void excute_reg_op(char * p)
+{
+ ulong addr;
+ ulong val, org;
+ char op;
+ char * endp;
+
+ while(1)
+ {
+ addr = simple_strtoul(p, &endp, 16);
+ if( *endp == '\0')
+ break;
+
+ op = *endp;
+ if( endp[1] == '~')
+ {
+ val = simple_strtoul(endp+2, &endp, 16);
+ val = ~val;
+ }
+ else
+ {
+ val = simple_strtoul(endp+1, &endp, 16);
+ }
+ if (addr&0x03) {
+ printf(" address not alginment to 32bit , address = 0x%x\n",addr);
+ goto nextcheck;
+ }
+ printf(" reg op: 0x%X %c 0x%X\n", addr, op, val);
+ org = REG32_VAL(addr);
+ switch(op)
+ {
+ case '|': org |= val; break;
+ case '=': org = val ; break;
+ case '&': org &= val; break;
+ default:
+ printf("Error, Unknown operator %c\n", op);
+ break;
+ }
+ REG32_VAL(addr) = org;
+nextcheck:
+ if(*endp == '\0')
+ break;
+ p = endp + 1;
+ }
+ return;
+}
+
+
+static int wmt_do_mbit (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ switch (argc) {
+ case 0:
+ case 1:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 0;
+ default:
+ if (argc == 2) {
+ excute_reg_op(argv[1]);
+ return 0;
+ }
+
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 0;
+ }
+ return 0;
+}
+
+U_BOOT_CMD(
+ mbit, 2, 1, wmt_do_mbit,
+ "memory bit operation : \n"
+ "Format : mbit <parameter>\n",
+ "Puepose : write bit to memory\n"
+ "Example : mbit -int D8000012|~1\n"
+ " VAL32(0xD8000012) | 0xFFFFFFFE"
+
+);
diff --git a/common/wmt_display/cmd_textout.c b/common/wmt_display/cmd_textout.c
new file mode 100755
index 0000000..dfc4d2d
--- /dev/null
+++ b/common/wmt_display/cmd_textout.c
@@ -0,0 +1,161 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+should have received a copy of the GNU General Public License along with this
+program. If not, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+#include <common.h>
+#include <command.h>
+#include <linux/ctype.h>
+#include <asm/arch/common_def.h>
+
+#include "wmt_display.h"
+#include "minivgui.h"
+
+//#define CHAR_WIDTH 8
+//#define CHAR_HEIGHT 20 // 16
+
+int text_x = 30, text_y = 30 - CHAR_HEIGHT;
+// ------------------- Extern Variable ------------------------
+extern int g_display_direction;
+
+//-------------------- Extern Function -----------------------
+extern void mv_initPrimary(int no,const mv_surface * s);
+//extern void arm_memset(void * s, int c, size_t count);
+extern int display_init(int on, int force);
+
+static int atoi(char *s) //added by howayhuo
+{
+ int i,n,sign;
+
+ for(i=0;isspace(s[i]);i++) //Ìø¹ý¿Õ°×·û
+ ;
+ sign=(s[i]=='-')?-1:1;
+ if(s[i]=='+'||s[i]=='-') //Ìø¹ý·ûºÅ
+ i++;
+ for(n=0;isdigit(s[i]);i++)
+ n=10*n+(s[i]-'0'); //½«Êý×Ö×Ö·ûת»»³ÉÕûÐÎÊý×Ö
+ return sign *n;
+}
+
+int do_textout(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int tmpx, tmpy;
+ unsigned int rgb = 0;
+ char *text_first, *text_last;
+ char r, g, b;
+ int i, len, textLen;
+ mv_Rect rect;
+ char tmpbuf[200];
+ int no;
+ mv_surface *s;
+
+ if(display_init(1, 0))
+ return -1;
+
+ switch (argc) {
+ case 1:
+ case 2:
+ case 3: /* use load_addr as default address */
+ case 4: /* use argument */
+ printf("<ERROR> too few argument\n");
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return -1;
+
+ default:
+ //tmpx = simple_strtoul(argv[1], NULL, 10);
+ //tmpy = simple_strtoul(argv[2], NULL, 10);
+ tmpx = atoi(argv[1]);
+ tmpy = atoi(argv[2]);
+
+ //printf("tmpx=%d, tmpy=%d\n", tmpx,tmpy);
+
+ if(tmpx >= 0)
+ text_x = tmpx;
+
+ if(tmpy >= 0)
+ text_y = tmpy;
+ else
+ text_y = text_y + CHAR_HEIGHT;
+
+ printf("x=%d, y=%d\n", text_y, text_y);
+
+ rgb = simple_strtoul(argv[argc - 1], NULL, 16);
+
+ text_first = argv[3];
+ if(*text_first != '"') {
+ printf("<ERROR> please specify the text begin with \" \n", *text_first);
+ printf ("Usage:\n%s\n", cmdtp->usage);
+
+ return -1;
+ }
+
+ text_last = argv[argc - 2];
+ while(*text_last != '\0')
+ text_last++;
+
+ if(*--text_last != '"') {
+ printf("<ERROR> please specify the text end with \" \n", *text_last);
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return -1;
+ }
+ break;
+ }
+ len = 0;
+ for(i = 3; i < argc - 1; i++) {
+ printf("%s ", argv[i]);
+ len += sprintf(tmpbuf + len, "%s ", argv[i]);
+ }
+ printf("\n");
+ //if you input:
+ // drawtext 0 0 "aa bb cc" ff0000
+ //then the tmpbuf is ["aa bb cc" ], it have redundant space at the end.
+ tmpbuf[len - 2] = '\0'; //ignore the last 'double quotation marks' and 'space'
+
+ for(no = 0; no < VPP_VOUT_INFO_NUM; no++) {
+ s = mv_getSurface(no);
+ if(s->startAddr == 0)
+ continue;
+
+ textLen = len - 3; // total len- ' start " ' (1 char) - 'space' (1 char) -' end " ' (1 char)
+ rect.left = 0;
+ rect.top = text_y;
+ rect.right = s->width; //vfb_var.xres;
+ rect.bottom = text_y + CHAR_HEIGHT;
+ if(g_display_direction == 0 || g_display_direction == 2) //the screen is portrait
+ rect.right = s->height; //vfb_var.yres;
+
+ mv_fillRect(no, &rect, 0, 0, 0);
+
+ r = (rgb >> 16) & 0xFF;
+ g = (rgb >> 8) & 0xFF;
+ b = rgb & 0xFF;
+ mv_textOut(no, text_x, text_y, tmpbuf + 1, r, g, b);
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ textout, 100, 5, do_textout,
+ "textout - show text to the screen. Example: textout 0 0 \\\"hello world\\\" FFFFFF\n",
+ "- show text to the screen \n"
+ "usage: textout x y \"str\" color\n"
+ "(x,y) is the coordinate. x, y are decimal. (x,y) default value is (30,30)\n"
+ "if x < 0, the x coordinate is unchaged\n"
+ "if y < 0, the y coordinate auto add 22 pixels to move to next line\n"
+ "color is 24bit Hex, R[23:16], G[15:8], B[7:0]\n"
+ "for example: textout 0 0 \\\"hello world\\\" FFFFFF\n"
+ " textout -1 -1 \\\"come on\\\" FF0000\n"
+);
+
diff --git a/common/wmt_display/com-fb.h b/common/wmt_display/com-fb.h
new file mode 100755
index 0000000..328bdbf
--- /dev/null
+++ b/common/wmt_display/com-fb.h
@@ -0,0 +1,143 @@
+/*++
+ * linux/drivers/video/wmt/com-fb.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef COM_FB_H
+#define COM_FB_H
+
+#ifdef __KERNEL__
+#include <linux/fb.h>
+#else
+#define FB_MODE_IS_VESA 4
+#define FB_MODE_IS_FROM_VAR 32
+
+#define FB_SYNC_HOR_HIGH_ACT 1
+#define FB_SYNC_VERT_HIGH_ACT 2
+
+#define FB_VMODE_NONINTERLACED 0 /* non interlaced */
+#define FB_VMODE_INTERLACED 1 /* interlaced */
+#define FB_VMODE_DOUBLE 2 /* double scan */
+
+struct fb_bitfield {
+ __u32 offset; /* beginning of bitfield */
+ __u32 length; /* length of bitfield */
+ __u32 msb_right; /* != 0 : Most significant bit is */
+ /* right */
+};
+
+struct fb_var_screeninfo {
+ __u32 xres; /* visible resolution */
+ __u32 yres;
+ __u32 xres_virtual; /* virtual resolution */
+ __u32 yres_virtual;
+ __u32 xoffset; /* offset from virtual to visible */
+ __u32 yoffset; /* resolution */
+
+ __u32 bits_per_pixel; /* guess what */
+ __u32 grayscale; /* != 0 Graylevels instead of colors */
+
+ struct fb_bitfield red; /* bitfield in fb mem if true color, */
+ struct fb_bitfield green; /* else only length is significant */
+ struct fb_bitfield blue;
+ struct fb_bitfield transp; /* transparency */
+
+ __u32 nonstd; /* != 0 Non standard pixel format */
+
+ __u32 activate; /* see FB_ACTIVATE_* */
+
+ __u32 height; /* height of picture in mm */
+ __u32 width; /* width of picture in mm */
+
+ __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */
+
+ /* Timing: All values in pixclocks, except pixclock (of course) */
+ __u32 pixclock; /* pixel clock in ps (pico seconds) */
+ __u32 left_margin; /* time from sync to picture */
+ __u32 right_margin; /* time from picture to sync */
+ __u32 upper_margin; /* time from sync to picture */
+ __u32 lower_margin;
+ __u32 hsync_len; /* length of horizontal sync */
+ __u32 vsync_len; /* length of vertical sync */
+ __u32 sync; /* see FB_SYNC_* */
+ __u32 vmode; /* see FB_VMODE_* */
+ __u32 rotate; /* angle we rotate counter clockwise */
+ __u32 reserved[5]; /* Reserved for future compatibility */
+};
+
+struct fb_fix_screeninfo {
+ char id[16]; /* identification string eg "TT Builtin" */
+ unsigned long smem_start; /* Start of frame buffer mem */
+ /* (physical address) */
+ __u32 smem_len; /* Length of frame buffer mem */
+ __u32 type; /* see FB_TYPE_* */
+ __u32 type_aux; /* Interleave for interleaved Planes */
+ __u32 visual; /* see FB_VISUAL_* */
+ __u16 xpanstep; /* zero if no hardware panning */
+ __u16 ypanstep; /* zero if no hardware panning */
+ __u16 ywrapstep; /* zero if no hardware ywrap */
+ __u32 line_length; /* length of a line in bytes */
+ unsigned long mmio_start; /* Start of Memory Mapped I/O */
+ /* (physical address) */
+ __u32 mmio_len; /* Length of Memory Mapped I/O */
+ __u32 accel; /* Indicate to driver which */
+ /* specific chip/card we have */
+ __u16 reserved[3]; /* Reserved for future compatibility */
+};
+
+struct fb_info {
+ int node;
+ int flags;
+ struct fb_var_screeninfo var; /* Current var */
+ struct fb_fix_screeninfo fix; /* Current fix */
+
+ __u32 state; /* Hardware state i.e suspend */
+ void *fbcon_par; /* fbcon use-only private area */
+ /* From here on everything is device dependent */
+ void *par;
+};
+
+struct fb_videomode {
+ const char *name; /* optional */
+ unsigned int refresh;
+ unsigned int xres;
+ unsigned int yres;
+ unsigned int pixclock;
+ unsigned int left_margin;
+ unsigned int right_margin;
+ unsigned int upper_margin;
+ unsigned int lower_margin;
+ unsigned int hsync_len;
+ unsigned int vsync_len;
+ unsigned int sync;
+ unsigned int vmode;
+ unsigned int flag;
+};
+
+#define KHZ2PICOS(a) (1000000000UL/(a))
+#define PICOS2KHZ(a) (1000000000UL/(a))
+
+struct timeval {
+ int tv_sec;
+ int tv_usec;
+};
+#endif // __KERNEL__
+#endif // COM_FB_H
diff --git a/common/wmt_display/com-video.h b/common/wmt_display/com-video.h
new file mode 100755
index 0000000..80cf508
--- /dev/null
+++ b/common/wmt_display/com-video.h
@@ -0,0 +1,103 @@
+/*++
+Copyright (c) 2008 WonderMedia Technologies, Inc. All Rights Reserved.
+
+This PROPRIETARY SOFTWARE is the property of WonderMedia Technologies, Inc.
+and may contain trade secrets and/or other confidential information of
+WonderMedia Technologies, Inc. This file shall not be disclosed to any third
+party, in whole or in part, without prior written consent of WonderMedia.
+
+THIS PROPRIETARY SOFTWARE AND ANY RELATED DOCUMENTATION ARE PROVIDED AS IS,
+WITH ALL FAULTS, AND WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS OR IMPLIED,
+AND WonderMedia TECHNOLOGIES, INC. DISCLAIMS ALL EXPRESS OR IMPLIED WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
+NON-INFRINGEMENT.
+--*/
+
+#ifndef COM_VIDEO_H
+/* To assert that only one occurrence is included */
+#define COM_VIDEO_H
+
+/*-------------------- MODULE DEPENDENCY -------------------------------------*/
+
+//#include "sim-kernel.h" // for POST only
+
+/*-------------------- EXPORTED PRIVATE CONSTANTS ----------------------------*/
+
+#define BIT(x) (1<<x)
+
+
+/*------------------------------------------------------------------------------
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ Definitions of enum
+------------------------------------------------------------------------------*/
+
+typedef enum {
+ VDO_COL_FMT_YUV420,
+ VDO_COL_FMT_YUV422H,
+ VDO_COL_FMT_YUV422V,
+ VDO_COL_FMT_YUV444,
+ VDO_COL_FMT_YUV411,
+ VDO_COL_FMT_GRAY,
+ VDO_COL_FMT_BGRA, /* B G R A from offset 0 ~ 3 */
+ VDO_COL_FMT_ARGB = VDO_COL_FMT_BGRA,
+ VDO_COL_FMT_AUTO,
+ VDO_COL_FMT_RGB_888,
+ VDO_COL_FMT_RGB_666,
+ VDO_COL_FMT_RGB_565,
+ VDO_COL_FMT_RGB_1555,
+ VDO_COL_FMT_RGB_5551,
+ VDO_COL_FMT_RGBA, /* R G B A from offset 0 ~ 3 */
+ VDO_COL_FMT_ABGR = VDO_COL_FMT_RGBA,
+ VDO_COL_FMT_MAX,
+ VDO_COL_FMT_UNKNOWN
+} vdo_color_fmt;
+
+
+/*------------------------------------------------------------------------------
+ Definitions of Struct
+------------------------------------------------------------------------------*/
+
+typedef struct {
+ /* Physical address for kernel space */
+ unsigned int y_addr; /* Addr of Y plane in YUV domain or RGB plane in ARGB domain */
+ unsigned int c_addr; /* C plane address */
+ unsigned int y_size; /* Buffer size in bytes */
+ unsigned int c_size; /* Buffer size in bytes */
+ unsigned int img_w; /* width of valid image (unit: pixel) */
+ unsigned int img_h; /* height of valid image (unit: line) */
+ unsigned int fb_w; /* width of frame buffer (scanline offset) (unit: pixel)*/
+ unsigned int fb_h; /* height of frame buffer (unit: line) */
+ unsigned int bpp; /* bits per pixel (8/16/24/32) */
+
+ vdo_color_fmt col_fmt; /* Color format on frame buffer */
+
+ unsigned int h_crop; /* Horental Crop (unit: pixel) */
+ unsigned int v_crop; /* Vertical Crop (unit: pixel) */
+
+ unsigned int flag; /* frame flags */
+} vdo_framebuf_t;
+
+#define VDO_FLAG_INTERLACE BIT(0)
+#define VDO_FLAG_MOTION_VECTOR BIT(1) /* frame buffer with motion vector table after C frame */
+#define VDO_FLAG_MB_ONE BIT(2) /* Y/C frame alloc in one mb */
+#define VDO_FLAG_MB_NO BIT(3) /* frame buffer is not alloc from mb */
+
+typedef struct {
+ unsigned int resx_src; /* source x resolution */
+ unsigned int resy_src; /* source y resolution */
+ unsigned int resx_virtual; /* virtual x resolution */
+ unsigned int resy_virtual; /* virtual y resolution */
+ unsigned int resx_visual; /* visual x resolution */
+ unsigned int resy_visual; /* visual y resolution */
+ unsigned int posx; /* x position to display screen */
+ unsigned int posy; /* y postion to display screen */
+ unsigned int offsetx; /* x pixel offset from source left edge */
+ unsigned int offsety; /* y pixel offset from source top edge */
+} vdo_view_t;
+
+#endif /* ifndef COM_VIDEO_H */
+
+/*=== END com-video.h ==========================================================*/
diff --git a/common/wmt_display/com-vpp.h b/common/wmt_display/com-vpp.h
new file mode 100755
index 0000000..ce6f2c3
--- /dev/null
+++ b/common/wmt_display/com-vpp.h
@@ -0,0 +1,455 @@
+/*++
+ * linux/drivers/video/wmt/com-vpp.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef COM_VPP_H
+#define COM_VPP_H
+
+#ifdef __KERNEL__
+ #include <linux/types.h>
+ #include <linux/fb.h>
+ #include <asm/io.h>
+ #include <mach/common_def.h>
+ #include <mach/com-video.h>
+#else
+ #include "com-video.h"
+#ifdef CFG_LOADER
+ #include "com-fb.h"
+#endif
+#endif
+
+#define VPP_NEW_FBUF_MANAGER
+
+#define VPP_AHB_CLK 250000000
+
+#ifdef CONFIG_MAX_RESX
+ #define VPP_HD_MAX_RESX CONFIG_MAX_RESX
+#else
+ #define VPP_HD_MAX_RESX 1920
+#endif
+
+#ifdef CONFIG_MAX_RESY
+ #define VPP_HD_MAX_RESY CONFIG_MAX_RESY
+#else
+ #define VPP_HD_MAX_RESY 1200
+#endif
+
+#ifdef CONFIG_DEFAULT_RESX
+ #define VPP_HD_DISP_RESX CONFIG_DEFAULT_RESX
+#else
+ #define VPP_HD_DISP_RESX 1024
+#endif
+
+#ifdef CONFIG_DEFAULT_RESY
+ #define VPP_HD_DISP_RESY CONFIG_DEFAULT_RESY
+#else
+ #define VPP_HD_DISP_RESY 768
+#endif
+
+#ifdef CONFIG_DEFAULT_FPS
+ #define VPP_HD_DISP_FPS CONFIG_DEFAULT_FPS
+#else
+ #define VPP_HD_DISP_FPS 60
+#endif
+
+#define VPP_HD_DISP_PIXCLK 65000000
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+#define VPP_YUV_BLACK 0x008080 /* Y, Cr, Cb */
+#define VPP_YUV_WHITE 0xff8080
+#define VPP_YUV_RED 0x51f05a
+#define VPP_YUV_GREEN 0x902235
+#define VPP_YUV_BLUE 0x286df0
+#define VPP_RGB32_BLACK 0x00000000
+
+#define VPP_COL_RGB32_BLACK 0x000000
+#define VPP_COL_RGB32_WHITE 0xFFFFFF
+#define VPP_COL_RGB32_RED 0xFF0000
+#define VPP_COL_RGB32_GREEN 0x00FF00
+#define VPP_COL_RGB32_BLUE 0x0000FF
+
+#define VPP_COL_BLACK 0x008080 /* Y, Cr, Cb */
+#define VPP_COL_WHITE 0xff8080
+#define VPP_COL_RED 0x41d464
+#define VPP_COL_GREEN 0x902235
+#define VPP_COL_BLUE 0x2372d4
+
+#define VPP_MAGNUM(s, e) ((2^((s)-(e)+1))-1)
+
+#define WMT_FB_COLFMT(a) (a & 0xFF)
+
+enum vpp_fbuf_s {
+ VPP_FBUF_GOVR_1,
+ VPP_FBUF_GOVR_2,
+ VPP_FBUF_SCLR_1,
+ VPP_FBUF_SCLR_2,
+ VPP_FBUF_MAX
+};
+#define vpp_fbuf_t enum vpp_fbuf_s
+
+enum vpp_flag_s {
+ VPP_FLAG_NULL = 0,
+ VPP_FLAG_ENABLE = 1,
+ VPP_FLAG_DISABLE = 0,
+ VPP_FLAG_TRUE = 1,
+ VPP_FLAG_FALSE = 0,
+ VPP_FLAG_ZERO = 0,
+ VPP_FLAG_ONE = 1,
+ VPP_FLAG_SUCCESS = 1,
+ VPP_FLAG_ERROR = 0,
+ VPP_FLAG_RD = 1,
+ VPP_FLAG_WR = 0,
+};
+#define vpp_flag_t enum vpp_flag_s
+
+enum vpp_mod_s {
+ VPP_MOD_GOVRH2,
+ VPP_MOD_GOVRH,
+ VPP_MOD_DISP,
+ VPP_MOD_GOVW,
+ VPP_MOD_GOVM,
+ VPP_MOD_SCL,
+ VPP_MOD_SCLW,
+ VPP_MOD_VPU,
+ VPP_MOD_VPUW,
+ VPP_MOD_PIP,
+ VPP_MOD_VPPM,
+ VPP_MOD_LCDC,
+ VPP_MOD_CURSOR,
+ VPP_MOD_MAX
+};
+#define vpp_mod_t enum vpp_mod_s
+
+enum vpp_vout_s {
+ VPP_VOUT_NONE = 0,
+ VPP_VOUT_SDA = 1,
+ VPP_VOUT_LCD = 2,
+ VPP_VOUT_DVI = 3,
+ VPP_VOUT_HDMI = 4,
+ VPP_VOUT_DVO2HDMI = 5,
+ VPP_VOUT_LVDS = 6,
+ VPP_VOUT_VGA = 7,
+ VPP_VOUT_FBDEV = 8,
+ VPP_VOUT_VIRDISP = 9,
+ VPP_VOUT_MAX
+};
+#define vpp_vout_t enum vpp_vout_s
+
+enum vpp_display_format_s {
+ VPP_DISP_FMT_FRAME, /* Progressive */
+ VPP_DISP_FMT_FIELD, /* Interlace */
+ VPP_DISP_FMT_MAX,
+};
+#define vpp_display_format_t enum vpp_display_format_s
+
+enum vpp_media_format_s {
+ VPP_MEDIA_FMT_MPEG,
+ VPP_MEDIA_FMT_H264,
+ VPP_MEDIA_FMT_MAX,
+};
+#define vpp_media_format_t enum vpp_media_format_s
+
+enum vpp_csc_s { /* don't change this order */
+ VPP_CSC_YUV2RGB2_MIN,
+ VPP_CSC_YUV2RGB_SDTV_0_255 = VPP_CSC_YUV2RGB2_MIN,
+ VPP_CSC_YUV2RGB_SDTV_16_235,
+ VPP_CSC_YUV2RGB_HDTV_0_255,
+ VPP_CSC_YUV2RGB_HDTV_16_235,
+ VPP_CSC_YUV2RGB_JFIF_0_255,
+ VPP_CSC_YUV2RGB_SMPTE170M,
+ VPP_CSC_YUV2RGB_SMPTE240M,
+ VPP_CSC_RGB2YUV_MIN,
+ VPP_CSC_RGB2YUV_SDTV_0_255 = VPP_CSC_RGB2YUV_MIN,
+ VPP_CSC_RGB2YUV_SDTV_16_235,
+ VPP_CSC_RGB2YUV_HDTV_0_255,
+ VPP_CSC_RGB2YUV_HDTV_16_235,
+ VPP_CSC_RGB2YUV_JFIF_0_255,
+ VPP_CSC_RGB2YUV_SMPTE170M,
+ VPP_CSC_RGB2YUV_SMPTE240M,
+ VPP_CSC_RGB2YUV_JFIF_VT1625,
+ VPP_CSC_MAX,
+ VPP_CSC_BYPASS
+};
+#define vpp_csc_t enum vpp_csc_s
+
+enum vpp_reglevel_s {
+ VPP_REG_LEVEL_1,
+ VPP_REG_LEVEL_2,
+ VPP_REG_LEVEL_MAX,
+};
+#define vpp_reglevel_t enum vpp_reglevel_s
+
+enum vpp_datawidht_s {
+ VPP_DATAWIDHT_12,
+ VPP_DATAWIDHT_24,
+ VPP_DATAWIDHT_MAX,
+};
+#define vpp_datawidht_t enum vpp_datawidht_s
+
+enum vpp_tvsys_s {
+ VPP_TVSYS_NTSC,
+ VPP_TVSYS_NTSCJ,
+ VPP_TVSYS_NTSC443,
+ VPP_TVSYS_PAL,
+ VPP_TVSYS_PALM,
+ VPP_TVSYS_PAL60,
+ VPP_TVSYS_PALN,
+ VPP_TVSYS_PALNC,
+ VPP_TVSYS_720P,
+ VPP_TVSYS_1080I,
+ VPP_TVSYS_1080P,
+ VPP_TVSYS_MAX
+};
+#define vpp_tvsys_t enum vpp_tvsys_s
+
+enum vpp_tvconn_s {
+ VPP_TVCONN_YCBCR,
+ VPP_TVCONN_SCART,
+ VPP_TVCONN_YPBPR,
+ VPP_TVCONN_VGA,
+ VPP_TVCONN_SVIDEO,
+ VPP_TVCONN_CVBS,
+ VPP_TVCONN_MAX
+};
+#define vpp_tvconn_t enum vpp_tvconn_s
+
+#define VPP_OPT_INTERLACE 0x01
+#define VPP_DVO_SYNC_POLAR_HI 0x08
+#define VPP_DVO_VSYNC_POLAR_HI 0x10
+
+struct vpp_clock_s {
+ int read_cycle;
+
+ unsigned int total_pixel_of_line;
+ unsigned int begin_pixel_of_active;
+ unsigned int end_pixel_of_active;
+
+ unsigned int total_line_of_frame;
+ unsigned int begin_line_of_active;
+ unsigned int end_line_of_active;
+
+ unsigned int hsync;
+ unsigned int vsync;
+ unsigned int line_number_between_VBIS_VBIE;
+ unsigned int line_number_between_PVBI_VBIS;
+};
+#define vpp_clock_t struct vpp_clock_s
+
+struct vpp_scale_s {
+ vdo_framebuf_t src_fb;
+ vdo_framebuf_t dst_fb;
+};
+#define vpp_scale_t struct vpp_scale_s
+
+struct vpp_scale_overlap_s {
+ int mode;
+ vdo_framebuf_t src_fb;
+ vdo_framebuf_t src2_fb;
+ vdo_framebuf_t dst_fb;
+};
+#define vpp_scale_overlap_t struct vpp_scale_overlap_s
+
+struct vpp_overlap_s {
+ unsigned int alpha_src_type:2; /* 0-mif1,1-mif2,2-fix */
+ unsigned int alpha_src:8;
+ unsigned int alpha_dst_type:2; /* 0-mif1,1-mif2,2-fix */
+ unsigned int alpha_dst:8;
+ unsigned int alpha_swap:1; /* 0-(alpha,1-alpha),1:(1-alpha,alpha) */
+ unsigned int color_key_from:2; /* 0-RMIF1,1-RMIF2 */
+ unsigned int color_key_comp:2; /* 0-888,1-777,2-666,3-555 */
+ unsigned int color_key_mode:3; /* (Non-Hit,Hit):0/1-(alpha,alpha),
+ 2-(alpha,pix1), 3-(pix1,alpha),4-(alpha,pix2),
+ 5-(pix2,alpha),6-(pix1,pix2),7-(pix2,pix1) */
+ unsigned int reserved:4;
+ unsigned int color_key; /* ARGB */
+};
+#define vpp_overlap_t struct vpp_overlap_s
+
+#define VPP_VOUT_STS_REGISTER 0x01
+#define VPP_VOUT_STS_ACTIVE 0x02
+#define VPP_VOUT_STS_PLUGIN 0x04
+#define VPP_VOUT_STS_EDID 0x08
+#define VPP_VOUT_STS_BLANK 0x10
+#define VPP_VOUT_STS_POWERDN 0x20
+#define VPP_VOUT_STS_CONTENT_PROTECT 0x40
+#define VPP_VOUT_STS_FB 0xF00
+#define VPP_VOUT_ARG_NUM 5
+struct vpp_vout_info_s {
+ enum vpp_vout_s mode[VPP_VOUT_ARG_NUM];
+ unsigned int status[VPP_VOUT_ARG_NUM];
+};
+#define vpp_vout_info_t struct vpp_vout_info_s
+
+struct vpp_vout_parm_s {
+ int num;
+ int arg;
+};
+#define vpp_vout_parm_t struct vpp_vout_parm_s
+
+#define VOUT_OPT_BLANK BIT(8)
+
+#define VPP_CAP_DUAL_DISPLAY BIT(0)
+struct vpp_cap_s {
+ unsigned int chip_id;
+ unsigned int version;
+ unsigned int resx_max;
+ unsigned int resy_max;
+ unsigned int pixel_clk;
+ unsigned int module;
+ unsigned int option;
+};
+#define vpp_cap_t struct vpp_cap_s
+
+struct vpp_i2c_s {
+ unsigned int addr;
+ unsigned int index;
+ unsigned int val;
+};
+#define vpp_i2c_t struct vpp_i2c_s
+
+struct vpp_mod_fbinfo_s {
+ vpp_mod_t mod;
+ int read;
+ vdo_framebuf_t fb;
+};
+#define vpp_mod_fbinfo_t struct vpp_mod_fbinfo_s
+
+struct vpp_vmode_parm_s {
+ unsigned int resx;
+ unsigned int resy;
+ unsigned int fps;
+ unsigned int option;
+};
+#define vpp_vmode_parm_t struct vpp_vmode_parm_s
+
+#define VPP_VOUT_VMODE_NUM 20
+struct vpp_vout_vmode_s {
+ vpp_vout_t mode;
+ int num;
+ vpp_vmode_parm_t parm[VPP_VOUT_VMODE_NUM];
+};
+#define vpp_vout_vmode_t struct vpp_vout_vmode_s
+
+struct vpp_vout_edid_s {
+ vpp_vout_t mode;
+ int size;
+ char *buf;
+};
+#define vpp_vout_edid_t struct vpp_vout_edid_s
+
+struct vpp_vout_cp_info_s {
+ int num;
+ unsigned int bksv[2];
+};
+#define vpp_vout_cp_info_t struct vpp_vout_cp_info_s
+
+#define VPP_VOUT_CP_NUM 336
+struct vpp_vout_cp_key_s {
+ char key[VPP_VOUT_CP_NUM];
+};
+#define vpp_vout_cp_key_t struct vpp_vout_cp_key_s
+
+struct vpp_mod_parm_t {
+ vpp_mod_t mod;
+ int read;
+ unsigned int parm;
+};
+
+#define VPPIO_MAGIC 'f'
+
+/* VPP common ioctl command */
+#define VPPIO_VPP_BASE 0x0
+#define VPPIO_VPPGET_INFO _IOR(VPPIO_MAGIC, VPPIO_VPP_BASE + 0, vpp_cap_t)
+#define VPPIO_VPPSET_INFO _IOW(VPPIO_MAGIC, VPPIO_VPP_BASE + 0, vpp_cap_t)
+#define VPPIO_I2CSET_BYTE _IOW(VPPIO_MAGIC, VPPIO_VPP_BASE + 1, vpp_i2c_t)
+#define VPPIO_I2CGET_BYTE _IOR(VPPIO_MAGIC, VPPIO_VPP_BASE + 1, vpp_i2c_t)
+#define VPPIO_MODSET_CSC \
+ _IOW(VPPIO_MAGIC, VPPIO_VPP_BASE + 2, struct vpp_mod_parm_t)
+#define VPPIO_MODULE_FBINFO \
+ _IOWR(VPPIO_MAGIC, VPPIO_VPP_BASE + 6, vpp_mod_fbinfo_t)
+#define VPPIO_STREAM_ENABLE _IO(VPPIO_MAGIC, VPPIO_VPP_BASE + 12)
+#define VPPIO_STREAM_GETFB \
+ _IOR(VPPIO_MAGIC, VPPIO_VPP_BASE + 13, vdo_framebuf_t)
+#define VPPIO_STREAM_PUTFB \
+ _IOW(VPPIO_MAGIC, VPPIO_VPP_BASE + 13, vdo_framebuf_t)
+#define VPPIO_MULTIVD_ENABLE _IO(VPPIO_MAGIC, VPPIO_VPP_BASE + 15)
+
+/* VOUT ioctl command */
+#define VPPIO_VOUT_BASE 0x10
+#define VPPIO_VOGET_INFO _IOR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 0, vpp_vout_info_t)
+#define VPPIO_VOGET_HDMI_3D \
+ _IOR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 1, struct vpp_vout_parm_s)
+#define VPPIO_VOUT_VMODE \
+ _IOWR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 7, vpp_vout_vmode_t)
+#define VPPIO_VOGET_EDID _IOR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 8, vpp_vout_edid_t)
+#define VPPIO_VOGET_CP_INFO \
+ _IOR(VPPIO_MAGIC, VPPIO_VOUT_BASE + 9, vpp_vout_cp_info_t)
+#define VPPIO_VOSET_CP_KEY \
+ _IOW(VPPIO_MAGIC, VPPIO_VOUT_BASE + 10, vpp_vout_cp_key_t)
+#define VPPIO_VOSET_AUDIO_PASSTHRU _IO(VPPIO_MAGIC, VPPIO_VOUT_BASE + 11)
+#define VPPIO_VOSET_VIRTUAL_FBDEV _IO(VPPIO_MAGIC, VPPIO_VOUT_BASE + 13)
+
+/* SCL ioctl command */
+#define VPPIO_SCL_BASE 0x60
+#define VPPIO_SCL_SCALE _IOWR(VPPIO_MAGIC, VPPIO_SCL_BASE + 0, vpp_scale_t)
+#define VPPIO_SCL_SCALE_ASYNC \
+ _IOWR(VPPIO_MAGIC, VPPIO_SCL_BASE + 2, vpp_scale_t)
+#define VPPIO_SCL_SCALE_FINISH _IO(VPPIO_MAGIC, VPPIO_SCL_BASE + 3)
+#define VPPIO_SCLSET_OVERLAP \
+ _IOW(VPPIO_MAGIC, VPPIO_SCL_BASE + 4, vpp_overlap_t)
+#define VPPIO_SCL_SCALE_OVERLAP \
+ _IOWR(VPPIO_MAGIC, VPPIO_SCL_BASE + 5, vpp_scale_overlap_t)
+
+#define VPPIO_MAX 0x70
+#endif /* COM_VPP_H */
diff --git a/common/wmt_display/devices/cs8556.c b/common/wmt_display/devices/cs8556.c
new file mode 100755
index 0000000..81a6455
--- /dev/null
+++ b/common/wmt_display/devices/cs8556.c
@@ -0,0 +1,400 @@
+/*++
+ * linux/drivers/video/wmt/cs8556.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2013 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define CS8556_C
+// #define DEBUG
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../vout.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define VT1632_XXXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define VT1632_XXXX 1 *//*Example*/
+#define CS8556_ADDR 0x3d
+#define CS8556_NAME "CS8556"
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx vt1632_xxx_t; *//*Example*/
+typedef enum {
+ TV_PAL,
+ TV_NTSC,
+ TV_UNDEFINED,
+ TV_MAX
+} vout_tvformat_t;
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in vt1632.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int vt1632_xxx; *//*Example*/
+static int s_cs8556_ready;
+static int s_cs8556_init;
+static int i2c_no = 1;
+static vout_tvformat_t s_tvformat = TV_MAX;
+
+static unsigned char s_CS8556_Original_Offset0[]={
+ 0xF0,0x7F,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x02,0x01,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+};
+
+static unsigned char s_RGB888_To_PAL_Offset0[]={
+ 0x01,0x80,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x00,
+ 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x5F,0x03,0x3F,0x00,0x7D,0x00,0x53,0x03,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,
+ 0x70,0x02,0x04,0x00,0x2E,0x00,0x62,0x02,0x00,0x00,0x84,0x00,0x2B,0x00,0x36,0x00,
+ 0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xBF,0x06,0x7F,0x00,0xFE,0x00,0xA4,0x06,0x00,0x00,0x2D,0x11,0x3C,0x01,0x3A,0x01,
+ 0x70,0x02,0x04,0x00,0x12,0x00,0x34,0x01,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,
+ 0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x04,0x41,0x18,0x09,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,
+ 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x24,0x1A,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x04,0x01,0xA4,0x06,0x0B,0x00,0x07,0x01,0xF0,0x00,0x00,0x00,0x00,0x04,0x40,0x01
+};
+
+static unsigned char s_RGB888_To_NTSC_Offset0[]={
+ 0x01,0x80,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x00,
+ 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x59,0x03,0x3D,0x00,0x7E,0x00,0x49,0x03,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,
+ 0x0C,0x02,0x05,0x00,0x21,0x00,0x03,0x02,0x00,0x00,0x7A,0x00,0x23,0x00,0x16,0x00,
+ 0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xB3,0x06,0x7F,0x00,0x00,0x01,0xA4,0x06,0x00,0x00,0x05,0x50,0x00,0x01,0x07,0x01,
+ 0x0C,0x02,0x02,0x00,0x12,0x00,0x07,0x01,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,
+ 0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x04,0x41,0x18,0x09,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,
+ 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x24,0x1A,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x04,0x01,0xA4,0x06,0x0B,0x00,0x07,0x01,0xF0,0x00,0x00,0x00,0x00,0x04,0x00,0x00
+};
+
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void vt1632_xxx(void); *//*Example*/
+static int I2CMultiPageRead(uchar maddr, uchar page, uchar saddr, int number, uchar *value)
+{
+ int ret;
+ uchar wbuf[2];
+ struct i2c_msg_s rd[2];
+
+ wbuf[0] = page;
+ wbuf[1] = saddr;
+
+ rd[0].addr = maddr;
+ rd[0].flags = I2C_M_WR;
+ rd[0].len = 2;
+ rd[0].buf = wbuf;
+
+ rd[1].addr = maddr;
+ rd[1].flags = I2C_M_RD;
+ rd[1].len = number;
+ rd[1].buf = value;
+
+ switch(i2c_no) {
+ case 0:
+ ret = i2c_transfer(rd, 2);
+ break;
+ case 1:
+ ret = i2c1_transfer(rd, 2);
+ break;
+ case 2:
+ ret = i2c2_transfer(rd, 2);
+ break;
+ case 3:
+ ret = i2c3_transfer(rd, 2);
+ break;
+ default:
+ DBG_ERR("i2c%d isn't exist in wm8880\n", i2c_no);
+ return -1;
+
+ }
+
+ if (ret != 2) {
+ DBG_ERR("fail\n", i2c_no);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int I2CMultiPageWrite(uchar maddr,uchar page,uchar saddr,int number,uchar *value)
+{
+ int ret;
+ uchar *pbuf;
+ struct i2c_msg_s wr[1];
+
+ pbuf = calloc(number + 2, sizeof(uchar));
+
+ pbuf[0] = page;
+ pbuf[1] = saddr;
+
+ memcpy(pbuf + 2, value, number);
+
+ wr[0].addr = maddr;
+ wr[0].flags = I2C_M_WR;
+ wr[0].len = number + 2;
+ wr[0].buf = pbuf;
+
+ switch(i2c_no) {
+ case 0:
+ ret = i2c_transfer(wr, 1);
+ break;
+ case 1:
+ ret = i2c1_transfer(wr, 1);
+ break;
+ case 2:
+ ret = i2c2_transfer(wr, 1);
+ break;
+ case 3:
+ ret = i2c3_transfer(wr, 1);
+ break;
+ default:
+ DBG_ERR("i2c%d isn't exist in wm8880\n", i2c_no);
+ return -1;
+
+ }
+
+ if (ret != 1) {
+ DBG_ERR("fail\n", i2c_no);
+ free(pbuf);
+ return -1;
+ }
+
+ free(pbuf);
+ return 0 ;
+}
+
+/*----------------------- Function Body --------------------------------------*/
+
+static int cs8556_check_plugin(int hotplug)
+{
+ return 1;
+}
+
+static int cs8556_init(struct vout_s *vo)
+{
+ int ret;
+ char buf[40];
+ int varlen = 40;
+ unsigned char rbuf[256] = {0};
+
+ if(s_tvformat == TV_MAX) {
+ if(wmt_getsyspara("wmt.display.tvformat", buf, &varlen) == 0) {
+ if(!strnicmp(buf, "PAL", 3))
+ s_tvformat = TV_PAL;
+ else if(!strnicmp(buf, "NTSC", 4))
+ s_tvformat = TV_NTSC;
+ else
+ s_tvformat = TV_UNDEFINED;
+ }
+ else
+ s_tvformat = TV_UNDEFINED;
+ }
+
+ if(s_tvformat == TV_UNDEFINED)
+ return -1;
+
+ if(!s_cs8556_init) {
+ if(wmt_getsyspara("wmt.cs8556.i2c", buf, &varlen) == 0) {
+ if(strlen(buf) > 0)
+ i2c_no = buf[0] - '0';
+ }
+
+ switch (i2c_no) {
+ case 0:
+ i2c_init(I2C_FAST_MODE, 0);
+ break;
+ case 1:
+ i2c1_init(I2C_FAST_MODE, 0);
+ break;
+ case 2:
+ i2c2_init(I2C_FAST_MODE, 0);
+ break;
+ case 3:
+ i2c3_init(I2C_FAST_MODE, 0);
+ break;
+ default:
+ DBG_ERR("i2c%d isn't exist in wm8850\n", i2c_no);
+ return -1;
+ }
+
+ s_cs8556_init = 1;
+ }
+
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf);
+ if(ret) {
+ DBG_ERR("I2C address 0x%02X is not found\n", CS8556_ADDR);
+ return -1;
+ }
+
+ switch(s_tvformat) {
+ case TV_PAL:
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, s_RGB888_To_PAL_Offset0);
+ if(ret) {
+ DBG_ERR("PAL init fail\n");
+ return -1;
+ }
+ break;
+
+ case TV_NTSC:
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, s_RGB888_To_NTSC_Offset0);
+ if(ret) {
+ DBG_ERR("NTSC init fail\n");
+ return -1;
+ }
+ break;
+
+ default:
+ return -1;
+ break;
+ }
+
+ s_cs8556_ready = 1;
+
+ DPRINT("cs8556 init ok\n");
+
+ return 0;
+}
+
+int cs8556_set_mode(unsigned int *option)
+{
+ if(!s_cs8556_ready )
+ return -1;
+
+ return 0;
+}
+
+void cs8556_set_power_down(int enable)
+{
+ int ret;
+ unsigned char rbuf[256] = {0};
+
+ if( !s_cs8556_ready )
+ return;
+
+ //DPRINT("cs8556_set_power_down(%d)\n",enable);
+
+ if(enable == 0) {
+ if(hdmi_get_plugin()) {
+ DPRINT("[CVBS] HDMI plugin. CVBS power down\n");
+ enable = 1;
+ } else
+ DPRINT("[CVBS] HDMI plugout. CVBS power up\n");
+ } else
+ DPRINT("[CVBS] CVBS power down\n");
+
+ ret = I2CMultiPageRead(CS8556_ADDR, 0x00, 0x00, 256, rbuf);
+ if(ret) {
+ DBG_ERR("I2C read Offset0 fail\n");
+ return;
+ }
+
+ if( enable ){
+ if(memcmp(rbuf, s_CS8556_Original_Offset0, 5) != 0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 5, s_CS8556_Original_Offset0);
+ if(ret)
+ DBG_ERR("I2C write Original_Offset0 fail\n");
+ }
+ }
+ else {
+ switch(s_tvformat) {
+ case TV_PAL:
+ if(memcmp(rbuf, s_RGB888_To_PAL_Offset0, 0x50) != 0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, s_RGB888_To_PAL_Offset0);
+ if(ret)
+ DBG_ERR("I2C write PAL_Offset0 fail\n");
+ }
+ break;
+ case TV_NTSC:
+ if(memcmp(rbuf, s_RGB888_To_NTSC_Offset0, 0x50) !=0) {
+ ret = I2CMultiPageWrite(CS8556_ADDR, 0x00, 0x00, 256, s_RGB888_To_NTSC_Offset0);
+ if(ret)
+ DBG_ERR("I2C write NTSC_Offset0 fail\n");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static int cs8556_config(vout_info_t *info)
+{
+ return 0;
+}
+
+static int cs8556_get_edid(char *buf)
+{
+ return -1;
+}
+
+/*
+static int cs8556_interrupt(void)
+{
+ return cs8556_check_plugin(1);
+}
+*/
+/*----------------------- vout device plugin --------------------------------------*/
+vout_dev_t cs8556_vout_dev_ops = {
+ .name = CS8556_NAME,
+ .mode = VOUT_INF_DVI,
+
+ .init = cs8556_init,
+ .set_power_down = cs8556_set_power_down,
+ .set_mode = cs8556_set_mode,
+ .config = cs8556_config,
+ .check_plugin = cs8556_check_plugin,
+ .get_edid = cs8556_get_edid,
+ //.interrupt = cs8556_interrupt,
+};
+
+int cs8556_module_init(void)
+{
+ vout_device_register(&cs8556_vout_dev_ops);
+ return 0;
+} /* End of cs8556_module_init */
+module_init(cs8556_module_init);
+
+/*--------------------End of Function Body -----------------------------------*/
+#undef CS8556_C
+
diff --git a/common/wmt_display/devices/lcd-AUO-A080SN01.c b/common/wmt_display/devices/lcd-AUO-A080SN01.c
new file mode 100755
index 0000000..f4602a1
--- /dev/null
+++ b/common/wmt_display/devices/lcd-AUO-A080SN01.c
@@ -0,0 +1,95 @@
+/*++
+ * linux/drivers/video/wmt/lcd-AUO-A080SN01.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define LCD_AUO_A080SN01_C
+/* #define DEBUG */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../lcd.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define LCD_A080SN01_XXXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define LCD_A080SN01_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx lcd_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/
+static void lcd_a080sn01_initial(void);
+
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int lcd_xxx; *//*Example*/
+struct lcd_parm_t lcd_a080sn01_parm = {
+ .bits_per_pixel = 24,
+ .capability = 0,
+ .vmode = {
+ .name = "AUO A080SN01",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = KHZ2PICOS(40000),
+ .left_margin = 88,
+ .right_margin = 40,
+ .upper_margin = 24,
+ .lower_margin = 1,
+ .hsync_len = 128,
+ .vsync_len = 3,
+ .sync = 0,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 162,
+ .height = 121,
+ .initial = lcd_a080sn01_initial,
+};
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void lcd_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+static void lcd_a080sn01_initial(void)
+{
+ DPRINT("lcd_a080sn01_initial\n");
+
+ /* TODO */
+}
+
+struct lcd_parm_t *lcd_a080sn01_get_parm(int arg)
+{
+ return &lcd_a080sn01_parm;
+}
+
+int lcd_a080sn01_init(void)
+{
+ int ret;
+
+ ret = lcd_panel_register(LCD_AUO_A080SN01,
+ (void *) lcd_a080sn01_get_parm);
+ return ret;
+} /* End of lcd_a080sn01_init */
+module_init(lcd_a080sn01_init);
+
+/*--------------------End of Function Body -----------------------------------*/
+#undef LCD_AUO_A080SN01_C
+
diff --git a/common/wmt_display/devices/lcd-CHILIN-LW700at9003.c b/common/wmt_display/devices/lcd-CHILIN-LW700at9003.c
new file mode 100755
index 0000000..af9752b
--- /dev/null
+++ b/common/wmt_display/devices/lcd-CHILIN-LW700at9003.c
@@ -0,0 +1,104 @@
+/*++
+ * linux/drivers/video/wmt/lcd-CHILIN-LW700at9003.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define LCD_CHILIN_LW700AT9003_C
+/* #define DEBUG */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../lcd.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define LCD_LW700AT9003_XXXX xxxx *//*Example*/
+
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define LCD_LW700AT9003_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx lcd_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/
+static void lcd_lw700at9003_power_on(void);
+static void lcd_lw700at9003_power_off(void);
+
+/*----------------------- INTERNAL PRIVATE VARIABLES ------------------------*/
+/* int lcd_xxx; *//*Example*/
+struct lcd_parm_t lcd_lw700at9003_parm = {
+ .bits_per_pixel = 18,
+ .capability = LCD_CAP_CLK_HI,
+ .vmode = {
+ .name = "CHILIN LW700AT9003",
+ .refresh = 48,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(33260),
+ .left_margin = 105,
+ .right_margin = 105,
+ .upper_margin = 23,
+ .lower_margin = 22,
+ .hsync_len = 40,
+ .vsync_len = 5,
+ .sync = 0,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 152,
+ .height = 91,
+ .initial = lcd_lw700at9003_power_on,
+ .uninitial = lcd_lw700at9003_power_off,
+};
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void lcd_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+static void lcd_lw700at9003_power_on(void)
+{
+ DPRINT("lcd_lw700at9003_power_on\n");
+ /* TODO */
+}
+
+static void lcd_lw700at9003_power_off(void)
+{
+ DPRINT("lcd_lw700at9003_power_off\n");
+
+ /* TODO */
+}
+
+struct lcd_parm_t *lcd_lw700at9003_get_parm(int arg)
+{
+ lcd_lw700at9003_parm.bits_per_pixel = arg;
+ return &lcd_lw700at9003_parm;
+}
+
+int lcd_lw700at9003_init(void)
+{
+ int ret;
+
+ ret = lcd_panel_register(LCD_CHILIN_LW0700AT9003,
+ (void *) lcd_lw700at9003_get_parm);
+ return ret;
+} /* End of lcd_oem_init */
+module_init(lcd_lw700at9003_init);
+
+/*--------------------End of Function Body -----------------------------------*/
+#undef LCD_CHILIN_LW700AT9003_C
diff --git a/common/wmt_display/devices/lcd-EKING-EK08009-70135.c b/common/wmt_display/devices/lcd-EKING-EK08009-70135.c
new file mode 100755
index 0000000..1d40188
--- /dev/null
+++ b/common/wmt_display/devices/lcd-EKING-EK08009-70135.c
@@ -0,0 +1,103 @@
+/*++
+ * linux/drivers/video/wmt/lcd-EKING_EK08009-70135.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define LCD_EKING_EK08009_C
+/* #define DEBUG */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../lcd.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define LCD_EK08009_XXXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define LCD_EK08009_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx lcd_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/
+static void lcd_ek08009_power_on(void);
+static void lcd_ek08009_power_off(void);
+
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int lcd_xxx; *//*Example*/
+struct lcd_parm_t lcd_ek08009_parm = {
+ .bits_per_pixel = 18,
+ .capability = LCD_CAP_CLK_HI,
+ .vmode = {
+ .name = "EKING EK08009",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = KHZ2PICOS(40000),
+ .left_margin = 46,
+ .right_margin = 210,
+ .upper_margin = 24,
+ .lower_margin = 12,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 162,
+ .height = 162,
+ .initial = lcd_ek08009_power_on,
+ .uninitial = lcd_ek08009_power_off,
+};
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void lcd_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+static void lcd_ek08009_power_on(void)
+{
+ DPRINT("lcd_ek08009_power_on\n");
+
+ /* TODO */
+}
+
+static void lcd_ek08009_power_off(void)
+{
+ DPRINT("lcd_ek08009_power_off\n");
+
+ /* TODO */
+}
+
+struct lcd_parm_t *lcd_ek08009_get_parm(int arg)
+{
+ return &lcd_ek08009_parm;
+}
+
+int lcd_ek08009_init(void)
+{
+ int ret;
+
+ ret = lcd_panel_register(LCD_EKING_EK08009,
+ (void *) lcd_ek08009_get_parm);
+ return ret;
+} /* End of lcd_oem_init */
+module_init(lcd_ek08009_init);
+
+/*--------------------End of Function Body -----------------------------------*/
+#undef LCD_EKING_EK08009_C
diff --git a/common/wmt_display/devices/lcd-HANNSTAR-HSD101PFW2.c b/common/wmt_display/devices/lcd-HANNSTAR-HSD101PFW2.c
new file mode 100755
index 0000000..438e3fe
--- /dev/null
+++ b/common/wmt_display/devices/lcd-HANNSTAR-HSD101PFW2.c
@@ -0,0 +1,103 @@
+/*++
+ * linux/drivers/video/wmt/lcd-HANNSTAR-HSD101PFW2.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define LCD_EKING_HSD101PFW2_C
+/* #define DEBUG */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../lcd.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define LCD_HSD101PFW2_XXXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define LCD_HSD101PFW2_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx lcd_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/
+static void lcd_HSD101PFW2_power_on(void);
+static void lcd_HSD101PFW2_power_off(void);
+
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int lcd_xxx; *//*Example*/
+struct lcd_parm_t lcd_HSD101PFW2_parm = {
+ .bits_per_pixel = 18,
+ .capability = 0,
+ .vmode = {
+ .name = "HANNSTAR HSD101PFW2",
+ .refresh = 60,
+ .xres = 1024,
+ .yres = 600,
+ .pixclock = KHZ2PICOS(45000),
+ .left_margin = 44,
+ .right_margin = 88,
+ .upper_margin = 10,
+ .lower_margin = 5,
+ .hsync_len = 44,
+ .vsync_len = 10,
+ .sync = FB_SYNC_VERT_HIGH_ACT,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 222,
+ .height = 125,
+ .initial = lcd_HSD101PFW2_power_on,
+ .uninitial = lcd_HSD101PFW2_power_off,
+};
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void lcd_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+static void lcd_HSD101PFW2_power_on(void)
+{
+ DPRINT("lcd_HSD101PFW2_power_on\n");
+
+ /* TODO */
+}
+
+static void lcd_HSD101PFW2_power_off(void)
+{
+ DPRINT("lcd_HSD101PFW2_power_off\n");
+
+ /* TODO */
+}
+
+struct lcd_parm_t *lcd_HSD101PFW2_get_parm(int arg)
+{
+ return &lcd_HSD101PFW2_parm;
+}
+
+int lcd_HSD101PFW2_init(void)
+{
+ int ret;
+
+ ret = lcd_panel_register(LCD_HANNSTAR_HSD101PFW2,
+ (void *) lcd_HSD101PFW2_get_parm);
+ return ret;
+} /* End of lcd_oem_init */
+module_init(lcd_HSD101PFW2_init);
+
+/*--------------------End of Function Body -----------------------------------*/
+#undef LCD_EKING_HSD101PFW2_C
diff --git a/common/wmt_display/devices/lcd-INNOLUX-AT070TN83.c b/common/wmt_display/devices/lcd-INNOLUX-AT070TN83.c
new file mode 100755
index 0000000..7c1da49
--- /dev/null
+++ b/common/wmt_display/devices/lcd-INNOLUX-AT070TN83.c
@@ -0,0 +1,118 @@
+/*++
+ * linux/drivers/video/wmt/lcd-INNOLUX-AT070TN83.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define LCD_INNOLUX_AT070TN83_C
+/* #define DEBUG */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../lcd.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define LCD_AT070TN83_XXXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define LCD_AT070TN83_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx lcd_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/
+static void lcd_at070tn83_initial(void);
+static void lcd_at070tn83_uninitial(void);
+
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int lcd_xxx; *//*Example*/
+struct lcd_parm_t lcd_at070tn83_parm = {
+ .bits_per_pixel = 18,
+ .capability = LCD_CAP_CLK_HI,
+ .vmode = {
+ .name = "INNOLUX AT707TN83",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(33333),
+ .left_margin = 45,
+ .right_margin = 210,
+ .upper_margin = 22,
+ .lower_margin = 22,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 154,
+ .height = 85,
+ .initial = lcd_at070tn83_initial,
+ .uninitial = lcd_at070tn83_uninitial,
+};
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void lcd_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+static void lcd_at070tn83_initial(void)
+{
+#if 0
+ outl(inl(GPIO_BASE_ADDR + 0x80) | BIT0, GPIO_BASE_ADDR + 0x80);
+ outl(inl(GPIO_BASE_ADDR + 0x4C) | BIT28, GPIO_BASE_ADDR + 0x4C);
+ outl(inl(GPIO_BASE_ADDR + 0x8C) | BIT28, GPIO_BASE_ADDR + 0x8C);
+ /* DVDD */
+ /* T2 > 0ms */ /* AVDD/VCOM(NANDQS) */
+ outl(inl(GPIO_BASE_ADDR + 0xCC) | BIT28, GPIO_BASE_ADDR + 0xCC);
+ /* T4 > 0ms */
+ /* VGH */
+ /* 0 < T6 <= 10ms */
+ lcd_enable_signal(1); /* signal, DVO enable */
+ lcd_oem_enable_backlight(200); /* T12 > 200ms, BL(bit0) */
+#endif
+}
+
+static void lcd_at070tn83_uninitial(void)
+{
+#if 0
+ /* BL(bit0) */
+ outl(inl(GPIO_BASE_ADDR + 0xC0) & ~BIT0, GPIO_BASE_ADDR + 0xC0);
+ mdelay(200); /* T12 > 200ms */
+ lcd_enable_signal(0); /* singal, DVO enable */
+ /* AVDD/VCOM(NANDQS) */
+ outl(inl(GPIO_BASE_ADDR + 0xCC) & ~BIT28, GPIO_BASE_ADDR + 0xCC);
+#endif
+}
+
+struct lcd_parm_t *lcd_at070tn83_get_parm(int arg)
+{
+ return &lcd_at070tn83_parm;
+}
+
+int lcd_at070tn83_init(void)
+{
+ int ret;
+
+ ret = lcd_panel_register(LCD_INNOLUX_AT070TN83,
+ (void *) lcd_at070tn83_get_parm);
+ return ret;
+} /* End of lcd_oem_init */
+module_init(lcd_at070tn83_init);
+
+/*--------------------End of Function Body -----------------------------------*/
+#undef LCD_INNOLUX_AT070TN83_C
diff --git a/common/wmt_display/devices/lcd-lvds-1024x600.c b/common/wmt_display/devices/lcd-lvds-1024x600.c
new file mode 100755
index 0000000..952a276
--- /dev/null
+++ b/common/wmt_display/devices/lcd-lvds-1024x600.c
@@ -0,0 +1,94 @@
+/*++
+ * linux/drivers/video/wmt/lcd-lvds-1024x600.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define LCD_LVDS_1024x600_C
+/* #define DEBUG */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../lcd.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define LCD_LVDS_1024x600_XXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define LCD_LVDS_1024x600_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx lcd_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/
+static void lcd_LVDS_1024x600_initial(void);
+
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int lcd_xxx; *//*Example*/
+struct lcd_parm_t lcd_LVDS_1024x600_parm = {
+ .bits_per_pixel = 24,
+ .capability = LCD_CAP_VSYNC_HI,
+ .vmode = {
+ .name = "ePAD 1024x600", /* LVDS_1024x600 */
+ .refresh = 60,
+ .xres = 1024,
+ .yres = 600,
+ .pixclock = KHZ2PICOS(45000),
+ .left_margin = 50,
+ .right_margin = 50,
+ .upper_margin = 10,
+ .lower_margin = 10,
+ .hsync_len = 4,
+ .vsync_len = 4,
+ .sync = FB_SYNC_VERT_HIGH_ACT,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 222,
+ .height = 125,
+ .initial = lcd_LVDS_1024x600_initial,
+};
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void lcd_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+static void lcd_LVDS_1024x600_initial(void)
+{
+ DPRINT("lcd_LVDS_1024x600_initial\n");
+
+ /* TODO */
+}
+
+struct lcd_parm_t *lcd_LVDS_1024x600_get_parm(int arg)
+{
+ return &lcd_LVDS_1024x600_parm;
+}
+
+int lcd_LVDS_1024x600_init(void)
+{
+ int ret;
+
+ ret = lcd_panel_register(LCD_LVDS_1024x600,
+ (void *) lcd_LVDS_1024x600_get_parm);
+ return ret;
+} /* End of lcd_oem_init */
+module_init(lcd_LVDS_1024x600_init);
+
+/*--------------------End of Function Body -----------------------------------*/
+#undef LCD_1024x600_C
diff --git a/common/wmt_display/devices/lcd-mipi-ssd2828.c b/common/wmt_display/devices/lcd-mipi-ssd2828.c
new file mode 100755
index 0000000..92d0b98
--- /dev/null
+++ b/common/wmt_display/devices/lcd-mipi-ssd2828.c
@@ -0,0 +1,375 @@
+/*
+ * ==========================================================================
+ *
+ * Filename: lcd-b079xan01.c
+ *
+ * Description:
+ *
+ * Version: 0.01
+ * Created: Thursday, December 27, 2012 02:50:05 HKT
+ *
+ * Author: Sam Mei (),
+ * Company:
+ *
+ * ==========================================================================
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/types.h>
+#include <asm/byteorder.h>
+
+#include "../../../board/wmt/include/wmt_spi.h"
+#include "../../../board/wmt/include/wmt_iomux.h"
+
+#include "../lcd.h"
+
+#define DELAY_MASK 0xff000000
+#define CHIPSELECT 0
+
+extern void spi1_write_then_read_data(unsigned char *wbuf, unsigned char *rbuf,
+ int num, int clk_mode, int chip_sel);
+
+static inline void __spi_write(u8 *buf, int len)
+{
+ spi1_write_then_read_data(buf, buf, sizeof(buf), SPI_MODE_3, CHIPSELECT);
+ udelay(10);
+}
+
+static void ssd2828_read(uint8_t reg, uint16_t *data)
+{
+ uint8_t buf1[3] = { 0x70, 0x00, 0x00 };
+ uint8_t buf2[3] = { 0x73, 0x00, 0x00 };
+
+ buf1[2] = reg;
+
+ spi1_write_then_read_data(buf1, buf1, sizeof(buf1), SPI_MODE_3, CHIPSELECT);
+ udelay(10);
+
+ spi1_write_then_read_data(buf2, buf1, sizeof(buf2), SPI_MODE_3, CHIPSELECT);
+ udelay(10);
+
+ *data = (buf1[1] << 8) | buf1[2];
+}
+
+static inline void spi_write_24bit(uint32_t data)
+{
+ uint8_t buf[3];
+
+ buf[0] = (data >> 16) & 0xff;
+ buf[1] = (data >> 8) & 0xff;
+ buf[2] = data & 0xff;
+
+ __spi_write(buf, 3);
+}
+
+static void ssd2828_reset(void)
+{
+ gpio_direction_output(14, 1);
+ mdelay(10);
+
+ gpio_direction_output(WMT_PIN_GP0_GPIO0, 1);
+ mdelay(10);
+ gpio_direction_output(WMT_PIN_GP0_GPIO0, 0);
+ mdelay(20);
+ gpio_direction_output(WMT_PIN_GP0_GPIO0, 1);
+ mdelay(20);
+}
+
+// BP080WX7
+
+static const uint32_t ssd2828_bp080wx7[] = {
+ 0x7000B1, // VSA=02 , HSA=02
+ 0x720202,
+ 0x7000B2, // VBP+VSA=8, HBP+HSA=40
+ 0x720828,
+ 0x7000B3, // VFP=04 , HFP=10
+ 0x72040A,
+ 0x7000B4, // HACT=1280
+ 0x720500,
+ 0x7000B5, // vACT=800
+ 0x720320,
+ 0x7000B6, // Non burst mode with sync event 24bpp
+ 0x720007,
+
+ //DELAY_MASK + 10,
+
+ 0x7000DE, // 4lanes
+ 0x720003,
+ 0x7000D6, //BGR
+ 0x720005,
+ 0x7000B9,
+ 0x720000,
+
+ //DELAY_MASK + 10,
+ 0x7000BA, //PLL=24*16 = 384MHz
+ 0x72C012,
+ 0x7000BB, //LP CLK=8.3MHz
+ 0x720008,
+ 0x7000B9,
+ 0x720001,
+
+ //DELAY_MASK + 200,
+ 0x7000B8, // Virtual Channel 0
+ 0x720000,
+
+ 0x7000B7, //LP Mode
+ 0x720342,
+
+ //DELAY_MASK + 10,
+ 0x7000BC,
+ 0x720000,
+ 0x700011, //sleep out
+
+ DELAY_MASK + 200,
+ 0x7000BC,
+ 0x720000,
+ 0x700029, //display on
+
+ // DELAY_MASK + 50, //Video Mode
+ 0x7000B7,
+ 0x72034B,
+
+ DELAY_MASK + 200,
+ 0x7000BC,
+ 0x720000,
+ 0x700029, //display on
+};
+
+static int bp080wx7_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ssd2828_bp080wx7); i++) {
+ if ((ssd2828_bp080wx7[i] & DELAY_MASK) == DELAY_MASK) {
+ mdelay(ssd2828_bp080wx7[i] & 0xff);
+ } else {
+ spi_write_24bit(ssd2828_bp080wx7[i]);
+ }
+ }
+
+ return 0;
+}
+
+static void lcd_bp080wx7_on(void)
+{
+ uint16_t id;
+
+ printf("%s\n", __FUNCTION__);
+ ssd2828_reset();
+
+ ssd2828_read(0xb0, &id);
+ if (id == 0x2828) {
+ printf("found SSD2828!\n");
+ bp080wx7_init();
+ lcd_enable_signal(1); /* singal on */
+ } else
+ printf("Error: SSD2828 not found! (0x%x)\n", id);
+}
+
+static void lcd_bp080wx7_off(void)
+{
+ lcd_enable_signal(0); /* singal on */
+ printf("lcd_b079xan01_power_off\n");
+}
+
+//Timing parameter for 3.0" QVGA LCD
+#define VBPD (6)
+#define VFPD (4)
+#define VSPW (2)
+
+#define HBPD (38)
+#define HFPD (10)
+#define HSPW (2)
+
+static struct lcd_parm_t lcd_bp080wx7_parm = {
+ .bits_per_pixel = 24,
+ .capability = 0,
+ .vmode = {
+ .name = "BP080WX7",
+ .refresh = 60,
+ .xres = 1280,
+ .yres = 800,
+ .pixclock = KHZ2PICOS(64800),
+ .left_margin = HBPD,
+ .right_margin = HFPD,
+ .upper_margin = VBPD,
+ .lower_margin = VFPD,
+ .hsync_len = HSPW,
+ .vsync_len = VSPW,
+ .sync = 0, //FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .initial = lcd_bp080wx7_on,
+ .uninitial = lcd_bp080wx7_off,
+};
+
+static struct lcd_parm_t *lcd_bp080wx7_get_parm(int arg)
+{
+ return &lcd_bp080wx7_parm;
+}
+
+// B079XAN01
+
+static const uint32_t ssd2828_b079xan01[] = {
+ 0x7000B1, //VSA=50, HAS=64
+ 0x723240,
+ 0x7000B2, //VBP=30+50, HBP=56+64
+ 0x725078,
+ 0x7000B3, //VFP=36, HFP=60
+ 0x72243C,
+ 0x7000B4, //HACT=768
+ 0x720300,
+ 0x7000B5, //VACT=1024
+ 0x720400,
+ 0x7000B6,
+ 0x72000b, //burst mode, 24bpp loosely packed
+ 0x7000DE, //no of lane=4
+ 0x720003,
+ 0x7000D6, //RGB order and packet number in blanking period
+ 0x720005,
+ 0x7000B9, //disable PLL
+ 0x720000,
+ 0x7000BA, //lane speed=576 (24MHz * 24 = 576)
+ 0x728018, //may modify according to requirement, 500Mbps to 560Mbps
+ 0x7000BB, //LP clock
+ 0x720008, // 576 / 9 / 8 = 8 MHz
+ 0x7000B9, //enable PPL
+ 0x720001,
+ 0x7000C4, //enable BTA
+ 0x720001,
+ 0x7000B7, //enter LP mode
+ 0x720342,
+ 0x7000B8, //VC
+ 0x720000,
+ 0x7000BC, //set packet size
+ 0x720000,
+ 0x700011, //sleep out cmd
+
+ DELAY_MASK + 200,
+ 0x700029, //display on
+ DELAY_MASK + 200,
+ 0x7000B7, //video mode on
+ 0x72030b,
+};
+
+static int b079xan01_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ssd2828_b079xan01); i++) {
+ if ((ssd2828_b079xan01[i] & DELAY_MASK) == DELAY_MASK) {
+ mdelay(ssd2828_b079xan01[i] & 0xff);
+ } else {
+ spi_write_24bit(ssd2828_b079xan01[i]);
+ }
+ }
+ return 0;
+}
+
+static void lcd_b079xan01_initial(void)
+{
+ uint16_t id;
+
+ printf("%s\n", __FUNCTION__);
+ ssd2828_reset();
+
+ ssd2828_read(0xb0, &id);
+ if (id == 0x2828) {
+ printf("found SSD2828!\n");
+ b079xan01_init();
+ lcd_enable_signal(1); /* singal on */
+ } else
+ printf("Error: SSD2828 not found! (0x%x)\n", id);
+}
+
+static void lcd_b079xan01_uninitial(void)
+{
+ lcd_enable_signal(0); /* singal on */
+ printf("lcd_b079xan01_power_off\n");
+}
+
+static struct lcd_parm_t lcd_b079xan01_parm = {
+ .bits_per_pixel = 24,
+ .capability = 0,
+ .vmode = {
+ .name = "B079XAN01",
+ .refresh = 60,
+ .xres = 768,
+ .yres = 1024,
+ .pixclock = KHZ2PICOS(64800),
+ .left_margin = 56,
+ .right_margin = 60,
+ .upper_margin = 30,
+ .lower_margin = 36,
+ .hsync_len = 64,
+ .vsync_len = 50,
+ .sync = 0, //FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .initial = lcd_b079xan01_initial,
+ .uninitial = lcd_b079xan01_uninitial,
+};
+
+static struct lcd_parm_t *lcd_b079xan01_get_parm(int arg)
+{
+ return &lcd_b079xan01_parm;
+}
+
+int lcd_ssd2828_init(void)
+{
+ lcd_panel_register(LCD_B079XAN01, (void *) lcd_b079xan01_get_parm);
+ lcd_panel_register(LCD_BP080WX7, (void *) lcd_bp080wx7_get_parm);
+ return 0;
+}
+
+module_init(lcd_ssd2828_init);
+
+static void ssd2828_register_dump(void)
+{
+ int reg;
+ uint16_t data;
+
+ for (reg = 0xb0; reg <= 0xff; reg++) {
+ ssd2828_read(reg, &data);
+ printf("reg 0x%02X : 0x%04x\n", reg, data);
+ }
+}
+
+static int do_b0lcd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ if (argc == 1)
+ return 0;
+
+ if (!strcmp(argv[1], "fill")) {
+ mv_Rect rect;
+ uint32_t color;
+
+ if (argc != 7) {
+ printf("hx fill left top right bottom color\n");
+ return 0;
+ }
+
+ rect.left = simple_strtoul(argv[2], NULL, 10);
+ rect.top = simple_strtoul(argv[3], NULL, 10);
+ rect.right = simple_strtoul(argv[4], NULL, 10);
+ rect.bottom = simple_strtoul(argv[5], NULL, 10);
+
+ color = simple_strtoul(argv[6], NULL, 16);
+
+ printf("fill %d %d %d %d 0x%x\n",
+ rect.left, rect.top, rect.right, rect.bottom, color);
+ mv_fillRect(&rect, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
+ } else if (!strcmp(argv[1], "dump")) {
+ ssd2828_register_dump();
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(b0, 10, 1, do_b0lcd,
+ "bmp - manipulate BMP image data\n",
+ "info <imageAddr> - display image info\n"
+ "bmp display <imageAddr> [x y] - display image at x,y\n");
diff --git a/common/wmt_display/devices/lcd-oem.c b/common/wmt_display/devices/lcd-oem.c
new file mode 100755
index 0000000..387f42c
--- /dev/null
+++ b/common/wmt_display/devices/lcd-oem.c
@@ -0,0 +1,408 @@
+/*++
+ * linux/drivers/video/wmt/lcd-oem.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define LCD_OEM_C
+/* #define DEBUG */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../lcd.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define LCD_OEM_XXXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define LCD_OEM_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx lcd_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/
+
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int lcd_xxx; *//*Example*/
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void lcd_xxx(void); *//*Example*/
+#ifdef CONFIG_UBOOT
+int lcd_bl_time;
+void lcd_uboot_set_backlight(void)
+{
+ int cur;
+ do {
+ wmt_read_ostc(&cur);
+ } while (cur < lcd_bl_time);
+ REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x800; /* BL( bit 11 ) */
+}
+
+#endif
+
+void lcd_oem_enable_backlight(int wait_ms)
+{
+#ifdef CONFIG_UBOOT
+ wmt_read_ostc(&lcd_bl_time);
+ lcd_bl_time += (wait_ms * 1000);
+#else
+ mdelay(wait_ms);
+ REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x800;
+#endif
+}
+
+#ifndef CONFIG_VPP_SHENZHEN
+static void lcd_oem_initial(void)
+{
+ outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, GPIO_BASE_ADDR + 0x80);
+ outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x801, GPIO_BASE_ADDR + 0xC0);
+ lcd_enable_signal(1);
+}
+
+static void lcd_oem_uninitial(void)
+{
+ outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x801, GPIO_BASE_ADDR + 0xC0);
+ lcd_enable_signal(0);
+}
+#endif
+
+struct lcd_parm_t lcd_oem_parm = {
+ .bits_per_pixel = 24,
+ .capability = LCD_CAP_VSYNC_HI,
+ .vmode = {
+ .name = "WonderMedia OEM LCD (VGA 1024x768)",
+ .refresh = 60,
+ .xres = 1024,
+ .yres = 768,
+ .pixclock = KHZ2PICOS(63500),
+ .left_margin = 152,
+ .right_margin = 48,
+ .upper_margin = 23,
+ .lower_margin = 3,
+ .hsync_len = 104,
+ .vsync_len = 4,
+ .sync = FB_SYNC_VERT_HIGH_ACT,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 222,
+ .height = 125,
+#ifndef CONFIG_VPP_SHENZHEN
+ .initial = lcd_oem_initial,
+ .uninitial = lcd_oem_uninitial
+#endif
+};
+
+#ifndef CONFIG_VPP_SHENZHEN
+static void lcd_oem_1024x600_initial(void)
+{
+ outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, GPIO_BASE_ADDR + 0x80);
+
+ /* DVDD */
+ /* T2 > 0ms */ /* AVDD/VCOM( bit 0 ) */
+ outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x01, GPIO_BASE_ADDR + 0xC0);
+ /* T4 > 0ms */
+ /* VGH */
+ /* 0 < T6 <= 10ms */
+ lcd_enable_signal(1); /* singal, DVO enable */
+ mdelay(200); /* T12 > 200ms */
+ outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x800, GPIO_BASE_ADDR + 0xC0);
+}
+
+static void lcd_oem_1024x600_uninitial(void)
+{
+ /* BL( bit 11 ) */
+ outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x800, GPIO_BASE_ADDR + 0xC0);
+ mdelay(200); /* T12 > 200ms */
+ lcd_enable_signal(0); /* singal, DVO enable */
+ /* AVDD/VCOM( bit 0 ) */
+ outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x01, GPIO_BASE_ADDR + 0xC0);
+}
+#endif
+
+struct lcd_parm_t lcd_oem_parm_1024x600 = {
+ .bits_per_pixel = 24,
+ .capability = LCD_CAP_VSYNC_HI,
+ .vmode = {
+#if 1 /* 7" HHX070ML208CP21A */
+ .name = "HHX070ML208CP21A",
+ .refresh = 60,
+ .xres = 1024,
+ .yres = 600,
+ .pixclock = KHZ2PICOS(51200),
+ .left_margin = 140,
+ .right_margin = 160,
+ .upper_margin = 20,
+ .lower_margin = 12,
+ .hsync_len = 20,
+ .vsync_len = 3,
+ .sync = FB_SYNC_VERT_HIGH_ACT,
+ .vmode = 0,
+ .flag = 0,
+#else
+ .name = "ePAD 1024x600", /* HannStar HSD070PFW3 */
+ .refresh = 60,
+ .xres = 1024,
+ .yres = 600,
+ .pixclock = KHZ2PICOS(45000),
+ .left_margin = 50,
+ .right_margin = 50,
+ .upper_margin = 10,
+ .lower_margin = 10,
+ .hsync_len = 4,
+ .vsync_len = 4,
+ .sync = FB_SYNC_VERT_HIGH_ACT,
+ .vmode = 0,
+ .flag = 0,
+#endif
+ },
+#ifndef CONFIG_VPP_SHENZHEN
+ .initial = lcd_oem_1024x600_initial,
+ .uninitial = lcd_oem_1024x600_uninitial,
+#endif
+};
+
+struct lcd_parm_t lcd_oem_parm_1024x768 = {
+ .bits_per_pixel = 24,
+ .capability = LCD_CAP_VSYNC_HI,
+ .vmode = {
+ .name = "OEM 1024x768", /* VGA 1024x768 */
+ .refresh = 60,
+ .xres = 1024,
+ .yres = 768,
+ .pixclock = KHZ2PICOS(63500),
+ .left_margin = 152,
+ .right_margin = 48,
+ .upper_margin = 23,
+ .lower_margin = 3,
+ .hsync_len = 104,
+ .vsync_len = 4,
+ .sync = FB_SYNC_VERT_HIGH_ACT,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 222,
+ .height = 125,
+#ifndef CONFIG_VPP_SHENZHEN
+ .initial = lcd_oem_initial,
+ .uninitial = lcd_oem_uninitial
+#endif
+};
+
+struct lcd_parm_t lcd_oem_parm_1366x768 = {
+ .bits_per_pixel = 18,
+ .capability = LCD_CAP_CLK_HI,
+ .vmode = {
+ .name = "OEM 1366X768",
+ .refresh = 60,
+ .xres = 1366,
+ .yres = 768,
+ .pixclock = KHZ2PICOS(75440),
+ .left_margin = 98,
+ .right_margin = 31,
+ .upper_margin = 22,
+ .lower_margin = 4,
+ .hsync_len = 65,
+ .vsync_len = 12,
+ .sync = 0,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 293,
+ .height = 164,
+#ifndef CONFIG_VPP_SHENZHEN
+ .initial = lcd_oem_initial,
+ .uninitial = lcd_oem_uninitial
+#endif
+};
+
+struct lcd_parm_t lcd_oem_parm_480x800 = {
+ .bits_per_pixel = 18,
+ .capability = LCD_CAP_CLK_HI,
+ .vmode = {
+ .name = "OEM 480x800",
+ .refresh = 60,
+ .xres = 480,
+ .yres = 800,
+ .pixclock = KHZ2PICOS(27000),
+ .left_margin = 78,
+ .right_margin = 78,
+ .upper_margin = 60,
+ .lower_margin = 60,
+ .hsync_len = 4,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = 0,
+ .flag = 0,
+ },
+#ifndef CONFIG_VPP_SHENZHEN
+ .initial = lcd_oem_initial,
+ .uninitial = lcd_oem_uninitial
+#endif
+};
+
+struct lcd_parm_t lcd_oem_parm_800x480 = {
+ .bits_per_pixel = 18,
+ .capability = LCD_CAP_CLK_HI,
+ .vmode = {
+ .name = "OEM 800x480",
+ .refresh = 48,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(27000),
+ .left_margin = 50,
+ .right_margin = 50,
+ .upper_margin = 17,
+ .lower_margin = 16,
+ .hsync_len = 10,
+ .vsync_len = 5,
+ .sync = 0,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 154,
+ .height = 85,
+#ifndef CONFIG_VPP_SHENZHEN
+ .initial = lcd_oem_initial,
+ .uninitial = lcd_oem_uninitial
+#endif
+};
+
+#ifndef CONFIG_VPP_SHENZHEN
+static void lcd_oem_1280x800_initial(void)
+{
+ DBG_MSG("lcd 10 power sequence\n");
+ outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801, GPIO_BASE_ADDR + 0x80);
+
+ /* VDD on */
+ /* 0 < T < 50ms */
+ lcd_enable_signal(1); /* singal on */
+ /* VGH,VGL low */ /* AVDD/VCOM( bit 0 ) */
+ outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x01, GPIO_BASE_ADDR + 0xC0);
+ mdelay(150); /* T5 > 120ms */
+ outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x800, GPIO_BASE_ADDR + 0xC0);
+}
+
+static void lcd_oem_1280x800_uninitial(void)
+{
+ /* turn off backlight */
+ outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x800, GPIO_BASE_ADDR + 0xC0);
+ mdelay(150);
+ /* turn off LCD */
+ outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x01, GPIO_BASE_ADDR + 0xC0);
+ lcd_enable_signal(0); /* turn off singal */
+}
+#endif
+
+struct lcd_parm_t lcd_oem_parm_800x1280 = {
+ .bits_per_pixel = 24,
+ .capability = LCD_CAP_CLK_HI,
+ .vmode = {
+ .name = "WY101ML369IN30A",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 1280,
+ .pixclock = KHZ2PICOS(71100),
+ .left_margin = 70,
+ .right_margin = 80,
+ .upper_margin = 10,
+ .lower_margin = 10,
+ .hsync_len = 10,
+ .vsync_len = 3,
+ .sync = 0,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 135,
+ .height = 217,
+#ifndef CONFIG_VPP_SHENZHEN
+ .initial = lcd_oem_1280x800_initial,
+ .uninitial = lcd_oem_1280x800_uninitial,
+#endif
+};
+
+struct lcd_parm_t lcd_oem_parm_1280x800 = {
+ .bits_per_pixel = 24,
+ .capability = LCD_CAP_CLK_HI,
+ .vmode = {
+ .name = "WY101ML369IN30A",
+ .refresh = 60,
+ .xres = 1280,
+ .yres = 800,
+ .pixclock = KHZ2PICOS(71100),
+ .left_margin = 70,
+ .right_margin = 80,
+ .upper_margin = 10,
+ .lower_margin = 10,
+ .hsync_len = 10,
+ .vsync_len = 3,
+ .sync = 0,
+ .vmode = 0,
+ .flag = 0,
+ },
+ .width = 217,
+ .height = 135,
+#ifndef CONFIG_VPP_SHENZHEN
+ .initial = lcd_oem_1280x800_initial,
+ .uninitial = lcd_oem_1280x800_uninitial,
+#endif
+};
+
+/*----------------------- Function Body --------------------------------------*/
+struct lcd_parm_t *lcd_oem_get_parm(int arg)
+{
+ return &lcd_oem_parm;
+}
+
+int lcd_oem_init(void)
+{
+ int ret;
+
+ ret = lcd_panel_register(LCD_WMT_OEM, (void *)lcd_oem_get_parm);
+ return ret;
+} /* End of lcd_oem_init */
+module_init(lcd_oem_init);
+
+struct lcd_parm_t *lcd_get_oem_parm(int resx, int resy)
+{
+ struct lcd_parm_t *oem_parm[] = {
+ &lcd_oem_parm_480x800,
+ &lcd_oem_parm_1024x600,
+ &lcd_oem_parm_1024x768,
+ &lcd_oem_parm_1366x768,
+ &lcd_oem_parm_800x480,
+ &lcd_oem_parm_800x1280,
+ &lcd_oem_parm_1280x800,
+ 0
+ };
+ struct lcd_parm_t *p;
+ int i;
+
+ for (i = 0; ; i++) {
+ p = oem_parm[i];
+ if (p == 0) {
+ p = oem_parm[0];
+ break;
+ }
+ if ((resx == p->vmode.xres) && (resy == p->vmode.yres))
+ break;
+ }
+ return p;
+}
+/*--------------------End of Function Body -----------------------------------*/
+#undef LCD_OEM_C
diff --git a/common/wmt_display/devices/lcd-setup.c b/common/wmt_display/devices/lcd-setup.c
new file mode 100755
index 0000000..6653fdc
--- /dev/null
+++ b/common/wmt_display/devices/lcd-setup.c
@@ -0,0 +1,212 @@
+/*
+ * ==========================================================================
+ *
+ * Filename: lcd-spi.c
+ *
+ * Description:
+ *
+ * Version: 0.01
+ * Created: Thursday, December 27, 2012 02:50:05 HKT
+ *
+ * Author: Sam Mei (),
+ * Company:
+ *
+ * ==========================================================================
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/types.h>
+#include <asm/errno.h>
+#include <asm/byteorder.h>
+
+#include "../../../board/wmt/include/wmt_spi.h"
+#include "../../../board/wmt/include/wmt_iomux.h"
+
+#include "../lcd.h"
+
+#define CHIPSELECT 0
+
+#ifndef SPI_GPIO
+static void spi_ctrl_9bit_tx(u8 val, int cmd_data)
+{
+ uint8_t buf[2],rbuf[2];
+
+ if (cmd_data)
+ buf[0] = (val >> 1) | BIT7;
+ else
+ buf[0] = (val >> 1) & 0x7f;
+
+ buf[1] = (val << 7);
+
+ spi_write_then_read_data(buf, rbuf, sizeof(buf), SPI_MODE_1, CHIPSELECT);
+}
+
+#else
+
+#define CLK WMT_PIN_GP12_SPI0CLK
+#define MOSI WMT_PIN_GP12_SPI0MOSI
+#define MISO WMT_PIN_GP12_SPI0MISO
+#define SS WMT_PIN_GP12_SPI0SS0
+
+static void spi_gpio_9bit_tx(u8 val, int cmd_data)
+{
+ int i;
+
+ // CS
+ gpio_direction_output(SS, 1);
+ gpio_direction_output(SS, 0);
+
+ // D/C
+ gpio_direction_output(MOSI, cmd_data);
+ gpio_direction_output(CLK, 0);
+ gpio_direction_output(CLK, 1);
+
+ // 8-bit value
+ for (i = 7; i >= 0; i--) {
+ gpio_direction_output(MOSI, !!(val & (1 << i)));
+ gpio_direction_output(CLK, 0);
+ gpio_direction_output(CLK, 1);
+ }
+
+ // CS
+ gpio_direction_output(SS, 1);
+}
+#endif
+
+static inline void spi_9bit_tx(u8 val, int cmd_data)
+{
+#ifdef SPI_GPIO
+ spi_gpio_9bit_tx(val, cmd_data);
+#else
+ spi_ctrl_9bit_tx(val, cmd_data);
+#endif
+}
+
+static int ts8224b_cmd(u8 cmd)
+{
+ spi_9bit_tx(cmd, 0);
+ return 0;
+}
+
+static int ts8224b_data(u8 data)
+{
+ spi_9bit_tx(data, 1);
+ return 0;
+}
+
+/*
+ * setenv wmt.lcd.setup 0
+ * setenv wmt.display.param 2:0:24:1024:600:60
+ * setenv wmt.display.tmr 30000:0:78:78:480:78:4:60:800:60
+ */
+static int ts8224b_init(void)
+{
+
+ static uint16_t settings[] = {
+ #include "ts8224b.h"
+ };
+ int i;
+
+ printf(" ## %s \n", __FUNCTION__);
+ for (i = 0; i < ARRAY_SIZE(settings); i += 2) {
+ ts8224b_cmd(settings[i] >> 8);
+ ts8224b_data(settings[i+1]);
+ }
+
+ ts8224b_cmd(0x11);
+ mdelay(120);
+
+ ts8224b_cmd(0x29);
+ mdelay(50);
+ ts8224b_cmd(0x2c);
+ return 0;
+}
+
+static int i2c_write(int i2c_idx, uint8_t reg, uint8_t value)
+{
+ unsigned char data[2] = { reg, value };
+ struct i2c_msg_s msg[1] = {
+ {
+ .addr = 0xE0 >> 1,
+ .flags = I2C_M_WR,
+ .len = 2,
+ .buf = data,
+ },
+ };
+
+ if (wmt_i2c_transfer(&msg[0], 1, i2c_idx) > 0)
+ return 0;
+
+ printf(" ## lcd i2c1 write error %s, %d\n", __func__, __LINE__);
+ return -1;
+}
+
+static uint8_t init_data[] = {
+ 0x4b, 0x01,
+ 0x0c, 0x01,
+ 0x05, 0x03,
+ 0x41, 0x03,
+ 0x10, 0x06,
+ 0x11, 0xE0,
+ 0x12, 0x00,
+ 0x13, 0x3C,
+ 0x14, 0x06,
+ 0x15, 0x40,
+ 0x16, 0x03,
+ 0x17, 0x9E,
+ 0x18, 0x00,
+ 0x19, 0x10,
+ 0x1a, 0x03,
+ 0x1b, 0x84,
+ 0x1c, 0x80,
+ 0x1d, 0x0A,
+ 0x1e, 0x80,
+ 0x1f, 0x06,
+ 0x3c, 0x17,
+ 0x3e, 0x16,
+ 0x36, 0x00,
+ 0x31, 0x00,
+ 0x35, 0x41,
+ 0x30, 0xB0,
+ 0x30, 0xB1,
+ 0x00, 0x0B,
+};
+
+static int chunghwa_init(void)
+{
+ int i;
+
+ printf(" ## %s, %d\n", __FUNCTION__, __LINE__);
+ for (i = 0; i < ARRAY_SIZE(init_data); i += 2) {
+ i2c_write(1, init_data[i], init_data[i+1]);
+ }
+
+ return 0;
+}
+
+enum {
+ LCD_SETUP_TS8224B,
+ LCD_SETUP_CHUNGHWA,
+ LCD_SETUP_MAX,
+};
+
+int lcd_spi_setup(void)
+{
+ int id;
+ char *s = getenv("wmt.lcd.setup");
+
+ if (!s)
+ return -ENODEV;
+
+ id = simple_strtoul(s, NULL, 10);
+ switch (id) {
+ case LCD_SETUP_TS8224B:
+ return ts8224b_init();
+ case LCD_SETUP_CHUNGHWA:
+ return chunghwa_init();
+ default:
+ return -EINVAL;
+ }
+}
+
diff --git a/common/wmt_display/devices/lcd.c b/common/wmt_display/devices/lcd.c
new file mode 100755
index 0000000..2e42a95
--- /dev/null
+++ b/common/wmt_display/devices/lcd.c
@@ -0,0 +1,448 @@
+/*++
+ * linux/drivers/video/wmt/lcd.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define LCD_C
+#undef DEBUG
+/* #define DEBUG */
+/* #define DEBUG_DETAIL */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#ifdef CONFIG_KERNEL
+#include <linux/gpio.h>
+#endif
+#include "../lcd.h"
+#include "../vout.h"
+
+#ifdef CONFIG_VPP_SHENZHEN
+#include "../../../board/wmt/include/wmt_iomux.h"
+#endif
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define LCD_XXXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define LCD_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx lcd_xxx_t; *//*Example*/
+struct lcd_device_t {
+ struct lcd_parm_t* (*get_parm)(int arg);
+};
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int lcd_xxx; *//*Example*/
+struct lcd_device_t lcd_device_array[LCD_PANEL_MAX];
+int lcd_panel_on = 1;
+int lcd_pwm_enable;
+enum lcd_panel_t lcd_panel_id = LCD_PANEL_MAX;
+int lcd_panel_bpp = 24;
+
+struct vout_dev_t lcd_vout_dev_ops;
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void lcd_xxx(void); *//*Example*/
+enum lcd_panel_t lcd_lvds_id = LCD_PANEL_MAX;
+int lcd_type;
+
+/*----------------------- Function Body --------------------------------------*/
+/*----------------------- Backlight --------------------------------------*/
+void lcd_set_type(int type)
+{
+ lcd_type = type; /* 0-LCD, 1-LVDS */
+}
+
+int lcd_get_type(void)
+{
+ return lcd_type;
+}
+
+#ifdef CONFIG_VPP_SHENZHEN
+
+#define MAX_LCD_GPIO_NUM 5
+
+static struct {
+ int gpio;
+ int active;
+} lcd_power[MAX_LCD_GPIO_NUM] = {{-1, 0}};
+
+static int parse_uboot_param(void)
+{
+ char buf[64];
+ unsigned int parm[32];
+ int l = sizeof(buf);
+ int i, gpio_num;
+
+ for(i = 0; i < MAX_LCD_GPIO_NUM; i++)
+ lcd_power[i].gpio = -1;
+
+ /*
+ * In hardware, maybe there are several gpio to control LCD power
+ * We can set the wmt.lcd.power as follows:
+ * setenv wmt.lcd.power gpio0:active0,gpio1:active1,....,gpio4:active4
+ */
+ if (wmt_getsyspara("wmt.lcd.power", buf, &l)) {
+ DBG_ERR("please set wmt.lcd.power\n");
+ return -22;
+ }
+
+ i = vpp_parse_param(buf, parm, 2 * MAX_LCD_GPIO_NUM, 0);
+ gpio_num = i / 2;
+
+ for(i = 0; i < gpio_num; i++) {
+
+ lcd_power[i].gpio = parm[i * 2];
+ lcd_power[i].active = parm[i * 2 + 1];
+
+ printf("lcd power%d: gpio%d, active %d\n",
+ i, lcd_power[i].gpio, lcd_power[i].active);
+ }
+
+ return 0;
+}
+
+void lcd_power_on(bool on)
+{
+ int i;
+
+ for(i = 0; i < MAX_LCD_GPIO_NUM; i++) {
+ if (lcd_power[i].gpio < 0)
+ return;
+
+ gpio_direction_output(lcd_power[i].gpio, on ?
+ lcd_power[i].active : !lcd_power[i].active);
+
+ DBG_MSG("lcd_power_on: i = %d, on = %d, gpio = %d, active = %d\n",
+ i, on, lcd_power[i].gpio, lcd_power[i].active);
+ }
+}
+
+#endif
+
+void lcd_set_lvds_id(int id)
+{
+ lcd_lvds_id = id;
+}
+
+int lcd_get_lvds_id(void)
+{
+ return lcd_lvds_id;
+}
+
+void lcd_set_parm(int id, int bpp)
+{
+ lcd_panel_id = id;
+ lcd_panel_bpp = bpp;
+}
+
+struct lcd_parm_t *lcd_get_parm(enum lcd_panel_t id, unsigned int arg)
+{
+ struct lcd_device_t *p;
+
+ p = &lcd_device_array[id];
+ if (p && p->get_parm)
+ return p->get_parm(arg);
+ return 0;
+}
+
+struct vout_dev_t *lcd_get_dev(void)
+{
+ if (lcd_panel_id >= LCD_PANEL_MAX)
+ return 0;
+ return &lcd_vout_dev_ops;
+}
+
+#ifdef CONFIG_KERNEL
+static DEFINE_SEMAPHORE(lcd_sem);
+#endif
+void lcd_set_mutex(int lock)
+{
+#ifdef CONFIG_KERNEL
+ if (lock)
+ down(&lcd_sem);
+ else
+ up(&lcd_sem);
+#endif
+}
+
+void lcd_set_enable(int enable)
+{
+ DBG_MSG("%d\n", enable);
+ if (!p_lcd)
+ return;
+
+ lcd_set_mutex(1);
+ if (enable) {
+ if (p_lcd->initial)
+ p_lcd->initial();
+ else {
+ lcd_enable_signal(1); /* singal enable */
+#ifndef CONFIG_VPP_SHENZHEN
+ outl(inl(GPIO_BASE_ADDR + 0x80) | 0x801,
+ GPIO_BASE_ADDR + 0x80);
+ outl(inl(GPIO_BASE_ADDR + 0xC0) | 0x801,
+ GPIO_BASE_ADDR + 0xC0);
+#endif
+ }
+ } else {
+ if (p_lcd->uninitial)
+ p_lcd->uninitial();
+ else {
+ lcd_enable_signal(0); /* singal disable */
+#ifndef CONFIG_VPP_SHENZHEN
+ outl(inl(GPIO_BASE_ADDR + 0xC0) & ~0x801,
+ GPIO_BASE_ADDR + 0xC0);
+#endif
+ }
+ }
+ lcd_set_mutex(0);
+}
+
+void lcd_enable_signal(int enable)
+{
+ int hdmi_off;
+
+ DBG_MSG("%d\n", enable);
+ if (lcd_get_type()) { /* LVDS */
+ /* TODO */
+ } else { /* LCD */
+ govrh_set_dvo_enable(p_govrh2, enable);
+ }
+
+ hdmi_off = (govrh_get_MIF_enable(p_govrh)) ? 0 : 1;
+ vpp_set_clock_enable(DEV_DVO, (hdmi_off && !enable) ? 0 : 1, 1);
+}
+
+#ifdef __KERNEL__
+/*----------------------- LCD --------------------------------------*/
+static int __init lcd_arg_panel_id
+(
+ char *str /*!<; // argument string */
+)
+{
+ sscanf(str, "%d", (int *) &lcd_panel_id);
+ if (lcd_panel_id >= LCD_PANEL_MAX)
+ lcd_panel_id = LCD_PANEL_MAX;
+ DBGMSG(KERN_INFO "set lcd panel id = %d\n", lcd_panel_id);
+ return 1;
+} /* End of lcd_arg_panel_id */
+
+__setup("lcdid=", lcd_arg_panel_id);
+#endif
+int lcd_panel_register(int no, void (*get_parm)(int mode))
+{
+ struct lcd_device_t *p;
+
+ if (no >= LCD_PANEL_MAX) {
+ DBGMSG(KERN_ERR "*E* lcd device no max is %d !\n",
+ LCD_PANEL_MAX);
+ return -1;
+ }
+
+ p = &lcd_device_array[no];
+ if (p->get_parm) {
+ DBGMSG(KERN_ERR "*E* lcd device %d exist !\n", no);
+ return -1;
+ }
+ p->get_parm = (void *) get_parm;
+ return 0;
+} /* End of lcd_device_register */
+
+/*----------------------- vout device plugin --------------------------------*/
+void lcd_set_power_down(int enable)
+{
+#ifdef CONFIG_VPP_SHENZHEN
+ static int save_state = -1;
+
+ if (save_state != enable) {
+ /* lcd enable control by user */
+ lcd_power_on(enable ? 0: 1);
+ lcd_set_enable(enable ? 0 : 1);
+ save_state = enable;
+ }
+#endif
+}
+
+#ifdef CONFIG_VPP_SHENZHEN
+void lcd_backlight_power_on(int on)
+{
+ if (parse_backlight_params())
+ return;
+
+ if (g_backlight_param.gpio < 0)
+ return;
+
+ gpio_direction_output(g_backlight_param.gpio,
+ on ? g_backlight_param.active : !g_backlight_param.active);
+}
+#endif
+
+static void wmt_config_govrh_polar(struct vout_t *vo)
+{
+ /* wmt.display.polar [clock polar]:[hsync polart]:[vsync polar]*/
+ char buf[64];
+ int l = sizeof(buf);
+ int clk_pol, hsync_pol, vsync_pol;
+ unsigned int parm[3];
+
+ if (wmt_getsyspara("wmt.display.polar", buf, &l))
+ return;
+
+ vpp_parse_param(buf, (unsigned int *)parm, 3, 0);
+ clk_pol = parm[0];
+ hsync_pol = parm[1];
+ vsync_pol = parm[2];
+ DBG_MSG("govrh polar: clk-pol %d, hsync %d, vsync %d\n",
+ clk_pol, hsync_pol, vsync_pol);
+ govrh_set_dvo_clock_delay(vo->govr, clk_pol ? 0 : 1, 0);
+ govrh_set_dvo_sync_polar(vo->govr,
+ hsync_pol ? 0 : 1, vsync_pol ? 0 : 1);
+}
+
+int lcd_set_mode(unsigned int *option)
+{
+ struct vout_t *vo;
+ enum vout_inf_mode_t inf_mode;
+
+ DBG_MSG("option %d,%d\n", option[0], option[1]);
+
+ vo = lcd_vout_dev_ops.vout;
+ inf_mode = vo->inf->mode;
+ if (option) {
+ unsigned int capability;
+
+ if (lcd_panel_id == 0)
+ p_lcd = lcd_get_oem_parm(vo->resx, vo->resy);
+ else
+ p_lcd = lcd_get_parm(lcd_panel_id, lcd_panel_bpp);
+
+ if (!p_lcd) {
+ DBG_ERR("lcd %d not support\n", lcd_panel_id);
+ return -1;
+ }
+ DBG_MSG("[%s] %s (id %d,bpp %d)\n", vout_inf_str[inf_mode],
+ p_lcd->vmode.name, lcd_panel_id, lcd_panel_bpp);
+ capability = p_lcd->capability;
+ switch (inf_mode) {
+ case VOUT_INF_LVDS:
+ lvds_set_sync_polar(
+ (capability & LCD_CAP_HSYNC_HI) ? 0 : 1,
+ (capability & LCD_CAP_VSYNC_HI) ? 0 : 1);
+ lvds_set_rgb_type(lcd_panel_bpp);
+ break;
+ case VOUT_INF_DVI:
+ govrh_set_dvo_clock_delay(vo->govr,
+ (capability & LCD_CAP_CLK_HI) ? 0 : 1, 0);
+ govrh_set_dvo_sync_polar(vo->govr,
+ (capability & LCD_CAP_HSYNC_HI) ? 0 : 1,
+ (capability & LCD_CAP_VSYNC_HI) ? 0 : 1);
+ switch (lcd_panel_bpp) {
+ case 15:
+ govrh_IGS_set_mode(vo->govr, 0, 1, 1);
+ break;
+ case 16:
+ govrh_IGS_set_mode(vo->govr, 0, 3, 1);
+ break;
+ case 18:
+ govrh_IGS_set_mode(vo->govr, 0, 2, 1);
+ break;
+ case 24:
+ govrh_IGS_set_mode(vo->govr, 0, 0, 0);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ } else
+ p_lcd = 0;
+
+ wmt_config_govrh_polar(vo);
+ return 0;
+}
+
+int lcd_check_plugin(int hotplug)
+{
+ return (p_lcd) ? 1 : 0;
+}
+
+int lcd_get_edid(char *buf)
+{
+ return 1;
+}
+
+int lcd_config(struct vout_info_t *info)
+{
+ info->resx = p_lcd->vmode.xres;
+ info->resy = p_lcd->vmode.yres;
+ info->fps = p_lcd->vmode.refresh;
+ return 0;
+}
+
+int lcd_init(struct vout_t *vo)
+{
+ DBG_MSG("%d\n", lcd_panel_id);
+
+ /* vo_set_lcd_id(LCD_CHILIN_LW0700AT9003); */
+ if (lcd_panel_id >= LCD_PANEL_MAX)
+ return -1;
+
+ if (lcd_panel_id == 0)
+ p_lcd = lcd_get_oem_parm(vo->resx, vo->resy);
+ else
+ p_lcd = lcd_get_parm(lcd_panel_id, 24);
+
+ if (p_lcd == 0)
+ return -1;
+
+ /* set default parameters */
+ vo->resx = p_lcd->vmode.xres;
+ vo->resy = p_lcd->vmode.yres;
+ vo->pixclk = PICOS2KHZ(p_lcd->vmode.pixclock) * 1000;
+ return 0;
+}
+
+struct vout_dev_t lcd_vout_dev_ops = {
+ .name = "LCD",
+ .mode = VOUT_INF_DVI,
+ .capability = VOUT_DEV_CAP_FIX_RES + VOUT_DEV_CAP_FIX_PLUG,
+
+ .init = lcd_init,
+ .set_power_down = lcd_set_power_down,
+ .set_mode = lcd_set_mode,
+ .config = lcd_config,
+ .check_plugin = lcd_check_plugin,
+ .get_edid = lcd_get_edid,
+};
+
+int lcd_module_init(void)
+{
+ parse_uboot_param();
+
+ vout_device_register(&lcd_vout_dev_ops);
+ return 0;
+} /* End of lcd_module_init */
+module_init(lcd_module_init);
+/*--------------------End of Function Body -----------------------------------*/
+#undef LCD_C
diff --git a/common/wmt_display/devices/sil902x.c b/common/wmt_display/devices/sil902x.c
new file mode 100755
index 0000000..186bb02
--- /dev/null
+++ b/common/wmt_display/devices/sil902x.c
@@ -0,0 +1,74 @@
+/*++
+ * linux/drivers/video/wmt/sil902x.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define SIL902X_C
+/*--------------------------------------------------------------------*
+SiI902x Software customization for PC platform.
+Based on :
+ Video input configuration=
+ 24 bit RGB in + Hsync + Vsync + DE + PCLK
+ rising edge is the 1st clock after DE=High
+ Audio input configuration=
+ SPDIF, word size, sample frequency all refer to stream header
+
+ SiI902x i2c device address=0x72. ( CI2CA pin=LOW)
+//================== i2c routine =========================
+SiI902x i2c max speed is 100KHz.
+A version max speed is 400KHz
+
+Data = I2C_ReadByte(TX_SLAVE_ADDR, RegOffset);
+I2C_WriteByte(TPI_BASE_ADDR, RegOffset, Data);
+I2C_WriteBlock(TPI_BASE_ADDR, TPI_Offset, pData, NBytes);
+I2C_ReadBlock(TPI_BASE_ADDR, TPI_Offset, pData, NBytes);
+
+------------------------------------------------------------------------------*/
+//#define DEBUG
+//#define DEBUG_DETAIL
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../vout.h"
+#include "sil902x.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define SIL902X_XXXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define SIL902X_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx sil902x_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in sil902x.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int sil902x_xxx; *//*Example*/
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void sil902x_xxx(void); *//*Example*/
+int sil902x_module_init(void)
+{
+// vout_device_register(&sil902x_vout_dev_ops);
+ return 0;
+} /* End of sil902x_module_init */
+module_init(sil902x_module_init);
+/*--------------------End of Function Body -----------------------------------*/
+#undef SIL902X_C
+
diff --git a/common/wmt_display/devices/sil902x.h b/common/wmt_display/devices/sil902x.h
new file mode 100755
index 0000000..a7e0f0d
--- /dev/null
+++ b/common/wmt_display/devices/sil902x.h
@@ -0,0 +1,71 @@
+/*++
+ * linux/drivers/video/wmt/devices/sil902x.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef SIL902X_H
+/* To assert that only one occurrence is included */
+#define SIL902X_H
+/*-------------------- MODULE DEPENDENCY -------------------------------------*/
+
+/* following is the C++ header */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------- EXPORTED PRIVATE CONSTANTS ----------------------------*/
+/* #define SIL902X_XXXX 1 *//*Example*/
+#define SIL902X_STATUS_ARG_NUM 3
+
+/*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/
+/* typedef void sil902x_xxx_t; *//*Example*/
+typedef struct {
+ int (*init)(void);
+ int (*poll)(void);
+ void (*cp_enable)(int enable);
+ void (*get_status)(int *arg);
+ void (*config)(int vic);
+} sil902x_ko_ops_t;
+
+/*-------------------- EXPORTED PRIVATE VARIABLES -----------------------------*/
+#ifdef SIL902X_C /* allocate memory for variables only in xxx.c */
+#define EXTERN
+#else
+#define EXTERN extern
+#endif /* ifdef SIL902X_C */
+
+/* EXTERN int sil902x_xxx; *//*Example*/
+EXTERN void sil902x_init_module(int ko);
+EXTERN int sil902x_enable_access(void);
+EXTERN int sil902x_get_cp_support(void);
+
+#undef EXTERN
+
+/*--------------------- EXPORTED PRIVATE MACROS -------------------------------*/
+/* #define SIL902X_XXX_YYY xxxx *//*Example*/
+/*--------------------- EXPORTED PRIVATE FUNCTIONS ---------------------------*/
+/* extern void sil902x_xxx(void); *//*Example*/
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ifndef SIL902X_H */
+
diff --git a/common/wmt_display/devices/ts8224b.h b/common/wmt_display/devices/ts8224b.h
new file mode 100755
index 0000000..8786628
--- /dev/null
+++ b/common/wmt_display/devices/ts8224b.h
@@ -0,0 +1,446 @@
+#ifndef _TS8224B_H_
+#define _TS8224B_H_
+
+//Enable Page1 hsd4.0
+0xFF00, 0x55,
+0xFF01, 0xAA,
+0xFF02, 0x52,
+0xFF03, 0x08,
+0xFF04, 0x80,
+
+0xF200, 0x00,
+0xF201, 0x84,
+0xF202, 0x02,
+
+0xF40A, 0x13,
+
+0xF000, 0x55,
+0xF001, 0xAA,
+0xF002, 0x52,
+0xF003, 0x08,
+0xF004, 0x01,
+
+0xB000, 0x0D,
+0xB001, 0x0D,
+0xB002, 0x0D,
+
+0xB600, 0x34,
+0xB601, 0x34,
+0xB602, 0x34,
+
+0xB100, 0x0D,
+0xB101, 0x0D,
+0xB102, 0x0D,
+
+// AVEE: manual, -6V : -2.5xVCI)
+0xB700, 0x34,
+0xB701, 0x34,
+0xB702, 0x34,
+
+//Power Control for VCL
+0xB200, 0x00,
+0xB201, 0x00,
+0xB202, 0x00,
+
+0xB800, 0x24,
+0xB801, 0x24,
+0xB802, 0x24,
+
+// VGH: Clamp Enable, 2*AVDD-AVEE, //11V
+0xBF00, 0X01,
+
+0xB300, 0x0F,
+0xB301, 0x0F,
+0xB302, 0x0F,
+
+0xB900, 0x34,//34
+0xB901, 0x34,
+0xB902, 0x34,
+
+// VGL_REG(VGLO):-10V
+0xB500, 0x08,
+0xB501, 0x08,
+0xB502, 0x08,
+
+0xC200, 0x03,
+
+//VGL(LVGL):
+0xBA00, 0x24,
+0xBA01, 0x24,
+0xBA02, 0x24,
+
+
+// VGMP/VGSP: 4.8v
+0xBC00, 0X00,
+0xBC01, 0x78,
+0xBC02, 0X00,
+
+// VGMN/VGSN -4.8v
+0xBD00, 0x00,
+0xBD01, 0x78,
+0xBD02, 0x00,
+
+// VCOM=-0.1
+0xBE00, 0x00,
+0xBE01, 0x80, //2f
+//R+
+0xD100, 0x00,
+0xD101, 0x05,
+0xD102, 0x00,
+0xD103, 0x06,
+0xD104, 0x00,
+0xD105, 0x0E,
+0xD106, 0x00,
+0xD107, 0x19,
+0xD108, 0x00,
+0xD109, 0x29,
+0xD10A, 0x00,
+0xD10B, 0x55,
+0xD10C, 0x00,
+0xD10D, 0x80,
+0xD10E, 0x00,
+0xD10F, 0xC7,
+0xD110, 0x00,
+0xD111, 0xFC,
+0xD112, 0x01,
+0xD113, 0x48,
+0xD114, 0x01,
+0xD115, 0x7C,
+0xD116, 0x01,
+0xD117, 0xC5,
+0xD118, 0x01,
+0xD119, 0xFE,
+0xD11A, 0x02,
+0xD11B, 0x00,
+0xD11C, 0x02,
+0xD11D, 0x30,
+0xD11E, 0x02,
+0xD11F, 0x60,
+0xD120, 0x02,
+0xD121, 0x7A,
+0xD122, 0x02,
+0xD123, 0x9A,
+0xD124, 0x02,
+0xD125, 0xAC,
+0xD126, 0x02,
+0xD127, 0xC4,
+0xD128, 0x02,
+0xD129, 0xD3,
+0xD12A, 0x02,
+0xD12B, 0xE9,
+0xD12C, 0x02,
+0xD12D, 0xF8,
+0xD12E, 0x03,
+0xD12F, 0x0D,
+0xD130, 0x03,
+0xD131, 0x3B,
+0xD132, 0x05,
+0xD133, 0xB5,
+//G+
+0xD200, 0x00,
+0xD201, 0x05,
+0xD202, 0x00,
+0xD203, 0x06,
+0xD204, 0x00,
+0xD205, 0x0E,
+0xD206, 0x00,
+0xD207, 0x19,
+0xD208, 0x00,
+0xD209, 0x29,
+0xD20A, 0x00,
+0xD20B, 0x55,
+0xD20C, 0x00,
+0xD20D, 0x80,
+0xD20E, 0x00,
+0xD20F, 0xC7,
+0xD210, 0x00,
+0xD211, 0xFC,
+0xD212, 0x01,
+0xD213, 0x48,
+0xD214, 0x01,
+0xD215, 0x7C,
+0xD216, 0x01,
+0xD217, 0xC5,
+0xD218, 0x01,
+0xD219, 0xFE,
+0xD21A, 0x02,
+0xD21B, 0x00,
+0xD21C, 0x02,
+0xD21D, 0x30,
+0xD21E, 0x02,
+0xD21F, 0x60,
+0xD220, 0x02,
+0xD221, 0x7A,
+0xD222, 0x02,
+0xD223, 0x9A,
+0xD224, 0x02,
+0xD225, 0xAC,
+0xD226, 0x02,
+0xD227, 0xC4,
+0xD228, 0x02,
+0xD229, 0xD3,
+0xD22A, 0x02,
+0xD22B, 0xE9,
+0xD22C, 0x02,
+0xD22D, 0xF8,
+0xD22E, 0x03,
+0xD22F, 0x0D,
+0xD230, 0x03,
+0xD231, 0x3B,
+0xD232, 0x05,
+0xD233, 0xB5,
+//B+
+0xD300, 0x00,
+0xD301, 0x05,
+0xD302, 0x00,
+0xD303, 0x06,
+0xD304, 0x00,
+0xD305, 0x0E,
+0xD306, 0x00,
+0xD307, 0x19,
+0xD308, 0x00,
+0xD309, 0x29,
+0xD30A, 0x00,
+0xD30B, 0x55,
+0xD30C, 0x00,
+0xD30D, 0x80,
+0xD30E, 0x00,
+0xD30F, 0xC7,
+0xD310, 0x00,
+0xD311, 0xFC,
+0xD312, 0x01,
+0xD313, 0x48,
+0xD314, 0x01,
+0xD315, 0x7C,
+0xD316, 0x01,
+0xD317, 0xC5,
+0xD318, 0x01,
+0xD319, 0xFE,
+0xD31A, 0x02,
+0xD31B, 0x00,
+0xD31C, 0x02,
+0xD31D, 0x30,
+0xD31E, 0x02,
+0xD31F, 0x60,
+0xD320, 0x02,
+0xD321, 0x7A,
+0xD322, 0x02,
+0xD323, 0x9A,
+0xD324, 0x02,
+0xD325, 0xAC,
+0xD326, 0x02,
+0xD327, 0xC4,
+0xD328, 0x02,
+0xD329, 0xD3,
+0xD32A, 0x02,
+0xD32B, 0xE9,
+0xD32C, 0x02,
+0xD32D, 0xF8,
+0xD32E, 0x03,
+0xD32F, 0x0D,
+0xD330, 0x03,
+0xD331, 0x3B,
+0xD332, 0x05,
+0xD333, 0xB5,
+//R-
+0xD400, 0x00,
+0xD401, 0x05,
+0xD402, 0x00,
+0xD403, 0x06,
+0xD404, 0x00,
+0xD405, 0x0E,
+0xD406, 0x00,
+0xD407, 0x19,
+0xD408, 0x00,
+0xD409, 0x29,
+0xD40A, 0x00,
+0xD40B, 0x55,
+0xD40C, 0x00,
+0xD40D, 0x80,
+0xD40E, 0x00,
+0xD40F, 0xC7,
+0xD410, 0x00,
+0xD411, 0xFC,
+0xD412, 0x01,
+0xD413, 0x48,
+0xD414, 0x01,
+0xD415, 0x7C,
+0xD416, 0x01,
+0xD417, 0xC5,
+0xD418, 0x01,
+0xD419, 0xFE,
+0xD41A, 0x02,
+0xD41B, 0x00,
+0xD41C, 0x02,
+0xD41D, 0x30,
+0xD41E, 0x02,
+0xD41F, 0x60,
+0xD420, 0x02,
+0xD421, 0x7A,
+0xD422, 0x02,
+0xD423, 0x9A,
+0xD424, 0x02,
+0xD425, 0xAC,
+0xD426, 0x02,
+0xD427, 0xC4,
+0xD428, 0x02,
+0xD429, 0xD3,
+0xD42A, 0x02,
+0xD42B, 0xE9,
+0xD42C, 0x02,
+0xD42D, 0xF8,
+0xD42E, 0x03,
+0xD42F, 0x0D,
+0xD430, 0x03,
+0xD431, 0x3B,
+0xD432, 0x05,
+0xD433, 0xB5,
+//G-
+0xD500, 0x00,
+0xD501, 0x05,
+0xD502, 0x00,
+0xD503, 0x06,
+0xD504, 0x00,
+0xD505, 0x0E,
+0xD506, 0x00,
+0xD507, 0x19,
+0xD508, 0x00,
+0xD509, 0x29,
+0xD50A, 0x00,
+0xD50B, 0x55,
+0xD50C, 0x00,
+0xD50D, 0x80,
+0xD50E, 0x00,
+0xD50F, 0xC7,
+0xD510, 0x00,
+0xD511, 0xFC,
+0xD512, 0x01,
+0xD513, 0x48,
+0xD514, 0x01,
+0xD515, 0x7C,
+0xD516, 0x01,
+0xD517, 0xC5,
+0xD518, 0x01,
+0xD519, 0xFE,
+0xD51A, 0x02,
+0xD51B, 0x00,
+0xD51C, 0x02,
+0xD51D, 0x30,
+0xD51E, 0x02,
+0xD51F, 0x60,
+0xD520, 0x02,
+0xD521, 0x7A,
+0xD522, 0x02,
+0xD523, 0x9A,
+0xD524, 0x02,
+0xD525, 0xAC,
+0xD526, 0x02,
+0xD527, 0xC4,
+0xD528, 0x02,
+0xD529, 0xD3,
+0xD52A, 0x02,
+0xD52B, 0xE9,
+0xD52C, 0x02,
+0xD52D, 0xF8,
+0xD52E, 0x03,
+0xD52F, 0x0D,
+0xD530, 0x03,
+0xD531, 0x3B,
+0xD532, 0x05,
+0xD533, 0xB5,
+//B-
+0xD600, 0x00,
+0xD601, 0x05,
+0xD602, 0x00,
+0xD603, 0x06,
+0xD604, 0x00,
+0xD605, 0x0E,
+0xD606, 0x00,
+0xD607, 0x19,
+0xD608, 0x00,
+0xD609, 0x29,
+0xD60A, 0x00,
+0xD60B, 0x55,
+0xD60C, 0x00,
+0xD60D, 0x80,
+0xD60E, 0x00,
+0xD60F, 0xC7,
+0xD610, 0x00,
+0xD611, 0xFC,
+0xD612, 0x01,
+0xD613, 0x48,
+0xD614, 0x01,
+0xD615, 0x7C,
+0xD616, 0x01,
+0xD617, 0xC5,
+0xD618, 0x01,
+0xD619, 0xFE,
+0xD61A, 0x02,
+0xD61B, 0x00,
+0xD61C, 0x02,
+0xD61D, 0x30,
+0xD61E, 0x02,
+0xD61F, 0x60,
+0xD620, 0x02,
+0xD621, 0x7A,
+0xD622, 0x02,
+0xD623, 0x9A,
+0xD624, 0x02,
+0xD625, 0xAC,
+0xD626, 0x02,
+0xD627, 0xC4,
+0xD628, 0x02,
+0xD629, 0xD3,
+0xD62A, 0x02,
+0xD62B, 0xE9,
+0xD62C, 0x02,
+0xD62D, 0xF8,
+0xD62E, 0x03,
+0xD62F, 0x0D,
+0xD630, 0x03,
+0xD631, 0x3B,
+0xD632, 0x05,
+0xD633, 0xB5,
+
+//Enable Page0
+0xF000, 0x55,
+0xF001, 0xAA,
+0xF002, 0x52,
+0xF003, 0x08,
+0xF004, 0x00,
+
+
+0xB100, 0xcc,
+0xB101, 0x00,
+
+0xB600, 0x05,
+
+//// Gate EQ:
+0xB700, 0x70,
+0xB701, 0x70,
+
+//// Source EQ:
+0xB800, 0x01,
+0xB801, 0x03,
+0xB802, 0x03,
+0xB803, 0x03,
+
+// #Inversion mode (2-dot)
+0xBC00, 0x02,
+0xBC01, 0x00,
+0xBC02, 0x00,
+
+// Timing control 4H w/ 4-delay
+0xC900, 0xD0,
+0xC901, 0x02,
+0xC902, 0x50,
+0xC903, 0x50,
+0xC904, 0x50,
+// Display Timing:
+
+0x3600, 0x00,
+0x3500, 0x00,
+
+0x3a00, 0x66,
+
+#endif
diff --git a/common/wmt_display/devices/vt1625.c b/common/wmt_display/devices/vt1625.c
new file mode 100755
index 0000000..35b60d7
--- /dev/null
+++ b/common/wmt_display/devices/vt1625.c
@@ -0,0 +1,949 @@
+/*++
+ * linux/drivers/video/wmt/vt1625.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define VT1625_C
+/* #define DEBUG */
+/* #define DEBUG_DETAIL */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../vout.h"
+
+#ifdef CONFIG_KERNEL
+#include <linux/workqueue.h>
+#endif
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define VT1625_XXXX xxxx *//*Example*/
+#ifdef CONFIG_KERNEL
+#define CONFIG_VT1625_INTERRUPT
+#endif
+#define CONFIG_VT1625_POWER
+#define CONFIG_VM700
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define VT1625_XXXX 1 *//*Example*/
+#define VT1625_ADDR 0x40
+
+enum {
+ VT1625_INPUT_SELECTION = 0x00,
+ VT1625_SYNC_SELECTION_0 = 0x01,
+ VT1625_SYNC_SELECTION_1 = 0x02,
+ VT1625_FILTER_SELECTION = 0x03,
+ VT1625_OUTPUT_MODE = 0x04,
+ VT1625_CLOCK_CONTROL = 0x05,
+
+ /* start position & overflow */
+ VT1625_OVERFLOW = 0x06,
+ VT1625_START_ACTIVE_VIDEO = 0x07,
+ VT1625_START_HORIZONTAL_POSITION = 0x08,
+ VT1625_START_VERTICAL_POSITION = 0x09,
+
+ /* amplitude factor */
+ VT1625_CR_AMPLITUDE_FACTOR = 0x0A,
+ VT1625_BLACK_LEVEL = 0x0B,
+ VT1625_Y_AMPLITUDE_FACTOR = 0x0C,
+ VT1625_CB_AMPLITUDE_FACTOR = 0x0D,
+
+ VT1625_POWER_MANAGEMENT = 0x0E,
+ VT1625_STATUS = 0x0F,
+
+ /* Hue */
+ VT1625_HUE_ADJUSTMENT = 0x10,
+ VT1625_OVERFLOW_MISC = 0x11,
+
+ /* PLL */
+ VT1625_PLL_P2 = 0x12,
+ VT1625_PLL_D = 0x13,
+ VT1625_PLL_N = 0x14,
+ VT1625_PLL_OVERFLOW = 0x15,
+
+ /* Sub Carrier */
+ VT1625_SUBCARRIER_VALUE_0 = 0x16,
+ VT1625_SUBCARRIER_VALUE_1 = 0x17,
+ VT1625_SUBCARRIER_VALUE_2 = 0x18,
+ VT1625_SUBCARRIER_VALUE_3 = 0x19,
+
+ VT1625_VERSION_ID = 0x1B,
+ VT1625_DAC_OVERFLOW = 0x1C,
+
+ /* test */
+ VT1625_TEST_0 = 0x1D,
+ VT1625_TEST_1 = 0x1E,
+
+ VT1625_FILTER_SWITCH = 0x1F,
+ VT1625_TV_SYNC_STEP = 0x20,
+ VT1625_TV_BURST_ENVELOPE_STEP = 0x21,
+ VT1625_TV_SUB_CARRIER_PHASE_ADJUST = 0x22,
+ VT1625_TV_BLANK_LEVEL = 0x23,
+ VT1625_TV_SIGNAL_OVERFLOW = 0x24,
+
+ /* DAC & GPO */
+ VT1625_DAC_SELECTION_0 = 0x4A,
+ VT1625_DAC_SELECTION_1 = 0x4B,
+ VT1625_GPO = 0x4C,
+
+ VT1625_COLBAR_LUMA_DELAY = 0x4D,
+ VT1625_UV_DELAY = 0x4E,
+ VT1625_BURST_MAX_AMPLITUDE = 0x4F,
+
+ /* Graphic timing */
+ VT1625_GRAPHIC_H_TOTAL = 0x50,
+ VT1625_GRAPHIC_H_ACTIVE = 0x51,
+ VT1625_GRAPHIC_H_OVERFLOW = 0x52,
+ VT1625_GRAPHIC_V_TOTAL = 0x53,
+ VT1625_GRAPHIC_V_OVERFLOW = 0x54,
+
+ /* TV timing */
+ VT1625_TV_H_TOTAL = 0x55,
+ VT1625_TV_H_ACTIVE = 0x56,
+ VT1625_TV_H_SYNC_WIDTH = 0x57,
+ VT1625_TV_H_OVERFLOW = 0x58,
+ VT1625_TV_BURST_START = 0x59,
+ VT1625_TV_BURST_END = 0x5A,
+ VT1625_TV_VIDEO_START = 0x5B,
+ VT1625_TV_VIDEO_END = 0x5C,
+ VT1625_TV_VIDEO_OVERFLOW = 0x5D,
+
+ /* scale factor */
+ VT1625_V_SCALE_FACTOR = 0x5E,
+ VT1625_H_SCALE_FACTOR = 0x5F,
+ VT1625_SCALE_OVERFLOW = 0x60,
+ VT1625_H_BLUR_SCALE_OVERFLOW = 0x61,
+ VT1625_ADAPTIVE_DEFLICKER_THR = 0x62,
+ VT1625_SCALE_H_TOTAL = 0x63,
+ VT1625_SCALE_H_TOTAL_OVERFLOW = 0x64,
+
+ /* Amplitude factor */
+ VT1625_PY_AMP_FACTOR = 0x65,
+ VT1625_PB_AMP_FACTOR = 0x66,
+ VT1625_PR_AMP_FACTOR = 0x67,
+
+ VT1625_POST_ADJUST = 0x68,
+ VT1625_AUTO_CORRECT_SENSE = 0x69,
+
+ /* WSS 0x6A - 0x73 */
+ VT1625_INT_WSS_2 = 0x71,
+
+ /* Close Caption 0x74 - 0x7A */
+
+ /* Signature Value 0x7B - 0x82 */
+} vt1625_reg_t;
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx vt1625_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in vt1625.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int vt1625_xxx; *//*Example*/
+
+static char vt1625_ntsc_param[] = {
+ 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x82, /* 00 - 07 */
+#ifdef CONFIG_VM700
+ 0x14, 0x05, 0x6E, 0x15, 0x51, 0x50, 0x37, 0xB7, /* 08 - 0f */
+ 0x00, 0x80, 0x04, 0x08, 0x08, 0x90, 0xD6, 0x7B, /* 10 - 17 */
+#else
+ 0x14, 0x05, 0x6E, 0x15, 0x52, 0x4E, 0x37, 0xB7, /* 08 - 0f */
+ 0x08, 0x80, 0x04, 0x08, 0x08, 0x90, 0xD6, 0x7B, /* 10 - 17 */
+#endif
+ 0xF0, 0x21, 0x02, 0x50, 0x43, 0x80, 0x00, 0xFC, /* 18 - 1f */
+ 0x16, 0x08, 0xDC, 0x7D, 0x02, 0x56, 0x33, 0x8F, /* 20 - 27 */
+ 0x58, 0x00, 0x00, 0xA6, 0x29, 0xD4, 0x81, 0x00, /* 28 - 2f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 37 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38 - 3f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 40 - 47 */
+#ifdef CONFIG_VM700
+ 0x00, 0x00, 0xC5, 0x0F, 0x08, 0x01, 0x01, 0x43, /* 48 - 4f */
+#else
+ 0x00, 0x00, 0xC5, 0x0F, 0x00, 0x01, 0x10, 0x44, /* 48 - 4f */
+#endif
+ 0x59, 0xCF, 0x23, 0x0C, 0x02, 0x59, 0xCF, 0x7F, /* 50 - 57 */
+ 0x23, 0x94, 0xD6, 0x00, 0x9C, 0x06, 0x00, 0x00, /* 58 - 5f */
+ 0x80, 0x28, 0xFF, 0x59, 0x03, 0x55, 0x56, 0x56, /* 60 - 67 */
+ 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 68 - 6f */
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 - 77 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78 - 7f */
+ 0x00, 0x00, 0x00
+};
+
+static char vt1625_pal_param[] = {
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x8C, /* 00 - 07 */
+#ifdef CONFIG_VM700
+ 0x0E, 0x01, 0x6E, 0x00, 0x51, 0x50, 0x37, 0xB7, /* 08 - 0f */
+ 0x00, 0x80, 0x04, 0x08, 0x08, 0x90, 0xCB, 0x8A, /* 10 - 17 */
+#else
+ 0x0E, 0x01, 0x7a, 0x00, 0x55, 0x58, 0x37, 0xB7, /* 08 - 0f */
+ 0xff, 0x87, 0x04, 0x08, 0x08, 0x90, 0xCB, 0x8A, /* 10 - 17 */
+#endif
+ 0x09, 0x2A, 0x06, 0x50, 0x41, 0x80, 0x00, 0xFC, /* 18 - 1f */
+ 0x17, 0x0C, 0x4E, 0x76, 0x02, 0x5F, 0x34, 0x8C, /* 20 - 27 */
+ 0x4F, 0x5E, 0x15, 0xA2, 0x22, 0x80, 0xD3, 0x10, /* 28 - 2f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 37 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38 - 3f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 40 - 47 */
+#ifdef CONFIG_VM700
+ 0x00, 0x00, 0xC5, 0x0F, 0x08, 0x02, 0x01, 0x43, /* 48 - 4f */
+#else
+ 0x00, 0x00, 0xC5, 0x0F, 0x00, 0x02, 0x10, 0x4C, /* 48 - 4f */
+#endif
+ 0x5f, 0xCF, 0x23, 0x70, 0x02, 0x5F, 0xD0, 0x7F, /* 50 - 57 */
+ 0x23, 0x92, 0xCE, 0xDF, 0xA0, 0x06, 0x00, 0x00, /* 58 - 5f */
+ 0x80, 0x20, 0xFF, 0x5F, 0x03, 0x5f, 0x00, 0x00, /* 60 - 67 */
+ 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 68 - 6f */
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 - 77 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78 - 7f */
+ 0x00, 0x00, 0x00
+};
+
+enum vt1625_out_t {
+ VT1625_OUT_CVBS,
+ VT1625_OUT_YUV,
+ VT1625_OUT_VGA,
+ VT1625_OUT_MAX
+};
+
+enum vt1625_out_t vt1625_out_mode;
+
+int vt1625_tv_mode;
+vdo_color_fmt vt1625_colfmt;
+
+static int pre_plugin;
+
+/*
+* VT1625 U-Boot Env to Set Register
+*/
+typedef struct {
+ unsigned char offset;
+ unsigned char value;
+} vt1625_reg_env_t;
+
+#define VT1625_REG_MAX_OFFSET 0x82 /* Register Offset: 0x00 ~ 0x82 */
+/*
+* setenv wmt.vt1625.pal.reg regOffset1=regValue1,regOffset2=regValue2,...
+* for example:
+* setenv wmt.vt1625.pal.reg 0a=75,0c=53,23=7a,4f=48
+* setenv wmt.vt1625.ntsc.reg 0a=75,0c=53,23=7a,4f=48
+*/
+#define VT1625_PAL_REG_ENV "wmt.vt1625.pal.reg"
+#define VT1625_NTSC_REG_ENV "wmt.vt1625.ntsc.reg"
+
+/*
+* setenv wmt.vt1625.cvbs.always.turnon 1
+* The cvbs is always turned on event if the av line is pluged out
+* setenv wmt.vt1625.cvbs.always.turnon 0
+* The cvbs is turned on if the av line is pluged in.
+* And the cvbs is turned off if the av line is pluged out
+*/
+#define VT1625_CVBS_ALWAYS_TURNON "wmt.vt1625.cvbs.always.turnon"
+
+static int vt1625_cvbs_always_turnon;
+
+#ifdef CONFIG_KERNEL
+/*
+* VT1625 Timer to Monitor Register
+*/
+/*
+* Monitor the vt1625 register for avoiding the register is cleared.
+* setenv wmt.vt1625.reg.monitor 1
+*
+* If the wmt.vt1625.reg.monitor is Not set or set to 0,
+* it will not monitor the register
+*
+*/
+#define VT1625_REG_MONITOR_ENV "wmt.vt1625.reg.monitor"
+
+#define VT1625_TIMER_INTERVAL 1000 // 1000 ms
+
+static struct timer_list vt1625_timer;
+static struct work_struct vt1625_work;
+
+static void vt1625_set_tv_mode(int ntsc);
+
+#endif
+
+#ifdef CONFIG_UBOOT
+#define msleep mdelay
+#endif
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void vt1625_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+/*
+* Function: register_is_right()
+* Parametr:
+* ntsc = 0: PAL
+* ntsc = 1: NTSC
+* Return :
+* 0: the register's values is wrong
+* 1: the register's values is right
+*/
+static int register_is_right(int ntsc)
+{
+ int i;
+ char buf[32];
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_INPUT_SELECTION, buf, 32);
+
+ for(i = 0; i < 32; i++) {
+ /*
+ * reg 0x0E is power management register. Skip it
+ * reg 0x0F is status register. it is volatile. Skip it
+ */
+ if(i == 14 || i == 15)
+ continue;
+
+
+ if(i == 0) {
+ if(vt1625_colfmt == VDO_COL_FMT_YUV444) {
+ if(buf[0] != 0x3A)
+ break;
+ } else {
+ if(buf[0] != 0x03)
+ break;
+ }
+ } else {
+ if(ntsc) {
+ /*
+ * NTSC
+ */
+ if(buf[i] != vt1625_ntsc_param[i])
+ break;
+ } else {
+ /*
+ * PAL
+ */
+ if(buf[i] != vt1625_pal_param[i])
+ break;
+ }
+ }
+ }
+
+ if(i != 32)
+ return 0;
+ else
+ return 1;
+}
+
+#ifdef CONFIG_KERNEL
+static void vt1625_reconfig(struct work_struct *work)
+{
+ int right;
+
+ if(vt1625_tv_mode) {
+ right = register_is_right((vt1625_tv_mode == 1) ? 1 : 0);
+ if(right == 0) {
+ DBG_ERR("VT1625 Reg Error, re-init the register\n");
+
+ vt1625_set_tv_mode((vt1625_tv_mode == 1) ? 1 : 0);
+ }
+ }
+
+ mod_timer(&vt1625_timer, jiffies + msecs_to_jiffies(VT1625_TIMER_INTERVAL));
+}
+
+static DECLARE_WORK(vt1625_work, vt1625_reconfig);
+
+static void vt1625_config_timer(unsigned long fcontext)
+{
+ schedule_work(&vt1625_work);
+}
+
+static void init_vt1625_timer(void)
+{
+ char buf[40];
+ int varlen = 40;
+ char *endp;
+ int value, reg_monitor;
+
+ reg_monitor = 0;
+
+ if (wmt_getsyspara(VT1625_REG_MONITOR_ENV, buf, &varlen) == 0) {
+ value = simple_strtoul(buf, &endp, 0);
+ if( value != 0)
+ reg_monitor = 1;
+ }
+
+ if(reg_monitor) {
+ init_timer(&vt1625_timer);
+ vt1625_timer.function = vt1625_config_timer;
+ vt1625_timer.data = 0;
+ } else
+ vt1625_timer.function = NULL;
+
+}
+
+static void start_vt1625_timer(void)
+{
+ if(vt1625_timer.function)
+ mod_timer(&vt1625_timer, jiffies + msecs_to_jiffies(VT1625_TIMER_INTERVAL));
+}
+
+static void stop_vt1625_timer(void)
+{
+ if(vt1625_timer.function)
+ del_timer_sync(&vt1625_timer);
+}
+#endif
+
+/*
+* Function : vt1625_parse_reg_env
+* Parameter:
+* p_env : env name
+* p_reg : store the vt1625 register offset and value
+* p_regnum: register number
+* Return:
+* 0 : the env is set and the env's value is available
+* -1 : the env is Not set or the env's value is wrong
+* -12 : no memory for parsing register env
+*/
+static int vt1625_parse_reg_env(char *p_env,
+ vt1625_reg_env_t *p_reg, int *p_regnum)
+{
+ int i;
+ char *buf;
+ int buflen = 1024;
+ unsigned int value;
+ const char *p;
+ char *endp;
+
+ buf = kmalloc(buflen, GFP_KERNEL);
+ if(buf == NULL) {
+ DBG_ERR("kzalloc fail\n");
+ return -12;
+ }
+
+ if(wmt_getsyspara(p_env, buf, &buflen) != 0) {
+ kfree(buf);
+ return -1;
+ }
+
+ *p_regnum = 0;
+ p = buf;
+
+ for(i = 0; i <= VT1625_REG_MAX_OFFSET; i++) {
+ value = simple_strtoul(p, &endp, 16);
+ if(value > VT1625_REG_MAX_OFFSET) {
+ DBG_ERR("wrong register offset\n");
+ kfree(buf);
+ return -1;
+ }
+ (p_reg + i)->offset = value;
+ /*
+ * reg_offset must be followed reg_value
+ * If reg_offset is NOT followed any reg_value, It is wrong format
+ */
+ if(*endp == '\0'|| *(endp + 1) == '\0') {
+ DBG_ERR("wrong env(%s) format\n", p_env);
+ kfree(buf);
+ return -1;
+ }
+
+ p = endp + 1;
+
+ value = simple_strtoul(p, &endp, 16);
+ if(value > 0xFF) {
+ DBG_ERR("wrong register value\n");
+ kfree(buf);
+ return -1;
+ }
+ (p_reg + i)->value = value;
+ *p_regnum = *p_regnum + 1;
+
+ if(*endp == '\0')
+ break;
+
+ p = endp + 1;
+ }
+
+ kfree(buf);
+ return 0;
+}
+
+/*the define and struct i2c_msg were declared int linux/i2c.h*/
+void vt1625_reg_dump(void)
+{
+ int i;
+ char buf[256];
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INPUT_SELECTION,
+ buf, 128);
+ for (i = 0; i < 128; i += 8) {
+ MSG("0x%02X : 0x%02X,0x%02X,0x%02X,0x%02X",
+ i, buf[i], buf[i + 1], buf[i + 2], buf[i + 3]);
+ MSG(",0x%02X,0x%02X,0x%02X,0x%02X\n",
+ buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]);
+ }
+}
+
+static char vt1625_get_dac_val(enum vt1625_out_t mode)
+{
+ char ret;
+
+ switch (mode) {
+ case VT1625_OUT_CVBS:
+ ret = 0x37;
+ break;
+ case VT1625_OUT_VGA:
+ ret = 0x38;
+ break;
+ case VT1625_OUT_YUV:
+ default:
+ ret = 0x0;
+ break;
+ }
+ return ret;
+}
+
+static void vt1625_set_tv_mode(int ntsc)
+{
+ char *p;
+ char buf[10];
+
+/*
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_INPUT_SELECTION, buf, 5);
+ DBG_MSG("ntsc %d, 0x%x, 0x%x\n", ntsc, buf[0], buf[4]);
+ vt1625_tv_mode = (ntsc) ? 1 : 2;
+#ifdef CONFIG_KERNEL
+ if (buf[0] && (vt1625_out_mode != VT1625_OUT_MAX)) {
+ if (ntsc && !(buf[4] & BIT0))
+ return;
+ if (!ntsc && (buf[4] & BIT0))
+ return;
+ }
+#endif
+*/
+ vt1625_tv_mode = (ntsc) ? 1 : 2;
+ if(register_is_right(ntsc))
+ return;
+
+ DBG_MSG("tv %s,mode %d\n", (ntsc) ? "NTSC" : "PAL", vt1625_out_mode);
+
+ p = (char *)((ntsc) ? vt1625_ntsc_param : vt1625_pal_param);
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INPUT_SELECTION,
+ &p[VT1625_INPUT_SELECTION], 0x71);
+ if (vt1625_out_mode == VT1625_OUT_MAX) { /* not stable so no use */
+ buf[0] = 0x0;
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_POWER_MANAGEMENT, buf, 1);
+ mdelay(10);
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_STATUS, buf, 1);
+ vt1625_out_mode = (buf[0] & 0x7) ?
+ VT1625_OUT_CVBS : VT1625_OUT_VGA;
+ DBG_MSG("get out mode %d, 0x%x\n", vt1625_out_mode, buf[0]);
+ }
+
+ if (vt1625_out_mode == VT1625_OUT_VGA) {
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_SYNC_SELECTION_1, buf, 1);
+ buf[0] |= 0xA0;
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_SYNC_SELECTION_1, buf, 1);
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_DAC_OVERFLOW, buf, 1);
+ buf[0] |= 0x20;
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_DAC_OVERFLOW, buf, 1);
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_TEST_1, buf, 1);
+ buf[0] |= 0x40;
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_TEST_1, buf, 1);
+ } else {
+#ifdef CONFIG_VT1625_INTERRUPT
+ /* interrupt (VGA no work) */
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_INT_WSS_2, buf, 1);
+ buf[0] |= 0xA0; /* enable sense interrupt */
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_INT_WSS_2, buf, 1);
+#endif
+ }
+
+ if (vt1625_colfmt == VDO_COL_FMT_YUV444) {
+ /*
+ * Force write reg0x00 and reg0x4C
+ */
+ buf[0] = 0x3A;
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_INPUT_SELECTION, buf, 1);
+ buf[0] = 0x08;
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_GPO, buf, 1);
+ }
+
+#ifdef CONFIG_VT1625_POWER
+ buf[0] = vt1625_get_dac_val(vt1625_out_mode);
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_POWER_MANAGEMENT, buf, 1);
+#endif
+}
+
+static int vt1625_check_plugin(int hotplug)
+{
+ char buf[2];
+ char cur[1];
+ int plugin;
+
+ /*
+ * Enable VT1625 Power First
+ */
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_POWER_MANAGEMENT, cur, 1);
+
+ buf[0] = vt1625_get_dac_val(vt1625_out_mode);
+
+ if(cur[0] != buf[0]) {
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_POWER_MANAGEMENT, buf, 1);
+
+ msleep(10);
+ }
+
+ if((vt1625_out_mode == VT1625_OUT_CVBS) && vt1625_cvbs_always_turnon)
+ return 1;
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_POWER_MANAGEMENT,
+ buf, 2);
+ plugin = ~buf[1] & (~buf[0] & 0x3F);
+ DBG_MSG("[VT1625] DAC A %d, B %d, C %d, D %d, E %d, F %d\n",
+ (plugin & 0x20) ? 1 : 0, (plugin & 0x10) ? 1 : 0,
+ (plugin & 0x08) ? 1 : 0, (plugin & 0x04) ? 1 : 0,
+ (plugin & 0x02) ? 1 : 0, (plugin & 0x01) ? 1 : 0);
+ return (plugin) ? 1 : 0;
+}
+
+static int vt1625_init(struct vout_t *vo)
+{
+ char buf[40];
+ int varlen = 40;
+ char *endp;
+ unsigned int value;
+
+ DBG_MSG("\n");
+
+#ifndef CONFIG_UBOOT
+ if (vt1625_tv_mode) { /* resume reinit */
+ MSG("[VT1625] DVI reinit\n");
+ vt1625_set_tv_mode((vt1625_tv_mode == 1) ? 1 : 0);
+ if (govrh_get_dvo_enable(p_govrh2) == 0)
+ govrh_set_dvo_enable(p_govrh2, VPP_FLAG_ENABLE);
+ pre_plugin = 0;
+ return 0;
+ }
+#endif
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_VERSION_ID, buf, 1);
+ if (buf[0] != 0x50) /* check version id */
+ return -1;
+
+ if (wmt_getsyspara("wmt.display.vt1625.mode", buf, &varlen) == 0) {
+ if (memcmp(buf, "yuv", 3) == 0)
+ vt1625_out_mode = VT1625_OUT_YUV;
+ else if (memcmp(buf, "vga", 3) == 0)
+ vt1625_out_mode = VT1625_OUT_VGA;
+ else
+ vt1625_out_mode = VT1625_OUT_CVBS;
+ DPRINT("[VT1625] mode %d\n", vt1625_out_mode);
+ } else
+ vt1625_out_mode = VT1625_OUT_CVBS; /* VT1625_OUT_MAX; */
+
+#ifdef CONFIG_VM700
+ vt1625_colfmt = VDO_COL_FMT_YUV444;
+#else
+ vt1625_colfmt = VDO_COL_FMT_ARGB;
+#endif
+ if (wmt_getsyspara("wmt.display.vt1625.colfmt", buf, &varlen) == 0) {
+ if (memcmp(buf, "yuv", 3) == 0)
+ vt1625_colfmt = VDO_COL_FMT_YUV444;
+ else if (memcmp(buf, "rgb", 3) == 0)
+ vt1625_colfmt = VDO_COL_FMT_ARGB;
+ }
+
+ vo->option[0] = (unsigned int) vt1625_colfmt;
+ vo->option[1] = (unsigned int) VPP_DATAWIDHT_12;
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_INPUT_SELECTION, buf, 5);
+ if (buf[0])
+ vt1625_tv_mode = (buf[4]) ? 2 : 1;
+
+ p_govrh2->fb_p->csc_mode = VPP_CSC_RGB2YUV_SDTV_0_255;
+
+ if (wmt_getsyspara(VT1625_CVBS_ALWAYS_TURNON, buf, &varlen) == 0) {
+ value = simple_strtoul(buf, &endp, 0);
+ if(value != 0)
+ vt1625_cvbs_always_turnon = 1;
+ else
+ vt1625_cvbs_always_turnon = 0;
+ } else
+ vt1625_cvbs_always_turnon = 0;
+
+#ifdef CONFIG_KERNEL
+ vt1625_set_tv_mode((vt1625_tv_mode == 1) ? 1 : 0);
+
+ start_vt1625_timer();
+#endif
+
+ MSG("[VT1625] DVI ext device\n");
+ return 0;
+}
+
+static int vt1625_set_mode(unsigned int *option)
+{
+#ifdef CONFIG_VT1625_INTERRUPT
+ char buf[1];
+#endif
+
+ DBG_MSG("\n");
+#ifdef CONFIG_VT1625_INTERRUPT
+ if (!g_vpp.dvi_int_disable) {
+ vout_set_int_type(1);
+ vout_set_int_enable(1);
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_INT_WSS_2, buf, 1);
+ buf[0] |= 0xA0; /* enable sense interrupt */
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_INT_WSS_2, buf, 1);
+ }
+#endif
+ return 0;
+}
+
+static void vt1625_set_power_down(int enable)
+{
+ struct vout_t *vo;
+ char buf[1];
+ char cur[1];
+
+ /*
+ bit 0-2 : DAC D/E/F - VGA
+ bit 3 : DAC C - CVBS
+ bit 3-5 : DAC A/B/C - YPbPr
+ bit 6 : PLL
+ bit 7 : IO pad
+ */
+ vo = vout_get_entry(VPP_VOUT_NUM_DVI);
+ if (vo->status & (VPP_VOUT_STS_BLANK + VPP_VOUT_STS_POWERDN))
+ enable = 1;
+
+ /* power down for not support resolution */
+//#ifndef CONFIG_VT1625_INTERRUPT
+ if ((vt1625_tv_mode != 0) && enable && g_vpp.dvi_int_disable)
+ buf[0] = 0xFF;
+ else
+//#endif
+ buf[0] = vt1625_get_dac_val(vt1625_out_mode);
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_POWER_MANAGEMENT, cur, 1);
+
+ if (cur[0] == buf[0])
+ return;
+
+ DBG_MSG("enable %d,cur 0x%x,new 0x%x\n", enable, cur[0], buf[0]);
+#if 1
+ if (enable == 0) {
+ cur[0] &= ~0x40; /* turn on PLL */
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_POWER_MANAGEMENT, cur, 1);
+ mdelay(3);
+
+ cur[0] &= ~0x80; /* turn on IO pad */
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_POWER_MANAGEMENT, cur, 1);
+ mdelay(3);
+ }
+#endif
+#ifdef CONFIG_VT1625_POWER
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_POWER_MANAGEMENT, buf, 1);
+#endif
+}
+
+static int vt1625_config(struct vout_info_t *info)
+{
+ int ntsc = -1;
+
+ DBG_MSG("%d,%d\n", info->resx, info->resy);
+ if (info->resx == 720) {
+ switch (info->resy) {
+ case 480:
+ ntsc = 1;
+ break;
+ case 576:
+ ntsc = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (ntsc != -1)
+ vt1625_set_tv_mode(ntsc);
+ else
+ vt1625_tv_mode = 0;
+ DBG_MSG("end\n");
+ return 0;
+}
+
+static int vt1625_get_edid(char *buf)
+{
+ return 0;
+}
+
+#ifdef CONFIG_VT1625_INTERRUPT
+static int vt1625_interrupt(void)
+{
+ char buf[1];
+
+ vppif_reg32_write(GPIO_BASE_ADDR + 0x4c0, 0x1 << VPP_VOINT_NO,
+ VPP_VOINT_NO, 0x0); /* GPIO pull-up */
+ /* interrupt */
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INT_WSS_2, buf, 1);
+ DBG_MSG("0x%x\n", buf[0]);
+ buf[0] &= ~0x40; /* clear interrupt */
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR, VT1625_INT_WSS_2, buf, 1);
+ return vt1625_check_plugin(1);
+}
+#endif
+
+static void vt1625_poll(void)
+{
+ int plugin;
+ char buf[1];
+ char cur[1];
+
+ if (govrh_get_dvo_enable(p_govrh2) == 0)
+ govrh_set_dvo_enable(p_govrh2, VPP_FLAG_ENABLE);
+
+ plugin = vt1625_check_plugin(0);
+ if (plugin != pre_plugin) {
+ struct vout_t *vo;
+
+ vo = vout_get_entry(VPP_VOUT_NUM_DVI);
+ vout_change_status(vo, VPP_VOUT_STS_PLUGIN, plugin);
+#ifdef CONFIG_KERNEL
+ vpp_netlink_notify_plug(VPP_VOUT_NUM_DVI, plugin);
+#endif
+ pre_plugin = plugin;
+ DMSG("%d\n", plugin);
+ }
+
+ /*
+ * Disable VT1625 Power if CVBS Not plugin
+ */
+ if(plugin == 0) {
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_POWER_MANAGEMENT, cur, 1);
+
+ buf[0] = 0xFF;
+
+ if(cur[0] != buf[0]) {
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1625_ADDR,
+ VT1625_POWER_MANAGEMENT, buf, 1);
+ }
+ }
+}
+
+static int vt1625_suspend(void)
+{
+ DMSG("\n");
+
+#ifdef CONFIG_KERNEL
+ stop_vt1625_timer();
+#endif
+
+ return 0;
+}
+
+static int vt1625_resume(void)
+{
+ DMSG("\n");
+
+#ifdef CONFIG_KERNEL
+ start_vt1625_timer();
+#endif
+ return 0;
+}
+
+/*----------------------- vout device plugin ---------------------------------*/
+struct vout_dev_t vt1625_vout_dev_ops = {
+ .name = "VT1625",
+ .mode = VOUT_INF_DVI,
+
+ .init = vt1625_init,
+ .set_power_down = vt1625_set_power_down,
+ .set_mode = vt1625_set_mode,
+ .config = vt1625_config,
+ .check_plugin = vt1625_check_plugin,
+ .get_edid = vt1625_get_edid,
+#ifdef CONFIG_VT1625_INTERRUPT
+ .interrupt = vt1625_interrupt,
+#endif
+ .poll = vt1625_poll,
+ .suspend = vt1625_suspend,
+ .resume = vt1625_resume,
+};
+
+int vt1625_module_init(void)
+{
+ vt1625_reg_env_t *p_reg;
+ int i, ret, regnum;
+
+ p_reg = kmalloc((VT1625_REG_MAX_OFFSET + 1) * sizeof(vt1625_reg_env_t),
+ GFP_KERNEL);
+ if(p_reg) {
+ ret = vt1625_parse_reg_env(VT1625_PAL_REG_ENV, p_reg, &regnum);
+ if(ret == 0) {
+ for(i = 0; i < regnum; i++)
+ vt1625_pal_param[(p_reg + i)->offset] =
+ (p_reg + i)->value;
+ }
+
+ ret = vt1625_parse_reg_env(VT1625_NTSC_REG_ENV, p_reg, &regnum);
+ if(ret == 0) {
+ for(i = 0; i < regnum; i++)
+ vt1625_ntsc_param[(p_reg + i)->offset] =
+ (p_reg + i)->value;
+ }
+
+ kfree(p_reg);
+ } else
+ DBG_ERR("kzalloc fail\n");
+
+#ifdef CONFIG_KERNEL
+ init_vt1625_timer();
+#endif
+
+ vout_device_register(&vt1625_vout_dev_ops);
+
+ return 0;
+}
+module_init(vt1625_module_init);
+/*--------------------End of Function Body -----------------------------------*/
+#undef VT1625_C
diff --git a/common/wmt_display/devices/vt1632.c b/common/wmt_display/devices/vt1632.c
new file mode 100755
index 0000000..b3950c0
--- /dev/null
+++ b/common/wmt_display/devices/vt1632.c
@@ -0,0 +1,157 @@
+/*++
+ * linux/drivers/video/wmt/vt1632.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define VT1632_C
+/* #define DEBUG */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "../vout.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define VT1632_XXXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define VT1632_XXXX 1 *//*Example*/
+#define VT1632_ADDR 0x10
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx vt1632_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in vt1632.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int vt1632_xxx; *//*Example*/
+static int vt1632_not_ready;
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void vt1632_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+
+/*the define and struct i2c_msg were declared int linux/i2c.h*/
+int vt1632_check_plugin(int hotplug)
+{
+ char buf[1];
+ int plugin;
+
+ if (vt1632_not_ready)
+ return 1;
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1632_ADDR, 0x9, buf, 1);
+ plugin = (buf[0] & 0x4) ? 1 : 0;
+ DPRINT("[VT1632] DVI plug%s\n", (plugin) ? "in" : "out");
+ vout_set_int_type(4);
+ return plugin;
+}
+
+int vt1632_init(struct vout_t *vo)
+{
+ char buf[16];
+
+ vt1632_not_ready = 1;
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1632_ADDR, 0x0, buf, 2);
+ if ((buf[0] != 0x06) || (buf[1] != 0x11)) /* check vender id */
+ return -1;
+ vt1632_not_ready = 0;
+
+ buf[0x0] = 0x37;
+ buf[0x1] = 0x20;
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 2);
+ DPRINT("[VT1632] DVI ext device\n");
+ return 0;
+}
+
+int vt1632_set_mode(unsigned int *option)
+{
+ char buf[1];
+ vpp_datawidht_t dwidth;
+
+ if (vt1632_not_ready)
+ return -1;
+
+ dwidth = option[1] & BIT0;
+ DBGMSG("vt1632_set_mode(%d)\n", (dwidth) ? 24 : 12);
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 1);
+ if (dwidth == VPP_DATAWIDHT_12) {
+ buf[0] &= ~BIT2;
+ buf[0] |= BIT3;
+ } else {
+ buf[0] |= BIT2;
+ buf[0] &= ~BIT3;
+ }
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 1);
+ return 0;
+}
+
+void vt1632_set_power_down(int enable)
+{
+ char buf[1];
+
+ if (vt1632_not_ready)
+ return;
+
+ DBGMSG("vt1632_set_power_down(%d)\n", enable);
+
+ vpp_i2c_read(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 1);
+ if (enable)
+ buf[0] &= ~BIT0;
+ else
+ buf[0] |= BIT0;
+ vpp_i2c_write(VPP_DVI_I2C_ID, VT1632_ADDR, 0x8, buf, 1);
+}
+
+int vt1632_config(struct vout_info_t *info)
+{
+ return 0;
+}
+
+int vt1632_get_edid(char *buf)
+{
+ return 0;
+}
+
+int vt1632_interrupt(void)
+{
+ return vt1632_check_plugin(1);
+}
+/*----------------------- vout device plugin ---------------------------------*/
+struct vout_dev_t vt1632_vout_dev_ops = {
+ .name = "VT1632",
+ .mode = VOUT_INF_DVI,
+
+ .init = vt1632_init,
+ .set_power_down = vt1632_set_power_down,
+ .set_mode = vt1632_set_mode,
+ .config = vt1632_config,
+ .check_plugin = vt1632_check_plugin,
+ .get_edid = vt1632_get_edid,
+ .interrupt = vt1632_interrupt,
+};
+
+int vt1632_module_init(void)
+{
+ vout_device_register(&vt1632_vout_dev_ops);
+ return 0;
+} /* End of vt1632_module_init */
+module_init(vt1632_module_init);
+/*--------------------End of Function Body -----------------------------------*/
+#undef VT1632_C
diff --git a/common/wmt_display/display_aligment.S b/common/wmt_display/display_aligment.S
new file mode 100755
index 0000000..285a922
--- /dev/null
+++ b/common/wmt_display/display_aligment.S
@@ -0,0 +1,482 @@
+/*******************************************************************************
+ Copyright (c) 2008 WonderMedia Technologies, Inc.
+
+ Module Name:
+
+ $Workfile: display_aligment.S $
+
+ Abstract:
+
+ Memory copy with aligment issue
+
+ Registers using:
+ r0: source address
+ r1: destination address
+ r2: len
+*******************************************************************************/
+
+ .text
+ .code 32
+
+ .global byte1_alig_mem_copy
+ .type byte1_alig_mem_copy, %function
+ .global byte1_less_bundle_copy
+ .type byte1_less_bundle_copy, %function
+
+ .global byte2_alig_mem_copy
+ .type byte2_alig_mem_copy, %function
+ .global byte2_less_bundle_copy
+ .type byte2_less_bundle_copy, %function
+
+ .global byte3_alig_mem_copy
+ .type byte3_alig_mem_copy, %function
+ .global byte3_less_bundle_copy
+ .type byte3_less_bundle_copy, %function
+
+ .global mem_copy
+ .type mem_copy, %function
+ .global less_mem_copy
+ .type less_mem_copy, %function
+
+ .global bit24_to_bit16_ali24
+ .type bit24_to_bit16_ali24, %function
+ .global bit24_to_bit16_ali32
+ .type bit24_to_bit16_ali32, %function
+byte1_alig_mem_copy:
+ stmfd sp!, {r0-r12}
+byte1cpy_loop:
+ ldmia r0!, {r3-r11} // r3-r10 store
+ mov r12, r4 // backup r4
+ mov r3, r3, lsr #8
+ mov r12, r12, lsl #24
+ orr r3, r3, r12 // r3 shift
+
+ mov r12, r5 // backup r5
+ mov r4, r4, lsr #8
+ mov r12, r12, lsl #24
+ orr r4, r4, r12 // r4 shift
+
+ mov r12, r6 // backup r6
+ mov r5, r5, lsr #8
+ mov r12, r12, lsl #24
+ orr r5, r5, r12 // r5 shift
+
+ mov r12, r7 // backup r7
+ mov r6, r6, lsr #8
+ mov r12, r12, lsl #24
+ orr r6, r6, r12 // r6 shift
+
+ mov r12, r8 // backup r8
+ mov r7, r7, lsr #8
+ mov r12, r12, lsl #24
+ orr r7, r7, r12 // r7 shift
+
+ mov r12, r9 // backup r9
+ mov r8, r8, lsr #8
+ mov r12, r12, lsl #24
+ orr r8, r8, r12 // r8 shift
+
+ mov r12, r10 // backup r10
+ mov r9, r9, lsr #8
+ mov r12, r12, lsl #24
+ orr r9, r9, r12 // r9 shift
+
+ mov r12, r11 // backup r11
+ mov r10, r10, lsr #8
+ mov r12, r12, lsl #24
+ orr r10, r10, r12 // r10 shift
+
+ stmia r1!, {r3-r10}
+ sub r0, r0, #4 // back to 32 bundle
+ subs r2, r2, #32
+ bne byte1cpy_loop
+ ldmfd sp!, {r0-r12}
+ mov pc, lr
+
+byte1_less_bundle_copy:
+ stmfd sp!, {r0-r4}
+byte1cpy_less_loop:
+ ldmia r0!, {r3-r4} // r3
+ mov r12, r4 // backup r4
+ mov r3, r3, lsr #8
+ mov r12, r12, lsl #24
+ orr r3, r3, r12 // r3 shift
+ stmia r1!, {r3}
+ sub r0, r0, #4
+ subs r2, r2, #4
+ bne byte1cpy_less_loop
+ ldmfd sp!, {r0-r4}
+ mov pc, lr
+
+byte2_alig_mem_copy:
+ stmfd sp!, {r0-r12}
+byte2cpy_loop:
+ ldmia r0!, {r3-r11} // r3-r10 store
+ mov r12, r4 // backup r4
+ mov r3, r3, lsr #16
+ mov r12, r12, lsl #16
+ orr r3, r3, r12 // r3 shift
+
+ mov r12, r5 // backup r5
+ mov r4, r4, lsr #16
+ mov r12, r12, lsl #16
+ orr r4, r4, r12 // r4 shift
+
+ mov r12, r6 // backup r6
+ mov r5, r5, lsr #16
+ mov r12, r12, lsl #16
+ orr r5, r5, r12 // r5 shift
+
+ mov r12, r7 // backup r7
+ mov r6, r6, lsr #16
+ mov r12, r12, lsl #16
+ orr r6, r6, r12 // r6 shift
+
+ mov r12, r8 // backup r8
+ mov r7, r7, lsr #16
+ mov r12, r12, lsl #16
+ orr r7, r7, r12 // r7 shift
+
+ mov r12, r9 // backup r9
+ mov r8, r8, lsr #16
+ mov r12, r12, lsl #16
+ orr r8, r8, r12 // r8 shift
+
+ mov r12, r10 // backup r10
+ mov r9, r9, lsr #16
+ mov r12, r12, lsl #16
+ orr r9, r9, r12 // r9 shift
+
+ mov r12, r11 // backup r11
+ mov r10, r10, lsr #16
+ mov r12, r12, lsl #16
+ orr r10, r10, r12 // r10 shift
+
+ stmia r1!, {r3-r10}
+ sub r0, r0, #4 // back to 32 bundle
+ subs r2, r2, #32
+ bne byte2cpy_loop
+ ldmfd sp!, {r0-r12}
+ mov pc, lr
+
+byte2_less_bundle_copy:
+ stmfd sp!, {r0-r4}
+byte2cpy_less_loop:
+ ldmia r0!, {r3-r4} // r3
+ mov r12, r4 // backup r4
+ mov r3, r3, lsr #16
+ mov r12, r12, lsl #16
+ orr r3, r3, r12 // r3 shift
+ stmia r1!, {r3}
+ sub r0, r0, #4
+ subs r2, r2, #4
+ bne byte2cpy_less_loop
+ ldmfd sp!, {r0-r4}
+ mov pc, lr
+
+byte3_alig_mem_copy:
+ stmfd sp!, {r0-r12}
+byte3cpy_loop:
+ ldmia r0!, {r3-r11} // r3-r10 store
+ mov r12, r4 // backup r4
+ mov r3, r3, lsr #24
+ mov r12, r12, lsl #8
+ orr r3, r3, r12 // r3 shift
+
+ mov r12, r5 // backup r5
+ mov r4, r4, lsr #24
+ mov r12, r12, lsl #8
+ orr r4, r4, r12 // r4 shift
+
+ mov r12, r6 // backup r6
+ mov r5, r5, lsr #24
+ mov r12, r12, lsl #8
+ orr r5, r5, r12 // r5 shift
+
+ mov r12, r7 // backup r7
+ mov r6, r6, lsr #24
+ mov r12, r12, lsl #8
+ orr r6, r6, r12 // r6 shift
+
+ mov r12, r8 // backup r8
+ mov r7, r7, lsr #24
+ mov r12, r12, lsl #8
+ orr r7, r7, r12 // r7 shift
+
+ mov r12, r9 // backup r9
+ mov r8, r8, lsr #24
+ mov r12, r12, lsl #8
+ orr r8, r8, r12 // r8 shift
+
+ mov r12, r10 // backup r10
+ mov r9, r9, lsr #24
+ mov r12, r12, lsl #8
+ orr r9, r9, r12 // r9 shift
+
+ mov r12, r11 // backup r11
+ mov r10, r10, lsr #24
+ mov r12, r12, lsl #8
+ orr r10, r10, r12 // r10 shift
+
+ stmia r1!, {r3-r10}
+ sub r0, r0, #4 // back to 32 bundle
+ subs r2, r2, #32
+ bne byte3cpy_loop
+ ldmfd sp!, {r0-r12}
+ mov pc, lr
+
+byte3_less_bundle_copy:
+ stmfd sp!, {r0-r4}
+byte3cpy_less_loop:
+ ldmia r0!, {r3-r4} // r3
+ mov r12, r4 // backup r4
+ mov r3, r3, lsr #24
+ mov r12, r12, lsl #8
+ orr r3, r3, r12 // r3 shift
+ stmia r1!, {r3}
+ sub r0, r0, #4
+ subs r2, r2, #4
+ bne byte3cpy_less_loop
+ ldmfd sp!, {r0-r4}
+ mov pc, lr
+
+mem_copy:
+ stmfd sp!, {r0-r10}
+ali_mem_copy:
+ ldmia r0!, {r3-r10}
+ stmia r1!, {r3-r10}
+ subs r2, r2, #32
+ bne ali_mem_copy
+ ldmfd sp!, {r0-r10}
+ mov pc, lr
+
+less_mem_copy:
+ stmfd sp!, {r0-r3}
+ali_less_mem_copy:
+ ldmia r0!, {r3}
+ stmia r1!, {r3}
+ subs r2, r2, #4
+ bne ali_less_mem_copy
+ ldmfd sp!, {r0-r3}
+ mov pc, lr
+
+bit24_to_bit16_ali24:
+ stmfd sp!, {r0-r11}
+bit24_to_bit16_ali24_loop:
+ ldmia r1!, {r3-r8}
+ // r11 : final data
+ // r10 : tmp_reg
+ mov r11, #0
+
+ // handle first 16bits ================
+ ldr r9, =0xFF
+ and r10, r3, r9 //B
+ lsr r10, #3
+ mov r11, r10
+
+ ldr r9, =0xFF00
+ and r10, r3, r9 //G
+ lsr r10, #10
+ lsl r10, #5
+ orr r11, r11, r10
+
+ ldr r9, =0xFF0000
+ and r10, r3, r9 //R
+ lsr r10, #19
+ lsl r10, #11
+ orr r11, r11, r10
+
+ // handle second 16bits ================
+ ldr r9, =0xFF000000
+ and r10, r3, r9 //B
+ lsr r10, #27
+ lsl r10, #16
+ orr r11, r11, r10
+
+ ldr r9, =0xFF
+ and r10, r4, r9 //G
+ lsr r10, #2
+ lsl r10, #21
+ orr r11, r11, r10
+
+ ldr r9, =0xFF00
+ and r10, r4, r9 //R
+ lsr r10, #11
+ lsl r10, #27
+ orr r11, r11, r10
+ mov r3, r11
+
+ // handle third 16bits ================
+ mov r11, #0
+ ldr r9, =0xFF0000
+ and r10, r4, r9 //B
+ lsr r10, #19
+ orr r11, r11, r10
+
+ ldr r9, =0xFF000000
+ and r10, r4, r9 //G
+ lsr r10, #26
+ lsl r10, #5
+ orr r11, r11, r10
+
+ ldr r9, =0xFF
+ and r10, r5, r9 //R
+ lsr r10, #3
+ lsl r10, #11
+ orr r11, r11, r10
+
+ // handle forth 16bits ================
+ ldr r9, =0xFF00
+ and r10, r5, r9 //B
+ lsr r10, #11
+ lsl r10, #16
+ orr r11, r11, r10
+
+ ldr r9, =0xFF0000
+ and r10, r5, r9 //G
+ lsr r10, #18
+ lsl r10, #21
+ orr r11, r11, r10
+
+ ldr r9, =0xFF000000
+ and r10, r5, r9 //R
+ lsr r10, #27
+ lsl r10, #27
+ orr r11, r11, r10
+ mov r4, r11
+
+ // handle fivth 16bits ================
+ ldr r9, =0xFF
+ and r10, r6, r9 //B
+ lsr r10, #3
+ mov r11, r10
+
+ ldr r9, =0xFF00
+ and r10, r6, r9 //G
+ lsr r10, #10
+ lsl r10, #5
+ orr r11, r11, r10
+
+ ldr r9, =0xFF0000
+ and r10, r6, r9 //R
+ lsr r10, #19
+ lsl r10, #11
+ orr r11, r11, r10
+
+ // handle sixth 16bits ================
+ ldr r9, =0xFF000000
+ and r10, r6, r9 //B
+ lsr r10, #27
+ lsl r10, #16
+ orr r11, r11, r10
+
+ ldr r9, =0xFF
+ and r10, r7, r9 //G
+ lsr r10, #2
+ lsl r10, #21
+ orr r11, r11, r10
+
+ ldr r9, =0xFF00
+ and r10, r7, r9 //R
+ lsr r10, #11
+ lsl r10, #27
+ orr r11, r11, r10
+ mov r5, r11
+
+ // handle seventh 16bits ================
+ mov r11, #0
+ ldr r9, =0xFF0000
+ and r10, r7, r9 //B
+ lsr r10, #19
+ orr r11, r11, r10
+
+ ldr r9, =0xFF000000
+ and r10, r7, r9 //G
+ lsr r10, #26
+ lsl r10, #5
+ orr r11, r11, r10
+
+ ldr r9, =0xFF
+ and r10, r8, r9 //R
+ lsr r10, #3
+ lsl r10, #11
+ orr r11, r11, r10
+
+ // handle eighth 16bits ================
+ ldr r9, =0xFF00
+ and r10, r8, r9 //B
+ lsr r10, #11
+ lsl r10, #16
+ orr r11, r11, r10
+
+ ldr r9, =0xFF0000
+ and r10, r8, r9 //G
+ lsr r10, #18
+ lsl r10, #21
+ orr r11, r11, r10
+
+ ldr r9, =0xFF000000
+ and r10, r8, r9 //R
+ lsr r10, #27
+ lsl r10, #27
+ orr r11, r11, r10
+ mov r6, r11
+
+ stmia r0!, {r3-r6}
+ subs r2, r2, #24
+ bne bit24_to_bit16_ali24_loop
+ ldmfd sp!, {r0-r11}
+ mov pc, lr
+
+bit24_to_bit16_ali32:
+ stmfd sp!, {r0-r11}
+bit24_to_bit16_ali32_copy:
+ ldmia r1!, {r3-r8}
+ // r11 : final data
+ // r10 : tmp_reg
+ // handle first 32bits ================
+ ldr r9, =0xffffff
+ and r11, r9, r3
+ // handle second 32bits ================
+ mov r10, r3, lsr #24
+ mov r3, r11
+ mov r9, r4 //backup r4
+ lsl r4, #16
+ lsr r4, #8
+ orr r4, r4, r10
+ // handle third 32bits ================
+ lsr r9, #16
+ mov r10, r5 //backup r5
+ lsl r5, #24
+ lsr r5, #8
+ orr r5, r5, r9
+ // handle fourth 32bits ================
+ lsr r10, #8
+ stmia r0!, {r3-r5, r10}
+
+ // handle fiveth 32bits ================
+ ldr r9, =0xffffff
+ and r11, r9, r6
+ // handle sixth 32bits ================
+ mov r10, r6, lsr #24
+ mov r6, r11
+ mov r9, r7 //backup r7
+ lsl r7, #16
+ lsr r7, #8
+ orr r7, r7, r10
+ // handle seventh 32bits ================
+ lsr r9, #16
+ mov r10, r8 //backup r8
+ lsl r8, #24
+ lsr r8, #8
+ orr r8, r8, r9
+ // handle eigth 32bits ================
+ lsr r10, #8
+ stmia r0!, {r6-r8, r10}
+
+ subs r2, r2, #24
+ bne bit24_to_bit16_ali32_copy
+ ldmfd sp!, {r0-r11}
+ mov pc, lr
+
+ \ No newline at end of file
diff --git a/common/wmt_display/edid.h b/common/wmt_display/edid.h
new file mode 100755
index 0000000..b476a78
--- /dev/null
+++ b/common/wmt_display/edid.h
@@ -0,0 +1,168 @@
+/*++
+ * linux/drivers/video/wmt/edid.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef EDID_H
+#define EDID_H
+
+#define EDID_BLOCK_MAX 4
+
+/*------------------------------------------------------------------------------
+ Following definitions, please refer spec of EDID. You may refer it on
+ http://en.wikipedia.org/wiki/EDID#EDID_1.3_data_format
+------------------------------------------------------------------------------*/
+
+#define EDID_LENGTH 0x80
+
+/*------------------------------------------------------------------------------
+ Offset 00-19: HEADER INFORMATION
+------------------------------------------------------------------------------*/
+/* 00¡V07: Header information "00h FFh FFh FFh FFh FFh FFh 00h" */
+#define EDID_HEADER 0x00
+#define EDID_HEADER_END 0x07
+
+/* 08¡V09: Manufacturer ID. These IDs are assigned by Microsoft.
+ "00001=A¡¨; ¡§00010=B¡¨; ... ¡§11010=Z¡¨. Bit 7 (at address 08h) is 0,
+ the first character (letter) is located at bits 6 ¡÷ 2
+ (at address 08h), the second character (letter) is located at
+ bits 1 & 0 (at address 08h) and bits 7 ¡÷ 5 (at address 09h), and the
+ third character (letter) is located at bits 4 ¡÷ 0 (at address 09h).
+*/
+#define ID_MANUFACTURER_NAME 0x08
+#define ID_MANUFACTURER_NAME_END 0x09
+
+/* 10¡V11: Product ID Code (stored as LSB first). Assigned by manufacturer */
+#define ID_MODEL 0x0a
+
+/* 12¡V15: 32-bit Serial Number. No requirement for the format. Usually
+ stored as LSB first. In order to maintain compatibility with previous
+ requirements the field should set at least one byte of the field to be
+ non-zero if an ASCII serial number descriptor is
+ provided in the detailed timing section.
+*/
+#define ID_SERIAL_NUMBER 0x0c
+
+/* 16: Week of Manufacture. This varies by manufacturer. One way is to count
+ January 1-7 as week 1, January 8-15 as week 2 and so on. Some count
+ based on the week number (Sunday-Saturday). Valid range is 1-54.
+ 17: Year of Manufacture. Add 1990 to the value for actual year. */
+#define MANUFACTURE_WEEK 0x10
+#define MANUFACTURE_YEAR 0x11
+
+/* 18: EDID Version Number. "01h"
+ 19: EDID Revision Number "03h" */
+#define EDID_STRUCT_VERSION 0x12
+#define EDID_STRUCT_REVISION 0x13
+
+#define EDID_MAX_HOR_IMAGE_SIZE 0x15
+#define EDID_MAX_VER_IMAGE_SIZE 0x16
+
+/*------------------------------------------------------------------------------
+ Offset 20-24: BASIC DISPLAY PARAMETERS
+------------------------------------------------------------------------------*/
+#define DPMS_FLAGS 0x18
+#define ESTABLISHED_TIMING_I 0x23
+#define ESTABLISHED_TIMING_II 0x24
+#define MANUFACTURERS_TIMINGS 0x25
+
+#define STANDARD_TIMING_IDENTIFICATION_START 0x26
+#define STANDARD_TIMING_IDENTIFICATION_SIZE 16
+
+#define DETAILED_TIMING_DESCRIPTIONS_START 0x36
+#define DETAILED_TIMING_DESCRIPTION_SIZE 18
+#define NO_DETAILED_TIMING_DESCRIPTIONS 4
+
+#define DETAILED_TIMING_DESCRIPTION_1 0x36
+#define DETAILED_TIMING_DESCRIPTION_2 0x48
+#define DETAILED_TIMING_DESCRIPTION_3 0x5a
+#define DETAILED_TIMING_DESCRIPTION_4 0x6c
+
+#define EDID_TMR_INTERLACE BIT(31)
+#define EDID_TMR_FREQ 0xFF
+struct edid_timing_t {
+ unsigned int resx;
+ unsigned int resy;
+ int freq; /* EDID_TMR_XXX */
+};
+
+struct vic_3d_t {
+ char vic;
+ unsigned int mask;
+};
+
+/* EDID option flag */
+#define EDID_OPT_VALID 0x01
+#define EDID_OPT_YUV422 0x10
+#define EDID_OPT_YUV444 0x20
+#define EDID_OPT_AUDIO 0x40
+#define EDID_OPT_UNDERSCAN 0x80
+#define EDID_OPT_HDMI 0x100
+#define EDID_OPT_3D BIT(9)
+#define EDID_OPT_16_9 BIT(10)
+
+struct edid_info_t {
+ unsigned int establish_timing;
+ struct edid_timing_t standard_timing[8];
+ struct fb_videomode detail_timing[4];
+ struct fb_videomode cea_timing[6];
+ char cea_vic[8];
+ struct vic_3d_t vic_3d[16];
+ unsigned int pixel_clock_limit;
+ unsigned int option;
+ unsigned short hdmi_phy_addr;
+ int width;
+ int height;
+};
+
+#define VENDOR_NAME_LEN 4
+#define MONITOR_NAME_LEN 20
+#define AUD_SAD_NUM 32
+struct sad_t {
+ char flag; /* 0: sad available, 1: sad invalid */
+ char sad_byte[3];
+};
+
+struct tv_name_t{
+ char vendor_name[VENDOR_NAME_LEN];
+ char monitor_name[MONITOR_NAME_LEN];
+};
+
+struct edid_parsed_t {
+ struct tv_name_t tv_name;
+ struct sad_t sad[AUD_SAD_NUM];
+};
+
+extern struct edid_info_t edid_info;
+extern int edid_msg_enable;
+extern int edid_disable;
+extern struct edid_parsed_t edid_parsed;
+
+extern int edid_parse(char *edid, struct edid_info_t *info);
+extern int edid_find_support(struct edid_info_t *info, unsigned int resx,
+ unsigned int resy, int freq, struct fb_videomode **vmode);
+extern void edid_dump(char *edid);
+extern int edid_checksum(char *edid, int len);
+extern unsigned int edid_get_hdmi_phy_addr(void);
+extern unsigned int edid_get_hdmi_3d_mask(struct edid_info_t *info,
+ int vic);
+
+#endif
diff --git a/common/wmt_display/env_parse.c b/common/wmt_display/env_parse.c
new file mode 100755
index 0000000..17953b7
--- /dev/null
+++ b/common/wmt_display/env_parse.c
@@ -0,0 +1,398 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+should have received a copy of the GNU General Public License along with this
+program. If not, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <version.h>
+#include <stdarg.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <linux/stddef.h>
+#include <asm/byteorder.h>
+
+#include "lcd.h"
+#include "wmt_display.h"
+
+#if 0
+int parse_display_params(char *name,long *ps)
+{
+ enum
+ {
+ idx_vout,
+ idx_op1,
+ idx_op2,
+ idx_resx,
+ idx_resy,
+ idx_fps_pixclk,
+ idx_max
+ };
+
+ char *p;
+// long ps[idx_max];
+ char * endp;
+ int i = 0;
+
+ p = getenv(name);
+ if (!p) {
+ printf("please set %s\n", name);
+ return -1;
+ } else
+ printf("display param (setting): %s\n", p);
+
+ while (i < idx_max) {
+ ps[i++] = simple_strtoul(p, &endp, 10);
+ if (*endp == '\0')
+ break;
+ p = endp + 1;
+
+ if (*p == '\0')
+ break;
+ }
+
+ if (i != idx_max) {
+ printf("display param Error: need %d arg count, but get %d\n", idx_max, i);
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+int parse_gpio_operation(char *name)
+{
+ enum
+ {
+ idx_id,
+ idx_act,
+ idx_bitmap,
+ idx_ctl,
+ idx_oc,
+ idx_od,
+ idx_max
+ };
+
+ char *p;
+ long ps[idx_max];
+ char * endp;
+ int i = 0;
+
+ p = getenv(name);
+ if (!p) {
+ printf("please set %s , for lcd power control pin\n", name);
+ return -1;
+ } else
+ printf("lcd power control pin (setting): %s\n", p);
+
+ while (i < idx_max) {
+ ps[i++] = simple_strtoul(p, &endp, 16);
+ if (*endp == '\0')
+ break;
+ p = endp + 1;
+
+ if (*p == '\0')
+ break;
+ }
+ g_lcd_pw_pin.id = ps[0];
+ g_lcd_pw_pin.act = ps[1];
+ g_lcd_pw_pin.bitmap = ps[2];
+ g_lcd_pw_pin.ctl = ps[3];
+ g_lcd_pw_pin.oc = ps[4];
+ g_lcd_pw_pin.od = ps[5];
+ return 0;
+}
+
+int parse_gpio_param(const char *name, struct gpio_param_t *p_gpio_pin)
+{
+ enum
+ {
+ idx_flag,
+ idx_gpiono,
+ idx_act,
+ idx_max
+ };
+
+ char *p;
+ long ps[idx_max] = {0};
+ char * endp;
+ int i = 0;
+
+ memset(p_gpio_pin, 0, sizeof(struct gpio_param_t));
+
+ p = getenv(name);
+ if (!p)
+ return -1;
+
+ //printf("parse_gpio_param: %s\n", p);
+
+ while (i < idx_max) {
+ ps[i++] = simple_strtoul(p, &endp, 10);
+
+ if (*endp == '\0')
+ break;
+ p = endp + 1;
+
+ if (*p == '\0')
+ break;
+ }
+ p_gpio_pin->flag = ps[0];
+ p_gpio_pin->gpiono = ps[1];
+ p_gpio_pin->act = ps[2];
+
+ return 0;
+}
+
+#if 0
+int parse_display_tmr(char *name)
+{
+ enum
+ {
+ idx_pixel_clock,
+ idx_option,
+ idx_hsync,
+ idx_hbp,
+ idx_hpixel,
+ idx_hfp,
+ idx_vsync,
+ idx_vbp,
+ idx_vpixel,
+ idx_vfp,
+ idx_max
+ };
+
+ char *p;
+ long ps[idx_max];
+ char * endp;
+ int i = 0;
+
+ p = getenv(name);
+ if (!p) {
+ printf("please set %s , for timing setting\n", name);
+ return -1;
+ } else
+ printf("display tmr (setting): %s\n", p);
+
+ g_display_vaild &= ~TMRFROMENV;
+ while (i < idx_max) {
+ ps[i++] = simple_strtoul(p, &endp, 10);
+ if (*endp == '\0')
+ break;
+ p = endp + 1;
+
+ if (*p == '\0')
+ break;
+ }
+
+ if (i != idx_max) {
+ printf("display tmr Error: need %d arg count, but get %d\n", idx_max, i);
+ return -1;
+ }
+
+ g_display_tmr.pixel_clock = ps[idx_pixel_clock]*1000;
+ g_display_tmr.option = ps[idx_option];
+
+ g_display_tmr.hsync = ps[idx_hsync];
+ g_display_tmr.hbp = ps[idx_hbp];
+ g_display_tmr.hpixel = ps[idx_hpixel];
+ g_display_tmr.hfp = ps[idx_hfp];
+
+ g_display_tmr.vsync = ps[idx_vsync];
+ g_display_tmr.vbp = ps[idx_vbp];
+ g_display_tmr.vpixel = ps[idx_vpixel];
+ g_display_tmr.vfp = ps[idx_vfp];
+
+ g_display_vaild |= TMRFROMENV;
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_VPP_SHENZHEN
+int parse_backlight_params(void)
+{
+ enum {
+ idx_pwm_no,
+ idx_invert,
+ idx_gpio, /* switch */
+ idx_active,
+ idx_max,
+ };
+
+ char *p;
+ long ps[idx_max] = { 0, 0, -1, 0 };
+ char *endp;
+ int i = 0;
+ static char env[] = "wmt.backlight.param";
+
+ p = getenv(env);
+ if (!p) {
+ printf("please set %s\n", env);
+ return -1;
+ }
+
+ while (i < idx_max) {
+ ps[i++] = simple_strtoul(p, &endp, 10);
+
+ if (*endp == '\0')
+ break;
+ p = endp + 1;
+
+ if (*p == '\0')
+ break;
+ }
+
+ memset(&g_backlight_param, 0, sizeof(g_backlight_param));
+ g_backlight_param.pwm_no = ps[0];
+ g_backlight_param.invert = ps[1];
+ g_backlight_param.gpio = ps[2];
+ g_backlight_param.active = ps[3];
+
+ printf("backlight: pwmno %d, invert %d, gpio %d, active %d\n",
+ g_backlight_param.pwm_no, g_backlight_param.invert,
+ g_backlight_param.gpio, g_backlight_param.active);
+
+ return 0;
+}
+#endif
+
+/*
+ val is used if setting comes from command , like
+ #display setpwm 0:2000:75
+ otherwise , we get pwm setting from env ("name")
+*/
+int parse_pwm_params(char *name, char *val)
+{
+ //pwmparam: no,scalar,period,duty
+ //comment:
+ // no: PWM no. Range: 0 ~ 3
+ // scalar: PWM scalar. Range: 1 ~ 1024
+ // period: PWM period. Range: 1 ~ 4096
+ // duty: PWM duty. Range: 1 ~ 4096
+ // -- Note: All PWM parameters are denoted using decimal number
+ enum
+ {
+ idx_pwm_no,
+ idx_scalar,
+ idx_period,
+ idx_duty,
+ idx_max
+ };
+
+ long ps[idx_max];
+ char * p;
+ char * p1;
+ char * endp;
+ int i = 0;
+ struct wmt_pwm_setting_t setting;
+
+ g_display_vaild &= ~PWMDEFMASK;
+ g_display_vaild |= PWMDEFTP;
+ g_pwm_setting.pwm_no = 0;
+ g_pwm_setting.scalar = 0;
+ g_pwm_setting.period = 2000;
+ g_pwm_setting.duty = 75;
+
+ if (val == NULL) {
+ p = getenv(name);
+ if (!p) {
+ printf("%s is not found , run PWM param (tp default) = 0:2000:75\n", name);
+ return 0;
+ }
+ } else
+ p = val;
+
+ p1 = p;
+ while (i < idx_max) {
+ if (i == 0)
+ ps[i++] = simple_strtoul(p, &endp, 16);
+ else
+ ps[i++] = simple_strtoul(p, &endp, 10);
+ if (*endp == '\0')
+ break;
+ p = endp + 1;
+
+ if (*p == '\0')
+ break;
+ }
+
+ memset(&setting, 0, sizeof(struct wmt_pwm_setting_t));
+ setting.config = ps[idx_pwm_no];
+ ps[idx_pwm_no] &= 0xf;
+ if (i == idx_duty) { // run as taipei define ( freq , level )
+ //printf("PWM param (tp setting) : freq,level = %s\n", p1);
+ if(ps[idx_pwm_no] >= 0 && ps[idx_pwm_no] <= 3)
+ setting.pwm_no = ps[idx_pwm_no];
+ else {
+ printf("PWM param Error: no = %d, it's range should be 0 ~3\n", ps[idx_pwm_no]);
+ printf("PWM param (tp default) = 0:2000:750\n");
+ return 0;
+ }
+ if (ps[idx_scalar] != 0)
+ setting.period = ps[idx_scalar];
+ else {
+ printf("PWM param error : freq = 0\n");
+ printf("PWM param (tp default) = 0:2000:75\n");
+ return 0;
+ }
+ setting.duty = ps[idx_period];
+ } else if (i == idx_max) {
+ //printf("PWM param (sz setting) : scalar,period,duty = %s\n", p1);
+ g_display_vaild &= ~PWMDEFMASK;
+ g_display_vaild |= PWMDEFSZ;
+ g_pwm_setting.pwm_no = 0;
+ g_pwm_setting.scalar = 319;
+ g_pwm_setting.period = 1000;
+ g_pwm_setting.duty = 750;
+
+ if(ps[idx_pwm_no] >= 0 && ps[idx_pwm_no] <= 3)
+ setting.pwm_no = ps[idx_pwm_no];
+ else {
+ printf("PWM param Error: no = %d, it's range should be 0 ~3\n", ps[idx_pwm_no]);
+ printf("So use defualt PWM param = 0:319:1000:750\n");
+ return 0;
+ }
+
+ if (ps[idx_scalar] > 0 && ps[idx_scalar] <= 1024)
+ setting.scalar = ps[idx_scalar];
+ else {
+ printf("PWM param Error: scalar = %d, it's range should be 1 ~ 1024\n", ps[idx_scalar]);
+ printf("So use defualt PWM param = 0:319:1000:750\n");
+ return 0;
+ }
+
+ if (ps[idx_period] > 0 && ps[idx_period] < 4096)
+ setting.period = ps[idx_period];
+ else {
+ printf("PWM param Error: period = %d, it's range should be 1 ~ 4096\n", ps[idx_period]);
+ printf("So use defualt PWM param = 0:319:1000:750\n");
+ return 0;
+ }
+
+ if (ps[idx_duty] > 0 && ps[idx_duty] < 4096)
+ setting.duty = ps[idx_duty];
+ else {
+ printf("PWM param Error: duty = %d, it's range should be 0 ~ 4096\n", ps[idx_duty]);
+ printf("So use defualt PWM param = 0:319:1000:750\n");
+ return 0;
+ }
+ } else {
+ printf("PWM param Error: need %d arg count, but get %d\n", idx_max, i);
+ printf("PWM param (default) = 0:2000:75 \n");
+ return 0;
+ }
+ memcpy(&g_pwm_setting, &setting, sizeof(struct wmt_pwm_setting_t));
+ return 0;
+}
diff --git a/common/wmt_display/govrh.c b/common/wmt_display/govrh.c
new file mode 100755
index 0000000..214cab6
--- /dev/null
+++ b/common/wmt_display/govrh.c
@@ -0,0 +1,1932 @@
+/*++
+ * linux/drivers/video/wmt/govrh.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define GOVRH_C
+#undef DEBUG
+/* #define DEBUG */
+/* #define DEBUG_DETAIL */
+
+#include "govrh.h"
+
+#ifdef WMT_FTBLK_GOVRH
+void govrh_reg_dump(struct vpp_mod_base_t *base)
+{
+ struct govrh_mod_t *p_govr = (struct govrh_mod_t *) base;
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ int igs_mode[4] = {888, 555, 666, 565};
+
+ DPRINT("========== GOVRH register dump ==========\n");
+ vpp_reg_dump((unsigned int)base->mmio, 512);
+ DPRINT("=========================================\n");
+ DPRINT("MIF enable %d\n", regs->mif.b.enable);
+ DPRINT("color bar enable %d,mode %d,inv %d\n",
+ regs->cb_enable.b.enable, regs->cb_enable.b.mode,
+ regs->cb_enable.b.inversion);
+ DPRINT("---------- frame buffer ----------\n");
+ DPRINT("colr format %s\n",
+ vpp_colfmt_str[govrh_get_color_format(p_govr)]);
+ DPRINT("width active %d,fb %d\n", regs->pixwid, regs->bufwid);
+ DPRINT("Y addr 0x%x, C addr 0x%x\n", regs->ysa, regs->csa);
+ DPRINT("Y addr2 0x%x, C addr2 0x%x\n", regs->ysa2, regs->csa2);
+ DPRINT("H crop %d, V crop %d\n", regs->hcrop, regs->vcrop);
+ DPRINT("source format %s,H264 %d\n",
+ (regs->srcfmt) ? "field" : "frame", regs->h264_input_en);
+ DPRINT("H scaleup %d,dirpath %d\n", regs->hscale_up, regs->dirpath);
+ DPRINT("---------- GOVRH TG1 ----------\n");
+ DPRINT("TG enable %d, Twin mode %d\n",
+ regs->tg_enable.b.enable, regs->tg_enable.b.mode);
+ DPRINT("DVO clk %d,%d,Read cyc %d\n",
+ vpp_get_base_clock(p_govr->mod),
+ auto_pll_divisor((p_govr->mod == VPP_MOD_GOVRH) ?
+ DEV_HDMILVDS : DEV_DVO, GET_FREQ, 0, 0),
+ regs->read_cyc);
+ DPRINT("H total %d, Sync %d, beg %d, end %d\n",
+ regs->h_allpxl, regs->hdmi_hsynw,
+ regs->actpx_bg, regs->actpx_end);
+ DPRINT("V total %d, Sync %d, beg %d, end %d\n",
+ regs->v_allln, regs->hdmi_vbisw,
+ regs->actln_bg, regs->actln_end);
+ DPRINT("VBIE %d,PVBI %d\n", regs->vbie_line, regs->pvbi_line);
+ DPRINT("---------- GOVRH TG2 ----------\n");
+ DPRINT("H total %d, Sync %d, beg %d, end %d\n",
+ regs->h_allpxl2, regs->hdmi_hsynw2,
+ regs->actpx_bg2, regs->actpx_end2);
+ DPRINT("V total %d, Sync %d, beg %d, end %d\n",
+ regs->v_allln2, regs->hdmi_vbisw2,
+ regs->actln_bg2, regs->actln_end2);
+ DPRINT("VBIE %d,PVBI %d\n", regs->vbie_line2, regs->pvbi_line2);
+ DPRINT("---------- DVO ----------------\n");
+ DPRINT("DVO enable %d,data width %d bits\n",
+ regs->dvo_set.b.enable, (regs->dvo_set.b.outwidth) ? 12 : 24);
+ DPRINT("DVO color format %s\n",
+ vpp_colfmt_str[govrh_get_dvo_color_format(p_govr)]);
+ DPRINT("Polar H %s,V %s\n",
+ (regs->dvo_set.b.hsync_polar) ? "Low" : "High",
+ (regs->dvo_set.b.vsync_polar) ? "Low" : "High");
+ DPRINT("DVO RGB mode %d,%s\n", igs_mode[regs->igs_mode.b.mode],
+ (regs->igs_mode.b.ldi) ? "msb" : "lsb");
+ DPRINT("RGB swap %d\n", regs->dvo_set.b.rgb_swap);
+ DPRINT("---------- CSC ----------------\n");
+ DPRINT("CSC mode %s\n",
+ (regs->csc_mode.b.mode) ? "YUV2RGB" : "RGB2YUV");
+ DPRINT("CSC enable DVO %d,DISP %d,LVDS %d,HDMI %d\n",
+ regs->yuv2rgb.b.dvo, regs->yuv2rgb.b.disp,
+ regs->yuv2rgb.b.lvds, regs->yuv2rgb.b.hdmi);
+ DPRINT("---------- Misc ----------------\n");
+ DPRINT("Contrast 0x%x,Brightness 0x%x\n",
+ regs->contrast.val, regs->brightness);
+ DPRINT("LVDS RGB mode %d,%s\n", igs_mode[regs->igs_mode2.b.mode],
+ (regs->igs_mode2.b.ldi) ? "msb" : "lsb");
+ DPRINT("HDMI 3D mode %d,blank 0x%x\n",
+ regs->hdmi_3d.b.mode, regs->hdmi_3d.b.blank_value);
+#ifdef WMT_FTBLK_GOVRH_CURSOR
+ DPRINT("---------- CURSOR -------------\n");
+ DPRINT("enable %d,field %d\n",
+ regs->cur_status.b.enable, regs->cur_status.b.out_field);
+ DPRINT("width %d,fb width %d\n", regs->cur_width, regs->cur_fb_width);
+ DPRINT("crop(%d,%d)\n", regs->cur_hcrop, regs->cur_vcrop);
+ DPRINT("coord H(%d,%d),V(%d,%d)\n",
+ regs->cur_hcoord.b.start, regs->cur_hcoord.b.end,
+ regs->cur_vcoord.b.start, regs->cur_vcoord.b.end);
+ DPRINT("color key enable 0x%x,color key 0x%x,alpha enable %d\n",
+ regs->cur_color_key.b.enable, regs->cur_color_key.b.colkey,
+ regs->cur_color_key.b.alpha);
+#endif
+}
+
+
+void govrh_set_tg_enable(struct govrh_mod_t *base, vpp_flag_t enable)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ?
+ 1 : 2, enable);
+
+ regs->tg_enable.b.enable = enable;
+}
+
+unsigned int govrh_set_clock(struct govrh_mod_t *base,
+ unsigned int pixel_clock)
+{
+ int pmc_clk = 0;
+
+ DBG_MSG("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ?
+ 1 : 2, pixel_clock);
+
+ base->vo_clock = pixel_clock;
+ if (base->mod == VPP_MOD_GOVRH) {
+ pmc_clk = auto_pll_divisor(DEV_HDMILVDS, SET_PLLDIV,
+ 0, pixel_clock);
+ DBG_MSG("set %d,get %d\n", pixel_clock,
+ auto_pll_divisor(DEV_HDMILVDS, GET_FREQ, 0, 0));
+ g_vpp.hdmi_pixel_clock = pmc_clk;
+ } else
+ pmc_clk = auto_pll_divisor(DEV_DVO, SET_PLLDIV, 0, pixel_clock);
+ return 0;
+}
+
+void govrh_set_tg1(struct govrh_mod_t *base, vpp_clock_t *timing)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ regs->tg_enable.b.mode = 0;
+ regs->dstfmt = 0;
+ regs->read_cyc = timing->read_cycle;
+
+ regs->actpx_bg = timing->begin_pixel_of_active;
+ regs->actpx_end = timing->end_pixel_of_active;
+ regs->h_allpxl = timing->total_pixel_of_line;
+
+ regs->actln_bg = timing->begin_line_of_active + 1;
+ regs->actln_end = timing->end_line_of_active + 1;
+ regs->v_allln = timing->total_line_of_frame;
+
+ regs->vbie_line = timing->line_number_between_VBIS_VBIE;
+ /* pre vbi should more 6 to avoid garbage line */
+ regs->pvbi_line = (timing->line_number_between_PVBI_VBIS < 6) ?
+ 6 : timing->line_number_between_PVBI_VBIS;
+
+ regs->hdmi_hsynw = timing->hsync;
+ regs->hdmi_vbisw = timing->vsync;
+
+#ifdef DEBUG_DETAIL
+ vpp_show_timing("govrh tg1", 0, timing);
+#endif
+}
+
+int govrh_get_tg_mode(struct govrh_mod_t *base)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ return regs->tg_enable.b.mode;
+}
+
+void govrh_set_tg2(struct govrh_mod_t *base, vpp_clock_t *timing)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ regs->tg_enable.b.mode = 1;
+ regs->dstfmt = 1;
+
+ regs->actpx_bg2 = timing->begin_pixel_of_active;
+ regs->actpx_end2 = timing->end_pixel_of_active;
+ regs->h_allpxl2 = timing->total_pixel_of_line;
+
+ regs->actln_bg2 = timing->begin_line_of_active + 1;
+ regs->actln_end2 = timing->end_line_of_active + 1;
+ regs->v_allln2 = timing->total_line_of_frame;
+
+ regs->vbie_line2 = timing->line_number_between_VBIS_VBIE;
+ regs->pvbi_line2 = (timing->line_number_between_PVBI_VBIS < 6) ?
+ 6 : timing->line_number_between_PVBI_VBIS;
+
+ regs->hdmi_hsynw2 = timing->hsync;
+ regs->hdmi_vbisw2 = timing->vsync;
+
+#ifdef DEBUG_DETAIL
+ vpp_show_timing("govrh tg2", 0, timing);
+#endif
+}
+
+void govrh_get_tg(struct govrh_mod_t *base, vpp_clock_t *tmr)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ tmr->read_cycle = regs->read_cyc;
+ tmr->total_pixel_of_line = regs->h_allpxl;
+ tmr->begin_pixel_of_active = regs->actpx_bg;
+ tmr->end_pixel_of_active = regs->actpx_end;
+
+ tmr->total_line_of_frame = regs->v_allln;
+ tmr->begin_line_of_active = (regs->actln_bg - 1);
+ tmr->end_line_of_active = (regs->actln_end - 1);
+
+ tmr->line_number_between_VBIS_VBIE = regs->vbie_line;
+ tmr->line_number_between_PVBI_VBIS = regs->pvbi_line;
+
+ tmr->hsync = regs->hdmi_hsynw;
+ tmr->vsync = regs->hdmi_vbisw;
+
+ if (regs->tg_enable.b.mode) {
+ tmr->vsync = (tmr->vsync - 1) * 2;
+ tmr->begin_line_of_active = (tmr->begin_line_of_active - 1) * 2;
+ tmr->end_line_of_active = (tmr->end_line_of_active - 1) * 2;
+ tmr->total_line_of_frame = (tmr->total_line_of_frame - 1) * 2;
+ }
+}
+
+int govrh_get_hscale_up(struct govrh_mod_t *base)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ int reg;
+
+ reg = regs->hscale_up & 0x1;
+ DBG_DETAIL("(govr %d,reg %d)\n", (base->mod == VPP_MOD_GOVRH) ?
+ 1 : 2, reg);
+ return reg;
+}
+
+void govrh_set_direct_path(struct govrh_mod_t *base, int enable)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ?
+ 1 : 2, enable);
+
+ regs->dirpath = enable;
+}
+
+enum vpp_int_err_t govrh_get_int_status(struct govrh_mod_t *base)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ enum vpp_int_err_t int_sts;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ int_sts = 0;
+ if (regs->interrupt.b.err_sts)
+ int_sts |= VPP_INT_ERR_GOVRH_MIF;
+ return int_sts;
+}
+
+void govrh_clean_int_status(struct govrh_mod_t *base,
+ enum vpp_int_err_t int_sts)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ unsigned int val;
+
+ DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ?
+ 1 : 2, int_sts);
+
+ if (int_sts & VPP_INT_ERR_GOVRH_MIF) {
+ val = regs->interrupt.val;
+ val = (val & 0xff) + 0x20000;
+ regs->interrupt.val = val;
+ }
+}
+
+void govrh_set_int_enable(struct govrh_mod_t *base,
+ vpp_flag_t enable, enum vpp_int_err_t int_bit)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ?
+ 1 : 2, enable);
+
+ /* clean status first before enable/disable interrupt */
+ govrh_clean_int_status(base, int_bit);
+
+ if (int_bit & VPP_INT_ERR_GOVRH_MIF)
+ regs->interrupt.b.mem_enable = enable;
+}
+
+int govrh_get_dvo_enable(struct govrh_mod_t *base)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ return regs->dvo_set.b.enable;
+}
+
+void govrh_set_dvo_enable(struct govrh_mod_t *base, vpp_flag_t enable)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+/* DPRINT("[GOVRH] %s(%d)\n",__FUNCTION__,enable); */
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, enable);
+
+ regs->dvo_set.b.enable = enable;
+ if (enable) {
+ /* GPIO to function pin */
+ outl(0x0, GPIO_BASE_ADDR + 0x44);
+ /* GPIO pull disable */
+ outl(0x0, GPIO_BASE_ADDR + 0x484);
+ /* 1:pullup,0:pulldn */
+ outl(0x0, GPIO_BASE_ADDR + 0x4C4);
+ return;
+ }
+ /* disable dvo */
+ outl(0xFFFFFFFF, GPIO_BASE_ADDR + 0x44); /* Enable GPIO */
+ outl(0x0, GPIO_BASE_ADDR + 0x84); /* GPIO output enable */
+ outl(0x0, GPIO_BASE_ADDR + 0x484); /* GPIO pull disable */
+ outl(0x0, GPIO_BASE_ADDR + 0x4C4); /* 1:pullup,0:pulldn */
+}
+
+void govrh_set_dvo_sync_polar(struct govrh_mod_t *base,
+ vpp_flag_t hsync, vpp_flag_t vsync)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, hsync, vsync);
+
+ regs->dvo_set.b.hsync_polar = hsync;
+ regs->dvo_set.b.vsync_polar = vsync;
+}
+
+vdo_color_fmt govrh_get_dvo_color_format(struct govrh_mod_t *base)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ if (regs->dvo_pix.b.rgb)
+ return VDO_COL_FMT_ARGB;
+ if (regs->dvo_pix.b.yuv422)
+ return VDO_COL_FMT_YUV422H;
+ return VDO_COL_FMT_YUV444;
+}
+
+void govrh_set_dvo_color_format(struct govrh_mod_t *base,
+ vdo_color_fmt fmt)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%s)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, vpp_colfmt_str[fmt]);
+
+ switch (fmt) {
+ case VDO_COL_FMT_ARGB:
+ regs->dvo_pix.b.rgb = 1;
+ regs->dvo_pix.b.yuv422 = 0;
+ break;
+ case VDO_COL_FMT_YUV422H:
+ regs->dvo_pix.b.rgb = 0;
+ regs->dvo_pix.b.yuv422 = 1;
+ break;
+ case VDO_COL_FMT_YUV444:
+ default:
+ regs->dvo_pix.b.rgb = 0;
+ regs->dvo_pix.b.yuv422 = 0;
+ break;
+ }
+}
+
+void govrh_set_dvo_outdatw(struct govrh_mod_t *base,
+ vpp_datawidht_t width)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ unsigned int clk_delay;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, width);
+
+ regs->dvo_set.b.outwidth = (width == VPP_DATAWIDHT_12) ? 1 : 0;
+
+ clk_delay = (width == VPP_DATAWIDHT_24) ?
+ VPP_GOVR_DVO_DELAY_24 : VPP_GOVR_DVO_DELAY_12;
+ govrh_set_dvo_clock_delay(base, ((clk_delay & BIT14) != 0x0),
+ clk_delay & 0x3FFF);
+}
+
+void govrh_set_dvo_clock_delay(struct govrh_mod_t *base,
+ int inverse, int delay)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d,%d)\n", (base->mod == VPP_MOD_GOVRH) ?
+ 1 : 2, inverse, delay);
+
+#ifdef CONFIG_HW_DVO_DELAY
+ regs = p_govrh->mmio;
+#endif
+
+ regs->dvo_dly_sel.b.inv = inverse;
+ regs->dvo_dly_sel.b.delay = delay;
+}
+
+void govrh_set_colorbar(struct govrh_mod_t *base,
+ vpp_flag_t enable, int mode, int inv)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, enable);
+
+ regs->cb_enable.b.enable = enable;
+ regs->cb_enable.b.mode = mode;
+ regs->cb_enable.b.inversion = inv;
+}
+
+void govrh_set_contrast(struct govrh_mod_t *base, unsigned int value)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,0x%x)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, value);
+
+ regs->contrast.val = value;
+}
+
+unsigned int govrh_get_contrast(struct govrh_mod_t *base)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ return regs->contrast.val;
+}
+
+void govrh_set_brightness(struct govrh_mod_t *base, unsigned int value)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,0x%x)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, value);
+
+ regs->brightness = value;
+}
+
+unsigned int govrh_get_brightness(struct govrh_mod_t *base)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ return regs->brightness;
+}
+
+void govrh_set_saturation(struct govrh_mod_t *base, unsigned int value)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,0x%x)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, value);
+
+ regs->saturation.val = value;
+ regs->saturation_enable.b.enable = 1;
+}
+
+unsigned int govrh_get_saturation(struct govrh_mod_t *base)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ return regs->saturation.val;
+}
+
+void govrh_set_MIF_enable(struct govrh_mod_t *base, vpp_flag_t enable)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, enable);
+
+ regs->mif.b.enable = enable;
+}
+
+int govrh_get_MIF_enable(struct govrh_mod_t *base)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ return regs->mif.b.enable;
+}
+
+void govrh_set_frame_mode(struct govrh_mod_t *base,
+ unsigned int width, vdo_color_fmt colfmt)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ int y_byte, c_byte;
+ int enable;
+
+ enable = 1;
+ vpp_get_colfmt_bpp(colfmt, &y_byte, &c_byte);
+ y_byte = width * y_byte / 8;
+ if (y_byte % 8)
+ enable = 0;
+ if (c_byte) {
+ c_byte = width * c_byte / 8;
+ if (c_byte % 8)
+ enable = 0;
+ }
+ if (regs->bufwid % 128)
+ enable = 0;
+ if (width == 720)
+ enable = 0;
+ regs->mif_frame_mode.b.frame_enable = enable;
+ regs->mif_frame_mode.b.req_num =
+ (y_byte / 128) + ((y_byte % 128) ? 1 : 0);
+ regs->mif_frame_mode.b.req_num_c =
+ (c_byte) ? ((c_byte / 128) + ((c_byte % 128) ? 1 : 0)) : 0;
+}
+
+void govrh_set_color_format(struct govrh_mod_t *base,
+ vdo_color_fmt format)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%s)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, vpp_colfmt_str[format]);
+
+ if (format < VDO_COL_FMT_ARGB)
+ regs->yuv2rgb.b.rgb_mode = 0;
+
+ switch (format) {
+ case VDO_COL_FMT_YUV420:
+ regs->colfmt = 1;
+ regs->colfmt2 = 0;
+ break;
+ case VDO_COL_FMT_YUV422H:
+ regs->colfmt = 0;
+ regs->colfmt2 = 0;
+ break;
+ case VDO_COL_FMT_YUV444:
+ regs->colfmt = 0;
+ regs->colfmt2 = 1;
+ break;
+ case VDO_COL_FMT_ARGB:
+ regs->yuv2rgb.b.rgb_mode = 1;
+ break;
+ case VDO_COL_FMT_RGB_1555:
+ regs->yuv2rgb.b.rgb_mode = 2;
+ break;
+ case VDO_COL_FMT_RGB_565:
+ regs->yuv2rgb.b.rgb_mode = 3;
+ break;
+ default:
+ DBGMSG("*E* check the parameter\n");
+ return;
+ }
+#ifdef WMT_FTBLK_GOVRH_CURSOR
+ govrh_CUR_set_colfmt((struct govrh_cursor_mod_t *)p_cursor, format);
+#endif
+ govrh_set_frame_mode(base, regs->pixwid, format);
+ regs->saturation_enable.b.format = (regs->yuv2rgb.b.rgb_mode) ? 1 : 0;
+}
+
+vdo_color_fmt govrh_get_color_format(struct govrh_mod_t *base)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ switch (regs->yuv2rgb.b.rgb_mode) {
+ case 1:
+ return VDO_COL_FMT_ARGB;
+ case 2:
+ return VDO_COL_FMT_RGB_1555;
+ case 3:
+ return VDO_COL_FMT_RGB_565;
+ default:
+ break;
+ }
+ if (regs->colfmt2)
+ return VDO_COL_FMT_YUV444;
+ if (regs->colfmt)
+ return VDO_COL_FMT_YUV420;
+ return VDO_COL_FMT_YUV422H;
+}
+
+void govrh_set_source_format(struct govrh_mod_t *base,
+ vpp_display_format_t format)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, format);
+
+ regs->srcfmt = (format == VPP_DISP_FMT_FIELD) ? 1 : 0;
+}
+
+void govrh_set_output_format(struct govrh_mod_t *base,
+ vpp_display_format_t field)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, field);
+
+ regs->dstfmt = (field == VPP_DISP_FMT_FIELD) ? 1 : 0;
+}
+
+void govrh_set_fb_addr(struct govrh_mod_t *base,
+ unsigned int y_addr, unsigned int c_addr)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ /* DBG_DETAIL("(govr %d,0x%x,0x%x)\n",
+ (base->mod == VPP_MOD_GOVRH)? 1:2,y_addr,c_addr); */
+#ifdef DEBUG
+ if ((y_addr % GOVRH_FRAMEBUF_ALIGN) || (c_addr % GOVRH_FRAMEBUF_ALIGN))
+ DBG_ERR("addr should align %d(0x%x,0x%x)\n",
+ GOVRH_FRAMEBUF_ALIGN, y_addr, c_addr);
+#endif
+ regs->ysa = y_addr;
+ regs->csa = c_addr;
+}
+
+void govrh_get_fb_addr(struct govrh_mod_t *base,
+ unsigned int *y_addr, unsigned int *c_addr)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ *y_addr = regs->ysa;
+ *c_addr = regs->csa;
+
+ DBG_DETAIL("(govr %d,0x%x,0x%x)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, *y_addr, *c_addr);
+}
+
+void govrh_set_fb2_addr(struct govrh_mod_t *base,
+ unsigned int y_addr, unsigned int c_addr)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,0x%x,0x%x)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, y_addr, c_addr);
+#ifdef DEBUG
+ if ((y_addr % GOVRH_FRAMEBUF_ALIGN) || (c_addr % GOVRH_FRAMEBUF_ALIGN))
+ DBG_ERR("addr should align %d(0x%x,0x%x)\n",
+ GOVRH_FRAMEBUF_ALIGN, y_addr, c_addr);
+#endif
+ regs->ysa2 = y_addr;
+ regs->csa2 = c_addr;
+}
+
+void govrh_get_fb2_addr(struct govrh_mod_t *base,
+ unsigned int *y_addr, unsigned int *c_addr)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ *y_addr = regs->ysa2;
+ *c_addr = regs->csa2;
+
+ DBG_DETAIL("(govr %d,0x%x,0x%x)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, *y_addr, *c_addr);
+}
+
+void govrh_set_fb_width(struct govrh_mod_t *base, unsigned int width)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, width);
+
+ regs->bufwid = width;
+}
+
+#define GOVRH_CURSOR_RIGHT_POS 6
+void govrh_set_fb_info(struct govrh_mod_t *base, unsigned int width,
+ unsigned int act_width, unsigned int x_offset, unsigned int y_offset)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,fb_w %d,img_w %d,x %d,y %d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2,
+ width, act_width, x_offset, y_offset);
+
+ regs->pixwid = act_width;
+ regs->bufwid = width;
+ regs->hcrop = x_offset;
+ regs->vcrop = y_offset;
+ govrh_set_frame_mode(base, act_width, govrh_get_color_format(base));
+
+#ifdef WMT_FTBLK_GOVRH_CURSOR
+ /* cursor postion over when change resolution */
+ if ((regs->actpx_end - regs->actpx_bg) != regs->pixwid) {
+ if (regs->cur_hcoord.b.end >=
+ (regs->pixwid - GOVRH_CURSOR_RIGHT_POS)) {
+ int pos;
+
+ pos = regs->pixwid - GOVRH_CURSOR_RIGHT_POS;
+ regs->cur_hcoord.b.end = pos;
+ pos -= regs->cur_width;
+ regs->cur_hcoord.b.start = (pos+1);
+
+ p_cursor->posx = pos;
+ }
+ }
+#endif
+}
+
+void govrh_get_fb_info(struct govrh_mod_t *base, unsigned int *width,
+ unsigned int *act_width, unsigned int *x_offset, unsigned int *y_offset)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ *act_width = regs->pixwid;
+ *width = regs->bufwid;
+ *x_offset = regs->hcrop;
+ *y_offset = regs->vcrop;
+}
+
+void govrh_set_fifo_index(struct govrh_mod_t *base, unsigned int index)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, index);
+
+ regs->fhi = index;
+}
+
+void govrh_set_reg_level(struct govrh_mod_t *base, vpp_reglevel_t level)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, level);
+
+ regs->sts.b.level = (level == VPP_REG_LEVEL_1) ? 0 : 1;
+}
+
+void govrh_set_reg_update(struct govrh_mod_t *base, vpp_flag_t enable)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, enable);
+
+ regs->sts.b.update = enable;
+}
+
+void govrh_set_tg(struct govrh_mod_t *base,
+ vpp_clock_t *tmr, unsigned int pixel_clock)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ int tg_enable;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, pixel_clock);
+
+ tg_enable = regs->tg_enable.b.enable;
+ regs->tg_enable.b.enable = 0;
+
+ tmr->read_cycle = govrh_set_clock(base, pixel_clock);
+ govrh_set_tg1(base, tmr);
+
+ regs->tg_enable.b.enable = tg_enable;
+}
+
+void govrh_set_csc_mode(struct govrh_mod_t *base, vpp_csc_t mode)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ vdo_color_fmt src_fmt, dst_fmt;
+ unsigned int enable;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, mode);
+
+ enable = 0;
+ src_fmt = (govrh_get_color_format(base) < VDO_COL_FMT_ARGB) ?
+ VDO_COL_FMT_YUV444 : VDO_COL_FMT_ARGB;
+ dst_fmt = (govrh_get_dvo_color_format(base) < VDO_COL_FMT_ARGB) ?
+ VDO_COL_FMT_YUV444 : VDO_COL_FMT_ARGB;
+ if (src_fmt == VDO_COL_FMT_ARGB)
+ enable |= (dst_fmt != VDO_COL_FMT_ARGB) ? BIT0 : 0x00; /* DVO */
+ else
+ enable |= (dst_fmt == VDO_COL_FMT_ARGB) ? BIT0 : 0x00; /* DVO */
+#ifdef WMT_FTBLK_LVDS
+ vpp_set_clock_enable(DEV_LVDS, 1, 0);
+ if (src_fmt == VDO_COL_FMT_ARGB) {
+ if (lvds_get_colfmt() < VDO_COL_FMT_ARGB)
+ enable |= BIT3;
+ } else {
+ if (lvds_get_colfmt() >= VDO_COL_FMT_ARGB)
+ enable |= BIT3;
+ }
+ vpp_set_clock_enable(DEV_LVDS, 0, 0);
+#endif
+#ifdef WMT_FTBLK_HDMI
+ vpp_set_clock_enable(DEV_HDMI, 1, 0);
+ if (src_fmt == VDO_COL_FMT_ARGB) {
+ if (hdmi_get_output_colfmt() < VDO_COL_FMT_ARGB)
+ enable |= BIT4;
+ } else {
+ if (hdmi_get_output_colfmt() >= VDO_COL_FMT_ARGB)
+ enable |= BIT4;
+ }
+ vpp_set_clock_enable(DEV_HDMI, 0, 0);
+#endif
+ mode = vpp_check_csc_mode(mode, src_fmt, dst_fmt, enable);
+ if (mode >= VPP_CSC_MAX) {
+ enable = 0;
+ /* for internal color bar (YUV base) */
+ mode = base->fb_p->csc_mode;
+ }
+
+ mode = (base->csc_mode_force) ? base->csc_mode_force : mode;
+
+ regs->dmacsc_coef0 = vpp_csc_parm[mode][0]; /* C1,C2 */
+ regs->dmacsc_coef1 = vpp_csc_parm[mode][1]; /* C3,C4 */
+ regs->dmacsc_coef2 = vpp_csc_parm[mode][2]; /* C5,C6 */
+ regs->dmacsc_coef3 = vpp_csc_parm[mode][3]; /* C7,C8 */
+ regs->dmacsc_coef4 = vpp_csc_parm[mode][4] & 0xFFFF; /* C9 */
+ regs->dmacsc_coef5 = ((vpp_csc_parm[mode][4] & 0xFFFF0000) >> 16) +
+ ((vpp_csc_parm[mode][5] & 0xFFFF) << 16); /* I,J */
+ regs->dmacsc_coef6 = (vpp_csc_parm[mode][5] & 0xFFFF0000) >> 16; /* K */
+ regs->csc_mode.val = (vpp_csc_parm[mode][6] & BIT0) +
+ ((vpp_csc_parm[mode][6] & BIT8) ? BIT1 : 0x0);
+
+ /* enable bit0:DVO, bit1:VGA, bit2:DISP, bit3:LVDS, bit4:HDMI */
+ regs->yuv2rgb.b.blank_zero = 1;
+ regs->yuv2rgb.b.dac_clkinv = 1;
+ regs->yuv2rgb.b.reserved1 =
+ (mode >= VPP_CSC_RGB2YUV_SDTV_0_255) ? 1 : 0;
+ regs->yuv2rgb.b.dvo = (enable & BIT0) ? 1 : 0;
+#ifdef WMT_FTBLK_LVDS
+ regs->yuv2rgb.b.lvds = (enable & BIT3) ? 1 : 0;
+#endif
+#ifdef WMT_FTBLK_HDMI
+ regs->yuv2rgb.b.hdmi = (enable & BIT4) ? 1 : 0;
+#endif
+}
+
+void govrh_set_media_format(struct govrh_mod_t *base, vpp_flag_t h264)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, h264);
+
+ regs->mif.b.h264 = h264;
+}
+
+void govrh_HDMI_set_blank_value(struct govrh_mod_t *base,
+ unsigned int val)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, val);
+
+ regs->hdmi_3d.b.blank_value = val;
+}
+
+void govrh_HDMI_set_3D_mode(struct govrh_mod_t *base, int mode)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, mode);
+
+ /* 0-disable,3-frame pack progress(use fb1&2),7-frame pack interlace */
+ regs->hdmi_3d.b.mode = mode;
+}
+
+int govrh_is_top_field(struct govrh_mod_t *base)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ return (regs->field_status) ? 1 : 0;
+}
+
+/*----------------------- GOVRH IGS --------------------------------------*/
+void govrh_IGS_set_mode(struct govrh_mod_t *base,
+ int no, int mode_18bit, int msb)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2, no);
+
+ if (no == 0) { /* DVO */
+ /* 0-24bit,10-18bit,01-555,11-565 */
+ regs->igs_mode.b.mode = mode_18bit;
+ regs->igs_mode.b.ldi = msb; /* 0-lsb,1-msb */
+ } else { /* LVDS */
+ /* 0-24bit,10-18bit,01-555,11-565 */
+ regs->igs_mode2.b.mode = mode_18bit;
+ regs->igs_mode2.b.ldi = msb; /* 0-lsb,1-msb */
+ }
+}
+
+void govrh_IGS_set_RGB_swap(struct govrh_mod_t *base, int mode)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ DBG_DETAIL("(govr %d,%d)\n",
+ (base->mod == VPP_MOD_GOVRH) ? 1 : 2, mode);
+
+ /* 0-RGB [7-0], 1-RGB [0-7], 2-BGR [7-0], 3-BGR [0-7] */
+ regs->dvo_set.b.rgb_swap = mode;
+}
+
+/*----------------------- GOVRH CURSOR --------------------------------------*/
+#ifdef WMT_FTBLK_GOVRH_CURSOR
+#define CONFIG_GOVR2_CURSOR
+void *govrh_CUR_get_mmio(struct govrh_cursor_mod_t *base)
+{
+#ifdef CONFIG_GOVR2_CURSOR
+ base = (struct govrh_cursor_mod_t *)
+ ((govrh_get_MIF_enable(p_govrh)) ? p_govrh : p_govrh2);
+#endif
+ return base->mmio;
+}
+
+void govrh_CUR_set_enable(struct govrh_cursor_mod_t *base,
+ vpp_flag_t enable)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base);
+
+ DBG_DETAIL("(0x%x,%d)\n", base->mmio, enable);
+
+ regs->cur_status.b.enable = enable;
+}
+
+void govrh_CUR_set_fb_addr(struct govrh_cursor_mod_t *base,
+ unsigned int y_addr, unsigned int c_addr)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base);
+
+ DBG_DETAIL("(0x%x,0x%x,0x%x)\n", base->mmio, y_addr, c_addr);
+
+ regs->cur_addr = y_addr;
+}
+
+void govrh_CUR_get_fb_addr(struct govrh_cursor_mod_t *base,
+ unsigned int *y_addr, unsigned int *c_addr)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base);
+
+ *y_addr = regs->cur_addr;
+ *c_addr = 0;
+
+ DBG_DETAIL("(0x%x,0x%x,0x%x)\n", base->mmio, *y_addr, *c_addr);
+}
+
+void govrh_CUR_set_coordinate(struct govrh_cursor_mod_t *base,
+ unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base);
+
+ DBG_DETAIL("(0x%x)\n", base->mmio);
+
+ regs->cur_hcoord.b.start = x1;
+ regs->cur_hcoord.b.end = x2;
+ regs->cur_vcoord.b.start = y1;
+ regs->cur_vcoord.b.end = y2;
+}
+
+void govrh_CUR_set_position(struct govrh_cursor_mod_t *base,
+ unsigned int x, unsigned int y)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base);
+ unsigned int w, h;
+
+ DBG_DETAIL("(0x%x,%d,%d)\n", base->mmio, x, y);
+
+/* w = regs->cur_hcoord.b.end - regs->cur_hcoord.b.start; */
+ w = regs->cur_width - 1;
+ h = regs->cur_vcoord.b.end - regs->cur_vcoord.b.start;
+ govrh_CUR_set_coordinate(base, x, y, x+w, y+h);
+}
+
+void govrh_CUR_set_color_key_mode(struct govrh_cursor_mod_t *base,
+ int enable, int alpha, int mode)
+{
+ /*
+ if( colkey_en )
+ colkey_hit = (mode)? (data == colkey):(data != colkey);
+
+ if( (alpha_en) or (colkey_hit) or (alpha value) )
+ show pixel
+ */
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base);
+
+ DBG_DETAIL("(0x%x,%d,%d,%d)\n", base->mmio, enable, alpha, mode);
+
+ regs->cur_color_key.b.alpha = alpha;
+ regs->cur_color_key.b.enable = enable;
+ regs->cur_color_key.b.invert = mode;
+}
+
+void govrh_CUR_set_color_key(struct govrh_cursor_mod_t *base,
+ int enable, int alpha, unsigned int colkey)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base);
+
+ DBG_DETAIL("(0x%x,0x%x)\n", base->mmio, colkey);
+
+ regs->cur_color_key.b.colkey = colkey;
+ regs->cur_color_key.b.alpha = 0;
+ regs->cur_color_key.b.enable = 0;
+
+#ifdef __KERNEL__
+ if (!(alpha) && enable) {
+ int i, j;
+ unsigned int *ptr1, *ptr2;
+ int yuv2rgb;
+
+ ptr1 = (unsigned int *)mb_phys_to_virt(regs->cur_addr);
+ for (i = 0; i < base->fb_p->fb.fb_h; i++) {
+ for (j = 0; j < base->fb_p->fb.fb_w; j++) {
+ if ((*ptr1 & 0xFFFFFF) == (colkey & 0xFFFFFF))
+ *ptr1 &= 0xFFFFFF;
+ else
+ *ptr1 |= 0xFF000000;
+ ptr1++;
+ }
+ }
+
+ yuv2rgb = (base->colfmt < VDO_COL_FMT_ARGB) ? 1 : 0;
+ ptr1 = (unsigned int *) mb_phys_to_virt(base->cursor_addr1);
+ ptr2 = (unsigned int *) mb_phys_to_virt(base->cursor_addr2);
+ for (i = 0; i < base->fb_p->fb.fb_h; i++) {
+ for (j = 0; j < base->fb_p->fb.fb_w; j++) {
+ *ptr2 = vpp_convert_colfmt(yuv2rgb, *ptr1);
+ ptr1++;
+ ptr2++;
+ }
+ }
+ }
+#endif
+}
+
+void govrh_CUR_set_colfmt(struct govrh_cursor_mod_t *base,
+ vdo_color_fmt colfmt)
+{
+#ifdef __KERNEL__
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base);
+#endif
+
+ DBG_DETAIL("(0x%x,%s)\n", base->mmio, vpp_colfmt_str[colfmt]);
+
+ colfmt = (colfmt < VDO_COL_FMT_ARGB) ?
+ VDO_COL_FMT_YUV444 : VDO_COL_FMT_ARGB;
+ if (base->fb_p->fb.col_fmt == colfmt)
+ return;
+
+ base->fb_p->fb.col_fmt = colfmt;
+#ifdef __KERNEL__
+ regs->cur_addr = (base->colfmt == colfmt) ?
+ base->cursor_addr1 : base->cursor_addr2;
+#endif
+ DBG_DETAIL("(0x%x)\n", regs->cur_addr);
+}
+
+int govrh_irqproc_set_position(void *arg)
+{
+ struct govrh_cursor_mod_t *base = (struct govrh_cursor_mod_t *) arg;
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base);
+
+ int begin;
+ int pos_x, pos_y;
+ int crop_x, crop_y;
+ int width, height;
+ int govrh_w, govrh_h;
+
+ govrh_w = regs->actpx_end - regs->actpx_bg;
+ govrh_h = regs->actln_end - regs->actln_bg;
+ if (regs->tg_enable.b.mode)
+ govrh_h *= 2;
+
+ /* cursor H */
+ width = base->fb_p->fb.img_w;
+ begin = base->posx - base->hotspot_x;
+ if (begin < 0) { /* over left edge */
+ pos_x = 0;
+ crop_x = 0 - begin;
+ width = width - crop_x;
+ } else {
+ pos_x = begin;
+ crop_x = 0;
+ }
+ if ((begin + base->fb_p->fb.img_w) > govrh_w) /* over right edge */
+ width = govrh_w - begin;
+
+/* DPRINT("[CURSOR] H pos %d,hotspot %d,posx %d,crop %d,width %d\n",
+ p_cursor->posx,p_cursor->hotspot_x,pos_x,crop_x,width); */
+
+ /* cursor V */
+ height = base->fb_p->fb.img_h;
+ begin = base->posy - base->hotspot_y;
+ if (begin < 0) { /* over top edge */
+ pos_y = 0;
+ crop_y = 0 - begin;
+ height = height - crop_y;
+ } else {
+ pos_y = begin;
+ crop_y = 0;
+ }
+ if ((begin + base->fb_p->fb.img_h) > govrh_h) /* over right edge */
+ height = govrh_h - begin;
+
+ if (regs->tg_enable.b.mode) {
+ regs->cur_fb_width = (base->fb_p->fb.fb_w*2);
+ pos_y /= 2;
+ crop_y /= 2;
+ height /= 2;
+ } else
+ regs->cur_fb_width = base->fb_p->fb.fb_w;
+
+/* DPRINT("[CURSOR] V pos %d,hotspot %d,posx %d,crop %d,height %d\n",
+ p_cursor->posy,p_cursor->hotspot_y,pos_y,crop_y,height); */
+
+ regs->cur_width = width;
+ regs->cur_vcrop = crop_y;
+ regs->cur_hcrop = crop_x;
+ govrh_CUR_set_coordinate(base, pos_x, pos_y,
+ pos_x + width - 1, pos_y + height - 1);
+ return 0;
+}
+
+void govrh_CUR_irqproc(int arg)
+{
+ if (p_cursor->enable) {
+ if (p_cursor->chg_flag) {
+ p_cursor->hide_cnt = 0;
+ govrh_CUR_set_enable(p_cursor, 1);
+ } else {
+ p_cursor->hide_cnt++;
+ if (p_cursor->hide_cnt >
+ (GOVRH_CURSOR_HIDE_TIME * p_govrh->fb_p->framerate))
+ govrh_CUR_set_enable(p_cursor, 0);
+ }
+ }
+
+ if (p_cursor->chg_flag) {
+ govrh_irqproc_set_position(p_cursor);
+ p_cursor->chg_flag = 0;
+ }
+}
+
+void govrh_CUR_proc_view(struct govrh_cursor_mod_t *base,
+ int read, vdo_view_t *view)
+{
+ vdo_framebuf_t *fb;
+
+ DBG_DETAIL("(0x%x)\n", base->mmio);
+
+ fb = &base->fb_p->fb;
+ if (read) {
+ view->resx_src = fb->fb_w;
+ view->resy_src = fb->fb_h;
+ view->resx_virtual = fb->img_w;
+ view->resy_virtual = fb->img_h;
+ view->resx_visual = fb->img_w;
+ view->resy_visual = fb->img_h;
+ view->posx = base->posx;
+ view->posy = base->posy;
+ view->offsetx = fb->h_crop;
+ view->offsety = fb->v_crop;
+ } else {
+ base->posx = view->posx;
+ base->posy = view->posy;
+ base->chg_flag = 1;
+ }
+}
+
+void govrh_CUR_set_framebuffer(struct govrh_cursor_mod_t *base,
+ vdo_framebuf_t *fb)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) govrh_CUR_get_mmio(base);
+
+ DBG_DETAIL("(0x%x)\n", base->mmio);
+
+ regs->cur_addr = fb->y_addr;
+ regs->cur_width = fb->img_w;
+ if (regs->tg_enable.b.mode)
+ regs->cur_fb_width = (fb->fb_w*2);
+ else
+ regs->cur_fb_width = fb->fb_w;
+ regs->cur_vcrop = fb->v_crop;
+ regs->cur_hcrop = fb->h_crop;
+ regs->cur_status.b.out_field = vpp_get_fb_field(fb);
+ govrh_irqproc_set_position(base);
+ base->colfmt = fb->col_fmt;
+ base->cursor_addr1 = fb->y_addr;
+#ifdef __KERNEL__
+ if (base->cursor_addr2 == 0)
+ base->cursor_addr2 = mb_alloc(64*64*4);
+#endif
+ vpp_cache_sync();
+}
+
+void govrh_CUR_init(void *base)
+{
+#ifdef CONFIG_GOVR2_CURSOR
+ HW_REG struct govrh_regs *regs;
+
+ regs = (HW_REG struct govrh_regs *) p_govrh->mmio;
+ regs->cur_color_key.b.invert = 1;
+ regs = (HW_REG struct govrh_regs *) p_govrh2->mmio;
+ regs->cur_color_key.b.invert = 1;
+#else
+ struct govrh_cursor_mod_t *mod_p;
+ HW_REG struct govrh_regs *regs;
+
+ mod_p = (struct govrh_cursor_mod_t *) base;
+ regs = (HW_REG struct govrh_regs *) mod_p->mmio;
+
+ regs->cur_color_key.b.invert = 1;
+#endif
+}
+#endif /* WMT_FTBLK_GOVRH_CURSOR */
+
+/*----------------------- GOVRH API --------------------------------------*/
+void govrh_vmode_to_timing(vpp_mod_t mod,
+ struct fb_videomode *vmode, vpp_clock_t *t)
+{
+ unsigned int pixel_clock;
+ int temp;
+
+ t->begin_pixel_of_active = vmode->hsync_len + vmode->left_margin;
+ t->end_pixel_of_active = t->begin_pixel_of_active + vmode->xres;
+ t->total_pixel_of_line = t->end_pixel_of_active + vmode->right_margin;
+ t->begin_line_of_active = vmode->vsync_len + vmode->upper_margin;
+ t->end_line_of_active = t->begin_line_of_active + vmode->yres;
+ t->total_line_of_frame = t->end_line_of_active + vmode->lower_margin;
+ t->line_number_between_VBIS_VBIE = vmode->vsync_len + 1;
+ temp = t->total_line_of_frame - t->end_line_of_active;
+ t->line_number_between_PVBI_VBIS = (temp > 2) ? (temp-1) : 1;
+ t->hsync = vmode->hsync_len;
+ t->vsync = vmode->vsync_len;
+
+ pixel_clock = PICOS2KHZ(vmode->pixclock) * 1000;
+ t->read_cycle = vpp_get_base_clock(mod) / pixel_clock;
+}
+
+void govrh_set_videomode(struct govrh_mod_t *base,
+ struct fb_videomode *p_vmode)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ struct fb_videomode vmode;
+ vpp_clock_t t1;
+ int tg_enable;
+
+ DBG_MSG("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ tg_enable = regs->tg_enable.b.enable;
+ regs->tg_enable.b.enable = 0;
+
+ vmode = *p_vmode;
+ if (vmode.vmode & FB_VMODE_DOUBLE) {
+ vmode.xres *= 2;
+ DBGMSG("[GOVRH] H scale up\n");
+ }
+
+ if (vmode.vmode & FB_VMODE_INTERLACED) {
+ vmode.vsync_len /= 2;
+ vmode.upper_margin /= 2;
+ vmode.yres /= 2;
+ vmode.lower_margin /= 2;
+ }
+
+ govrh_vmode_to_timing(base->mod, &vmode, &t1);
+ t1.read_cycle = govrh_set_clock(base, PICOS2KHZ(vmode.pixclock)*1000);
+ if (vmode.vmode & FB_VMODE_INTERLACED) {
+ t1.total_line_of_frame += 1;
+ t1.begin_line_of_active += 1;
+ t1.end_line_of_active += 1;
+ t1.vsync += 1;
+ }
+ govrh_set_tg1(base, &t1);
+
+ if (vmode.vmode & FB_VMODE_INTERLACED) {
+ vpp_clock_t t2;
+
+ vmode.upper_margin += 1;
+ /* 480i/576i repeat 2 pixel */
+ if (vmode.vmode & FB_VMODE_DOUBLE)
+ vmode.xres *= 2;
+ govrh_vmode_to_timing(base->mod, &vmode, &t2);
+ t2.total_line_of_frame -= 1;
+ t2.vsync += 1;
+ govrh_set_tg2(base, &t2);
+ }
+ govrh_set_output_format(base,
+ (vmode.vmode & FB_VMODE_INTERLACED) ? 1 : 0);
+ regs->hscale_up = (vmode.vmode & FB_VMODE_DOUBLE) ? 1 : 0;
+ regs->vsync_offset.val = (vmode.vmode & FB_VMODE_INTERLACED) ?
+ ((regs->h_allpxl / 2) | BIT16) : 0;
+
+ regs->tg_enable.b.enable = tg_enable;
+}
+
+void govrh_get_videomode(struct govrh_mod_t *base,
+ struct fb_videomode *vmode)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ vpp_clock_t t;
+ int htotal, vtotal;
+ unsigned int pixel_clock;
+
+ vmode->flag = FB_MODE_IS_FROM_VAR;
+ vmode->name = 0;
+
+ govrh_get_tg(base, &t);
+ pixel_clock = vpp_get_base_clock(base->mod);
+ vmode->pixclock = KHZ2PICOS(pixel_clock/1000);
+
+ vmode->hsync_len = t.hsync;
+ vmode->left_margin = t.begin_pixel_of_active - t.hsync;
+ vmode->xres = t.end_pixel_of_active - t.begin_pixel_of_active;
+ vmode->right_margin = t.total_pixel_of_line - t.end_pixel_of_active;
+
+ vmode->vsync_len = t.vsync;
+ vmode->upper_margin = t.begin_line_of_active - t.vsync;
+ vmode->yres = t.end_line_of_active - t.begin_line_of_active;
+ vmode->lower_margin = t.total_line_of_frame - t.end_line_of_active;
+
+ htotal = vmode->xres + vmode->right_margin
+ + vmode->hsync_len + vmode->left_margin;
+ vtotal = vmode->yres + vmode->lower_margin
+ + vmode->vsync_len + vmode->upper_margin;
+ vmode->vmode = (regs->tg_enable.b.mode) ? FB_VMODE_INTERLACED : 0;
+ if (vmode->vmode & FB_VMODE_INTERLACED)
+ vtotal /= 2;
+ if (vmode->vmode & FB_VMODE_DOUBLE)
+ vtotal *= 2;
+
+ if (htotal && vtotal) {
+ unsigned int temp;
+ temp = (pixel_clock * 10)/(htotal * vtotal);
+ vmode->refresh = temp / 10;
+ if ((temp % 10) >= 5)
+ vmode->refresh += 1;
+ } else
+ vmode->refresh = 60;
+
+ { /* get sync polar */
+ int hsync_hi, vsync_hi;
+ enum vout_inf_mode_t interface;
+
+ switch (base->mod) {
+ case VPP_MOD_GOVRH:
+ interface = VOUT_INF_HDMI;
+ break;
+ case VPP_MOD_GOVRH2:
+ interface = VOUT_INF_DVI;
+ if (lcd_get_type())
+ interface = VOUT_INF_LVDS;
+ break;
+ default:
+ interface = VOUT_INF_DVI;
+ break;
+ }
+
+ switch (interface) {
+ case VOUT_INF_DVI:
+ hsync_hi = (regs->dvo_set.b.hsync_polar) ? 0 : 1;
+ vsync_hi = (regs->dvo_set.b.vsync_polar) ? 0 : 1;
+ break;
+ case VOUT_INF_HDMI:
+ vo_hdmi_set_clock(1);
+ hdmi_get_sync_polar(&hsync_hi, &vsync_hi);
+ vo_hdmi_set_clock(0);
+ break;
+ case VOUT_INF_LVDS:
+ lvds_get_sync_polar(&hsync_hi, &vsync_hi);
+ break;
+ default:
+ hsync_hi = 0;
+ vsync_hi = 0;
+ break;
+ }
+ vmode->sync = (hsync_hi) ? FB_SYNC_HOR_HIGH_ACT : 0;
+ vmode->sync |= (vsync_hi) ? FB_SYNC_VERT_HIGH_ACT : 0;
+ }
+}
+
+void govrh_set_framebuffer(struct govrh_mod_t *base, vdo_framebuf_t *fb)
+{
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ govrh_set_fb_addr(base, fb->y_addr, fb->c_addr);
+ govrh_set_color_format(base, fb->col_fmt);
+ govrh_set_fb_info(base, fb->fb_w, fb->img_w, fb->h_crop, fb->v_crop);
+ govrh_set_source_format(base, vpp_get_fb_field(fb));
+ govrh_set_csc_mode(base, base->fb_p->csc_mode);
+}
+
+void govrh_get_framebuffer(struct govrh_mod_t *base, vdo_framebuf_t *fb)
+{
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+ vpp_clock_t clock;
+ int y_bpp, c_bpp;
+
+ DBG_DETAIL("(govr %d)\n", (base->mod == VPP_MOD_GOVRH) ? 1 : 2);
+
+ govrh_get_fb_addr(base, &fb->y_addr, &fb->c_addr);
+ fb->col_fmt = govrh_get_color_format(base);
+ govrh_get_fb_info(base, &fb->fb_w,
+ &fb->img_w, &fb->h_crop, &fb->v_crop);
+ govrh_get_tg(base, &clock);
+ fb->img_h = clock.end_line_of_active - clock.begin_line_of_active;
+ fb->fb_h = fb->img_h;
+ fb->flag = (regs->srcfmt) ? VDO_FLAG_INTERLACE : 0;
+ vpp_get_colfmt_bpp(fb->col_fmt, &y_bpp, &c_bpp);
+ fb->bpp = y_bpp + c_bpp;
+ fb->y_size = fb->fb_w * fb->fb_h * y_bpp / 8;
+ fb->c_size = fb->fb_w * fb->fb_h * c_bpp / 8;
+}
+
+/*----------------------- GOVRH MODULE API -----------------------------*/
+int govrh_suspend_yaddr;
+void govrh_suspend(struct govrh_mod_t *base, int sts)
+{
+#ifdef CONFIG_PM
+ HW_REG struct govrh_regs *regs =
+ (HW_REG struct govrh_regs *) base->mmio;
+
+ switch (sts) {
+ case 0: /* disable module */
+ base->pm_enable = govrh_get_MIF_enable(base);
+ govrh_set_MIF_enable(base, 0);
+ break;
+ case 1: /* disable tg */
+ base->pm_tg = regs->tg_enable.b.enable;
+ govrh_set_tg_enable(base, 0);
+ break;
+ case 2: /* backup register */
+ base->reg_bk = vpp_backup_reg((unsigned int)base->mmio,
+ (REG_GOVRH_BASE2_END-REG_GOVRH_BASE1_BEGIN));
+ if (base->vo_clock == 0)
+ base->vo_clock = vpp_get_base_clock(base->mod);
+ govrh_suspend_yaddr = 0;
+ break;
+ default:
+ break;
+ }
+#endif
+}
+
+void govrh_resume(struct govrh_mod_t *base, int sts)
+{
+#ifdef CONFIG_PM
+ switch (sts) {
+ case 0: /* restore register */
+ govrh_set_clock(base, base->vo_clock);
+ vpp_restore_reg((unsigned int)base->mmio,
+ (REG_GOVRH_BASE2_END-REG_GOVRH_BASE1_BEGIN),
+ base->reg_bk);
+ if (base == p_govrh && govrh_suspend_yaddr)
+ govrh_set_fb_addr(p_govrh, govrh_suspend_yaddr, 0);
+ base->reg_bk = 0;
+ break;
+ case 1: /* enable module */
+ govrh_set_MIF_enable(base, base->pm_enable);
+ break;
+ case 2: /* enable tg */
+ govrh_set_tg_enable(base, base->pm_tg);
+ break;
+ default:
+ break;
+ }
+#endif
+}
+
+void govrh_init(void *base)
+{
+ struct govrh_mod_t *mod_p;
+ HW_REG struct govrh_regs *regs;
+
+ mod_p = (struct govrh_mod_t *) base;
+ regs = (HW_REG struct govrh_regs *) mod_p->mmio;
+
+ govrh_set_reg_level(base, VPP_REG_LEVEL_1);
+ govrh_set_colorbar(base, VPP_FLAG_DISABLE, 1, 0);
+ govrh_set_tg_enable(base, VPP_FLAG_ENABLE);
+ govrh_set_dvo_color_format(base, VDO_COL_FMT_ARGB);
+ govrh_set_dvo_enable(base, VPP_FLAG_DISABLE);
+
+ govrh_set_framebuffer(base, &mod_p->fb_p->fb);
+ govrh_set_fifo_index(base, 0xf);
+ govrh_set_csc_mode(base, mod_p->fb_p->csc_mode);
+
+ govrh_set_reg_update(base, VPP_FLAG_ENABLE);
+ govrh_set_tg_enable(base, VPP_FLAG_ENABLE);
+/* govrh_set_MIF_enable(base, VPP_FLAG_ENABLE); */
+ govrh_set_int_enable(base, VPP_FLAG_ENABLE, mod_p->int_catch);
+}
+
+void govrh_mod_dump_reg(void)
+{
+ govrh_reg_dump((void *)p_govrh);
+}
+
+void govrh_mod_set_enable(vpp_flag_t enable)
+{
+ govrh_set_MIF_enable(p_govrh, enable);
+}
+
+void govrh_mod_set_colorbar(vpp_flag_t enable, int mode, int inv)
+{
+ govrh_set_colorbar(p_govrh, enable, mode, inv);
+}
+
+void govrh_mod_set_tg(vpp_clock_t *tmr, unsigned int pixel_clock)
+{
+ govrh_set_tg(p_govrh, tmr, pixel_clock);
+}
+
+void govrh_mod_get_tg(vpp_clock_t *tmr)
+{
+ govrh_get_tg(p_govrh, tmr);
+}
+
+unsigned int govrh_mod_get_sts(void)
+{
+ return govrh_get_int_status(p_govrh);
+}
+
+void govrh_mod_clr_sts(unsigned int sts)
+{
+ govrh_clean_int_status(p_govrh, sts);
+}
+
+void govrh_mod_suspend(int sts)
+{
+ govrh_suspend(p_govrh, sts);
+}
+
+void govrh_mod_resume(int sts)
+{
+ govrh_resume(p_govrh, sts);
+}
+
+void govrh_mod_set_framebuf(vdo_framebuf_t *fb)
+{
+ govrh_set_framebuffer(p_govrh, fb);
+}
+void govrh_mod_set_addr(unsigned int yaddr, unsigned int caddr)
+{
+ govrh_set_fb_addr(p_govrh, yaddr, caddr);
+}
+void govrh_mod_get_addr(unsigned int *yaddr, unsigned int *caddr)
+{
+ govrh_get_fb_addr(p_govrh, yaddr, caddr);
+}
+void govrh_mod_set_csc(vpp_csc_t mode)
+{
+ govrh_set_csc_mode(p_govrh, mode);
+}
+vdo_color_fmt govrh_mod_get_color_fmt(void)
+{
+ return govrh_get_color_format(p_govrh);
+}
+void govrh_mod_set_color_fmt(vdo_color_fmt colfmt)
+{
+ govrh_set_color_format(p_govrh, colfmt);
+}
+
+#ifdef WMT_FTBLK_GOVRH_CURSOR
+void cursor_mod_set_enable(vpp_flag_t enable)
+{
+ govrh_CUR_set_enable(p_cursor, enable);
+}
+
+void cursor_mod_set_framebuf(vdo_framebuf_t *fb)
+{
+ govrh_CUR_set_framebuffer(p_cursor, fb);
+}
+
+void cursor_mod_set_addr(unsigned int yaddr, unsigned int caddr)
+{
+ govrh_CUR_set_fb_addr(p_cursor, yaddr, caddr);
+}
+
+void cursor_mod_get_addr(unsigned int *yaddr, unsigned int *caddr)
+{
+ govrh_CUR_get_fb_addr(p_cursor, yaddr, caddr);
+}
+
+void cursor_mod_fn_view(int read, vdo_view_t *view)
+{
+ govrh_CUR_proc_view(p_cursor, read, view);
+}
+#endif
+
+#ifdef WMT_FTBLK_GOVRH2
+void govrh2_mod_dump_reg(void)
+{
+ govrh_reg_dump((void *)p_govrh2);
+}
+
+void govrh2_mod_set_enable(vpp_flag_t enable)
+{
+ govrh_set_MIF_enable(p_govrh2, enable);
+}
+
+void govrh2_mod_set_colorbar(vpp_flag_t enable, int mode, int inv)
+{
+ govrh_set_colorbar(p_govrh2, enable, mode, inv);
+}
+
+void govrh2_mod_set_tg(vpp_clock_t *tmr, unsigned int pixel_clock)
+{
+ govrh_set_tg(p_govrh2, tmr, pixel_clock);
+}
+
+void govrh2_mod_get_tg(vpp_clock_t *tmr)
+{
+ govrh_get_tg(p_govrh2, tmr);
+}
+
+unsigned int govrh2_mod_get_sts(void)
+{
+ return govrh_get_int_status(p_govrh2);
+}
+
+void govrh2_mod_clr_sts(unsigned int sts)
+{
+ govrh_clean_int_status(p_govrh2, sts);
+}
+
+void govrh2_mod_suspend(int sts)
+{
+ govrh_suspend(p_govrh2, sts);
+}
+
+void govrh2_mod_resume(int sts)
+{
+ govrh_resume(p_govrh2, sts);
+}
+
+void govrh2_mod_set_framebuf(vdo_framebuf_t *fb)
+{
+ govrh_set_framebuffer(p_govrh2, fb);
+}
+void govrh2_mod_set_addr(unsigned int yaddr, unsigned int caddr)
+{
+ govrh_set_fb_addr(p_govrh2, yaddr, caddr);
+}
+void govrh2_mod_get_addr(unsigned int *yaddr, unsigned int *caddr)
+{
+ govrh_get_fb_addr(p_govrh2, yaddr, caddr);
+}
+void govrh2_mod_set_csc(vpp_csc_t mode)
+{
+ govrh_set_csc_mode(p_govrh2, mode);
+}
+vdo_color_fmt govrh2_mod_get_color_fmt(void)
+{
+ return govrh_get_color_format(p_govrh2);
+}
+void govrh2_mod_set_color_fmt(vdo_color_fmt colfmt)
+{
+ govrh_set_color_format(p_govrh2, colfmt);
+}
+
+#endif
+int govrh_mod_init(void)
+{
+ struct govrh_mod_t *mod_p;
+ struct vpp_fb_base_t *mod_fb_p;
+ vdo_framebuf_t *fb_p;
+
+ mod_p = (struct govrh_mod_t *) vpp_mod_register(VPP_MOD_GOVRH,
+ sizeof(struct govrh_mod_t),
+ VPP_MOD_FLAG_FRAMEBUF);
+ if (!mod_p) {
+ DPRINT("*E* GOVRH module register fail\n");
+ return -1;
+ }
+
+ /* module member variable */
+ mod_p->mmio = (void *)REG_GOVRH_BASE1_BEGIN;
+ mod_p->int_catch = VPP_INT_NULL; /* VPP_INT_ERR_GOVRH_MIF; */
+
+ /* module member function */
+ mod_p->init = govrh_init;
+ mod_p->dump_reg = govrh_mod_dump_reg;
+ mod_p->set_enable = govrh_mod_set_enable;
+ mod_p->set_colorbar = govrh_mod_set_colorbar;
+ mod_p->set_tg = govrh_mod_set_tg;
+ mod_p->get_tg = govrh_mod_get_tg;
+ mod_p->get_sts = govrh_mod_get_sts;
+ mod_p->clr_sts = govrh_mod_clr_sts;
+ mod_p->suspend = govrh_mod_suspend;
+ mod_p->resume = govrh_mod_resume;
+
+ /* module frame buffer */
+ mod_fb_p = mod_p->fb_p;
+ mod_fb_p->csc_mode = VPP_CSC_RGB2YUV_JFIF_0_255;
+ mod_fb_p->framerate = VPP_HD_DISP_FPS;
+ mod_fb_p->media_fmt = VPP_MEDIA_FMT_MPEG;
+ mod_fb_p->wait_ready = 0;
+ mod_fb_p->capability = BIT(VDO_COL_FMT_YUV420)
+ | BIT(VDO_COL_FMT_YUV422H)
+ | BIT(VDO_COL_FMT_YUV444) | BIT(VDO_COL_FMT_ARGB)
+ | BIT(VDO_COL_FMT_RGB_1555) | BIT(VDO_COL_FMT_RGB_565)
+ | VPP_FB_FLAG_CSC | VPP_FB_FLAG_MEDIA
+ | VPP_FB_FLAG_FIELD;
+
+ /* module frame buffer member function */
+ mod_fb_p->set_framebuf = govrh_mod_set_framebuf;
+ mod_fb_p->set_addr = govrh_mod_set_addr;
+ mod_fb_p->get_addr = govrh_mod_get_addr;
+ mod_fb_p->set_csc = govrh_mod_set_csc;
+ mod_fb_p->get_color_fmt = govrh_mod_get_color_fmt;
+ mod_fb_p->set_color_fmt = govrh_mod_set_color_fmt;
+
+ fb_p = &mod_p->fb_p->fb;
+ fb_p->y_addr = 0;
+ fb_p->c_addr = 0;
+ fb_p->col_fmt = VPP_UBOOT_COLFMT;
+ fb_p->img_w = VPP_HD_DISP_RESX;
+ fb_p->img_h = VPP_HD_DISP_RESY;
+ fb_p->fb_w = VPP_HD_MAX_RESX;
+ fb_p->fb_h = VPP_HD_MAX_RESY;
+ fb_p->h_crop = 0;
+ fb_p->v_crop = 0;
+ fb_p->flag = 0;
+
+ p_govrh = mod_p;
+
+#ifdef WMT_FTBLK_GOVRH_CURSOR
+ mod_p = (struct govrh_mod_t *) vpp_mod_register(VPP_MOD_CURSOR,
+ sizeof(struct govrh_cursor_mod_t),
+ VPP_MOD_FLAG_FRAMEBUF);
+ if (!mod_p) {
+ DPRINT("*E* CURSOR module register fail\n");
+ return -1;
+ }
+
+ /* module member function */
+ mod_p->init = govrh_CUR_init;
+ mod_p->set_enable = cursor_mod_set_enable;
+ mod_p->mmio = (void *)REG_GOVRH_BASE1_BEGIN;
+
+ /* module frame buffer */
+ mod_fb_p = mod_p->fb_p;
+ mod_fb_p->csc_mode = VPP_CSC_RGB2YUV_SDTV_0_255;
+ mod_fb_p->framerate = VPP_HD_DISP_FPS;
+ mod_fb_p->media_fmt = VPP_MEDIA_FMT_MPEG;
+ mod_fb_p->wait_ready = 0;
+ mod_fb_p->capability = BIT(VDO_COL_FMT_YUV420)
+ | BIT(VDO_COL_FMT_YUV422H)
+ | BIT(VDO_COL_FMT_YUV444) | BIT(VDO_COL_FMT_ARGB)
+ | VPP_FB_FLAG_CSC | VPP_FB_FLAG_MEDIA
+ | VPP_FB_FLAG_FIELD;
+
+ /* module frame buffer member function */
+ mod_fb_p->set_framebuf = cursor_mod_set_framebuf;
+ mod_fb_p->set_addr = cursor_mod_set_addr;
+ mod_fb_p->get_addr = cursor_mod_get_addr;
+ mod_fb_p->fn_view = cursor_mod_fn_view;
+
+ fb_p = &mod_p->fb_p->fb;
+ fb_p->y_addr = 0;
+ fb_p->c_addr = 0;
+ fb_p->col_fmt = VDO_COL_FMT_YUV444;
+ fb_p->img_w = VPP_HD_DISP_RESX;
+ fb_p->img_h = VPP_HD_DISP_RESY;
+ fb_p->fb_w = VPP_HD_MAX_RESX;
+ fb_p->fb_h = VPP_HD_MAX_RESY;
+ fb_p->h_crop = 0;
+ fb_p->v_crop = 0;
+ fb_p->flag = 0;
+
+ p_cursor = (struct govrh_cursor_mod_t *) mod_p;
+#endif
+
+#ifdef WMT_FTBLK_GOVRH2
+ mod_p = (struct govrh_mod_t *) vpp_mod_register(VPP_MOD_GOVRH2,
+ sizeof(struct govrh_mod_t),
+ VPP_MOD_FLAG_FRAMEBUF);
+ if (!mod_p) {
+ DPRINT("*E* GOVRH module register fail\n");
+ return -1;
+ }
+
+ /* module member variable */
+ mod_p->mmio = (void *)REG_GOVRH2_BASE1_BEGIN;
+ mod_p->int_catch = VPP_INT_NULL; /* VPP_INT_ERR_GOVRH_MIF; */
+
+ /* module member function */
+ mod_p->init = govrh_init;
+ mod_p->dump_reg = govrh2_mod_dump_reg;
+ mod_p->set_enable = govrh2_mod_set_enable;
+ mod_p->set_colorbar = govrh2_mod_set_colorbar;
+ mod_p->set_tg = govrh2_mod_set_tg;
+ mod_p->get_tg = govrh2_mod_get_tg;
+ mod_p->get_sts = govrh2_mod_get_sts;
+ mod_p->clr_sts = govrh2_mod_clr_sts;
+ mod_p->suspend = govrh2_mod_suspend;
+ mod_p->resume = govrh2_mod_resume;
+
+ /* module frame buffer */
+ mod_fb_p = mod_p->fb_p;
+ mod_fb_p->csc_mode = VPP_CSC_RGB2YUV_JFIF_0_255;
+ mod_fb_p->framerate = VPP_HD_DISP_FPS;
+ mod_fb_p->media_fmt = VPP_MEDIA_FMT_MPEG;
+ mod_fb_p->wait_ready = 0;
+ mod_fb_p->capability = BIT(VDO_COL_FMT_YUV420)
+ | BIT(VDO_COL_FMT_YUV422H)
+ | BIT(VDO_COL_FMT_YUV444) | BIT(VDO_COL_FMT_ARGB)
+ | BIT(VDO_COL_FMT_RGB_1555) | BIT(VDO_COL_FMT_RGB_565)
+ | VPP_FB_FLAG_CSC | VPP_FB_FLAG_MEDIA | VPP_FB_FLAG_FIELD;
+
+ /* module frame buffer member function */
+ mod_fb_p->set_framebuf = govrh2_mod_set_framebuf;
+ mod_fb_p->set_addr = govrh2_mod_set_addr;
+ mod_fb_p->get_addr = govrh2_mod_get_addr;
+ mod_fb_p->set_csc = govrh2_mod_set_csc;
+ mod_fb_p->get_color_fmt = govrh2_mod_get_color_fmt;
+ mod_fb_p->set_color_fmt = govrh2_mod_set_color_fmt;
+
+ fb_p = &mod_p->fb_p->fb;
+ fb_p->y_addr = 0;
+ fb_p->c_addr = 0;
+ fb_p->col_fmt = VPP_UBOOT_COLFMT;
+ fb_p->img_w = VPP_HD_DISP_RESX;
+ fb_p->img_h = VPP_HD_DISP_RESY;
+ fb_p->fb_w = VPP_HD_MAX_RESX;
+ fb_p->fb_h = VPP_HD_MAX_RESY;
+ fb_p->h_crop = 0;
+ fb_p->v_crop = 0;
+ fb_p->flag = 0;
+
+ p_govrh2 = mod_p;
+#endif
+ return 0;
+}
+module_init(govrh_mod_init);
+#endif /* WMT_FTBLK_GOVRH */
diff --git a/common/wmt_display/govrh.h b/common/wmt_display/govrh.h
new file mode 100755
index 0000000..a7dc062
--- /dev/null
+++ b/common/wmt_display/govrh.h
@@ -0,0 +1,184 @@
+/*++
+ * linux/drivers/video/wmt/govrh.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#include "vpp.h"
+
+#ifdef WMT_FTBLK_GOVRH
+
+#ifndef GOVRH_H
+#define GOVRH_H
+
+struct govrh_mod_t {
+ VPP_MOD_BASE;
+
+ unsigned int *reg_bk2;
+ unsigned int pm_enable;
+ unsigned int pm_tg;
+ unsigned int vo_clock;
+ unsigned int underrun_cnt;
+ unsigned int csc_mode_force;
+};
+
+#ifdef WMT_FTBLK_GOVRH_CURSOR
+#define GOVRH_CURSOR_HIDE_TIME 15
+struct govrh_cursor_mod_t {
+ VPP_MOD_BASE;
+
+ unsigned int posx;
+ unsigned int posy;
+ unsigned int hotspot_x;
+ unsigned int hotspot_y;
+ int chg_flag;
+ vdo_color_fmt colfmt;
+ unsigned int cursor_addr1;
+ unsigned int cursor_addr2;
+ int enable;
+ int hide_cnt;
+};
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef GOVRH_C
+#define EXTERN
+#else
+#define EXTERN extern
+#endif
+
+EXTERN struct govrh_mod_t *p_govrh;
+#ifdef WMT_FTBLK_GOVRH_CURSOR
+EXTERN struct govrh_cursor_mod_t *p_cursor;
+#endif
+#ifdef WMT_FTBLK_GOVRH2
+EXTERN struct govrh_mod_t *p_govrh2;
+#endif
+
+EXTERN void govrh_set_tg_enable(struct govrh_mod_t *base,
+ vpp_flag_t enable);
+EXTERN int govrh_get_tg_mode(struct govrh_mod_t *base);
+EXTERN int govrh_get_hscale_up(struct govrh_mod_t *base);
+EXTERN void govrh_set_direct_path(struct govrh_mod_t *base, int enable);
+EXTERN int govrh_get_dvo_enable(struct govrh_mod_t *base);
+EXTERN void govrh_set_dvo_enable(struct govrh_mod_t *base,
+ vpp_flag_t enable);
+EXTERN void govrh_set_dvo_sync_polar(struct govrh_mod_t *base,
+ vpp_flag_t hsync, vpp_flag_t vsync);
+EXTERN void govrh_set_dvo_outdatw(struct govrh_mod_t *base,
+ vpp_datawidht_t width);
+EXTERN void govrh_set_dvo_clock_delay(struct govrh_mod_t *base,
+ int inverse, int delay);
+EXTERN void govrh_set_colorbar(struct govrh_mod_t *base,
+ vpp_flag_t enable, int mode, int inv);
+EXTERN void govrh_set_contrast(struct govrh_mod_t *base,
+ unsigned int value);
+EXTERN unsigned int govrh_get_contrast(struct govrh_mod_t *base);
+EXTERN void govrh_set_brightness(struct govrh_mod_t *base,
+ unsigned int value);
+EXTERN unsigned int govrh_get_brightness(struct govrh_mod_t *base);
+EXTERN void govrh_set_saturation(struct govrh_mod_t *base, unsigned int value);
+EXTERN unsigned int govrh_get_saturation(struct govrh_mod_t *base);
+EXTERN void govrh_set_MIF_enable(struct govrh_mod_t *base, vpp_flag_t enable);
+EXTERN int govrh_get_MIF_enable(struct govrh_mod_t *base);
+EXTERN void govrh_set_color_format(struct govrh_mod_t *base,
+ vdo_color_fmt format);
+EXTERN vdo_color_fmt govrh_get_color_format(struct govrh_mod_t *base);
+EXTERN void govrh_set_source_format(struct govrh_mod_t *base,
+ vpp_display_format_t format);
+EXTERN void govrh_set_output_format(struct govrh_mod_t *base,
+ vpp_display_format_t field);
+EXTERN void govrh_set_fb_addr(struct govrh_mod_t *base,
+ unsigned int y_addr, unsigned int c_addr);
+EXTERN void govrh_get_fb_addr(struct govrh_mod_t *base,
+ unsigned int *y_addr, unsigned int *c_addr);
+EXTERN void govrh_set_fb_width(struct govrh_mod_t *base,
+ unsigned int width);
+EXTERN void govrh_set_fb_info(struct govrh_mod_t *base,
+ unsigned int width, unsigned int act_width,
+ unsigned int x_offset, unsigned int y_offset);
+EXTERN void govrh_get_fb_info(struct govrh_mod_t *base,
+ unsigned int *width, unsigned int *act_width,
+ unsigned int *x_offset, unsigned int *y_offset);
+EXTERN void govrh_set_fifo_index(struct govrh_mod_t *base,
+ unsigned int index);
+EXTERN void govrh_set_reg_level(struct govrh_mod_t *base,
+ vpp_reglevel_t level);
+EXTERN void govrh_set_reg_update(struct govrh_mod_t *base,
+ vpp_flag_t enable);
+EXTERN void govrh_set_csc_mode(struct govrh_mod_t *base,
+ vpp_csc_t mode);
+EXTERN void govrh_set_framebuffer(struct govrh_mod_t *base,
+ vdo_framebuf_t *inbuf);
+EXTERN void govrh_get_framebuffer(struct govrh_mod_t *base,
+ vdo_framebuf_t *fb);
+EXTERN vdo_color_fmt govrh_get_dvo_color_format(
+ struct govrh_mod_t *base);
+EXTERN void govrh_set_dvo_color_format(struct govrh_mod_t *base,
+ vdo_color_fmt fmt);
+EXTERN enum vpp_int_err_t govrh_get_int_status(struct govrh_mod_t *base);
+EXTERN void govrh_clean_int_status(struct govrh_mod_t *base,
+ enum vpp_int_err_t int_sts);
+EXTERN unsigned int govrh_set_clock(struct govrh_mod_t *base,
+ unsigned int pixel_clock);
+EXTERN void govrh_set_videomode(struct govrh_mod_t *base,
+ struct fb_videomode *vmode);
+EXTERN void govrh_get_tg(struct govrh_mod_t *base, vpp_clock_t *tmr);
+EXTERN void govrh_get_videomode(struct govrh_mod_t *base,
+ struct fb_videomode *vmode);
+EXTERN void govrh_HDMI_set_blank_value(struct govrh_mod_t *base,
+ unsigned int val);
+EXTERN void govrh_HDMI_set_3D_mode(struct govrh_mod_t *base,
+ int mode);
+EXTERN int govrh_is_top_field(struct govrh_mod_t *base);
+EXTERN void govrh_IGS_set_mode(struct govrh_mod_t *base,
+ int no, int mode_18bit, int msb);
+EXTERN void govrh_IGS_set_RGB_swap(struct govrh_mod_t *base,
+ int mode);
+EXTERN int govrh_mod_init(void);
+
+#ifdef WMT_FTBLK_GOVRH_CURSOR
+EXTERN void govrh_CUR_set_enable(struct govrh_cursor_mod_t *base,
+ vpp_flag_t enable);
+EXTERN void govrh_CUR_set_framebuffer(struct govrh_cursor_mod_t *base,
+ vdo_framebuf_t *fb);
+EXTERN void govrh_CUR_set_coordinate(struct govrh_cursor_mod_t *base,
+ unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2);
+EXTERN void govrh_CUR_set_position(struct govrh_cursor_mod_t *base,
+ unsigned int x, unsigned int y);
+EXTERN void govrh_CUR_set_color_key_mode(struct govrh_cursor_mod_t *base,
+ int alpha, int enable, int mode);
+EXTERN void govrh_CUR_set_color_key(struct govrh_cursor_mod_t *base,
+ int enable, int alpha, unsigned int colkey);
+EXTERN void govrh_CUR_set_colfmt(struct govrh_cursor_mod_t *base,
+ vdo_color_fmt colfmt);
+EXTERN void govrh_CUR_irqproc(int arg);
+#endif
+
+#undef EXTERN
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* GOVRH_H */
+#endif /* WMT_FTBLK_GOVRH */
diff --git a/common/wmt_display/hdmi.c b/common/wmt_display/hdmi.c
new file mode 100755
index 0000000..c181d75
--- /dev/null
+++ b/common/wmt_display/hdmi.c
@@ -0,0 +1,1457 @@
+/*++
+ * linux/drivers/video/wmt/hdmi.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define HDMI_C
+#undef DEBUG
+/* #define DEBUG */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "hdmi.h"
+#include "vout.h"
+#ifdef __KERNEL__
+#include <asm/div64.h>
+#endif
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define HDMI_XXXX 1 *//*Example*/
+/* #define CONFIG_HDMI_INFOFRAME_DISABLE */
+/* #define CONFIG_HDMI_EDID_DISABLE */
+
+#define HDMI_I2C_FREQ 80000
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx hdmi_xxx_t; *//*Example*/
+enum hdmi_fifo_slot_t {
+ HDMI_FIFO_SLOT_AVI = 0,
+ HDMI_FIFO_SLOT_VENDOR = 1,
+ HDMI_FIFO_SLOT_AUDIO = 2,
+ HDMI_FIFO_SLOT_CONTROL = 3,
+ HDMI_FIFO_SLOT_MAX = 15
+};
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in hdmi.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int hdmi_xxx; *//*Example*/
+
+HW_REG struct hdmi_base1_regs *hdmi_regs1 = (void *) (HDMI_BASE_ADDR + 0x100);
+HW_REG struct hdmi_base2_regs *hdmi_regs2 = (void *) HDMI_BASE2_ADDR;
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void hdmi_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+/*---------------------------- HDMI COMMON API -------------------------------*/
+unsigned char hdmi_ecc(unsigned char *buf, int bit_cnt)
+{
+ #define HDMI_CRC_LEN 9
+
+ int crc[HDMI_CRC_LEN], crc_o[HDMI_CRC_LEN];
+ int i, j;
+ int input, result, result_rev = 0;
+
+ for (i = 0; i < HDMI_CRC_LEN; i++)
+ crc[i] = 0;
+
+ for (i = 0; i < bit_cnt; i++) {
+ for (j = 0; j < HDMI_CRC_LEN; j++)
+ crc_o[j] = crc[j];
+ input = (buf[i/8] & (1<<(i%8))) ? 1 : 0;
+ crc[0] = crc_o[7] ^ input;
+ crc[1] = crc_o[0];
+ crc[2] = crc_o[1];
+ crc[3] = crc_o[2];
+ crc[4] = crc_o[3];
+ crc[5] = crc_o[4];
+ crc[6] = crc_o[5] ^ crc_o[7] ^ input;
+ crc[7] = crc_o[6] ^ crc_o[7] ^ input;
+ crc[8] = crc_o[7];
+
+ result = 0;
+ result_rev = 0;
+ for (j = 0; j < HDMI_CRC_LEN - 1; j++) {
+ result += (crc[j] << j);
+ result_rev += (crc[j] << (HDMI_CRC_LEN - 2 - j));
+ }
+ }
+
+/* DPRINT("[HDMI] crc 0x%x, %x %x %x %x %x %x %x\n",result_rev,
+ buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6]); */
+ return result_rev;
+}
+
+unsigned char hdmi_checksum(unsigned char *header,
+ unsigned char *buf, int cnt)
+{
+ unsigned char sum;
+ int i;
+
+ for (i = 0, sum = 0; i < cnt; i++)
+ sum += buf[i];
+ for (i = 0; i < 3; i++)
+ sum += header[i];
+ return 0 - sum;
+}
+
+#ifdef WMT_FTBLK_HDMI
+/*---------------------------- HDMI HAL --------------------------------------*/
+void hdmi_set_power_down(int pwrdn)
+{
+ DBG_DETAIL("(%d)\n", pwrdn);
+
+ if ((hdmi_regs2->test.b.pd == 0) && (pwrdn == 0))
+ return; /* avoid HDMI reset */
+
+ hdmi_regs2->status.b.internal_ldo = (pwrdn) ? 0 : 1;
+ hdmi_regs2->test.b.pd = pwrdn;
+ if (!pwrdn) {
+ hdmi_regs2->dftset2.b.reset_pll = 1;
+ mdelay(1);
+ hdmi_regs2->dftset2.b.reset_pll = 0;
+ }
+ mdelay(1);
+ hdmi_regs2->test2.b.pd_l2ha = pwrdn;
+}
+
+int hdmi_get_power_down(void)
+{
+ return hdmi_regs2->test.b.pd;
+}
+
+void hdmi_set_enable(vpp_flag_t enable)
+{
+ hdmi_regs1->general_ctrl.b.enable = enable;
+ hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */
+ hdmi_regs2->test2.b.mode = (enable) ? 0 : 1;
+}
+
+void hdmi_set_avmute(vpp_flag_t mute)
+{
+ hdmi_regs1->aud_insert_ctrl.b.avmute_set_enable = mute;
+}
+
+void hdmi_set_dvi_enable(vpp_flag_t enable)
+{
+ hdmi_regs1->general_ctrl.b.dvi_mode_enable = enable;
+ hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */
+}
+
+void hdmi_set_sync_low_active(vpp_flag_t hsync, vpp_flag_t vsync)
+{
+ hdmi_regs1->general_ctrl.b.hsync_low_active = hsync;
+ hdmi_regs1->general_ctrl.b.vsync_low_active = vsync;
+ hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */
+}
+
+void hdmi_get_sync_polar(int *hsync_hi, int *vsync_hi)
+{
+ *hsync_hi = (hdmi_regs1->general_ctrl.b.hsync_low_active) ? 0 : 1;
+ *vsync_hi = (hdmi_regs1->general_ctrl.b.vsync_low_active) ? 0 : 1;
+}
+
+void hdmi_set_output_colfmt(vdo_color_fmt colfmt)
+{
+ unsigned int val;
+
+ switch (colfmt) {
+ default:
+ case VDO_COL_FMT_ARGB:
+ val = 0;
+ break;
+ case VDO_COL_FMT_YUV444:
+ val = 1;
+ break;
+ case VDO_COL_FMT_YUV422H:
+ case VDO_COL_FMT_YUV422V:
+ val = 2;
+ break;
+ }
+ hdmi_regs1->general_ctrl.b.convert_yuv422 = (val == 2) ? 1 : 0;
+ hdmi_regs1->general_ctrl.b.output_format = val;
+ hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */
+}
+
+vdo_color_fmt hdmi_get_output_colfmt(void)
+{
+ unsigned int val;
+
+ val = hdmi_regs1->general_ctrl.b.output_format;
+ switch (val) {
+ default:
+ case 0:
+ return VDO_COL_FMT_ARGB;
+ case 1:
+ return VDO_COL_FMT_YUV444;
+ case 2:
+ return VDO_COL_FMT_YUV422H;
+ }
+ return VDO_COL_FMT_ARGB;
+}
+
+int hdmi_get_plugin(void)
+{
+ int plugin;
+
+ if (hdmi_regs1->hotplug_detect.b.in_enable) {
+ plugin = hdmi_regs1->hotplug_detect.b.sts;
+ } else {
+ int tre_en;
+
+ tre_en = hdmi_regs2->test.b.tre_en;
+ hdmi_regs2->test.b.tre_en = 0;
+ plugin = hdmi_regs2->detect.b.rsen;
+ hdmi_regs2->test.b.tre_en = tre_en;
+ }
+ return plugin;
+}
+
+int hdmi_get_plug_status(void)
+{
+ int reg;
+
+ reg = hdmi_regs1->hotplug_detect.val;
+ return reg & 0x3000000;
+}
+
+void hdmi_clear_plug_status(void)
+{
+ hdmi_regs1->hotplug_detect.b.in_sts = 1;
+ hdmi_regs1->hotplug_detect.b.out_sts = 1;
+}
+
+void hdmi_enable_plugin(int enable)
+{
+ hdmi_regs1->hotplug_detect.b.out_enable = enable;
+ hdmi_regs1->hotplug_detect.b.in_enable = enable;
+}
+
+void hdmi_write_fifo(enum hdmi_fifo_slot_t no, unsigned int *buf, int cnt)
+{
+ int i;
+
+ if (no > HDMI_FIFO_SLOT_MAX)
+ return;
+#ifdef DEBUG
+{
+ char *ptr;
+
+ DPRINT("[HDMI] wr fifo %d,cnt %d", no, cnt);
+ ptr = (char *) buf;
+ for (i = 0; i < cnt; i++) {
+ if ((i % 4) == 0)
+ DPRINT("\n %02d :", i);
+ DPRINT(" 0x%02x", ptr[i]);
+ }
+ DPRINT("\n[HDMI] AVI info package end\n");
+}
+#endif
+ hdmi_regs1->fifo_ctrl.val = (no << 8);
+ cnt = (cnt + 3) / 4;
+ for (i = 0; i < cnt; i++)
+ hdmi_regs1->wr_fifo_addr[i] = buf[i];
+ hdmi_regs1->fifo_ctrl.b.wr_strobe = 1;
+}
+
+void hdmi_read_fifo(enum hdmi_fifo_slot_t no, unsigned int *buf, int cnt)
+{
+ int i;
+ int rdy;
+
+ if (no > HDMI_FIFO_SLOT_MAX)
+ return;
+
+ rdy = hdmi_regs1->infoframe_ctrl.b.fifo1_rdy;
+ hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 0;
+
+ no = no - 1;
+ hdmi_regs1->fifo_ctrl.val = (no << 8);
+ hdmi_regs1->fifo_ctrl.b.rd_strobe = 1;
+ cnt = (cnt + 3) / 4;
+ for (i = 0; i < cnt; i++)
+ buf[i] = hdmi_regs1->rd_fifo_addr[i];
+ hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = rdy;
+#ifdef DEBUG
+{
+ char *ptr;
+
+ cnt *= 4;
+ DPRINT("[HDMI] rd fifo %d,cnt %d", no, cnt);
+ ptr = (char *) buf;
+ for (i = 0; i < cnt; i++) {
+ if ((i % 4) == 0)
+ DPRINT("\n %02d :", i);
+ DPRINT(" 0x%02x", ptr[i]);
+ }
+ DPRINT("\n[HDMI] AVI info package end\n");
+}
+#endif
+}
+
+#if 1
+int hdmi_ddc_delay_us = 5;
+int hdmi_ddc_ctrl_delay_us = 5;
+
+#define HDMI_DDC_OUT
+#define HDMI_DDC_DELAY hdmi_ddc_delay_us
+#define HDMI_DDC_CHK_DELAY 1
+#define HDMI_DDC_CTRL_DELAY hdmi_ddc_ctrl_delay_us
+#else
+#define HDMI_DDC_OUT
+#define HDMI_DDC_DELAY 1
+#define HDMI_DDC_CHK_DELAY 1
+#define HDMI_DDC_CTRL_DELAY 1
+#endif
+
+#define HDMI_STATUS_START BIT16
+#define HDMI_STATUS_STOP BIT17
+#define HDMI_STATUS_WR_AVAIL BIT18
+#define HDMI_STATUS_CP_USE BIT19
+#define HDMI_STATUS_SW_READ BIT25
+int hdmi_DDC_check_status(unsigned int checkbits, int condition)
+{
+ int status = 1;
+ unsigned int i = 0, maxloop;
+
+ maxloop = 500 / HDMI_DDC_CHK_DELAY;
+ udelay(HDMI_DDC_DELAY);
+
+ if (condition) { /* wait 1 --> 0 */
+ while ((hdmi_regs1->i2c_ctrl2.val & checkbits)
+ && (i < maxloop)) {
+ udelay(HDMI_DDC_CHK_DELAY);
+ if (++i == maxloop)
+ status = 0;
+ }
+ } else { /* wait 0 --> 1 */
+ while (!(hdmi_regs1->i2c_ctrl2.val & checkbits)
+ && (i < maxloop)) {
+ udelay(HDMI_DDC_CHK_DELAY);
+ if (++i == maxloop)
+ status = 0;
+ }
+ }
+
+ if ((status == 0) && (checkbits != HDMI_STATUS_SW_READ)) {
+ unsigned int reg;
+
+ reg = hdmi_regs1->i2c_ctrl2.val;
+ DBG_DETAIL("[HDMI] status timeout check 0x%x,wait to %s\n",
+ checkbits, (condition) ? "0" : "1");
+ DBG_DETAIL("[HDMI] 0x%x,sta %d,stop %d,wr %d,rd %d,cp %d\n",
+ reg, (reg & HDMI_STATUS_START) ? 1 : 0,
+ (reg & HDMI_STATUS_STOP) ? 1 : 0,
+ (reg & HDMI_STATUS_WR_AVAIL) ? 1 : 0,
+ (reg & HDMI_STATUS_SW_READ) ? 1 : 0,
+ (reg & HDMI_STATUS_CP_USE) ? 1 : 0);
+ }
+ return status;
+}
+
+void hdmi_DDC_set_freq(unsigned int hz)
+{
+ unsigned int clock;
+ unsigned int div;
+
+ clock = 25000000*15/100; /* RTC clock source */
+ div = clock / hz;
+
+ hdmi_regs1->i2c_ctrl.b.i2c_clk_divider = div;
+ DBG_DETAIL("[HDMI] set freq(%d,clk %d,div %d)\n", hz, clock, div);
+}
+
+void hdmi_DDC_reset(void)
+{
+ hdmi_regs1->i2c_ctrl.b.i2c_sw_reset = 1;
+ udelay(1);
+ hdmi_regs1->i2c_ctrl.b.i2c_sw_reset = 0;
+}
+
+int hdmi_DDC_read_func(char addr, int index, char *buf, int length)
+{
+ int status = 1;
+ unsigned int i = 0;
+ int err_cnt = 0;
+
+ DBG_DETAIL("[HDMI] read DDC(index 0x%x,len %d),reg 0x%x\n",
+ index, length, hdmi_regs1->i2c_ctrl2.val);
+
+#ifdef CONFIG_HDMI_EDID_DISABLE
+ return status;
+#endif
+
+ hdmi_DDC_set_freq(g_vpp.hdmi_i2c_freq);
+ /* enhanced DDC read */
+ if (index >= 256) {
+ /* sw start, write data avail */
+ vppif_reg32_write((unsigned int) &hdmi_regs1->i2c_ctrl2,
+ BIT18 + BIT16, 16, 0x5);
+ udelay(HDMI_DDC_CTRL_DELAY);
+ /* wait start & wr data avail */
+ status = hdmi_DDC_check_status(HDMI_STATUS_START +
+ HDMI_STATUS_WR_AVAIL, 1);
+ if (status == 0) {
+ DBGMSG("[HDMI] *E* start\n");
+ err_cnt++;
+ goto ddc_read_fail;
+ }
+
+ /* Slave address */
+ hdmi_regs1->i2c_ctrl2.b.wr_data = 0x60;
+ hdmi_regs1->i2c_ctrl2.b.wr_data_avail = 1;
+ udelay(HDMI_DDC_CTRL_DELAY);
+ /* wait wr data avail */
+ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1);
+ if (status == 0) {
+ DBGMSG("[HDMI] *E* slave addr 0x%x\n", addr);
+ err_cnt++;
+ goto ddc_read_fail;
+ }
+
+ /* Offset */
+ hdmi_regs1->i2c_ctrl2.b.wr_data = 0x1;
+ hdmi_regs1->i2c_ctrl2.b.wr_data_avail = 1;
+ udelay(HDMI_DDC_CTRL_DELAY);
+ /* wait wr data avail */
+ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1);
+ if (status == 0) {
+ DBGMSG("[HDMI] *E* index 0x%x\n", index);
+ err_cnt++;
+ goto ddc_read_fail;
+ }
+ index -= 256;
+ }
+
+ /* START */
+ hdmi_regs1->i2c_ctrl2.val = 0x50000; /* start & data avail */
+ udelay(HDMI_DDC_CTRL_DELAY);
+ /* wait start & wr data avail */
+ status = hdmi_DDC_check_status(HDMI_STATUS_START +
+ HDMI_STATUS_WR_AVAIL, 1);
+ if (status == 0) {
+ DBGMSG("[HDMI] *E* start\n");
+ err_cnt++;
+ goto ddc_read_fail;
+ }
+
+ /* Slave address */
+ hdmi_regs1->i2c_ctrl2.val = 0x400A0; /* addr & data avail */
+ udelay(HDMI_DDC_CTRL_DELAY);
+ /* wait wr data avail */
+ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1);
+ if (status == 0) {
+ DBGMSG("[HDMI] *E* slave addr 0x%x\n", addr);
+ err_cnt++;
+ goto ddc_read_fail;
+ }
+
+ /* Offset */
+ hdmi_regs1->i2c_ctrl2.val = (0x40000 + index); /* index & data avail */
+ udelay(HDMI_DDC_CTRL_DELAY);
+ /* wait wr data avail */
+ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1);
+ if (status == 0) {
+ DBGMSG("[HDMI] *E* index 0x%x\n", index);
+ err_cnt++;
+ goto ddc_read_fail;
+ }
+
+ /* START */
+ hdmi_regs1->i2c_ctrl2.val = 0x50000; /* start & data avail */
+ udelay(HDMI_DDC_CTRL_DELAY);
+ /* wait start & wr data avail */
+ status = hdmi_DDC_check_status(HDMI_STATUS_START +
+ HDMI_STATUS_WR_AVAIL, 1);
+ if (status == 0) {
+ DBGMSG("[HDMI] *E* restart\n");
+ err_cnt++;
+ goto ddc_read_fail;
+ }
+
+ /* Slave Address + 1 */
+ hdmi_regs1->i2c_ctrl2.val = 0x400A1; /* addr(rd) & data avail */
+ udelay(HDMI_DDC_CTRL_DELAY);
+ /* wait wr data avail */
+ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1);
+ if (status == 0) {
+ DBGMSG("[HDMI] *E* slave addr 0x%x\n", addr + 1);
+ err_cnt++;
+ goto ddc_read_fail;
+ }
+
+ /* Read Data */
+ for (i = 0; i < length; i++) {
+ hdmi_regs1->i2c_ctrl2.val = 0x40000; /* data avail */
+ udelay(HDMI_DDC_CTRL_DELAY);
+ /* wait wr data avail */
+ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1);
+ if (status == 0) {
+ DBGMSG("[HDMI] *E* wr ACK(%d)\n", i);
+ err_cnt++;
+ goto ddc_read_fail;
+ /* break; */
+ }
+
+ /* wait sw read not set */
+ status = hdmi_DDC_check_status(HDMI_STATUS_SW_READ, 0);
+ if (status == 0) {
+ DBGMSG("[HDMI] *E* read avail(%d)\n", i);
+ if (i == 0) {
+ err_cnt++;
+ /* goto ddc_read_fail; */
+ } else {
+ /* g_vpp.dbg_hdmi_ddc_read_err++; */
+ }
+ goto ddc_read_fail;
+ /* break; */
+ }
+
+ *buf++ = hdmi_regs1->i2c_ctrl2.b.rd_data;
+ udelay(HDMI_DDC_DELAY);
+ hdmi_regs1->i2c_ctrl2.val = 0x2000000; /* clr sw read */
+ udelay(HDMI_DDC_DELAY);
+ }
+
+ /* STOP */
+ /* sw stop, write data avail */
+ vppif_reg32_write((unsigned int) &hdmi_regs1->i2c_ctrl2.val,
+ BIT18 + BIT17, 17, 3);
+ udelay(HDMI_DDC_CTRL_DELAY);
+ /* wait start & wr data avail */
+ status = hdmi_DDC_check_status(HDMI_STATUS_STOP +
+ HDMI_STATUS_WR_AVAIL + HDMI_STATUS_CP_USE, 1);
+ if (status == 0) {
+ DBGMSG("[HDMI] *E* stop\n");
+ err_cnt++;
+ goto ddc_read_fail;
+ }
+ udelay(HDMI_DDC_DELAY);
+
+ddc_read_fail:
+ if (err_cnt)
+ DBGMSG("[HDMI] *E* read DDC %d\n", err_cnt);
+ return (err_cnt) ? 1 : 0;
+}
+
+int hdmi_DDC_read(char addr, int index, char *buf, int length)
+{
+ int retry = 3;
+ int ret;
+
+ DBG_MSG("(0x%x,0x%x,%d)\n", addr, index, length);
+
+ do {
+ ret = hdmi_DDC_read_func(addr, index, buf, length);
+ if (ret == 0)
+ break;
+ hdmi_DDC_reset();
+ DPRINT("[HDMI] *W* DDC reset %d\n", ret);
+ retry--;
+ } while (retry);
+
+ return (retry == 0) ? 1 : 0;
+}
+
+void hdmi_audio_enable(vpp_flag_t enable)
+{
+ if (hdmi_regs1->aud_enable != enable) {
+ if (!enable) {
+#ifdef CONFIG_KERNEL
+ msleep(5);
+#endif
+ if (g_vpp.hdmi_ch_change)
+ REG32_VAL(I2S_BASE_ADDR + 0x188) = 0;
+ }
+ hdmi_regs1->aud_enable = (enable) ? 1 : 0;
+ }
+}
+
+void hdmi_audio_mute(vpp_flag_t enable)
+{
+ hdmi_regs1->aud_ratio.b.mute = enable;
+}
+
+/*----------------------- HDMI API --------------------------------------*/
+void hdmi_write_packet(unsigned int header, unsigned char *packet,
+ int cnt)
+{
+ unsigned char buf[36];
+ int i;
+ enum hdmi_fifo_slot_t no;
+
+#ifdef CONFIG_HDMI_INFOFRAME_DISABLE
+ return;
+#endif
+ memcpy(&buf[0], &header, 3);
+ buf[3] = hdmi_ecc((unsigned char *)&header, 24);
+ for (i = 0; i < cnt / 7; i++) {
+ memcpy(&buf[4+8*i], &packet[7*i], 7);
+ buf[11+8*i] = hdmi_ecc(&packet[7*i], 56);
+ }
+
+ switch (header & 0xFF) {
+ case HDMI_PACKET_INFOFRAME_AVI:
+ no = HDMI_FIFO_SLOT_AVI;
+ break;
+ case HDMI_PACKET_INFOFRAME_AUDIO:
+ no = HDMI_FIFO_SLOT_AUDIO;
+ break;
+ case HDMI_PACKET_INFOFRAME_VENDOR:
+ no = HDMI_FIFO_SLOT_VENDOR;
+ break;
+ default:
+ no = HDMI_FIFO_SLOT_CONTROL;
+ break;
+ }
+ hdmi_write_fifo(no, (unsigned int *)buf, (4 + 8 * (cnt / 7)));
+}
+
+void hdmi_tx_null_packet(void)
+{
+ hdmi_write_packet(HDMI_PACKET_NULL, 0, 0);
+}
+
+void hdmi_tx_general_control_packet(int mute)
+{
+ unsigned char buf[7];
+ memset(buf, 0x0, 7);
+ buf[0] = (mute) ? 0x01 : 0x10;
+ buf[1] = HDMI_COLOR_DEPTH_24 | (HDMI_PHASE_4 << 4);
+ hdmi_write_packet(HDMI_PACKET_GENERAL_CTRL, buf, 7);
+}
+
+int hdmi_get_pic_aspect(enum hdmi_video_code_t vic)
+{
+ switch (vic) {
+ case HDMI_640x480p60_4x3:
+ case HDMI_720x480p60_4x3:
+ case HDMI_1440x480i60_4x3:
+ case HDMI_1440x240p60_4x3:
+ case HDMI_2880x480i60_4x3:
+ case HDMI_2880x240p60_4x3:
+ case HDMI_1440x480p60_4x3:
+ case HDMI_720x576p50_4x3:
+ case HDMI_1440x576i50_4x3:
+ case HDMI_1440x288p50_4x3:
+ case HDMI_2880x576i50_4x3:
+ case HDMI_2880x288p50_4x3:
+ case HDMI_1440x576p50_4x3:
+ return HDMI_PIC_ASPECT_4_3;
+ default:
+ break;
+ }
+ return HDMI_PIC_ASPECT_16_9;
+}
+
+int hdmi_get_vic(int resx, int resy, int fps, int interlace)
+{
+ struct hdmi_vic_t info;
+ int i;
+
+ info.resx = resx;
+ info.resy = resy;
+ info.freq = fps;
+ info.option = (interlace) ? HDMI_VIC_INTERLACE : HDMI_VIC_PROGRESS;
+ info.option |= (vout_check_ratio_16_9(resx, resy)) ?
+ HDMI_VIC_16x9 : HDMI_VIC_4x3;
+ for (i = 0; i < HDMI_VIDEO_CODE_MAX; i++) {
+ if (memcmp(&hdmi_vic_info[i], &info,
+ sizeof(struct hdmi_vic_t)) == 0)
+ return i;
+ }
+ return HDMI_UNKNOW;
+}
+
+void hdmi_tx_avi_infoframe_packet(vdo_color_fmt colfmt,
+ enum hdmi_video_code_t vic)
+{
+ unsigned int header;
+ unsigned char buf[28];
+ unsigned char temp;
+
+ memset(buf, 0x0, 28);
+ header = HDMI_PACKET_INFOFRAME_AVI + (0x2 << 8) + (0x0d << 16);
+ buf[1] = HDMI_SI_NO_DATA + (HDMI_BI_V_H_VALID << 2) +
+ (HDMI_AF_INFO_NO_DATA << 4);
+ switch (colfmt) {
+ case VDO_COL_FMT_YUV422H:
+ case VDO_COL_FMT_YUV422V:
+ temp = HDMI_OUTPUT_YUV422;
+ break;
+ case VDO_COL_FMT_YUV444:
+ temp = HDMI_OUTPUT_YUV444;
+ break;
+ case VDO_COL_FMT_ARGB:
+ default:
+ temp = HDMI_OUTPUT_RGB;
+ break;
+ }
+ buf[1] += (temp << 5);
+ buf[2] = HDMI_ASPECT_RATIO_PIC + (hdmi_get_pic_aspect(vic) << 4) +
+ (HDMI_COLORIMETRY_ITU709 << 6);
+ buf[3] = 0x84;
+ buf[4] = vic;
+ switch (vic) {
+ case HDMI_1440x480i60_16x9:
+ case HDMI_1440x576i50_16x9:
+ buf[5] = HDMI_PIXEL_REP_2;
+ break;
+ default:
+ buf[5] = HDMI_PIXEL_REP_NO;
+ break;
+ }
+ buf[0] = hdmi_checksum((unsigned char *)&header, buf, 28);
+ hdmi_write_packet(header, buf, 28);
+}
+
+void hdmi_tx_audio_infoframe_packet(int channel, int freq)
+{
+ unsigned int header;
+ unsigned char buf[28];
+
+ memset(buf, 0x0, 28);
+ header = HDMI_PACKET_INFOFRAME_AUDIO + (0x1 << 8) + (0x0a << 16);
+ buf[1] = (channel - 1) + (HDMI_AUD_TYPE_REF_STM << 4);
+ buf[2] = 0x0; /* HDMI_AUD_SAMPLE_24 + (freq << 2); */
+ buf[3] = 0x00;
+ /* 0x13: RRC RLC RR RL FC LFE FR FL
+ 0x1F: FRC FLC RR RL FC LFE FR FL */
+ buf[4] = (channel == 8) ? 0x13 : 0;
+ buf[5] = 0x0; /* 0 db */
+ buf[0] = hdmi_checksum((unsigned char *)&header, buf, 28);
+ hdmi_write_packet(header, buf, 28);
+}
+
+void hdmi_tx_vendor_specific_infoframe_packet(void)
+{
+ unsigned int header;
+ unsigned char buf[28];
+ unsigned char structure_3d, meta_present;
+ unsigned char hdmi_video_format;
+
+ /* 0-No,1-1 byte param,2-3D format */
+ hdmi_video_format = (g_vpp.hdmi_3d_type) ? 2 : 0;
+ /* HDMI_3D_STRUCTURE_XXX; */
+ structure_3d = (g_vpp.hdmi_3d_type == 1) ? 0 : g_vpp.hdmi_3d_type;
+ meta_present = 0;
+
+ memset(buf, 0x0, 28);
+ header = HDMI_PACKET_INFOFRAME_VENDOR + (0x1 << 8) + (0xa << 16);
+ buf[1] = 0x3;
+ buf[2] = 0xC;
+ buf[3] = 0x0;
+ buf[4] = (hdmi_video_format << 5);
+ buf[5] = (structure_3d << 4) + ((meta_present) ? 0x8 : 0x0);
+ buf[6] = 0x0; /* 3D_Ext_Data */
+#if 0 /* metadata present */
+ buf[7] = 0x0; /* 3D_Metadata_type,3D_Metadata_Length(N) */
+ buf[8] = 0x0; /* 3D Metadata 1_N */
+#endif
+ buf[0] = hdmi_checksum((unsigned char *)&header, buf, 28);
+ hdmi_write_packet(header, buf, 28);
+}
+
+#define HDMI_N_CTS_USE_TABLE
+#ifdef HDMI_N_CTS_USE_TABLE
+struct hdmi_n_cts_s {
+ unsigned int n;
+ unsigned int cts;
+};
+
+struct hdmi_n_cts_s hdmi_n_cts_table[7][11] = {
+ /* 32kHz */
+ {{ 9152, 84375 }, {4096, 37800}, {4096, 40500}, {8192, 81081},
+ { 4096, 81000 }, {4096, 81081}, {11648, 316406}, {4096, 111375},
+ { 11648, 632812}, {4096, 222750}, {4096, 0}},
+ /* 44.1kHz */
+ {{7007, 46875}, {6272, 42000}, {6272, 45000}, {6272, 45045},
+ {6272, 90000}, {6272, 90090}, {17836, 351562}, {6272, 123750},
+ {17836, 703125}, {6272, 247500}, {6272, 0}},
+ /* 88.2kHz */
+ {{14014, 46875}, {12544, 42000}, {12544, 45000}, {12544, 45045},
+ {12544, 90000}, {12544, 90090}, {35672, 351562}, {12544, 123750},
+ {35672, 703125}, {12544, 247500}, {12544, 0}},
+ /* 176.4kHz */
+ {{28028, 46875}, {25088, 42000}, {25088, 45000}, {25088, 45045},
+ {25088, 90000}, {25088, 90090}, {71344, 351562}, {25088, 123750},
+ {71344, 703125}, {25088, 247500}, {25088, 0}},
+ /* 48kHz */
+ {{9152, 56250}, {6144, 37800}, {6144, 40500}, {8192, 54054},
+ {6144, 81000}, {6144, 81081}, {11648, 210937}, {6144, 111375},
+ {11648, 421875}, {6144, 222750}, {6144, 0}},
+ /* 96kHz */
+ {{18304, 56250}, {12288, 37800}, {12288, 40500}, {16384, 54054},
+ {12288, 81000}, {12288,81081}, {23296, 210937}, {12288, 111375},
+ {23296, 421875}, {12288, 222750}, {12288, 0}},
+ /* 192kHz */
+ {{36608, 56250}, {24576, 37800}, {24576, 40500}, {32768, 54054},
+ {24576, 81000}, {24576, 81081}, {46592, 210937}, {24576, 111375},
+ {46592, 421875}, {24576, 222750}, {24576, 0}}
+};
+
+struct hdmi_n_cts_s *hdmi_get_n_cts(unsigned int tmds_clk,
+ unsigned int freq)
+{
+ int i, j;
+
+ switch (freq) {
+ case 32000:
+ i = 0;
+ break;
+ case 44100:
+ i = 1;
+ break;
+ case 88200:
+ i = 2;
+ break;
+ case 176400:
+ i = 3;
+ break;
+ case 48000:
+ i = 4;
+ break;
+ case 96000:
+ i = 5;
+ break;
+ case 192000:
+ i = 6;
+ break;
+ default:
+ return 0;
+ }
+
+ switch (tmds_clk) {
+ case 25174825:
+ j = 0;
+ break;
+ case 25200000:
+ j = 1;
+ break;
+ case 27000000:
+ j = 2;
+ break;
+ case 27027000:
+ j = 3;
+ break;
+ case 54000000:
+ j = 4;
+ break;
+ case 54054000:
+ j = 5;
+ break;
+ case 74175824:
+ j = 6;
+ break;
+ case 74250000:
+ j = 7;
+ break;
+ case 148351648:
+ j = 8;
+ break;
+ case 148500000:
+ j = 9;
+ break;
+ default:
+ j = 10;
+ break;
+ }
+ return &hdmi_n_cts_table[i][j];
+}
+#endif
+
+void hdmi_set_audio_n_cts(unsigned int freq)
+{
+ unsigned int n = 0, cts = 0;
+
+#ifdef HDMI_N_CTS_USE_TABLE
+ struct hdmi_n_cts_s *p;
+
+ p = hdmi_get_n_cts(g_vpp.hdmi_pixel_clock, freq);
+ if (p) {
+ n = p->n;
+ cts = p->cts;
+ MSG("[HDMI] use table n %d, cts %d\n", n, cts);
+ }
+#endif
+
+ if (n == 0)
+ n = 128 * freq / 1000;
+
+ if (cts == 0) {
+#ifdef __KERNEL__
+ unsigned int tmp;
+ unsigned int pll_clk;
+
+ pll_clk = auto_pll_divisor(DEV_I2S, GET_FREQ, 0, 0);
+ tmp = (inl(AUDREGF_BASE_ADDR + 0x70) & 0xF);
+
+ switch (tmp) {
+ case 0 ... 4:
+ tmp = 0x01 << tmp;
+ break;
+ case 9 ... 12:
+ tmp = 3 * (0x1 << (tmp-9));
+ break;
+ default:
+ tmp = 1;
+ break;
+ }
+ {
+ unsigned long long tmp2;
+ unsigned long long div2;
+ unsigned long mod;
+
+ tmp2 = g_vpp.hdmi_pixel_clock;
+ tmp2 = tmp2 * n * tmp;
+ div2 = pll_clk;
+ mod = do_div(tmp2, div2);
+ cts = tmp2;
+ }
+ DBGMSG("[HDMI] i2s %d,cts %d,reg 0x%x\n", pll_clk, cts,
+ vppif_reg32_in(AUDREGF_BASE_ADDR + 0x70));
+#else
+ cts = (g_vpp.hdmi_pixel_clock / 1000) - 1;
+#endif
+ }
+ hdmi_regs1->aud_sample_rate1.b.n_20bits = n;
+ hdmi_regs1->aud_ratio.b.acr_ratio = cts - 1;
+ hdmi_regs1->aud_sample_rate2.b.cts_select = 0;
+ cts = 0;
+ hdmi_regs1->aud_sample_rate1.b.cts_low_12bits = cts & 0xFFF;
+ hdmi_regs1->aud_sample_rate2.b.cts_hi_8bits = (cts & 0xFF000) >> 12;
+ DBGMSG("[HDMI] set audio freq %d,n %d,cts %d,tmds %d\n",
+ freq, n, cts, g_vpp.hdmi_pixel_clock);
+}
+
+void hdmi_config_audio(struct vout_audio_t *info)
+{
+ unsigned int freq;
+
+ g_vpp.hdmi_audio_channel = info->channel;
+ g_vpp.hdmi_audio_freq = info->sample_rate;
+
+ /* enable ARF & ARFP clock */
+ REG32_VAL(PM_CTRL_BASE_ADDR + 0x254) |= (BIT4 | BIT3);
+ hdmi_tx_audio_infoframe_packet(info->channel, info->sample_rate);
+ hdmi_audio_enable(VPP_FLAG_DISABLE);
+ hdmi_regs1->aud_mode.b.layout = (info->channel > 2) ? 1 : 0;
+ hdmi_regs1->aud_mode.b._2ch_eco = (info->channel > 2) ? 0 : 1;
+ switch (info->sample_rate) {
+ case 32000:
+ freq = 0x3;
+ break;
+ case 44100:
+ freq = 0x0;
+ break;
+ case 88200:
+ freq = 0x8;
+ break;
+ case 176400:
+ freq = 0xC;
+ break;
+ default:
+ case 48000:
+ freq = 0x2;
+ break;
+ case 96000:
+ freq = 0xA;
+ break;
+ case 192000:
+ freq = 0xE;
+ break;
+ case 768000:
+ freq = 0x9;
+ break;
+ }
+ hdmi_regs1->aud_chan_status0 = (freq << 24) + 0x4;
+ hdmi_regs1->aud_chan_status1 = 0x0;
+ hdmi_regs1->aud_chan_status2 = 0xb;
+ hdmi_regs1->aud_chan_status3 = 0x0;
+ hdmi_regs1->aud_chan_status4 = 0x0;
+ hdmi_regs1->aud_chan_status5 = 0x0;
+
+ hdmi_set_audio_n_cts(info->sample_rate);
+ hdmi_regs1->aud_ratio.b.acr_enable = 1;
+ hdmi_regs1->aud_sample_rate2.b.aipclk_rate = 0;
+ hdmi_audio_enable(VPP_FLAG_ENABLE);
+}
+
+void hdmi_config_video(struct hdmi_info_t *info)
+{
+ hdmi_set_output_colfmt(info->outfmt);
+ hdmi_tx_avi_infoframe_packet(info->outfmt, info->vic);
+ hdmi_tx_vendor_specific_infoframe_packet();
+}
+
+void hdmi_set_option(unsigned int option)
+{
+ vdo_color_fmt colfmt;
+ int temp;
+
+ hdmi_set_dvi_enable((option & EDID_OPT_HDMI) ?
+ VPP_FLAG_DISABLE : VPP_FLAG_ENABLE);
+ hdmi_audio_enable((option & EDID_OPT_AUDIO) ?
+ VPP_FLAG_ENABLE : VPP_FLAG_DISABLE);
+
+ colfmt = hdmi_get_output_colfmt();
+ switch (colfmt) {
+ case VDO_COL_FMT_YUV422H:
+ temp = option & EDID_OPT_YUV422;
+ break;
+ case VDO_COL_FMT_YUV444:
+ temp = option & EDID_OPT_YUV444;
+ break;
+ default:
+ temp = 1;
+ break;
+ }
+ if (temp == 0) {
+ hdmi_set_output_colfmt(VDO_COL_FMT_ARGB);
+ DBG_MSG("[HDMI] TV not support %s,use default RGB\n",
+ vpp_colfmt_str[colfmt]);
+ }
+ DBG_MSG("[HDMI] set option(8-HDMI,6-AUDIO) 0x%x\n", option);
+}
+
+void hdmi_config(struct hdmi_info_t *info)
+{
+ struct vout_audio_t audio_info;
+ int h_porch;
+ int delay_cfg;
+ vpp_clock_t clock;
+
+ hdmi_regs1->ctrl.b.hden = 0;
+ hdmi_regs1->infoframe_ctrl.b.select = 0;
+ hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 0;
+ hdmi_config_video(info);
+
+ govrh_get_tg(p_govrh, &clock);
+ h_porch = clock.total_pixel_of_line - clock.end_pixel_of_active; /*fp*/
+ delay_cfg = 47 - h_porch;
+ if (delay_cfg <= 0)
+ delay_cfg = 1;
+ h_porch = clock.begin_pixel_of_active; /* bp */
+ h_porch = (h_porch - (delay_cfg + 1) - 26) / 32;
+ if (h_porch <= 0)
+ h_porch = 1;
+ if (h_porch >= 8)
+ h_porch = 0;
+
+ hdmi_regs1->general_ctrl.b.cp_delay = delay_cfg;
+ hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */
+ hdmi_regs1->infoframe_ctrl.b.horiz_blank_max_pck = h_porch;
+ DBGMSG("[HDMI] H blank max pck %d,delay %d\n", h_porch, delay_cfg);
+
+ audio_info.fmt = 16;
+ audio_info.channel = info->channel;
+ audio_info.sample_rate = info->freq;
+ hdmi_config_audio(&audio_info);
+
+ hdmi_regs1->infoframe_ctrl.b.fifo1_addr = 0;
+ hdmi_regs1->infoframe_ctrl.b.fifo1_len = 2;
+ hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 1;
+ hdmi_set_option(info->option);
+ hdmi_regs2->test.b.tre_en =
+ (g_vpp.hdmi_pixel_clock < 40000000) ? 3 : 2;
+}
+
+/*----------------------- Module API --------------------------------------*/
+void hdmi_set_cp_enable(vpp_flag_t enable)
+{
+ if (!g_vpp.hdmi_cp_enable)
+ enable = 0;
+
+ if (hdmi_cp)
+ hdmi_cp->enable(enable);
+
+#ifdef __KERNEL__
+ if (hdmi_cp && hdmi_cp->poll) {
+ vpp_irqproc_del_work(VPP_INT_GOVRH_VBIS, (void *)hdmi_cp->poll);
+ if (enable)
+ vpp_irqproc_work(VPP_INT_GOVRH_VBIS,
+ (void *)hdmi_cp->poll, 0, 0, 0);
+ }
+#endif
+}
+
+int hdmi_check_cp_int(void)
+{
+ int ret = 0;
+
+ if (hdmi_cp)
+ ret = hdmi_cp->interrupt();
+ return ret;
+}
+
+void hdmi_get_bksv(unsigned int *bksv)
+{
+ if (hdmi_cp)
+ hdmi_cp->get_bksv(bksv);
+}
+
+#ifdef __KERNEL__
+void hdmi_hotplug_notify(int plug_status)
+{
+ if (g_vpp.hdmi_disable)
+ return;
+ vpp_netlink_notify_plug(VPP_VOUT_NUM_HDMI, plug_status);
+}
+#else
+#define hdmi_hotplug_notify
+#endif
+
+int hdmi_check_plugin(int hotplug)
+{
+ static int last_plugin = -1;
+ int plugin;
+ int flag;
+
+ if (g_vpp.hdmi_disable)
+ return 0;
+
+ plugin = hdmi_get_plugin();
+ hdmi_clear_plug_status();
+#ifdef __KERNEL__
+ /* disable HDMI before change clock */
+ if (plugin == 0) {
+ hdmi_set_enable(0);
+ hdmi_set_power_down(1);
+ }
+ vpp_set_clock_enable(DEV_HDMII2C, plugin, 1);
+ vpp_set_clock_enable(DEV_HDCE, plugin, 1);
+
+ /* slow down clock for plugout */
+ flag = (auto_pll_divisor(DEV_HDMILVDS, GET_FREQ, 0, 0)
+ == 8000000) ? 0 : 1;
+ if ((plugin != flag) && !g_vpp.virtual_display) {
+ int pixclk;
+
+ pixclk = (plugin) ? g_vpp.hdmi_pixel_clock : 8000000;
+ auto_pll_divisor(DEV_HDMILVDS, SET_PLLDIV, 0, pixclk);
+ }
+#endif
+ if (last_plugin != plugin) {
+ DPRINT("[HDMI] HDMI plug%s,hotplug %d\n", (plugin) ?
+ "in" : "out", hotplug);
+ last_plugin = plugin;
+ }
+#if 0 /* Denzel test */
+ if (plugin == 0)
+ hdmi_set_dvi_enable(VPP_FLAG_ENABLE);
+#endif
+ return plugin;
+}
+
+void hdmi_reg_dump(void)
+{
+ DPRINT("========== HDMI register dump ==========\n");
+ vpp_reg_dump(REG_HDMI_BEGIN, REG_HDMI_END - REG_HDMI_BEGIN);
+ vpp_reg_dump(REG_HDMI2_BEGIN, REG_HDMI2_END - REG_HDMI2_BEGIN);
+
+ DPRINT("---------- HDMI common ----------\n");
+ DPRINT("enable %d,hden %d,reset %d,dvi %d\n",
+ hdmi_regs1->general_ctrl.b.enable,
+ hdmi_regs1->ctrl.b.hden,
+ hdmi_regs1->general_ctrl.b.reset,
+ hdmi_regs1->general_ctrl.b.dvi_mode_enable);
+ DPRINT("colfmt %d,conv 422 %d,hsync low %d,vsync low %d\n",
+ hdmi_regs1->general_ctrl.b.output_format,
+ hdmi_regs1->general_ctrl.b.convert_yuv422,
+ hdmi_regs1->general_ctrl.b.hsync_low_active,
+ hdmi_regs1->general_ctrl.b.vsync_low_active);
+ DPRINT("dbg bus sel %d,state mach %d\n",
+ hdmi_regs1->general_ctrl.b.dbg_bus_select,
+ hdmi_regs1->general_ctrl.b.state_machine_status);
+ DPRINT("eep reset %d,encode %d,eess %d\n",
+ hdmi_regs1->ctrl.b.eeprom_reset,
+ hdmi_regs1->ctrl.b.encode_enable,
+ hdmi_regs1->ctrl.b.eess_enable);
+ DPRINT("verify pj %d,auth test %d,cipher %d\n",
+ hdmi_regs1->ctrl.b.verify_pj_enable,
+ hdmi_regs1->ctrl.b.auth_test_key,
+ hdmi_regs1->ctrl.b.cipher_1_1);
+ DPRINT("preamble %d\n", hdmi_regs1->ctrl.b.preamble);
+
+ DPRINT("---------- HDMI hotplug ----------\n");
+ DPRINT("plug %s\n", (hdmi_regs1->hotplug_detect.b.sts) ? "in" : "out");
+ DPRINT("plug in enable %d, status %d\n",
+ hdmi_regs1->hotplug_detect.b.in_enable,
+ hdmi_regs1->hotplug_detect.b.in_sts);
+ DPRINT("plug out enable %d, status %d\n",
+ hdmi_regs1->hotplug_detect.b.out_enable,
+ hdmi_regs1->hotplug_detect.b.out_sts);
+ DPRINT("debounce detect %d,sample %d\n",
+ hdmi_regs1->hotplug_debounce.b.detect,
+ hdmi_regs1->hotplug_debounce.b.sample);
+
+ DPRINT("---------- I2C ----------\n");
+ DPRINT("enable %d,exit FSM %d,key read %d\n",
+ hdmi_regs1->ctrl.b.i2c_enable,
+ hdmi_regs1->i2c_ctrl.b.force_exit_fsm,
+ hdmi_regs1->i2c_ctrl.b.key_read_word);
+ DPRINT("clk divid %d,rd data 0x%x,wr data 0x%x\n",
+ hdmi_regs1->i2c_ctrl.b.i2c_clk_divider,
+ hdmi_regs1->i2c_ctrl2.b.rd_data,
+ hdmi_regs1->i2c_ctrl2.b.wr_data);
+ DPRINT("start %d,stop %d,wr avail %d\n",
+ hdmi_regs1->i2c_ctrl2.b.sw_start_req,
+ hdmi_regs1->i2c_ctrl2.b.sw_stop_req,
+ hdmi_regs1->i2c_ctrl2.b.wr_data_avail);
+ DPRINT("status %d,sw read %d,sw i2c req %d\n",
+ hdmi_regs1->i2c_ctrl2.b.i2c_status,
+ hdmi_regs1->i2c_ctrl2.b.sw_read,
+ hdmi_regs1->i2c_ctrl2.b.sw_i2c_req);
+
+ DPRINT("---------- AUDIO ----------\n");
+ DPRINT("enable %d,sub pck %d,spflat %d\n",
+ hdmi_regs1->aud_enable,
+ hdmi_regs1->aud_mode.b.sub_packet,
+ hdmi_regs1->aud_mode.b.spflat);
+ DPRINT("aud pck insert reset %d,enable %d,delay %d\n",
+ hdmi_regs1->aud_insert_ctrl.b.pck_insert_reset,
+ hdmi_regs1->aud_insert_ctrl.b.pck_insert_enable,
+ hdmi_regs1->aud_insert_ctrl.b.insert_delay);
+ DPRINT("avmute set %d,clr %d,pixel repete %d\n",
+ hdmi_regs1->aud_insert_ctrl.b.avmute_set_enable,
+ hdmi_regs1->aud_insert_ctrl.b.avmute_clr_enable,
+ hdmi_regs1->aud_insert_ctrl.b.pixel_repetition);
+ DPRINT("acr ratio %d,acr enable %d,mute %d\n",
+ hdmi_regs1->aud_ratio.b.acr_ratio,
+ hdmi_regs1->aud_ratio.b.acr_enable,
+ hdmi_regs1->aud_ratio.b.mute);
+ DPRINT("layout %d,pwr save %d,n 20bits %d\n",
+ hdmi_regs1->aud_mode.b.layout,
+ hdmi_regs1->aud_mode.b.pwr_saving,
+ hdmi_regs1->aud_sample_rate1.b.n_20bits);
+ DPRINT("cts low 12 %d,hi 8 %d,cts sel %d\n",
+ hdmi_regs1->aud_sample_rate1.b.cts_low_12bits,
+ hdmi_regs1->aud_sample_rate2.b.cts_hi_8bits,
+ hdmi_regs1->aud_sample_rate2.b.cts_select);
+ DPRINT("aipclk rate %d\n", hdmi_regs1->aud_sample_rate2.b.aipclk_rate);
+
+ DPRINT("---------- INFOFRAME ----------\n");
+ DPRINT("sel %d,hor blank pck %d\n",
+ hdmi_regs1->infoframe_ctrl.b.select,
+ hdmi_regs1->infoframe_ctrl.b.horiz_blank_max_pck);
+ DPRINT("fifo1 ready %d,addr 0x%x,len %d\n",
+ hdmi_regs1->infoframe_ctrl.b.fifo1_rdy,
+ hdmi_regs1->infoframe_ctrl.b.fifo1_addr,
+ hdmi_regs1->infoframe_ctrl.b.fifo1_len);
+ DPRINT("fifo2 ready %d,addr 0x%x,len %d\n",
+ hdmi_regs1->infoframe_ctrl.b.fifo2_rdy,
+ hdmi_regs1->infoframe_ctrl.b.fifo2_addr,
+ hdmi_regs1->infoframe_ctrl.b.fifo2_len);
+ DPRINT("wr strobe %d,rd strobe %d,fifo addr %d\n",
+ hdmi_regs1->fifo_ctrl.b.wr_strobe,
+ hdmi_regs1->fifo_ctrl.b.rd_strobe,
+ hdmi_regs1->fifo_ctrl.b.addr);
+
+ {
+ int i;
+ unsigned int buf[32];
+
+ for (i = 0; i <= hdmi_regs1->infoframe_ctrl.b.fifo1_len; i++) {
+ DPRINT("----- infoframe %d -----\n", i);
+ hdmi_read_fifo(i, buf, 32);
+ vpp_reg_dump((unsigned int) buf, 32);
+ }
+ }
+
+ DPRINT("---------- HDMI test ----------\n");
+ DPRINT("ch0 enable %d, data 0x%x\n",
+ hdmi_regs1->channel_test.b.ch0_enable,
+ hdmi_regs1->channel_test.b.ch0_data);
+ DPRINT("ch1 enable %d, data 0x%x\n",
+ hdmi_regs1->channel_test.b.ch1_enable,
+ hdmi_regs1->channel_test.b.ch1_data);
+ DPRINT("ch2 enable %d, data 0x%x\n",
+ hdmi_regs1->hotplug_detect.b.ch2_enable,
+ hdmi_regs1->hotplug_detect.b.ch2_data);
+ if (hdmi_cp)
+ hdmi_cp->dump();
+}
+
+#ifdef CONFIG_PM
+static unsigned int *hdmi_pm_bk;
+static unsigned int *hdmi_pm_bk2;
+static unsigned int hdmi_pm_enable;
+static unsigned int hdmi_pm_enable2;
+static int hdmi_plug_enable = 0xFF;
+static int hdmi_resume_plug_cnt;
+#define HDMI_RESUME_PLUG_MS 50
+#define HDMI_RESUME_PLUG_CNT 20
+static void hdmi_do_resume_plug(struct work_struct *ptr)
+{
+ struct vout_t *vo;
+ int plugin;
+ struct delayed_work *dwork = to_delayed_work(ptr);
+
+ plugin = hdmi_check_plugin(0);
+ vo = vout_get_entry(VPP_VOUT_NUM_HDMI);
+ vout_change_status(vo, VPP_VOUT_STS_PLUGIN, plugin);
+ if (plugin)
+ hdmi_hotplug_notify(1);
+ hdmi_resume_plug_cnt--;
+ if (hdmi_resume_plug_cnt && (vpp_sdev.state == 0))
+ schedule_delayed_work(dwork,
+ msecs_to_jiffies(HDMI_RESUME_PLUG_MS));
+}
+
+DECLARE_DELAYED_WORK(hdmi_resume_work, hdmi_do_resume_plug);
+
+void hdmi_suspend(int sts)
+{
+ vo_hdmi_set_clock(1);
+ switch (sts) {
+ case 0: /* disable module */
+ cancel_delayed_work_sync(&hdmi_resume_work);
+ hdmi_pm_enable = hdmi_regs1->general_ctrl.b.enable;
+ hdmi_regs1->general_ctrl.b.enable = 0;
+ hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for wr only */
+ hdmi_pm_enable2 = hdmi_regs1->ctrl.b.hden;
+ hdmi_regs1->ctrl.b.hden = 0;
+ if (hdmi_plug_enable == 0xFF)
+ hdmi_plug_enable =
+ hdmi_regs1->hotplug_detect.b.out_enable;
+ hdmi_enable_plugin(0);
+ break;
+ case 1: /* disable tg */
+ break;
+ case 2: /* backup register */
+ hdmi_pm_bk = vpp_backup_reg(REG_HDMI_BEGIN,
+ (REG_HDMI_END - REG_HDMI_BEGIN));
+ hdmi_pm_bk2 = vpp_backup_reg(REG_HDMI2_BEGIN,
+ (REG_HDMI2_END - REG_HDMI2_BEGIN));
+ hdmi_resume_plug_cnt = 20;
+ break;
+ default:
+ break;
+ }
+ vo_hdmi_set_clock(0);
+}
+
+void hdmi_resume(int sts)
+{
+ vo_hdmi_set_clock(1);
+ switch (sts) {
+ case 0: /* restore register */
+ switch_set_state(&vpp_sdev, 0);
+ vpp_restore_reg(REG_HDMI_BEGIN,
+ (REG_HDMI_END - REG_HDMI_BEGIN), hdmi_pm_bk);
+ vpp_restore_reg(REG_HDMI2_BEGIN,
+ (REG_HDMI2_END - REG_HDMI2_BEGIN), hdmi_pm_bk2);
+ hdmi_pm_bk = 0;
+ hdmi_pm_bk2 = 0;
+ hdmi_config(&hdmi_info); /* re-config HDMI info frame */
+ if (g_vpp.hdmi_cp_p && hdmi_cp)
+ hdmi_cp->init();
+ break;
+ case 1: /* enable module */
+ hdmi_regs1->general_ctrl.b.enable = hdmi_pm_enable;
+ hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for wr only */
+ hdmi_regs1->ctrl.b.hden = hdmi_pm_enable2;
+ break;
+ case 2: /* enable tg */
+ hdmi_check_plugin(0);
+ hdmi_clear_plug_status();
+ hdmi_enable_plugin(hdmi_plug_enable);
+ hdmi_plug_enable = 0xFF;
+ if (vpp_sdev.state == 0) {
+ hdmi_resume_plug_cnt = HDMI_RESUME_PLUG_CNT;
+ schedule_delayed_work(&hdmi_resume_work,
+ msecs_to_jiffies(HDMI_RESUME_PLUG_MS));
+ }
+ break;
+ default:
+ break;
+ }
+ vo_hdmi_set_clock(0);
+}
+#else
+#define hdmi_suspend NULL
+#define hdmi_resume NULL
+#endif
+
+void hdmi_init(void)
+{
+ struct fb_videomode vmode;
+
+ g_vpp.hdmi_pixel_clock = vpp_get_base_clock(VPP_MOD_GOVRH);
+ g_vpp.hdmi_i2c_freq = HDMI_I2C_FREQ;
+ g_vpp.hdmi_i2c_udelay = 0;
+ g_vpp.hdmi_ctrl = 0x1000000;
+ g_vpp.hdmi_audio_pb4 = 0x0;
+ g_vpp.hdmi_audio_pb1 = 0x0;
+
+ hdmi_info.outfmt = hdmi_get_output_colfmt();
+ govrh_get_videomode(p_govrh, &vmode);
+ hdmi_info.vic = hdmi_get_vic(vmode.xres, vmode.yres, vmode.refresh,
+ (vmode.vmode & FB_VMODE_INTERLACED) ? 1 : 0);
+ hdmi_info.channel = 2;
+ hdmi_info.freq = 48000;
+ hdmi_info.option = EDID_OPT_AUDIO + EDID_OPT_HDMI;
+
+ hdmi_enable_plugin(0);
+
+ if (g_vpp.govrh_preinit) {
+ DBGMSG("[HDMI] hdmi_init for uboot logo\n");
+ } else {
+ /* bit8-HDMI SDA,bit9-HDMI SCL,bit10-Hotplug,bit26-CEC */
+ /* GPIO disable GPIO function */
+ vppif_reg32_write(GPIO_BASE_ADDR+0x54, 0x4000700, 0, 0);
+ /* GPIO4 disable GPIO out */
+ vppif_reg32_write(GPIO_BASE_ADDR+0x494, 0x4000700, 0, 0);
+#if 0
+ /* Suspend GPIO output enable */
+ vppif_reg32_write(GPIO_BASE_ADDR+0x80, BIT23, 23, 1);
+ /* Suspend GPIO output high */
+ vppif_reg32_write(GPIO_BASE_ADDR+0xC0, BIT23, 23, 1);
+ /* Wake3 disable pull ctrl */
+ vppif_reg32_write(GPIO_BASE_ADDR+0x480, BIT19, 19, 0);
+#endif
+ hdmi_regs2->level.b.level = 1;
+ hdmi_regs2->level.b.update = 1;
+ hdmi_regs2->igs.b.ldi_shift_left = 1;
+ hdmi_regs2->status.val = 0x0008c000;
+ hdmi_regs2->test.val = 0x00450409;
+ hdmi_regs2->test2.val = 0x00005022;
+ hdmi_regs2->test3 = (g_vpp.hdmi_sp_mode) ?
+ 0x00010100 : 0x00000100;
+ hdmi_set_enable(VPP_FLAG_DISABLE);
+ hdmi_set_dvi_enable(VPP_FLAG_DISABLE);
+ hdmi_regs1->ctrl.b.cipher_1_1 = 0;
+
+ hdmi_regs1->tmds_ctrl.b.infoframe_sram_enable = 1;
+ hdmi_regs1->infoframe_ctrl.b.select = 0;
+ hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 0;
+
+ hdmi_regs1->hotplug_detect.val = 0x0;
+ hdmi_regs1->channel_test.val = 0x1;
+
+ hdmi_DDC_reset();
+ hdmi_DDC_set_freq(g_vpp.hdmi_i2c_freq);
+ hdmi_regs1->ctrl.b.i2c_enable = 1;
+ }
+ g_vpp.hdmi_init = 1;
+ if (hdmi_cp)
+ hdmi_cp->init();
+}
+#endif /* WMT_FTBLK_HDMI */
diff --git a/common/wmt_display/hdmi.h b/common/wmt_display/hdmi.h
new file mode 100755
index 0000000..13c8094
--- /dev/null
+++ b/common/wmt_display/hdmi.h
@@ -0,0 +1,352 @@
+/*++
+ * linux/drivers/video/wmt/hdmi.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef HDMI_H
+/* To assert that only one occurrence is included */
+#define HDMI_H
+/*-------------------- MODULE DEPENDENCY -------------------------------------*/
+#include "vpp.h"
+
+/* following is the C++ header */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------- EXPORTED PRIVATE CONSTANTS ----------------------------*/
+/* #define HDMI_XXXX 1 *//*Example*/
+#define CONFIG_HDMI_INTERRUPT
+#define HDMI_PLUG_DELAY 300 /* plug stable delay ms */
+#define HDMI_CP_TIME 3 /* should more than 2 seconds */
+
+enum hdmi_packet_type_t {
+ HDMI_PACKET_NULL = 0x0,
+ HDMI_PACKET_AUD_CLOCK_REGEN = 0x1,
+ HDMI_PACKET_AUD_SAMPLE = 0x2,
+ HDMI_PACKET_GENERAL_CTRL = 0x3,
+ HDMI_PACKET_ACP = 0x4,
+ HDMI_PACKET_ISRC1 = 0x5,
+ HDMI_PACKET_ISRC2 = 0x6,
+ HDMI_PACKET_AUD_ONE_BIT_SAMPLE = 0x7,
+ HDMI_PACKET_AUD_DST = 0x8,
+ HDMI_PACKET_AUD_HBR = 0x9,
+ HDMI_PACKET_GAMUT_METADATA = 0xA,
+ HDMI_PACKET_INFOFRAME_VENDOR = 0x81,
+ HDMI_PACKET_INFOFRAME_AVI = 0x82,
+ HDMI_PACKET_INFOFRAME_SRC_PRODUCT_DESC = 0x83,
+ HDMI_PACKET_INFOFRAME_AUDIO = 0x84,
+ HDMI_PACKET_INFOFRAME_MPEG_SOURCE = 0x85
+};
+
+/* color depth (CD field) */
+#define HDMI_COLOR_DEPTH_24 0x4
+#define HDMI_COLOR_DEPTH_30 0x5
+#define HDMI_COLOR_DEPTH_36 0x6
+#define HDMI_COLOR_DEPTH_48 0x7
+
+/* pixel packing phase (PP field) */
+#define HDMI_PHASE_4 0x0
+#define HDMI_PHASE_1 0x1
+#define HDMI_PHASE_2 0x2
+#define HDMI_PHASE_3 0x3
+
+/* Scan Information (AVI InfoFrame S0/S1) */
+#define HDMI_SI_NO_DATA 0x0
+#define HDMI_SI_OVERSCAN 0x1
+#define HDMI_SI_UNDERSCAN 0x2
+
+/* Bar Info (AVI InfoFrame B0/B1) */
+#define HDMI_BI_DATA_NOT_VALID 0x0
+#define HDMI_BI_VERT_VALID 0x1
+#define HDMI_BI_HORIZ_VALID 0x2
+#define HDMI_BI_V_H_VALID 0x3
+
+/* Active Format Information Present (AVI InfoFrame A0) */
+#define HDMI_AF_INFO_NO_DATA 0x0
+#define HDMI_AF_INFO_PRESENT 0x1
+
+/* RGB or YCbCr (AVI InfoFrame Y0/Y1) */
+#define HDMI_OUTPUT_RGB 0x0
+#define HDMI_OUTPUT_YUV422 0x1
+#define HDMI_OUTPUT_YUV444 0x2
+
+/* Aspect Ratio (AVI InfoFrame R0/R1/R2/R3) */
+#define HDMI_ASPECT_RATIO_PIC 0x8
+#define HDMI_ASPECT_RATIO_4_3 0x9
+#define HDMI_ASPECT_RATIO_16_9 0xA
+#define HDMI_ASPECT_RATIO_14_9 0xB
+
+/* Picture Aspect Ratio (AVI InfoFrame M0/M1) */
+#define HDMI_PIC_ASPECT_NO_DATA 0x0
+#define HDMI_PIC_ASPECT_4_3 0x1
+#define HDMI_PIC_ASPECT_16_9 0x2
+
+/* Colorimetry (AVI InfoFrame C0/C1) */
+#define HDMI_COLORIMETRY_NO 0x0
+#define HDMI_COLORIMETRY_ITU601 0x1
+#define HDMI_COLORIMETRY_ITU709 0x2
+
+/* Non-uniform Picture Scaling (AVI InfoFrame SC0/SC1) */
+#define HDMI_NUSCALE_NO 0x0
+#define HDMI_NUSCALE_HOR 0x1
+#define HDMI_NUSCALE_VERT 0x2
+#define HDMI_NUSCALE_HOR_VERT 0x3
+
+/* Pixel Repetition (AVI InfoFrame PR0/PR1/PR2/PR3) */
+#define HDMI_PIXEL_REP_NO 0x0
+#define HDMI_PIXEL_REP_2 0x1
+#define HDMI_PIXEL_REP_3 0x2
+#define HDMI_PIXEL_REP_4 0x3
+#define HDMI_PIXEL_REP_5 0x4
+#define HDMI_PIXEL_REP_6 0x5
+#define HDMI_PIXEL_REP_7 0x6
+#define HDMI_PIXEL_REP_8 0x7
+#define HDMI_PIXEL_REP_9 0x8
+#define HDMI_PIXEL_REP_10 0x9
+
+/* Video Code */
+enum hdmi_video_code_t {
+ HDMI_UNKNOW = 0,
+ HDMI_640x480p60_4x3,
+ HDMI_720x480p60_4x3,
+ HDMI_720x480p60_16x9,
+ HDMI_1280x720p60_16x9,
+ HDMI_1920x1080i60_16x9,
+ HDMI_1440x480i60_4x3,
+ HDMI_1440x480i60_16x9,
+ HDMI_1440x240p60_4x3,
+ HDMI_1440x240p60_16x9,
+ HDMI_2880x480i60_4x3, /* 10 */
+ HDMI_2880x480i60_16x9,
+ HDMI_2880x240p60_4x3,
+ HDMI_2880x240p60_16x9,
+ HDMI_1440x480p60_4x3,
+ HDMI_1440x480p60_16x9,
+ HDMI_1920x1080p60_16x9,
+ HDMI_720x576p50_4x3,
+ HDMI_720x576p50_16x9,
+ HDMI_1280x720p50_16x9,
+ HDMI_1920x1080i50_16x9, /* 20 */
+ HDMI_1440x576i50_4x3,
+ HDMI_1440x576i50_16x9,
+ HDMI_1440x288p50_4x3,
+ HDMI_1440x288p50_16x9,
+ HDMI_2880x576i50_4x3,
+ HDMI_2880x576i50_16x9,
+ HDMI_2880x288p50_4x3,
+ HDMI_2880x288p50_16x9,
+ HDMI_1440x576p50_4x3,
+ HDMI_1440x576p50_16x9, /* 30 */
+ HDMI_1920x1080p50_16x9,
+ HDMI_1920x1080p24_16x9,
+ HDMI_1920x1080p25_16x9,
+ HDMI_1920x1080p30_16x9,
+ HDMI_VIDEO_CODE_MAX
+};
+
+/* Audio Channel Count (Audio InfoFrame CC0/CC1/CC2) */
+enum hdmi_audio_channel_count_t {
+ HDMI_AUD_CHAN_REF_STM = 0,
+ HDMI_AUD_CHAN_2CH,
+ HDMI_AUD_CHAN_3CH,
+ HDMI_AUD_CHAN_4CH,
+ HDMI_AUD_CHAN_5CH,
+ HDMI_AUD_CHAN_6CH,
+ HDMI_AUD_CHAN_7CH,
+ HDMI_AUD_CHAN_8CH
+};
+
+/* Audio Coding type (Audio InfoFrame CT0/CT1/CT2/CT3) */
+#define HDMI_AUD_TYPE_REF_STM 0x0
+#define HDMI_AUD_TYPE_PCM 0x1
+#define HDMI_AUD_TYPE_AC3 0x2
+#define HDMI_AUD_TYPE_MPEG1 0x3
+#define HDMI_AUD_TYPE_MP3 0x4
+#define HDMI_AUD_TYPE_MPEG2 0x5
+#define HDMI_AUD_TYPE_AAC 0x6
+#define HDMI_AUD_TYPE_DTS 0x7
+#define HDMI_AUD_TYPE_ATRAC 0x8
+
+/* Audio Sample size (Audio InfoFrame SS0/SS1) */
+#define HDMI_AUD_SAMPLE_REF_STM 0x0
+#define HDMI_AUD_SAMPLE_16 0x1
+#define HDMI_AUD_SAMPLE_20 0x2
+#define HDMI_AUD_SAMPLE_24 0x3
+
+/* Audio Sample frequency (Audio InfoFrame SF0/SF1/SF2) */
+#define HDMI_AUD_FREQ_REF_STM 0x0
+#define HDMI_AUD_FREQ_32K 0x1
+#define HDMI_AUD_FREQ_44_1K 0x2
+#define HDMI_AUD_FREQ_48K 0x3
+#define HDMI_AUD_FREQ_88_2K 0x4
+#define HDMI_AUD_FREQ_96K 0x5
+#define HDMI_AUD_FREQ_176_4K 0x6
+#define HDMI_AUD_FREQ_192K 0x7
+
+/* 3D_Structure */
+#define HDMI_3D_STRUCTURE_FRAME_PACKING 0x0
+#define HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE 0x1
+#define HDMI_3D_STRUCTURE_LINE_ALTERNATIVE 0x2
+#define HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL 0x3
+#define HDMI_3D_STRUCTURE_L_DEPTH 0x4
+#define HDMI_3D_STRUCTURE_L_DEP_GRA_GDEP 0x5
+#define HDMI_3D_STRUCTURE_TOP_AND_BOTTOM 0x6
+#define HDMI_3D_STRUCTURE_SIZE_BY_SIZE_HALF 0x8
+
+/*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/
+/* typedef void hdmi_xxx_t; *//*Example*/
+struct hdmi_info_t {
+ /* video */
+ vdo_color_fmt outfmt;
+ int vic;
+
+ /* audio */
+ int channel;
+ int freq;
+
+ /* option */
+ int option;
+
+};
+
+#define HDMI_VIC_INTERLACE BIT(0)
+#define HDMI_VIC_PROGRESS 0
+#define HDMI_VIC_4x3 BIT(1)
+#define HDMI_VIC_16x9 0
+
+struct hdmi_vic_t {
+ unsigned short resx;
+ unsigned short resy;
+ char freq;
+ char option;
+};
+
+struct hdmi_cp_t {
+ void (*init)(void);
+ void (*enable)(int on);
+ int (*poll)(void);
+ void (*dump)(void);
+ int (*interrupt)(void);
+ void (*get_bksv)(unsigned int *bksv);
+};
+
+/*-------------------- EXPORTED PRIVATE VARIABLES ---------------------------*/
+#ifdef VPP_C
+#define EXTERN
+
+const struct hdmi_vic_t hdmi_vic_info[HDMI_VIDEO_CODE_MAX] = {
+ { 0, 0, 0, 0 }, /* HDMI_UNKNOW = 0 */
+ { 640, 480, 60, HDMI_VIC_4x3 }, /* HDMI_640x480p60_4x3 */
+ { 720, 480, 60, HDMI_VIC_4x3 }, /* HDMI_720x480p60_4x3 */
+ { 720, 480, 60, 0 }, /* HDMI_720x480p60_16x9 */
+ { 1280, 720, 60, 0 }, /* HDMI_1280x720p60_16x9 */
+ { 1920, 1080, 60, HDMI_VIC_INTERLACE }, /* HDMI_1920x1080i60_16x9 */
+ { 720, 480, 60, HDMI_VIC_4x3 | HDMI_VIC_INTERLACE }, /*1440x480i60_4x3*/
+ { 720, 480, 60, HDMI_VIC_INTERLACE }, /* HDMI_1440x480i60_16x9 */
+ { 720, 240, 60, HDMI_VIC_4x3 }, /* HDMI_1440x240p60_4x3 */
+ { 720, 240, 60, 0 }, /* HDMI_1440x240p60_16x9 */
+ { 2880, 480, 60, HDMI_VIC_4x3 | HDMI_VIC_INTERLACE },/*2880x480i60_4x3*/
+ { 2880, 480, 60, HDMI_VIC_INTERLACE }, /* HDMI_2880x480i60_16x9 */
+ { 2880, 240, 60, HDMI_VIC_4x3 }, /* HDMI_2880x240p60_4x3 */
+ { 2880, 240, 60, 0 }, /* HDMI_2880x240p60_16x9 */
+ { 1440, 480, 60, HDMI_VIC_4x3 }, /* HDMI_1440x480p60_4x3 */
+ { 1440, 480, 60, 0 }, /* HDMI_1440x480p60_16x9 */
+ { 1920, 1080, 60, 0 }, /* HDMI_1920x1080p60_16x9 */
+ { 720, 576, 50, HDMI_VIC_4x3 }, /* HDMI_720x576p50_4x3 */
+ { 720, 576, 50, 0 }, /* HDMI_720x576p50_16x9 */
+ { 1280, 720, 50, 0 }, /* HDMI_1280x720p50_16x9 */
+ { 1920, 1080, 50, HDMI_VIC_INTERLACE }, /* HDMI_1920x1080i50_16x9, 20 */
+ { 720, 576, 50, HDMI_VIC_INTERLACE | HDMI_VIC_4x3 }, /*1440x576i50_4x3*/
+ { 720, 576, 50, HDMI_VIC_INTERLACE }, /* HDMI_1440x576i50_16x9 */
+ { 720, 288, 50, HDMI_VIC_4x3 }, /* HDMI_1440x288p50_4x3 */
+ { 720, 288, 50, 0 }, /* HDMI_1440x288p50_16x9 */
+ { 2880, 576, 50, HDMI_VIC_INTERLACE | HDMI_VIC_4x3}, /*2880x576i50_4x3*/
+ { 2880, 576, 50, HDMI_VIC_INTERLACE }, /* HDMI_2880x576i50_16x9 */
+ { 2880, 288, 50, HDMI_VIC_4x3 }, /* HDMI_2880x288p50_4x3 */
+ { 2880, 288, 50, 0 }, /* HDMI_2880x288p50_16x9 */
+ { 1440, 576, 50, HDMI_VIC_4x3 }, /* HDMI_1440x576p50_4x3 */
+ { 1440, 576, 50, 0 }, /* HDMI_1440x576p50_16x9, // 30 */
+ { 1920, 1080, 50, 0 }, /* HDMI_1920x1080p50_16x9 */
+ { 1920, 1080, 24, 0 }, /* HDMI_1920x1080p24_16x9 */
+ { 1920, 1080, 25, 0 }, /* HDMI_1920x1080p25_16x9 */
+ { 1920, 1080, 30, 0 } /* HDMI_1920x1080p30_16x9 */
+};
+#else
+#define EXTERN extern
+
+EXTERN const struct hdmi_vic_t hdmi_vic_info[HDMI_VIDEO_CODE_MAX];
+#endif /* ifdef HDMI_C */
+
+EXTERN struct hdmi_cp_t *hdmi_cp;
+EXTERN int hdmi_ri_tm_cnt;
+EXTERN struct hdmi_info_t hdmi_info;
+
+#ifdef VPP_C
+EXPORT_SYMBOL(hdmi_cp);
+EXPORT_SYMBOL(hdmi_ri_tm_cnt);
+EXPORT_SYMBOL(hdmi_regs1);
+EXPORT_SYMBOL(hdmi_regs2);
+#endif
+
+/* EXTERN int hdmi_xxx; *//*Example*/
+#undef EXTERN
+
+/*--------------------- EXPORTED PRIVATE MACROS -----------------------------*/
+/* #define HDMI_XXX_YYY xxxx *//*Example*/
+/*--------------------- EXPORTED PRIVATE FUNCTIONS -------------------------*/
+/* extern void hdmi_xxx(void); *//*Example*/
+
+void hdmi_init(void);
+void hdmi_reg_dump(void);
+void hdmi_audio_enable(vpp_flag_t enable);
+void hdmi_audio_mute(vpp_flag_t enable);
+void hdmi_set_enable(vpp_flag_t enable);
+void hdmi_set_avmute(vpp_flag_t mute);
+void hdmi_set_dvi_enable(vpp_flag_t enable);
+void hdmi_set_cp_enable(vpp_flag_t enable);
+int hdmi_check_cp_int(void);
+void hdmi_config(struct hdmi_info_t *info);
+int hdmi_DDC_read(char addr, int index, char *buf, int length);
+int hdmi_get_plugin(void);
+int hdmi_get_plug_status(void);
+void hdmi_clear_plug_status(void);
+void hdmi_suspend(int sts);
+void hdmi_resume(int sts);
+void hdmi_set_power_down(int pwrdn);
+void hdmi_enable_plugin(int enable);
+vdo_color_fmt hdmi_get_output_colfmt(void);
+void hdmi_set_sync_low_active(vpp_flag_t hsync, vpp_flag_t vsync);
+void hdmi_get_sync_polar(int *hsync_hi, int *vsync_hi);
+int hdmi_check_plugin(int hotplug);
+void hdmi_set_cypher(int func);
+void hdmi_set_option(unsigned int option);
+void hdmi_get_bksv(unsigned int *bksv);
+int hdmi_check_cp_dev_cnt(void);
+void hdmi_hotplug_notify(int plug_status);
+void hdmi_tx_vendor_specific_infoframe_packet(void);
+int hdmi_get_vic(int resx, int resy, int fps, int interlace);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ifndef HDMI_H */
+
diff --git a/common/wmt_display/hw/wmt-govrh-reg.h b/common/wmt_display/hw/wmt-govrh-reg.h
new file mode 100755
index 0000000..ecdeb4f
--- /dev/null
+++ b/common/wmt_display/hw/wmt-govrh-reg.h
@@ -0,0 +1,366 @@
+/*++
+ * linux/drivers/video/wmt/hw/wmt-govrh-reg.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef WMT_GOVRH_REG_H
+#define WMT_GOVRH_REG_H
+
+/* feature */
+#define WMT_FTBLK_GOVRH
+#ifndef CONFIG_UBOOT
+#define WMT_FTBLK_GOVRH_CURSOR
+#endif
+#define WMT_FTBLK_GOVRH2
+
+#define GOVRH_FRAMEBUF_ALIGN 128
+
+struct govrh_regs {
+ /* base1 */
+ unsigned int cur_addr; /* 0x00 */
+ unsigned int cur_width;
+ unsigned int cur_fb_width;
+ unsigned int cur_vcrop;
+ unsigned int cur_hcrop; /* 0x10 */
+ union {
+ unsigned int val;
+ struct {
+ unsigned int start:11;
+ unsigned int reserved:5;
+ unsigned int end:11;
+ } b;
+ } cur_hcoord; /* 0x14 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int start:11;
+ unsigned int reserved:5;
+ unsigned int end:11;
+ } b;
+ } cur_vcoord; /* 0x18 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int enable:1;
+ unsigned int reserved:7;
+ unsigned int out_field:1; /* 0:frame,1-field */
+ } b;
+ } cur_status; /* 0x1C */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int colkey:24;
+ unsigned int enable:1;
+ unsigned int invert:1;
+ unsigned int reserved:2;
+ unsigned int alpha:1;
+ } b;
+ } cur_color_key; /* 0x20 */
+
+ unsigned int reserved[3];
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int rgb:1;
+ unsigned int yuv422:1;
+ } b;
+ } dvo_pix; /* 0x30 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int delay:14;
+ unsigned int inv:1;
+ } b;
+ } dvo_dly_sel; /* 0x34 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int cur_enable:1;
+ unsigned int mem_enable:1;
+ unsigned int reserved:7;
+ unsigned int err_sts:1;
+ unsigned int reserved2:6;
+ unsigned int cur_sts:1;
+ unsigned int mem_sts:1;
+ } b;
+ } interrupt; /* 0x38 */
+
+ unsigned int dvo_blank_data;
+ unsigned int dirpath; /* 0x40 */
+ union {
+ unsigned int val;
+ struct {
+ unsigned int v:8;
+ unsigned int u:8;
+ unsigned int y:8;
+ } b;
+ } saturation; /* 0x44 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int enable:1;
+ unsigned int format:1; /* 0:YCbCr, 1:RGB */
+ } b;
+ } saturation_enable; /* 0x48 */
+
+ unsigned int reserved2[13];
+ union {
+ unsigned int val;
+ struct {
+ unsigned int enable:1;
+ unsigned int reserved:7;
+ unsigned int h264:1;
+ } b;
+ } mif; /* 0x80 */
+
+ unsigned int colfmt; /* 0x84, 0:422,1:420 */
+ unsigned int srcfmt; /* 0x88, 0:frame,1:field */
+ unsigned int dstfmt; /* 0x8C, 0:frame,1:field */
+ unsigned int ysa; /* 0x90 */
+ unsigned int csa;
+ unsigned int pixwid;
+ unsigned int bufwid;
+ unsigned int vcrop; /* 0xA0 */
+ unsigned int hcrop;
+ unsigned int fhi;
+ unsigned int colfmt2; /* 0xAC, 1-444,other refer 0x84 */
+ unsigned int ysa2; /* 0xB0 */
+ unsigned int csa2;
+ union {
+ unsigned int val;
+ struct {
+ unsigned int req_num:8; /* Y & RGB */
+ unsigned int req_num_c:8; /* C */
+ unsigned int frame_enable:1;
+ } b;
+ } mif_frame_mode; /* 0xB8 */
+
+ unsigned int reserved3[10];
+ union {
+ unsigned int val;
+ struct {
+ unsigned int update:1;
+ unsigned int reserved:7;
+ unsigned int level:1; /* 0:level 1, 1:level2 */
+ } b;
+ } sts; /* 0xE4 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int fixed:1; /* 0-top, 1-bottom */
+ unsigned int enable:1;
+ } b;
+ } swfld; /* 0xE8 */
+
+ unsigned int reserved4[5];
+ /* base2 */
+ union {
+ unsigned int val;
+ struct {
+ unsigned int enable:1;
+ unsigned int reserved:7;
+ unsigned int mode:1; /* 0-frame,1-field */
+ } b;
+ } tg_enable; /* 0x100 */
+
+ unsigned int read_cyc;
+ unsigned int h_allpxl;
+ unsigned int v_allln;
+ unsigned int actln_bg; /* 0x110 */
+ unsigned int actln_end;
+ unsigned int actpx_bg;
+ unsigned int actpx_end;
+ unsigned int vbie_line; /* 0x120 */
+ unsigned int pvbi_line;
+ unsigned int hdmi_vbisw;
+ unsigned int hdmi_hsynw;
+ union {
+ unsigned int val;
+ struct {
+ unsigned int offset:12;
+ unsigned int reserved:4;
+ unsigned int field_invert:1;
+ } b;
+ } vsync_offset; /* 0x130 */
+
+ unsigned int field_status; /* 0x134, 1-BOTTOM,0-TOP */
+ unsigned int reserved5[1]; /* 0x138 */
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mode:3; /* 011-frame packing progressive
+ format,111-frame packing interlace format */
+ unsigned int inv_filed_polar:1;
+ unsigned int blank_value:16;
+ unsigned int reserved:11;
+ unsigned int addr_sel:1; /* in frame packing
+ interlace mode */
+ } b;
+ } hdmi_3d; /* 0x13C */
+
+ unsigned int reserved5_2[2];
+ union {
+ unsigned int val;
+ struct {
+ unsigned int outwidth:1; /* 0-24bit,1-12bit */
+ unsigned int hsync_polar:1; /* 0-act high,1-act low */
+ unsigned int enable:1;
+ unsigned int vsync_polar:1; /* 0-act high,1-act low */
+ unsigned int reserved:4;
+ unsigned int rgb_swap:2; /* 0-RGB[7:0],1-RGB[0:7],
+ 2-BGR[7:0],3-BGR[0:7] */
+ unsigned int reserved2:6;
+ unsigned int blk_dis:1; /* 0-Blank Data,
+ 1-Embeded sync CCIR656 */
+ } b;
+ } dvo_set; /* 0x148 */
+
+ unsigned int reserved6;
+ union {
+ unsigned int val;
+ struct {
+ unsigned int enable:1;
+ unsigned int reserved1:7;
+ unsigned int mode:1;
+ unsigned int reserved2:7;
+ unsigned int inversion:1;
+ } b;
+ } cb_enable; /* 0x150 */
+
+ unsigned int reserved7;
+ unsigned int h_allpxl2;
+ unsigned int v_allln2;
+ unsigned int actln_bg2; /* 0x160 */
+ unsigned int actln_end2;
+ unsigned int actpx_bg2;
+ unsigned int actpx_end2;
+ unsigned int vbie_line2; /* 0x170 */
+ unsigned int pvbi_line2;
+ unsigned int hdmi_vbisw2;
+ unsigned int hdmi_hsynw2;
+ union {
+ unsigned int val;
+ struct {
+ unsigned int outwidth:1; /* 0-24bit,1-12bit */
+ unsigned int hsync_polar:1; /* 0-act high,1-act low */
+ unsigned int enable:1;
+ unsigned int vsync_polar:1; /* 0-act high,1-act low */
+ } b;
+ } lvds_ctrl; /* 0x180 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int pix:2; /* 0-YUV444,1-RGB,2-YUV422,3-RGB */
+ } b;
+ } lvds_ctrl2; /* 0x184 */
+
+ unsigned int reserved_dac[12];
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int praf:8;
+ unsigned int pbaf:8;
+ unsigned int yaf:8;
+ } b;
+ } contrast; /* 0x1B8 */
+
+ unsigned int brightness;
+ unsigned int dmacsc_coef0; /* 0x1C0 */
+ unsigned int dmacsc_coef1;
+ unsigned int dmacsc_coef2;
+ unsigned int dmacsc_coef3;
+ unsigned int dmacsc_coef4; /* 0x1D0 */
+ unsigned int reserved8;
+ unsigned int dmacsc_coef5;
+ unsigned int dmacsc_coef6;
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mode:1; /* 1: YUV2RGB, 0: RGB2YUV */
+ unsigned int clamp:1; /* 0:Y,1:Y-16 */
+ } b;
+ } csc_mode; /* 0x1E0 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int dvo:1;
+ unsigned int vga:1;
+ unsigned int reserved1:1;
+ unsigned int dac_clkinv:1;
+ unsigned int blank_zero:1;
+ unsigned int disp:1;
+ unsigned int lvds:1;
+ unsigned int hdmi:1;
+ unsigned int rgb_mode:2; /*0-YUV,1-RGB24,2-1555,3-565*/
+ } b;
+ } yuv2rgb; /* 0x1E4 */
+
+ unsigned int h264_input_en; /* 0x1E8 */
+ unsigned int reserved9;
+ unsigned int lvds_clkinv; /* 0x1F0 */
+ unsigned int hscale_up; /* 0x1F4 */
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mode:3; /* 0:888,1:555,2:666,3:565,4:ori */
+ unsigned int reserved:5;
+ unsigned int ldi:1; /* 0:shift right,1:shift left */
+ } b;
+ } igs_mode; /* 0x1F8 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mode:3; /* 0:888,1:555,2:666,3:565,4:ori */
+ unsigned int reserved:5;
+ unsigned int ldi:1; /* 0:shift right,1:shift left */
+ } b;
+ } igs_mode2; /* 0x1FC */
+};
+
+/* GOVRH */
+#define REG_GOVRH_BASE1_BEGIN (GOVRH_BASE1_ADDR+0x00)
+#define REG_GOVRH_YSA (GOVRH_BASE1_ADDR+0x90)
+#define REG_GOVRH_CSA (GOVRH_BASE1_ADDR+0x94)
+#define REG_GOVRH_BASE1_END (GOVRH_BASE1_ADDR+0xe8)
+#define REG_GOVRH_BASE2_BEGIN (GOVRH_BASE2_ADDR+0x00)
+#define REG_GOVRH_BASE2_END (GOVRH_BASE2_ADDR+0xFC)
+
+/* GOVRH2 */
+#define REG_GOVRH2_BASE1_BEGIN (GOVRH2_BASE1_ADDR+0x00)
+#define REG_GOVRH2_YSA (GOVRH2_BASE1_ADDR+0x90)
+#define REG_GOVRH2_CSA (GOVRH2_BASE1_ADDR+0x94)
+#define REG_GOVRH2_BASE1_END (GOVRH2_BASE1_ADDR+0xe8)
+#define REG_GOVRH2_BASE2_BEGIN (GOVRH2_BASE2_ADDR+0x00)
+#define REG_GOVRH2_BASE2_END (GOVRH2_BASE2_ADDR+0xFC)
+
+#endif /* WMT_GOVRH_REG_H */
diff --git a/common/wmt_display/hw/wmt-hdmi-reg.h b/common/wmt_display/hw/wmt-hdmi-reg.h
new file mode 100755
index 0000000..c065055
--- /dev/null
+++ b/common/wmt_display/hw/wmt-hdmi-reg.h
@@ -0,0 +1,379 @@
+/*++
+ * linux/drivers/video/wmt/hw/wmt-hdmi-reg.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef WMT_HDMI_REG_H
+#define WMT_HDMI_REG_H
+
+#define WMT_FTBLK_HDMI
+
+#define HDMI_BASE_ADDR (HDMI_TRANSMITTE_BASE_ADDR + 0xC000)
+
+struct hdmi_base1_regs {
+ unsigned int _100_11c[8];
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int eeprom_reset:1;
+ unsigned int encode_enable:1;
+ unsigned int hden:1;
+ unsigned int eess_enable:1;
+ unsigned int verify_pj_enable:1;
+ unsigned int i2c_enable:1;
+ unsigned int auth_test_key:1;
+ unsigned int _7:1;
+ unsigned int cipher_1_1:1;
+ unsigned int _9_11:3;
+ unsigned int preamble:4;
+ unsigned int _16_19:4;
+ unsigned int encode_window:3;
+ } b;
+ } ctrl; /* 0x120 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int _0_6:7;
+ unsigned int force_exit_fsm:1;
+ unsigned int key_read_word:7;
+ unsigned int i2c_sw_reset:1;
+ unsigned int i2c_clk_divider:16;
+ } b;
+ } i2c_ctrl; /* 0x124 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int wr_data:8;
+ unsigned int rd_data:8;
+ unsigned int sw_start_req:1;
+ unsigned int sw_stop_req:1;
+ unsigned int wr_data_avail:1;
+ unsigned int i2c_status:1; /* 0-not using,1-in using */
+ unsigned int cp_key_req:1;
+ unsigned int cp_key_read:1;
+ unsigned int cp_key_last:1;
+ unsigned int _23:1;
+ unsigned int cp_src_sel:1;
+ unsigned int sw_read:1;
+ unsigned int sw_i2c_req:1;
+ unsigned int ksv_list_avail:1;
+ unsigned int ksv_verify_done:1;
+ } b;
+ } i2c_ctrl2; /* 0x128 */
+
+ unsigned int _12c_27c[85];
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int reset:1;
+ unsigned int enable:1;
+ unsigned int _2_5:4;
+ unsigned int dvi_mode_enable:1;
+ unsigned int output_format:2; /* 0-RGB,
+ 1-YUV444,2-YUV422 */
+ unsigned int convert_yuv422:1;
+ unsigned int hsync_low_active:1; /* 0-active hi,1-lo */
+ unsigned int dbg_bus_select:1; /* 0-before,1-after */
+ unsigned int _12:1;
+ unsigned int vsync_low_active:1; /* 0-active hi,1-lo */
+ unsigned int _14_15:2;
+ unsigned int cp_delay:7;
+ unsigned int _23:1;
+ unsigned int vsync_enable:3; /* write only */
+ unsigned int state_machine_status:5;
+ } b;
+ } general_ctrl; /* 0x280 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int select:1; /* 0-fifo1,1-fifo2 */
+ unsigned int fifo1_rdy:1; /* Info frame FIFO 1 ready */
+ unsigned int fifo2_rdy:1; /* Info frame FIFO 2 ready */
+ unsigned int _3:1;
+ unsigned int fifo1_addr:4; /* FIFO 1 start address */
+ unsigned int fifo1_len:5; /* FIFO 1 length */
+ unsigned int _13_15:3;
+ unsigned int fifo2_addr:4; /* FIFO 2 start address */
+ unsigned int fifo2_len:5; /* FIFO 2 length */
+ unsigned int _25_27:3;
+ unsigned int horiz_blank_max_pck:3; /* Max packets
+ that insert during HSYNC */
+ } b;
+ } infoframe_ctrl; /* 0x284 */
+ unsigned int _288_290[3];
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int pck_insert_reset:1;
+ unsigned int pck_insert_enable:1;
+ unsigned int avmute_set_enable:1;
+ unsigned int avmute_clr_enable:1;
+ unsigned int insert_delay:12;
+ unsigned int _16_29:14;
+ unsigned int pixel_repetition:2; /* 0-none,1-2x,2-4x */
+ } b;
+ } aud_insert_ctrl; /* 0x294 */
+
+ unsigned int _298;
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int _0_7:8;
+ unsigned int acr_ratio:20;
+ unsigned int acr_enable:1;
+ unsigned int mute:1;
+ } b;
+ } aud_ratio; /* 0x29c */
+
+ unsigned int aud_enable; /* 0x2a0 */
+ unsigned int _2a4_2a8[2];
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int sub_packet:4;
+ unsigned int spflat:4;
+ unsigned int _2ch_eco:1;
+ unsigned int _9:1;
+ unsigned int layout:1; /* 0-2 channel,1-8 channel */
+ unsigned int pwr_saving:1; /* 0-normal,1-power saving */
+ } b;
+ } aud_mode; /* 0x2ac */
+
+ unsigned int _2b0_38c[56];
+ unsigned int aud_chan_status0; /* 0x390 */
+ unsigned int aud_chan_status1; /* 0x394 */
+ unsigned int aud_chan_status2; /* 0x398 */
+ unsigned int aud_chan_status3; /* 0x39c */
+ unsigned int aud_chan_status4; /* 0x3a0 */
+ unsigned int aud_chan_status5; /* 0x3a4 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int n_20bits:20;
+ unsigned int cts_low_12bits:12;
+ } b;
+ } aud_sample_rate1; /* 0x3a8 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int cts_hi_8bits:8;
+ unsigned int _8_27:20;
+ unsigned int aipclk_rate:2; /* 0-N/2,1-N,2-N/4,3-N*2 */
+ unsigned int cts_select:1; /* 0-auto,1-fixed from reg */
+ } b;
+ } aud_sample_rate2; /* 0x3ac */
+
+ unsigned int _3b0_3bc[4];
+ unsigned int wr_fifo_addr[9]; /* 0x3c0 - 0x3e0 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int wr_strobe:1;
+ unsigned int rd_strobe:1;
+ unsigned int _2_7:6;
+ unsigned int addr:8;
+ } b;
+ } fifo_ctrl; /* 0x3e4 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int ch0_data:10;
+ unsigned int ch0_enable:1;
+ unsigned int _11_15:5;
+ unsigned int ch1_data:10;
+ unsigned int ch1_enable:1;
+ } b;
+ } channel_test; /* 0x3e8 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int ch2_data:10;
+ unsigned int ch2_enable:1;
+ unsigned int _11_15:5;
+ unsigned int in_enable:1;
+ unsigned int out_enable:1;
+ unsigned int _18_23:6;
+ unsigned int in_sts:1;
+ unsigned int out_sts:1;
+ unsigned int _26_30:5;
+ unsigned int sts:1; /* 0-plug out,1-plug in */
+ } b;
+ } hotplug_detect; /* 0x3ec */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int sample:8;
+ unsigned int _8_15:8;
+ unsigned int detect:9;
+ } b;
+ } hotplug_debounce; /* 0x3f0 */
+
+ unsigned int _3f4;
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int test_enable:1;
+ unsigned int test_format:1;
+ unsigned int _2_9:8;
+ unsigned int infoframe_sram_enable:1;
+ unsigned int _11_15:5;
+ unsigned int clock_select:1; /* 0-clk 1x, 1-clk 2x */
+ } b;
+ } tmds_ctrl; /* 0x3f8 */
+
+ unsigned int _3fc;
+ unsigned int rd_fifo_addr[9]; /* 0x400 - 0x420 */
+};
+
+struct hdmi_base2_regs {
+ union {
+ unsigned int val;
+ struct {
+ unsigned int inv_clk:1;
+ unsigned int _1_3:3;
+ unsigned int dual_channel:1;
+ unsigned int _5_7:3;
+ unsigned int test:4;
+ unsigned int _12_18:7;
+ unsigned int internal_ldo:1;
+ } b;
+ } status; /* 0x00 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int drv_pdmode:1;
+ unsigned int _1:1;
+ unsigned int vbg_sel:2;
+ unsigned int _4_7:4;
+ unsigned int pd:1;
+ unsigned int tre_en:2;
+ unsigned int _11:1;
+ unsigned int pllck_dly:3;
+ unsigned int _15:1;
+ unsigned int pll_cpset:2;
+ unsigned int pll_r_f:1;
+ } b;
+ } test; /* 0x04 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int update:1;
+ unsigned int _1_7:7;
+ unsigned int level:1;
+ } b;
+ } level; /* 0x08 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int bpp_type:3; /* 0-888,1-555,2-666,3-565 */
+ unsigned int _3_7:5;
+ unsigned int ldi_shift_left:1; /* 0-right,1-left */
+ } b;
+ } igs; /* 0x0c */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int out_data_12:1; /* 0-24bit,1-12bit */
+ unsigned int hsync_polar_lo:1; /* 0-act hi,1-act low */
+ unsigned int dvo_enable:1;
+ unsigned int vsync_polar_lo:1; /* 0-act hi,1-act low */
+ } b;
+ } set; /* 0x10 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int colfmt_rgb:1;/* 0-RGB or YUV444,1-YUV422 */
+ unsigned int colfmt_yuv422:1;
+ } b;
+ } set2; /* 0x14 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int pll_ready:1;
+ unsigned int _1_7:7;
+ unsigned int rsen:1;
+ } b;
+ } detect; /* 0x18 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int pll_tsync:1;
+ unsigned int tp2s_type:1;
+ unsigned int div_sel:2;
+ unsigned int pd_v2i:1;
+ unsigned int vco_sx:1;
+ unsigned int vco_mode:1;
+ unsigned int _7:1;
+ unsigned int vsref_sel:2;
+ unsigned int mode:1;
+ unsigned int pd_l2ha:1;
+ unsigned int pd_l2hb:1;
+ unsigned int l2ha_hsen:1;
+ unsigned int resa_en:1;
+ unsigned int resa_s:1;
+ unsigned int pll_lpfs:2;
+ } b;
+ } test2; /* 0x1c */
+
+ unsigned int test3; /* 0x20 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int _0_15:16;
+ unsigned int reset_pll:1;
+ } b;
+ } dftset2; /* 0x24 */
+};
+
+#define REG_HDMI_BEGIN (HDMI_BASE_ADDR + 0x100)
+#define REG_HDMI_END (HDMI_BASE_ADDR + 0x420)
+#define REG_HDMI2_BEGIN (HDMI_BASE2_ADDR + 0x00)
+#define REG_HDMI2_END (HDMI_BASE2_ADDR + 0x28)
+
+#ifndef HDMI_C
+extern HW_REG struct hdmi_base1_regs *hdmi_regs1;
+extern HW_REG struct hdmi_base2_regs *hdmi_regs2;
+#endif
+#endif /* WMT_HDMI_REG_H */
+
diff --git a/common/wmt_display/hw/wmt-lvds-reg.h b/common/wmt_display/hw/wmt-lvds-reg.h
new file mode 100755
index 0000000..0a6e616
--- /dev/null
+++ b/common/wmt_display/hw/wmt-lvds-reg.h
@@ -0,0 +1,129 @@
+/*++
+ * linux/drivers/video/wmt/hw/wmt-lvds-reg.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef WMT_LVDS_REG_H
+#define WMT_LVDS_REG_H
+
+#define WMT_FTBLK_LVDS
+
+struct lvds_base_regs {
+ union {
+ unsigned int val;
+ struct {
+ unsigned int inv_clk:1;
+ unsigned int _01_03:3;
+ unsigned int dual_channel:1;
+ unsigned int _05_07:3;
+ unsigned int test:4;
+ } b;
+ } status; /* 0x00 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int drv_pdmode:1;
+ unsigned int _01:1;
+ unsigned int vbg_sel:2;
+ unsigned int _04_07:4;
+ unsigned int pd:1;
+ unsigned int tre_en:2;
+ unsigned int _11:1;
+ unsigned int pllck_dly:3;
+ unsigned int _15:1;
+ unsigned int pll_cpset:2;
+ unsigned int pll_r_f:1;
+ } b;
+ } test; /* 0x04 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int update:1;
+ unsigned int _01_07:7;
+ unsigned int level:1;
+ } b;
+ } level; /* 0x08 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int bpp_type:3; /* 0-888,1-555,2-666,3-565 */
+ unsigned int _03_07:5;
+ unsigned int ldi_shift_left:1; /* 0-shift right,1-left*/
+ } b;
+ } igs; /* 0x0c */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int out_data_12:1; /* 0-24bit,1-12bit */
+ unsigned int hsync_polar_lo:1; /* 0-active hi,1-low */
+ unsigned int dvo_enable:1;
+ unsigned int vsync_polar_lo:1; /* 0-active hi,1-low */
+ } b;
+ } set; /* 0x10 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int colfmt:2; /* 0-YUV444,1/3-RGB,2-YUV422 */
+ } b;
+ } set2; /* 0x14 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int pll_ready:1;
+ unsigned int _01_07:7;
+ unsigned int rsen:1;
+ } b;
+ } detect; /* 0x18 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int pll_tsync:1;
+ unsigned int tp2s_type:1;
+ unsigned int div_sel:2;
+ unsigned int pd_v2i:1;
+ unsigned int vco_sx:1;
+ unsigned int vco_mode:1;
+ unsigned int _07:1;
+ unsigned int vsref_sel:2;
+ unsigned int mode:1;
+ unsigned int pd_l2ha:1;
+ unsigned int pd_l2hb:1;
+ unsigned int l2ha_hsen:1;
+ unsigned int resa_en:1;
+ unsigned int resa_s:1;
+ unsigned int pll_lpfs:2;
+ } b;
+ } test2; /* 0x1c */
+};
+
+#define REG_LVDS_BEGIN (LVDS_BASE_ADDR + 0x00)
+#define REG_LVDS_END (LVDS_BASE_ADDR + 0x1C)
+#ifndef LVDS_C
+extern struct lvds_base_regs *lvds_regs;
+#endif
+#endif /* WMT_LVDS_REG_H */
diff --git a/common/wmt_display/hw/wmt-ost.h b/common/wmt_display/hw/wmt-ost.h
new file mode 100755
index 0000000..024ddb6
--- /dev/null
+++ b/common/wmt_display/hw/wmt-ost.h
@@ -0,0 +1,37 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+should have received a copy of the GNU General Public License along with this
+program. If not, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef WMT_OST_H
+/* To assert that only one occurrence is included */
+#define WMT_OST_H
+
+typedef struct
+{
+ volatile unsigned long ostm[4]; // [Rx100-Rx10C] OS Timer Match Register0-3
+ volatile unsigned long ostct; // [Rx110-113] OS Timer Counter Register
+ volatile unsigned long osts; // [Rx114-117] OS Timer Status Register
+ volatile unsigned long ostwe; // [Rx118-Rx11B]
+ volatile unsigned long ostie; // [Rx11C-Rx11F]
+ volatile unsigned long ostctrl; // [Rx120-Rx123] OS Timer Control Register
+ volatile unsigned long ostas; // [Rx124-Rx127] OS Timer Access Status Register
+} WMT_OST_REG;
+
+int wmt_delayus(int us);
+int wmt_read_ostc(int *val);
+
+#endif
+/*=== END wmt-ost.h ==========================================================*/
diff --git a/common/wmt_display/hw/wmt-pwm.h b/common/wmt_display/hw/wmt-pwm.h
new file mode 100755
index 0000000..e13a0a1
--- /dev/null
+++ b/common/wmt_display/hw/wmt-pwm.h
@@ -0,0 +1,110 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+should have received a copy of the GNU General Public License along with this
+program. If not, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef WMT_PWM_H
+/* To assert that only one occurrence is included */
+#define WMT_PWM_H
+
+/*-------------------- MODULE DEPENDENCY -------------------------------------*/
+
+
+// Include your headers here
+
+/*-------------------- EXPORTED PRIVATE CONSTANTS ----------------------------*/
+/* #define PWM_XXXX 1 *//*Example*/
+#define PWM_NUM_MAX 4
+#define PWM_PERIOD_VAL 1000 //modified by howayhuo . org:1000
+
+#define PWM_BASE_ADDR 0xD8220000
+
+// PWM Control Register
+#define PWM_CTRL_REG_ADDR (PWM_BASE_ADDR+0x00)
+#define PWM_ENABLE 0x01
+#define PWM_INVERT 0x02
+#define PWM_AUTOLOAD 0x04
+#define PWM_STOP_IMM 0x08
+#define PWM_LOAD_PRESCALE 0x10
+#define PWM_LOAD_PERIOD 0x20
+
+// PWM Pre scalar
+#define PWM_SCALAR_REG_ADDR (PWM_BASE_ADDR+0x04)
+#define PWM_PRE_SCALE_MASK 0x3FF
+
+// PWM Period value
+#define PWM_PERIOD_REG_ADDR (PWM_BASE_ADDR+0x08)
+#define PWM_PERIOD_MASK 0xFFF
+
+// PWM Duty value
+#define PWM_DUTY_REG_ADDR (PWM_BASE_ADDR+0x0C)
+#define PWM_DUTY_MASK 0xFFF
+
+// PWM Timer Status
+#define PWM_STS_REG_ADDR (PWM_BASE_ADDR+0x40)
+#define PWM_CTRL_UPDATE 0x01
+#define PWM_SCALAR_UPDATE 0x02
+#define PWM_PERIOD_UPDATE 0x04
+#define PWM_DUTY_UPDATE 0x08
+
+#define PWM_GPIO_CTRL_REG (0xd8110000 + 0x500)
+#define PWM_GPIO_OC_REG (0xd8110000 + 0x504)
+#define PWM_GPIO_OD_REG (0xd8110000 + 0x508)
+#define PWM_GPIO_BIT_0 BIT4
+#define PWM_GPIO_BIT_1 BIT5
+
+/*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/
+/* typedef void pwm_xxx_t; *//*Example*/
+typedef struct {
+ int no;
+ unsigned int value;
+} pwm_ctrl_t;
+
+
+/*-------------------- EXPORTED PRIVATE VARIABLES -----------------------------*/
+#ifdef WMT_PWM_C /* allocate memory for variables only in wmt-pwm.c */
+# define EXTERN
+#else
+# define EXTERN extern
+#endif /* ifdef WMT_PWM_C */
+
+/* EXTERN int pwm_xxxx; *//*Example*/
+
+#undef EXTERN
+
+/*--------------------- EXPORTED PRIVATE MACROS -------------------------------*/
+#define PWM_IOC_MAGIC 'p'
+
+// #define PWMIOSET_THRESHOLD _IOW(PWM_IOC_MAGIC, 1, sizeof(int))
+#define PWMIOSET_ENABLE _IOW(PWM_IOC_MAGIC, 0, pwm_ctrl_t)
+#define PWMIOSET_FREQ _IOW(PWM_IOC_MAGIC, 1, pwm_ctrl_t)
+#define PWMIOGET_FREQ _IOWR(PWM_IOC_MAGIC, 1, pwm_ctrl_t)
+#define PWMIOSET_LEVEL _IOW(PWM_IOC_MAGIC, 2, pwm_ctrl_t)
+#define PWMIOGET_LEVEL _IOWR(PWM_IOC_MAGIC, 2, pwm_ctrl_t)
+
+#define PWM_IOC_MAXNR 3
+
+/*--------------------- EXPORTED PRIVATE FUNCTIONS ---------------------------*/
+/* extern void pwm_xxxx(vdp_Void); *//*Example*/
+void pwm_set_period(int no,unsigned int period);
+void pwm_set_scalar(int no,unsigned int scalar);
+void pwm_set_duty(int no,unsigned int duty);
+void pwm_set_enable(int no,int enable);
+void pwm_set_gpio(int no,int enable);
+void pwm_set_control(int no,unsigned int ctrl);
+
+#endif /* ifndef WMT_PWM_H */
+
+/*=== END wmt-pwm.h ==========================================================*/
diff --git a/common/wmt_display/hw/wmt-scl-reg.h b/common/wmt_display/hw/wmt-scl-reg.h
new file mode 100755
index 0000000..773fad9
--- /dev/null
+++ b/common/wmt_display/hw/wmt-scl-reg.h
@@ -0,0 +1,543 @@
+/*++
+ * linux/drivers/video/wmt/hw/wmt-scl-reg.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef WMT_SCL_REG_H
+#define WMT_SCL_REG_H
+
+/* feature */
+#define WMT_FTBLK_SCL
+
+/* constant */
+#define WMT_SCL_RCYC_MIN 0 /* 1T */
+#define WMT_SCL_H_DIV_MAX 8192
+#define WMT_SCL_V_DIV_MAX 8192
+#define WMT_SCL_FB_WIDTH_MAX 8192
+
+#define WMT_SCL_SCALE_DST_H_MAX 1920 /* bypass no limit */
+
+struct scl_base1_regs {
+ union {
+ unsigned int val;
+ struct {
+ unsigned int alu_enable:1;
+ } b;
+ } en; /* 0x0 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int reg_update:1;
+ } b;
+ } upd; /* 0x04 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int reg_level:1;
+ } b;
+ } sel; /* 0x08 */
+
+ unsigned int _0c_38[12];
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int hxwidth:13;
+ } b;
+ } hxwidth; /* 0x3c */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mif_en:1;
+ unsigned int _01_03:3;
+ unsigned int rgb_mode:2; /* 0-YUV,1-RGB565,3-RGB32 */
+ unsigned int _06_07:2;
+ unsigned int _420c_fmt:1; /* 0-frame,1-field */
+ unsigned int vfmt:3; /* 0-YUV422,1-YUV420,
+ 2-YUV444,4-RGB32 */
+ unsigned int h264_fmt:1; /* 0-MPEG,1-H264 */
+ unsigned int _13_15:3;
+ unsigned int iofmt:1; /* 0-frame,1-field */
+ unsigned int _17_23:7;
+ unsigned int color_en:1; /* 0-disable,1-enable */
+ unsigned int color_wide:1; /* 0-Normal,1-Wider */
+ unsigned int color_inv:1; /* 0-Normal,1-Opposite color*/
+ } b;
+ } r2_ctl; /* 0x40 */
+
+ unsigned int r2_ysa; /* 0x44 */
+ unsigned int r2_csa; /* 0x48 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int fbw:13; /* frame buffer width pixel */
+ unsigned int _13_15:3;
+ unsigned int lnsize:13; /* line width pixel */
+ } b;
+ } r2_h_size; /* 0x4c */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int hcrop:13;
+ unsigned int _13_15:3;
+ unsigned int vcrop:13;
+ } b;
+ } r2_crop; /* 0x50 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int src:2; /* 0-RMIF1,1-RMIF2,2-Fixed ALPHA */
+ unsigned int _02_07:6;
+ unsigned int dst:2; /* 0-RMIF1,1-RMIF2,2-Fixed ALPHA */
+ unsigned int _09_15:6;
+ unsigned int swap:1; /* 0-(alpha,1-a),1:(1-a,alpha) */
+ } b;
+ } alpha_md; /* 0x54 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int src_fixed:8;
+ unsigned int dst_fixed:8;
+ } b;
+ } alpha_fxd; /* 0x58 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int enable:1;
+ unsigned int _01_07:7;
+ unsigned int from:1; /* 0-RMIF1,1-RMIF2 */
+ unsigned int _09_15:7;
+ unsigned int comp:2; /* 0-888,1-777,2-666,3-555 */
+ unsigned int _17_23:7;
+ unsigned int mode:3; /* (Non-Hit,Hit):0/1-(alpha,alpha),
+ 2-(alpha,pix1),3-(pix1,alpha),4-(alpha,pix2),
+ 5-(pix2,alpha),6-(pix1,pix2),7-(pix2,pix1) */
+ } b;
+ } alpha_colorkey; /* 0x5c */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int r:8;
+ unsigned int g:8;
+ unsigned int b:8;
+ } b;
+ } alpha_colorkey_rgb; /* 0x60 */
+
+ unsigned int _64_6c[3];
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int vxwidth:13;
+ unsigned int _13_15:3;
+ unsigned int dst_vxwidth:13;
+ } b;
+ } vxwidth; /* 0x70 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int h:1;
+ unsigned int _01_15:15;
+ unsigned int v:1;
+ } b;
+ } sclup_en; /* 0x74 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int thr:13;
+ unsigned int _13_15:3;
+ unsigned int substep:13;
+ } b;
+ } vscale1; /* 0x78 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int substepcnt:13;
+ unsigned int _13_15:3;
+ unsigned int step:13;
+ } b;
+ } vscale2; /* 0x7c */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int stepcnt:17;
+ } b;
+ } vscale3; /* 0x80 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int thr:13;
+ unsigned int _13_15:3;
+ unsigned int substep:13;
+ } b;
+ } hscale1; /* 0x84 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int substepcnt:13;
+ unsigned int _13_15:3;
+ unsigned int step:13;
+ } b;
+ } hscale2; /* 0x88 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int stepcnt:17;
+ } b;
+ } hscale3; /* 0x8c */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int y_req_num:8;
+ unsigned int c_req_num:8;
+ } b;
+ } r_req_num; /* 0x90 */
+
+ unsigned int scldw; /* 0x94 */ /* (VPU path, scale dn)
+ 0 - bilinear mode, quality better */
+ unsigned int sw_426; /* 0x98 */ /* 1-follow 426, 0-437 */
+ unsigned int vbypass; /* 0x9c */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int enable:1;
+ unsigned int _1_3:3;
+ unsigned int err_off:1; /*disable TG_EN in tg timeout*/
+ unsigned int _5_7:3;
+ unsigned int watchdog_enable:1;
+ unsigned int _9_15:7;
+ unsigned int rdcyc:8;
+ unsigned int oneshot:1; /* sacling complete will set
+ SCL tg enable to 0 */
+ } b;
+ } tg_ctl; /* 0xa0 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int h_allpixel:13;
+ unsigned int _13_15:3;
+ unsigned int v_allline:13;
+ } b;
+ } tg_total; /* 0xa4 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int v_actbg:8;
+ unsigned int _8_15:8;
+ unsigned int v_actend:13;
+ } b;
+ } tg_v_active; /* 0xa8 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int h_actbg:10;
+ unsigned int _10_15:6;
+ unsigned int h_actend:13;
+ } b;
+ } tg_h_active; /* 0xac */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int vbie:7;
+ unsigned int _7:1;
+ unsigned int pvbi:5;
+ } b;
+ } tg_vbi; /* 0xb0 */
+
+ unsigned int tg_watchdog; /* 0xb4 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int tgerr:1;
+ } b;
+ } tg_sts; /* 0xb8 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int enable:1;
+ } b;
+ } tg_govw; /* 0xbc */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mif_enable:1; /*0:Disable, 1:Enable */
+ unsigned int _1_3:3;
+ unsigned int rgb_mode:2; /*0:YC,1:RGB565,3:RGB32 */
+ unsigned int _6_7:2;
+ unsigned int src_disp_fmt:1; /*420C 0:Frame, 1:Field */
+ unsigned int yuv:2; /*0:422,1:420,2:444*/
+ unsigned int rgb:1; /*0:YCbCr, 1:RGB32 */
+ unsigned int h264:1; /*0:MPEG, 1:H264 */
+ unsigned int _13_15:3;
+ unsigned int field:1; /*0:Frame, 1:Field */
+ unsigned int _17_23:7;
+ unsigned int colorbar_enable:1;
+ unsigned int colorbar_mode:1;
+ unsigned int colorbar_inv:1;
+ } b;
+ } r_ctl; /* 0xc0 */
+
+ unsigned int r_ysa; /* 0xc4 */
+ unsigned int r_csa; /* 0xc8 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int fb_w:13;
+ unsigned int _13_15:3;
+ unsigned int pix_w:13;
+ } b;
+ } r_h_size; /* 0xcc */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int hcrop:13;
+ unsigned int _13_15:3;
+ unsigned int vcrop:13;
+ } b;
+ } r_crop; /* 0xd0 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int thr:4;
+ unsigned int _4_7:4;
+ unsigned int r1_mif_err:1;
+ unsigned int r2_mif_err:1;
+ } b;
+ } r_fifo_ctl; /* 0xd4 */
+
+ unsigned int _d8_dc[2];
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mif_enable:1;
+ unsigned int _1_7:7;
+ unsigned int yuv:1; /* 0-444,1-422 */
+ unsigned int rgb:1; /* 0-YC,1-RGB32 */
+ } b;
+ } w_ctl; /* 0xe0 */
+
+ unsigned int w_ysa; /* 0xe4 */
+ unsigned int w_csa; /* 0xe8 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int fb_w:13;
+ unsigned int _13_15:3;
+ unsigned int pxl_w:13;
+ } b;
+ } w_y_time; /* 0xec */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int fb_w:13;
+ unsigned int _13_15:3;
+ unsigned int pxl_w:12;
+ } b;
+ } w_c_time; /* 0xf0 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mif_c_err:1;
+ unsigned int _1_7:7;
+ unsigned int mif_y_err:1;
+ unsigned int _9_15:7;
+ unsigned int mif_rgb_err:1;
+ } b;
+ } w_ff_ctl; /* 0xf4 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mif_c_err:1;
+ unsigned int mif_y_err:1;
+ unsigned int mif_rgb_err:1;
+ unsigned int _3_7:5;
+ unsigned int r2_mif_enable:1;
+ unsigned int r1_mif_enable:1;
+ unsigned int _10_15:6;
+ unsigned int tg_err:1;
+ } b;
+ } w_int_en; /* 0xf8 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int h:1;
+ unsigned int _1_7:7;
+ unsigned int v:1;
+ } b;
+ } true_bilinear; /* 0xfc */
+};
+
+struct scl_base2_regs {
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mode:1; /* 0-RGB2YC,1-YC2RGB */
+ unsigned int _01_07:7;
+ unsigned int clamp_enable:1; /* clamp to 16-235 */
+ unsigned int _09_15:7;
+ unsigned int enable:1;
+ } b;
+ } csc_ctl; /* 0x0 */
+
+ unsigned int csc1; /* 0x4 */
+ unsigned int csc2; /* 0x8 */
+ unsigned int csc3; /* 0xc */
+ unsigned int csc4; /* 0x10 */
+ unsigned int csc5; /* 0x14 */
+ unsigned int csc6; /* 0x18 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int enable:1;
+ unsigned int _01_07:7;
+ unsigned int data:8;
+ } b;
+ } argb_alpha; /* 0x1c */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mode:2; /* 0-888,1-555,2-666,3-565 */
+ } b;
+ } igs; /* 0x20 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int mode:1; /* 0-CCIR/ITU-601 */
+ unsigned int _01_07:7;
+ unsigned int clamp:1; /* 0-direct,1-16-235 */
+ unsigned int _09_15:7;
+ unsigned int enable:1;
+ } b;
+ } r2_csc; /* 0x24 */
+
+ unsigned int r2_csc1; /* 0x28 */
+ unsigned int r2_csc2; /* 0x2c */
+ unsigned int r2_csc3; /* 0x30 */
+ unsigned int r2_csc4; /* 0x34 */
+ unsigned int r2_csc5; /* 0x38 */
+ unsigned int r2_csc6; /* 0x3c */
+ unsigned int _40_9c[24];
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int h:1;
+ unsigned int _01_07:7;
+ unsigned int v:1;
+ } b;
+ } recursive_mode; /* 0xa0 */
+
+ unsigned int _a4_bc[7];
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int deblock:1;
+ unsigned int field_deflicker:1;
+ unsigned int frame_deflicker:1;
+ } b;
+ } field_mode; /* 0xc0 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int layer1_boundary:8;
+ unsigned int layer2_boundary:8;
+ } b;
+ } dblk_threshold; /* 0xc4 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int condition:1; /* 0-up or down,1-up & down */
+ unsigned int _01_07:7;
+ unsigned int y_thd:8;
+ unsigned int c_thd:8;
+ } b;
+ } field_flicker; /* 0xc8 */
+ union {
+ unsigned int val;
+ struct {
+ unsigned int rgb:1; /* 0-Y,1-RGB */
+ unsigned int _01_07:7;
+ unsigned int sampler:5; /* 2^x */
+ unsigned int _13_15:3;
+ unsigned int scene_chg_thd:8;
+ } b;
+ } frame_flicker; /* 0xcc */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int rdcyc_1t:1;
+ } b;
+ } readcyc_1t; /* 0xd0 */
+
+ unsigned int _d4_e0[4];
+};
+
+#define REG_SCL_BASE1_BEGIN (SCL_BASE_ADDR + 0x00)
+#define REG_SCL_BASE1_END (SCL_BASE_ADDR + 0xFC)
+#define REG_SCL_BASE2_BEGIN (SCL_BASE2_ADDR + 0x00)
+#define REG_SCL_BASE2_END (SCL_BASE2_ADDR + 0xE0)
+
+#ifndef SCL_C
+extern HW_REG struct scl_base1_regs *scl_regs1;
+extern HW_REG struct scl_base2_regs *scl_regs2;
+#endif
+#endif /* WMT_SCL_REG_H */
diff --git a/common/wmt_display/hw/wmt-vpp-hw.h b/common/wmt_display/hw/wmt-vpp-hw.h
new file mode 100755
index 0000000..599ebe0
--- /dev/null
+++ b/common/wmt_display/hw/wmt-vpp-hw.h
@@ -0,0 +1,137 @@
+/*++
+ * linux/drivers/video/wmt/hw/wmt-vpp-hw.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef WMT_VPP_HW_H
+#define WMT_VPP_HW_H
+
+/*-------------------- EXPORTED PRIVATE CONSTANTS ----------------------------*/
+/*
+* Product ID / Project ID
+* 84xx series: 8420/3300, 8430/3357, 8435/3437
+* 85xx series: 8500/3400, 8510/3426, 8520/3429
+*/
+/* 84xx series, (1-100) with VDU & DSP */
+#define VIA_PID_8420 10 /* 3300 */
+#define VIA_PID_8430 12 /* 3357 */
+#define WMT_PID_8435 14 /* 3437 */
+#define WMT_PID_8440 16 /* 3451 */
+#define WMT_PID_8425 18 /* 3429 */
+#define WMT_PID_8710 20 /* 3445 */
+#define WMT_PID_8950 22 /* 3481 */
+#define WMT_PID_8980 24 /* 3498 */
+
+/* 85xx series, (101-200) */
+#define VIA_PID_8500 110 /* 3400 */
+#define WMT_PID_8505 111
+#define WMT_PID_8510 112 /* 3426* */
+
+#define WMT_PID_8950_A 1
+
+/* current pid */
+#define WMT_CUR_PID WMT_PID_8980
+#define WMT_SUB_PID 0
+
+/* #define WMT_SUB_PID WMT_PID_8505 */
+#ifndef WMT_SUB_PID
+ #define WMT_SUB_PID 0
+#endif
+
+/* VPP interrupt map to irq */
+#define VPP_IRQ_SCL_FINISH IRQ_VPP_IRQ0
+#define VPP_IRQ_SCL IRQ_VPP_IRQ1
+#define VPP_IRQ_SCL444_TG IRQ_VPP_IRQ2
+#define VPP_IRQ_VPPM IRQ_VPP_IRQ3
+#define VPP_IRQ_GOVW_TG IRQ_VPP_IRQ4
+#define VPP_IRQ_GOVW IRQ_VPP_IRQ5
+#define VPP_IRQ_GOVM IRQ_VPP_IRQ6
+#define VPP_IRQ_GE IRQ_VPP_IRQ7
+#define VPP_IRQ_GOVRH_TG IRQ_VPP_IRQ8 /* PVBI or VBIS or VBIE */
+#define VPP_IRQ_DVO IRQ_VPP_IRQ9
+#define VPP_IRQ_VID IRQ_VPP_IRQ10
+#define VPP_IRQ_GOVR IRQ_VPP_IRQ11 /* underrun & mif */
+#define VPP_IRQ_GOVRSD_TG IRQ_VPP_IRQ12
+#define VPP_IRQ_VPU IRQ_VPP_IRQ13
+#define VPP_IRQ_VPU_TG IRQ_VPP_IRQ14
+#define VPP_IRQ_HDMI_CP IRQ_VPP_IRQ15
+#define VPP_IRQ_HDMI_HPDH IRQ_VPP_IRQ16
+#define VPP_IRQ_HDMI_HPDL IRQ_VPP_IRQ17
+#define VPP_IRQ_GOVR_0 IRQ_VPP_IRQ18
+#define VPP_IRQ_GOVR_2 IRQ_VPP_IRQ19
+#define VPP_IRQ_CEC IRQ_VPP_IRQ20
+#define VPP_IRQ_GOVR2_0 IRQ_VPP_IRQ21
+#define VPP_IRQ_GOVR2 IRQ_VPP_IRQ22
+#define VPP_IRQ_GOVR2_2 IRQ_VPP_IRQ23
+#define VPP_IRQ_DVO2 IRQ_VPP_IRQ24
+#define VPP_IRQ_GOVR2_TG IRQ_VPP_IRQ25
+
+/* DVI I2C */
+#define VPP_DVI_I2C_DEFAULT 1 /* default i2c bus */
+#define VPP_DVI_I2C_SW_BIT 0x10 /* hw or sw i2c */
+#define VPP_DVI_I2C_ID_MASK 0x1F
+#define VPP_DVI_I2C_ID g_vpp.dvi_i2c_no
+#define VPP_DVI_EDID_ID (VPP_DVI_I2C_SW_BIT + 0x1) /* DVO EDID use
+ sw i2c bus 1 */
+
+/* vout */
+#define VPP_VOUT_INFO_NUM 5 /* linux fb or govr number */
+
+#define VPP_VOUT_NUM 2
+#define VPP_VOUT_ALL 0xFFFFFFFF
+#define VPP_VOUT_NUM_HDMI 0
+#define VPP_VOUT_NUM_LVDS 1
+#define VPP_VOUT_NUM_DVI 1
+
+#define WMT_FTBLK_VOUT_DVI
+#define WMT_FTBLK_VOUT_HDMI
+#define WMT_FTBLK_VOUT_LVDS
+
+/* hw parameter */
+#define VPP_DVI_INT_DEFAULT 0 /* default interrupt gpio */
+#define VPP_VOINT_NO g_vpp.dvi_int_no
+#define VPP_UBOOT_COLFMT VDO_COL_FMT_RGB_565
+#define VPP_FB_ADDR_ALIGN 64
+#define VPP_FB_WIDTH_ALIGN 64 /* hw should 4 byte align,android
+ framework 8 byte align modify by aksenxu VPU need 64bytes alignment
+ you need modify FramebufferNativeWindow::FramebufferNativeWindow
+ in android framework together */
+#define VPP_GOVR_DVO_DELAY_24 0x4036
+#define VPP_GOVR_DVO_DELAY_12 0x120
+
+/*-------------------- DEPENDENCY -------------------------------------*/
+#ifdef __KERNEL__
+#ifndef CONFIG_WMT_HDMI
+#undef WMT_FTBLK_VOUT_HDMI
+#endif
+#endif
+
+#include "wmt-vpp-reg.h"
+#include "wmt-govrh-reg.h"
+#include "wmt-lvds-reg.h"
+#ifdef WMT_FTBLK_VOUT_HDMI
+#include "wmt-hdmi-reg.h"
+#endif
+#include "wmt-scl-reg.h"
+#ifndef CONFIG_UBOOT
+#include "wmt-cec-reg.h"
+#endif
+#endif /* WMT_VPP_HW_H */
diff --git a/common/wmt_display/hw/wmt-vpp-reg.h b/common/wmt_display/hw/wmt-vpp-reg.h
new file mode 100755
index 0000000..b96e64d
--- /dev/null
+++ b/common/wmt_display/hw/wmt-vpp-reg.h
@@ -0,0 +1,132 @@
+/*++
+ * linux/drivers/video/wmt/hw/wmt-vpp-reg.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef WMT_VPP_REG_H
+#define WMT_VPP_REG_H
+
+#define VPP_DAC_SEL_TV 1
+#define VPP_DAC_SEL_VGA 0
+
+struct vppm_base_regs {
+ unsigned int _00; /* 0x00 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int _0_7:8;
+ unsigned int govrh_pvbi:1;
+ unsigned int govrh_vbis:1;
+ unsigned int govrh_vbie:1;
+ unsigned int _11:1;
+ unsigned int govrh2_pvbi:1;
+ unsigned int govrh2_vbis:1;
+ unsigned int govrh2_vbie:1;
+ unsigned int _15:1;
+ unsigned int scl_pvbi:1;
+ unsigned int scl_vbis:1;
+ unsigned int scl_vbie:1;
+ unsigned int _19:1;
+ unsigned int ge_tg:1;
+ } b;
+ } int_sts; /* 0x4 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int _0_7:8;
+ unsigned int govrh_pvbi:1;
+ unsigned int govrh_vbis:1;
+ unsigned int govrh_vbie:1;
+ unsigned int _11:1;
+ unsigned int govrh2_pvbi:1;
+ unsigned int govrh2_vbis:1;
+ unsigned int govrh2_vbie:1;
+ unsigned int _15:1;
+ unsigned int scl_pvbi:1;
+ unsigned int scl_vbis:1;
+ unsigned int scl_vbie:1;
+ unsigned int _19:1;
+ unsigned int ge_tg:1;
+ } b;
+ } int_en; /* 0x8 */
+
+ unsigned int watch_sel; /* 0x0C */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int scl:1;
+ unsigned int _1_7:7;
+ unsigned int vid:1;
+ unsigned int _9_15:7;
+ unsigned int ge:1;
+ } b;
+ } sw_reset1; /* 0x10 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int govrh:1;
+ unsigned int _1_3:3;
+ unsigned int lvds:1;
+ unsigned int _5_7:3;
+ unsigned int dvo:1;
+ unsigned int dvo2:1;
+ unsigned int _10_11:2;
+ unsigned int cec:1;
+ } b;
+ } sw_reset2; /* 0x14 */
+
+ unsigned int dac_sel; /* 0x18 */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int hdmi:1;
+ unsigned int _1_7:7;
+ unsigned int ddc:1;
+ unsigned int _9_15:7;
+ unsigned int hdmi2:1;
+ } b;
+ } sw_reset3; /* 0x1C */
+
+ union {
+ unsigned int val;
+ struct {
+ unsigned int disable:1;
+ unsigned int _1_7:7;
+ unsigned int csi_act_lane_sel:1; /*0-lane 0/1,1-2/3*/
+ } b;
+ } sscg; /* 0x20 */
+};
+
+#define REG_VPP_BEGIN (VPP_BASE_ADDR + 0x00)
+#define REG_VPP_END (VPP_BASE_ADDR + 0x28)
+
+#ifndef VPPM_C
+extern HW_REG struct vppm_base_regs *vppm_regs;
+#endif
+
+
+#endif /* WMT_VPP_REG_H */
+
diff --git a/common/wmt_display/hw/wmt_gpio.h b/common/wmt_display/hw/wmt_gpio.h
new file mode 100755
index 0000000..0f5cf87
--- /dev/null
+++ b/common/wmt_display/hw/wmt_gpio.h
@@ -0,0 +1,791 @@
+/*++
+linux/arch/arm/mach-wmt/include/mach/wmt_gpio.h
+
+Copyright (c) 2014 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with
+this program. If not, see <http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+/* Be sure that virtual mapping is defined right */
+
+#ifndef __WMT_GPIO_H
+/* To assert that only one occurrence is included */
+#define __WMT_GPIO_H
+
+/*-------------------- MODULE DEPENDENCY ------------------------------------*/
+#ifndef APPLICATION
+#else
+#endif
+
+
+/*-------------------- EXPORTED PRIVATE CONSTANTS ---------------------------*/
+
+/*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/
+
+/*-------------------- EXPORTED PRIVATE VARIABLES -----------------------------*/
+#ifdef XXX_C /* allocate memory for variables only in xxx.c */
+# define EXTERN
+#else
+# define EXTERN extern
+#endif /* ifdef XXX_C */
+
+
+#undef EXTERN
+
+/*--------------------- EXPORTED PRIVATE MACROS -------------------------------*/
+#define __GPIO_BASE GPIO_BASE_ADDR
+
+#define GIRQ_LOW 0x00 /* Input zero generate GPIO_IRQ signal */
+#define GIRQ_HIGH 0x01 /* Input one generate GPIO_IRQ signal */
+#define GIRQ_FALLING 0x02 /* Falling edge generate GPIO_IRQ signal */
+#define GIRQ_RISING 0x03 /* Rising edge generate GPIO_IRQ signal */
+#define GIRQ_BOTHEDGE 0x04
+#define GIRQ_TYPEMASK 0x07
+#define GIRQ_TYPE(idx, type) ((type & GIRQ_TYPEMASK) << (idx * 8)) /* idx must be 0-3 */
+#define GIRQ_EN_STS(idx) ( 1 << ((idx+1)*8-1) ) /* idx must be 0-3 */
+
+#define GPIO_ID_GP0_BYTE_ADDR (__GPIO_BASE + 0x00 )/* [0x0] */
+#define GPIO_ID_GP1_BYTE_ADDR (__GPIO_BASE + 0x01 )/* [0x1] */
+#define GPIO_ID_GP2_BYTE_ADDR (__GPIO_BASE + 0x02 )/* [0x2] */
+#define GPIO_ID_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0x04 )/* [0x4] */
+#define GPIO_ID_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0x05 )/* [0x5] */
+#define GPIO_ID_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0x06 )/* [0x6] */
+#define GPIO_ID_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0x07 )/* [0x7] */
+#define GPIO_ID_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0x08 )/* [0x8] */
+#define GPIO_ID_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0x09 )/* [0x9] */
+#define GPIO_ID_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0x0A )/* [0xA] */
+#define GPIO_ID_GP11_I2S_BYTE_ADDR (__GPIO_BASE + 0x0B )/* [0xB] */
+#define GPIO_ID_GP12_SPI_BYTE_ADDR (__GPIO_BASE + 0x0C )/* [0xC] */
+#define GPIO_ID_GP13_SD0_BYTE_ADDR (__GPIO_BASE + 0x0D )/* [0xD] */
+#define GPIO_ID_GP14_NAND_SD1_BYTE_ADDR (__GPIO_BASE + 0x0E )/* [0xE] */
+#define GPIO_ID_GP15_NAND_BYTE_ADDR (__GPIO_BASE + 0x0F )/* [0xF] */
+#define GPIO_ID_GP16_NAND_SD1_BYTE_ADDR (__GPIO_BASE + 0x10 )/* [0x10] */
+#define GPIO_ID_GP17_I2C_BYTE_ADDR (__GPIO_BASE + 0x11 )/* [0x11] */
+#define GPIO_ID_GP18_UART_BYTE_ADDR (__GPIO_BASE + 0x12 )/* [0x12] */
+#define GPIO_ID_GP19_SD2_BYTE_ADDR (__GPIO_BASE + 0x13 )/* [0x13] */
+#define GPIO_ID_GP20_PWM0_BYTE_ADDR (__GPIO_BASE + 0x14 )/* [0x14] */
+#define GPIO_ID_GP21_HDMI_BYTE_ADDR (__GPIO_BASE + 0x15 )/* [0x15] */
+#define GPIO_ID_GP23_I2C3_BYTE_ADDR (__GPIO_BASE + 0x17 )/* [0x17] */
+#define GPIO_ID_GP24_SF_BYTE_ADDR (__GPIO_BASE + 0x18 )/* [0x18] */
+#define GPIO_ID_GP26_PCM_BYTE_ADDR (__GPIO_BASE + 0x1A )/* [0x1A] */
+#define GPIO_ID_GP60_USB_BYTE_ADDR (__GPIO_BASE + 0x3C )/* [0x3C] */
+#define GPIO_ID_GP62_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0x3E )/* [0x3E] */
+#define GPIO_ID_GP63_SD02CD_BYTE_ADDR (__GPIO_BASE + 0x3F )/* [0x3F] */
+#define GPIO_CTRL_GP0_BYTE_ADDR (__GPIO_BASE + 0x40 )/* [0x40] */
+#define GPIO_CTRL_GP1_BYTE_ADDR (__GPIO_BASE + 0x41 )/* [0x41] */
+#define GPIO_CTRL_GP2_BYTE_ADDR (__GPIO_BASE + 0x42 )/* [0x42] */
+#define GPIO_CTRL_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0x44 )/* [0x44] */
+#define GPIO_CTRL_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0x45 )/* [0x45] */
+#define GPIO_CTRL_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0x46 )/* [0x46] */
+#define GPIO_CTRL_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0x47 )/* [0x47] */
+#define GPIO_CTRL_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0x48 )/* [0x48] */
+#define GPIO_CTRL_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0x49 )/* [0x49] */
+#define GPIO_CTRL_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0x4A )/* [0x4A] */
+#define GPIO_CTRL_GP11_I2S_BYTE_ADDR (__GPIO_BASE + 0x4B )/* [0x4B] */
+#define GPIO_CTRL_GP12_SPI_BYTE_ADDR (__GPIO_BASE + 0x4C )/* [0x4C] */
+#define GPIO_CTRL_GP13_SD0_BYTE_ADDR (__GPIO_BASE + 0x4D )/* [0x4D] */
+#define GPIO_CTRL_GP14_NAND_SD1_BYTE_ADDR (__GPIO_BASE + 0x4E )/* [0x4E] */
+#define GPIO_CTRL_GP15_NAND_BYTE_ADDR (__GPIO_BASE + 0x4F )/* [0x4F] */
+#define GPIO_CTRL_GP16_NAND_SD1_BYTE_ADDR (__GPIO_BASE + 0x50 )/* [0x50] */
+#define GPIO_CTRL_GP17_I2C_BYTE_ADDR (__GPIO_BASE + 0x51 )/* [0x51] */
+#define GPIO_CTRL_GP18_UART_BYTE_ADDR (__GPIO_BASE + 0x52 )/* [0x52] */
+#define GPIO_CTRL_GP19_SD2_BYTE_ADDR (__GPIO_BASE + 0x53 )/* [0x53] */
+#define GPIO_CTRL_GP20_PWM0_BYTE_ADDR (__GPIO_BASE + 0x54 )/* [0x54] */
+#define GPIO_CTRL_GP21_HDMI_BYTE_ADDR (__GPIO_BASE + 0x55 )/* [0x55] */
+#define GPIO_CTRL_GP23_I2C3_BYTE_ADDR (__GPIO_BASE + 0x57 )/* [0x57] */
+#define GPIO_CTRL_GP24_SF_BYTE_ADDR (__GPIO_BASE + 0x58 )/* [0x58] */
+#define GPIO_CTRL_GP26_PCM_BYTE_ADDR (__GPIO_BASE + 0x5A )/* [0x5A] */
+#define GPIO_CTRL_GP60_USB_BYTE_ADDR (__GPIO_BASE + 0x7C )/* [0x7C] */
+#define GPIO_CTRL_GP62_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0x7E )/* [0x7E] */
+#define GPIO_CTRL_GP63_SD02CD_BYTE_ADDR (__GPIO_BASE + 0x7F )/* [0x7F] */
+#define GPIO_OC_GP0_BYTE_ADDR (__GPIO_BASE + 0x80 )/* [0x80] */
+#define GPIO_OC_GP1_BYTE_ADDR (__GPIO_BASE + 0x81 )/* [0x81] */
+#define GPIO_OC_GP2_BYTE_ADDR (__GPIO_BASE + 0x82 )/* [0x82] */
+#define GPIO_OC_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0x84 )/* [0x84] */
+#define GPIO_OC_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0x85 )/* [0x85] */
+#define GPIO_OC_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0x86 )/* [0x86] */
+#define GPIO_OC_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0x87 )/* [0x87] */
+#define GPIO_OC_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0x88 )/* [0x88] */
+#define GPIO_OC_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0x89 )/* [0x89] */
+#define GPIO_OC_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0x8A )/* [0x8A] */
+#define GPIO_OC_GP11_I2S_BYTE_ADDR (__GPIO_BASE + 0x8B )/* [0x8B] */
+#define GPIO_OC_GP12_SPI_BYTE_ADDR (__GPIO_BASE + 0x8C )/* [0x8C] */
+#define GPIO_OC_GP13_SD0_BYTE_ADDR (__GPIO_BASE + 0x8D )/* [0x8D] */
+#define GPIO_OC_GP14_NAND_SD1_BYTE_ADDR (__GPIO_BASE + 0x8E )/* [0x8E] */
+#define GPIO_OC_GP15_NAND_BYTE_ADDR (__GPIO_BASE + 0x8F )/* [0x8F] */
+#define GPIO_OC_GP16_NAND_SD1_BYTE_ADDR (__GPIO_BASE + 0x90 )/* [0x90] */
+#define GPIO_OC_GP17_I2C_BYTE_ADDR (__GPIO_BASE + 0x91 )/* [0x91] */
+#define GPIO_OC_GP18_UART_BYTE_ADDR (__GPIO_BASE + 0x92 )/* [0x92] */
+#define GPIO_OC_GP19_SD2_BYTE_ADDR (__GPIO_BASE + 0x93 )/* [0x93] */
+#define GPIO_OC_GP20_PWM0_BYTE_ADDR (__GPIO_BASE + 0x94 )/* [0x94] */
+#define GPIO_OC_GP21_HDMI_BYTE_ADDR (__GPIO_BASE + 0x95 )/* [0x95] */
+#define GPIO_OC_GP22_I2C3_BYTE_ADDR (__GPIO_BASE + 0x96 )/* [0x96] */
+#define GPIO_OC_GP24_SF_BYTE_ADDR (__GPIO_BASE + 0x98 )/* [0x98] */
+#define GPIO_OC_GP26_PCM_BYTE_ADDR (__GPIO_BASE + 0x9A )/* [0x9A] */
+#define GPIO_OC_GP60_USB_BYTE_ADDR (__GPIO_BASE + 0xBC )/* [0xBC] */
+#define GPIO_OC_GP62_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0xBE )/* [0xBE] */
+#define GPIO_OC_GP63_SD02CD_BYTE_ADDR (__GPIO_BASE + 0xBF )/* [0xBF] */
+#define GPIO_OD_GP0_BYTE_ADDR (__GPIO_BASE + 0xC0 )/* [0xC0] */
+#define GPIO_OD_GP1_BYTE_ADDR (__GPIO_BASE + 0xC1 )/* [0xC1] */
+#define GPIO_OD_GP2_BYTE_ADDR (__GPIO_BASE + 0xC2 )/* [0xC2] */
+#define GPIO_OD_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0xC4 )/* [0xC4] */
+#define GPIO_OD_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0xC5 )/* [0xC5] */
+#define GPIO_OD_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0xC6 )/* [0xC6] */
+#define GPIO_OD_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0xC7 )/* [0xC7] */
+#define GPIO_OD_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0xC8 )/* [0xC8] */
+#define GPIO_OD_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0xC9 )/* [0xC9] */
+#define GPIO_OD_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0xCA )/* [0xCA] */
+#define GPIO_OD_GP11_I2S_BYTE_ADDR (__GPIO_BASE + 0xCB )/* [0xCB] */
+#define GPIO_OD_GP12_SPI_BYTE_ADDR (__GPIO_BASE + 0xCC )/* [0xCC] */
+#define GPIO_OD_GP13_SD0_BYTE_ADDR (__GPIO_BASE + 0xCD )/* [0xCD] */
+#define GPIO_OD_GP14_NAND_SD1_BYTE_ADDR (__GPIO_BASE + 0xCE )/* [0xCE] */
+#define GPIO_OD_GP15_NAND_BYTE_ADDR (__GPIO_BASE + 0xCF )/* [0xCF] */
+#define GPIO_OD_GP16_NAND_SD1_BYTE_ADDR (__GPIO_BASE + 0xD0 )/* [0xD0] */
+#define GPIO_OD_GP17_I2C_BYTE_ADDR (__GPIO_BASE + 0xD1 )/* [0xD1] */
+#define GPIO_OD_GP18_UART_BYTE_ADDR (__GPIO_BASE + 0xD2 )/* [0xD2] */
+#define GPIO_OD_GP19_SD2_BYTE_ADDR (__GPIO_BASE + 0xD3 )/* [0xD3] */
+#define GPIO_OD_GP20_PWM0_BYTE_ADDR (__GPIO_BASE + 0xD4 )/* [0xD4] */
+#define GPIO_OD_GP21_HDMI_BYTE_ADDR (__GPIO_BASE + 0xD5 )/* [0xD5] */
+#define GPIO_OD_GP23_I2C3_BYTE_ADDR (__GPIO_BASE + 0xD7 )/* [0xD7] */
+#define GPIO_OD_GP24_SF_BYTE_ADDR (__GPIO_BASE + 0xD8 )/* [0xD8] */
+#define GPIO_OD_GP26_PCM_BYTE_ADDR (__GPIO_BASE + 0xDA )/* [0xDA] */
+#define GPIO_OD_GP60_USB_BYTE_ADDR (__GPIO_BASE + 0xFC )/* [0xFC] */
+#define GPIO_OD_GP62_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0xFE )/* [0xFE] */
+#define GPIO_OD_GP63_SD02CD_BYTE_ADDR (__GPIO_BASE + 0xFF )/* [0xFF] */
+#define STRAP_STATUS_ADDR (__GPIO_BASE + 0x100 )/* [0x100 ~ 0x103] */
+#define AHB_CTRL_4BYTE_ADDR (__GPIO_BASE + 0x108 )/* [0x108 ~ 0x10B] */
+#define USB_OP_CTRL_4BYTE_ADDR (__GPIO_BASE + 0x10C )/* [0x10C ~ 0x10F] */
+#define BONDING_OPTION_4BYTE_ADDR (__GPIO_BASE + 0x110 )/* [0x110 ~ 0x113] */
+#define PIN_SHARING_SEL_4BYTE_ADDR (__GPIO_BASE + 0x200 )/* [0x200 ~ 0x203] */
+#define TPIU_CLK_DATA_4BYTE_ADDR (__GPIO_BASE + 0x244 )/* [0x244 ~ 0x247] */
+#define GPIO0_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x300 )/* [0x300] */
+#define GPIO1_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x301 )/* [0x301] */
+#define GPIO2_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x302 )/* [0x302] */
+#define GPIO3_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x303 )/* [0x303] */
+#define GPIO4_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x304 )/* [0x304] */
+#define GPIO5_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x305 )/* [0x305] */
+#define GPIO6_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x306 )/* [0x306] */
+#define GPIO7_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x307 )/* [0x307] */
+#define GPIO8_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x308 )/* [0x308] */
+#define GPIO9_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x309 )/* [0x309] */
+#define GPIO10_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30A )/* [0x30A] */
+#define GPIO11_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30B )/* [0x30B] */
+#define GPIO12_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30C )/* [0x30C] */
+#define GPIO13_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30D )/* [0x30D] */
+#define GPIO18_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30E )/* [0x30E] */
+#define GPIO19_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30F )/* [0x30F] */
+#define VOUT20_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x310 )/* [0x310] */
+#define VOUT21_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x311 )/* [0x311] */
+#define VOUT22_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x312 )/* [0x312] */
+#define VOUT23_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x313 )/* [0x313] */
+#define GPIO20_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x314 )/* [0x314] */
+#define GPIO21_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x315 )/* [0x315] */
+#define GPIO22_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x316 )/* [0x316] */
+#define GPIO23_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x317 )/* [0x317] */
+#define GPIO24_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x318 )/* [0x318] */
+#define GPIO25_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x319 )/* [0x319] */
+#define GPIO0_INT_REQ_STS_ADDR (__GPIO_BASE + 0x360 )/* [0x360] */
+#define GPIO1_INT_REQ_STS_ADDR (__GPIO_BASE + 0x361 )/* [0x361] */
+#define GPIO2_INT_REQ_STS_ADDR (__GPIO_BASE + 0x362 )/* [0x362] */
+#define GPIO3_INT_REQ_STS_ADDR (__GPIO_BASE + 0x363 )/* [0x363] */
+#define DRV_DVO_CLK_BYTE_ADDR (__GPIO_BASE + 0x402 )/* [0x402] */
+#define DRV_DVO_VDEN_BYTE_ADDR (__GPIO_BASE + 0x403 )/* [0x403] */
+#define SD0_DPCTL_4BYTE_ADDR (__GPIO_BASE + 0x404 )/* [0x404 ~ 0x407] */
+#define SD0_DNCTL_4BYTE_ADDR (__GPIO_BASE + 0x408 )/* [0x408 ~ 0x40B] */
+#define DRV_SD0_USB_BYTE_ADDR (__GPIO_BASE + 0x464 )/* [0x464] */
+#define DRV_USB_SWOC0_BYTE_ADDR (__GPIO_BASE + 0x465 )/* [0x465] */
+#define DRV_USB_OC12_BYTE_ADDR (__GPIO_BASE + 0x466 )/* [0x466] */
+#define DRV_USBOC3_CIR_BYTE_ADDR (__GPIO_BASE + 0x467 )/* [0x467] */
+#define DRV_PWREN_BYTE_ADDR (__GPIO_BASE + 0x468 )/* [0x468] */
+#define DRV_PWREN_WAKEUP0_BYTE_ADDR (__GPIO_BASE + 0x469 )/* [0x469] */
+#define DRV_SUSGP01_BYTE_ADDR (__GPIO_BASE + 0x46A )/* [0x46A] */
+#define DRV_WAKEUP23_BYTE_ADDR (__GPIO_BASE + 0x46B )/* [0x46B] */
+#define DRV_WAKEUP45_BYTE_ADDR (__GPIO_BASE + 0x46C )/* [0x46C] */
+#define DRV_I2C_BYTE_ADDR (__GPIO_BASE + 0x46D )/* [0x46D] */
+#define DRV_HDMI_BYTE_ADDR (__GPIO_BASE + 0x46E )/* [0x46E] */
+#define PULL_EN_GP0_BYTE_ADDR (__GPIO_BASE + 0x480 )/* [0x480] */
+#define PULL_EN_GP1_BYTE_ADDR (__GPIO_BASE + 0x481 )/* [0x481] */
+#define PULL_EN_GP2_BYTE_ADDR (__GPIO_BASE + 0x482 )/* [0x482] */
+#define PULL_EN_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0x484 )/* [0x484] */
+#define PULL_EN_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0x485 )/* [0x485] */
+#define PULL_EN_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0x486 )/* [0x486] */
+#define PULL_EN_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0x487 )/* [0x487] */
+#define PULL_EN_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0x488 )/* [0x488] */
+#define PULL_EN_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0x489 )/* [0x489] */
+#define PULL_EN_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0x48A )/* [0x48A] */
+#define PULL_EN_GP11_I2S_BYTE_ADDR (__GPIO_BASE + 0x48B )/* [0x48B] */
+#define PULL_EN_GP12_SPI_BYTE_ADDR (__GPIO_BASE + 0x48C )/* [0x48C] */
+#define PULL_EN_GP13_SD0_BYTE_ADDR (__GPIO_BASE + 0x48D )/* [0x48D] */
+#define PULL_EN_GP14_NAND_BYTE_ADDR (__GPIO_BASE + 0x48E )/* [0x48E] */
+#define PULL_EN_GP15_NAND_BYTE_ADDR (__GPIO_BASE + 0x48F )/* [0x48F] */
+#define PULL_EN_GP16_NANDIO_BYTE_ADDR (__GPIO_BASE + 0x490 )/* [0x490] */
+#define PULL_EN_GP17_I2C_BYTE_ADDR (__GPIO_BASE + 0x491 )/* [0x491] */
+#define PULL_EN_GP18_UART_BYTE_ADDR (__GPIO_BASE + 0x492 )/* [0x492] */
+#define PULL_EN_GP19_SD2_BYTE_ADDR (__GPIO_BASE + 0x493 )/* [0x493] */
+#define PULL_EN_GP20_PWM0_BYTE_ADDR (__GPIO_BASE + 0x494 )/* [0x494] */
+#define PULL_EN_GP21_HDMI_BYTE_ADDR (__GPIO_BASE + 0x495 )/* [0x495] */
+#define PULL_EN_GP23_I2C3_BYTE_ADDR (__GPIO_BASE + 0x497 )/* [0x497] */
+#define PULL_EN_GP24_SF_BYTE_ADDR (__GPIO_BASE + 0x498 )/* [0x498] */
+#define PULL_EN_GP26_PCM_BYTE_ADDR (__GPIO_BASE + 0x49A )/* [0x49A] */
+#define PULL_EN_GP60_USB_BYTE_ADDR (__GPIO_BASE + 0x4BC )/* [0x4BC] */
+#define PULL_EN_GP62_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0x4BE )/* [0x4BE] */
+#define PULL_EN_GP63_SD02_BYTE_ADDR (__GPIO_BASE + 0x4BF )/* [0x4BF] */
+#define PULL_CTRL_GP0_BYTE_ADDR (__GPIO_BASE + 0x4C0 )/* [0x4C0] */
+#define PULL_CTRL_GP1_BYTE_ADDR (__GPIO_BASE + 0x4C1 )/* [0x4C1] */
+#define PULL_CTRL_GP2_BYTE_ADDR (__GPIO_BASE + 0x4C2 )/* [0x4C2] */
+#define PULL_CTRL_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0x4C4 )/* [0x4C4] */
+#define PULL_CTRL_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0x4C5 )/* [0x4C5] */
+#define PULL_CTRL_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0x4C6 )/* [0x4C6] */
+#define PULL_CTRL_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0x4C7 )/* [0x4C7] */
+#define PULL_CTRL_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0x4C8 )/* [0x4C8] */
+#define PULL_CTRL_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0x4C9 )/* [0x4C9] */
+#define PULL_CTRL_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0x4CA )/* [0x4CA] */
+#define PULL_CTRL_GP11_I2S_BYTE_ADDR (__GPIO_BASE + 0x4CB )/* [0x4CB] */
+#define PULL_CTRL_GP12_SPI_BYTE_ADDR (__GPIO_BASE + 0x4CC )/* [0x4CC] */
+#define PULL_CTRL_GP13_SD0_BYTE_ADDR (__GPIO_BASE + 0x4CD )/* [0x4CD] */
+#define PULL_CTRL_GP14_NAND_BYTE_ADDR (__GPIO_BASE + 0x4CE )/* [0x4CE] */
+#define PULL_CTRL_GP15_NAND_BYTE_ADDR (__GPIO_BASE + 0x4CF )/* [0x4CF] */
+#define PULL_CTRL_GP16_NANDIO_BYTE_ADDR (__GPIO_BASE + 0x4D0 )/* [0x4D0] */
+#define PULL_CTRL_GP17_I2C_BYTE_ADDR (__GPIO_BASE + 0x4D1 )/* [0x4D1] */
+#define PULL_CTRL_GP18_UART_BYTE_ADDR (__GPIO_BASE + 0x4D2 )/* [0x4D2] */
+#define PULL_CTRL_GP19_SD2_BYTE_ADDR (__GPIO_BASE + 0x4D3 )/* [0x4D3] */
+#define PULL_CTRL_GP20_PWM0_BYTE_ADDR (__GPIO_BASE + 0x4D4 )/* [0x4D4] */
+#define PULL_CTRL_GP21_HDMI_BYTE_ADDR (__GPIO_BASE + 0x4D5 )/* [0x4D5] */
+#define PULL_CTRL_GP23_I2C3_BYTE_ADDR (__GPIO_BASE + 0x4D7 )/* [0x4D7] */
+#define PULL_CTRL_GP24_SF_BYTE_ADDR (__GPIO_BASE + 0x4D8 )/* [0x4D8] */
+#define PULL_CTRL_GP26_PCM_BYTE_ADDR (__GPIO_BASE + 0x4DA )/* [0x4DA] */
+#define PULL_CTRL_GP27_SD0_BYTE_ADDR (__GPIO_BASE + 0x4DB )/* [0x4DB] */
+#define PULL_CTRL_GP60_USB_BYTE_ADDR (__GPIO_BASE + 0x4FC )/* [0x4FC] */
+#define PULL_CTRL_GP62_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0x4FE )/* [0x4FE] */
+#define PULL_CTRL_GP63_SD02_BYTE_ADDR (__GPIO_BASE + 0x4FF )/* [0x4FF] */
+#define DRV_GPIO_7_0_4BYTE_ADDR (__GPIO_BASE + 0x800 )/* [0x800 ~ 0x803] */
+#define DRV_GPIO_13_8_4BYTE_ADDR (__GPIO_BASE + 0x804 )/* [0x804 ~ 0x807] */
+#define DRV_GPIO_19_14_4BYTE_ADDR (__GPIO_BASE + 0x808 )/* [0x808 ~ 0x80B] */
+#define DRV_VDIN_3_0_4BYTE_ADDR (__GPIO_BASE + 0x80C )/* [0x80C ~ 0x80F] */
+#define DRV_VDIN_4_6_4BYTE_ADDR (__GPIO_BASE + 0x810 )/* [0x810 ~ 0x813] */
+#define DRV_VDIN_SPI_4BYTE_ADDR (__GPIO_BASE + 0x814 )/* [0x814 ~ 0x817] */
+#define DRV_SPI_NAND_4BYTE_ADDR (__GPIO_BASE + 0x818 )/* [0x818 ~ 0x81B] */
+#define DRV_NAND_4BYTE_ADDR (__GPIO_BASE + 0x81C )/* [0x81C ~ 0x81F] */
+#define DRV_NANDIO_4BYTE_ADDR (__GPIO_BASE + 0x820 )/* [0x820 ~ 0x823] */
+#define DRV_HDMI_I2C_4BYTE_ADDR (__GPIO_BASE + 0x824 )/* [0x824 ~ 0x827] */
+#define DRV_I2C_SD0_4BYTE_ADDR (__GPIO_BASE + 0x828 )/* [0x828 ~ 0x82B] */
+#define DRV_SD0_SD2_4BYTE_ADDR (__GPIO_BASE + 0x82C )/* [0x82C ~ 0x82F] */
+#define DRV_SD2_I2S_4BYTE_ADDR (__GPIO_BASE + 0x830 )/* [0x830 ~ 0x833] */
+#define DRV_I2S_UART_4BYTE_ADDR (__GPIO_BASE + 0x834 )/* [0x834 ~ 0x837] */
+#define DRV_UART_4BYTE_ADDR (__GPIO_BASE + 0x838 )/* [0x838 ~ 0x83B] */
+#define DRV_SF_JTAGT_4BYTE_ADDR (__GPIO_BASE + 0x83C )/* [0x83C ~ 0x83F] */
+#define DRV_JTAGT_PWM_4BYTE_ADDR (__GPIO_BASE + 0x840 )/* [0x840 ~ 0x843] */
+#define DRV_PCM_BYTE_ADDR (__GPIO_BASE + 0x844 )/* [0x844] */
+#define DRV_SPI_BYTE_ADDR (__GPIO_BASE + 0x84C )/* [0x84C] */
+
+
+
+#define GPIO_ID_GP0_BYTE_REG REG8_PTR(GPIO_ID_GP0_BYTE_ADDR )
+#define GPIO_ID_GP1_BYTE_REG REG8_PTR(GPIO_ID_GP1_BYTE_ADDR )
+#define GPIO_ID_GP2_BYTE_REG REG8_PTR(GPIO_ID_GP2_BYTE_ADDR )
+#define GPIO_ID_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(GPIO_ID_GP4_VDOUT_7_0_BYTE_ADDR )
+#define GPIO_ID_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(GPIO_ID_GP5_VDOUT_15_8_BYTE_ADDR )
+#define GPIO_ID_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(GPIO_ID_GP6_VDOUT_23_16_BYTE_ADDR )
+#define GPIO_ID_GP7_VD_BYTE_REG REG8_PTR(GPIO_ID_GP7_VD_BYTE_ADDR )
+#define GPIO_ID_GP8_VDIN_BYTE_REG REG8_PTR(GPIO_ID_GP8_VDIN_BYTE_ADDR )
+#define GPIO_ID_GP9_VSYNC_BYTE_REG REG8_PTR(GPIO_ID_GP9_VSYNC_BYTE_ADDR )
+#define GPIO_ID_GP10_I2S_BYTE_REG REG8_PTR(GPIO_ID_GP10_I2S_BYTE_ADDR )
+#define GPIO_ID_GP11_I2S_BYTE_REG REG8_PTR(GPIO_ID_GP11_I2S_BYTE_ADDR )
+#define GPIO_ID_GP12_SPI_BYTE_REG REG8_PTR(GPIO_ID_GP12_SPI_BYTE_ADDR )
+#define GPIO_ID_GP13_SD0_BYTE_REG REG8_PTR(GPIO_ID_GP13_SD0_BYTE_ADDR )
+#define GPIO_ID_GP14_NAND_SD1_BYTE_REG REG8_PTR(GPIO_ID_GP14_NAND_SD1_BYTE_ADDR )
+#define GPIO_ID_GP15_NAND_BYTE_REG REG8_PTR(GPIO_ID_GP15_NAND_BYTE_ADDR )
+#define GPIO_ID_GP16_NAND_SD1_BYTE_REG REG8_PTR(GPIO_ID_GP16_NAND_SD1_BYTE_ADDR )
+#define GPIO_ID_GP17_I2C_BYTE_REG REG8_PTR(GPIO_ID_GP17_I2C_BYTE_ADDR )
+#define GPIO_ID_GP18_UART_BYTE_REG REG8_PTR(GPIO_ID_GP18_UART_BYTE_ADDR )
+#define GPIO_ID_GP19_SD2_BYTE_REG REG8_PTR(GPIO_ID_GP19_SD2_BYTE_ADDR )
+#define GPIO_ID_GP20_PWM0_BYTE_REG REG8_PTR(GPIO_ID_GP20_PWM0_BYTE_ADDR )
+#define GPIO_ID_GP21_HDMI_BYTE_REG REG8_PTR(GPIO_ID_GP21_HDMI_BYTE_ADDR )
+#define GPIO_ID_GP23_I2C3_BYTE_REG REG8_PTR(GPIO_ID_GP23_I2C3_BYTE_ADDR )
+#define GPIO_ID_GP24_SF_BYTE_REG REG8_PTR(GPIO_ID_GP24_SF_BYTE_ADDR )
+#define GPIO_ID_GP26_PCM_BYTE_REG REG8_PTR(GPIO_ID_GP26_PCM_BYTE_ADDR )
+#define GPIO_ID_GP60_USB_BYTE_REG REG8_PTR(GPIO_ID_GP60_USB_BYTE_ADDR )
+#define GPIO_ID_GP62_WAKEUP_SUS_BYTE_REG REG8_PTR(GPIO_ID_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define GPIO_ID_GP63_SD02CD_BYTE_REG REG8_PTR(GPIO_ID_GP63_SD02CD_BYTE_ADDR )
+#define GPIO_CTRL_GP0_BYTE_REG REG8_PTR(GPIO_CTRL_GP0_BYTE_ADDR )
+#define GPIO_CTRL_GP1_BYTE_REG REG8_PTR(GPIO_CTRL_GP1_BYTE_ADDR )
+#define GPIO_CTRL_GP2_BYTE_REG REG8_PTR(GPIO_CTRL_GP2_BYTE_ADDR )
+#define GPIO_CTRL_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(GPIO_CTRL_GP4_VDOUT_7_0_BYTE_ADDR )
+#define GPIO_CTRL_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(GPIO_CTRL_GP5_VDOUT_15_8_BYTE_ADDR )
+#define GPIO_CTRL_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(GPIO_CTRL_GP6_VDOUT_23_16_BYTE_ADDR )
+#define GPIO_CTRL_GP7_VD_BYTE_REG REG8_PTR(GPIO_CTRL_GP7_VD_BYTE_ADDR )
+#define GPIO_CTRL_GP8_VDIN_BYTE_REG REG8_PTR(GPIO_CTRL_GP8_VDIN_BYTE_ADDR )
+#define GPIO_CTRL_GP9_VSYNC_BYTE_REG REG8_PTR(GPIO_CTRL_GP9_VSYNC_BYTE_ADDR )
+#define GPIO_CTRL_GP10_I2S_BYTE_REG REG8_PTR(GPIO_CTRL_GP10_I2S_BYTE_ADDR )
+#define GPIO_CTRL_GP11_I2S_BYTE_REG REG8_PTR(GPIO_CTRL_GP11_I2S_BYTE_ADDR )
+#define GPIO_CTRL_GP12_SPI_BYTE_REG REG8_PTR(GPIO_CTRL_GP12_SPI_BYTE_ADDR )
+#define GPIO_CTRL_GP13_SD0_BYTE_REG REG8_PTR(GPIO_CTRL_GP13_SD0_BYTE_ADDR )
+#define GPIO_CTRL_GP14_NAND_SD1_BYTE_REG REG8_PTR(GPIO_CTRL_GP14_NAND_SD1_BYTE_ADDR )
+#define GPIO_CTRL_GP15_NAND_BYTE_REG REG8_PTR(GPIO_CTRL_GP15_NAND_BYTE_ADDR )
+#define GPIO_CTRL_GP16_NAND_SD1_BYTE_REG REG8_PTR(GPIO_CTRL_GP16_NAND_SD1_BYTE_ADDR )
+#define GPIO_CTRL_GP17_I2C_BYTE_REG REG8_PTR(GPIO_CTRL_GP17_I2C_BYTE_ADDR )
+#define GPIO_CTRL_GP18_UART_BYTE_REG REG8_PTR(GPIO_CTRL_GP18_UART_BYTE_ADDR )
+#define GPIO_CTRL_GP19_SD2_BYTE_REG REG8_PTR(GPIO_CTRL_GP19_SD2_BYTE_ADDR )
+#define GPIO_CTRL_GP20_PWM0_BYTE_REG REG8_PTR(GPIO_CTRL_GP20_PWM0_BYTE_ADDR )
+#define GPIO_CTRL_GP21_HDMI_BYTE_REG REG8_PTR(GPIO_CTRL_GP21_HDMI_BYTE_ADDR )
+#define GPIO_CTRL_GP23_I2C3_BYTE_REG REG8_PTR(GPIO_CTRL_GP23_I2C3_BYTE_ADDR )
+#define GPIO_CTRL_GP24_SF_BYTE_REG REG8_PTR(GPIO_CTRL_GP24_SF_BYTE_ADDR )
+#define GPIO_CTRL_GP26_PCM_BYTE_REG REG8_PTR(GPIO_CTRL_GP26_PCM_BYTE_ADDR )
+#define GPIO_CTRL_GP60_USB_BYTE_REG REG8_PTR(GPIO_CTRL_GP60_USB_BYTE_ADDR )
+#define GPIO_CTRL_GP62_WAKEUP_SUS_BYTE_REG REG8_PTR(GPIO_CTRL_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define GPIO_CTRL_GP63_SD02CD_BYTE_REG REG8_PTR(GPIO_CTRL_GP63_SD02CD_BYTE_ADDR )
+#define GPIO_OC_GP0_BYTE_REG REG8_PTR(GPIO_OC_GP0_BYTE_ADDR )
+#define GPIO_OC_GP1_BYTE_REG REG8_PTR(GPIO_OC_GP1_BYTE_ADDR )
+#define GPIO_OC_GP2_BYTE_REG REG8_PTR(GPIO_OC_GP2_BYTE_ADDR )
+#define GPIO_OC_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(GPIO_OC_GP4_VDOUT_7_0_BYTE_ADDR )
+#define GPIO_OC_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(GPIO_OC_GP5_VDOUT_15_8_BYTE_ADDR )
+#define GPIO_OC_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(GPIO_OC_GP6_VDOUT_23_16_BYTE_ADDR )
+#define GPIO_OC_GP7_VD_BYTE_REG REG8_PTR(GPIO_OC_GP7_VD_BYTE_ADDR )
+#define GPIO_OC_GP8_VDIN_BYTE_REG REG8_PTR(GPIO_OC_GP8_VDIN_BYTE_ADDR )
+#define GPIO_OC_GP9_VSYNC_BYTE_REG REG8_PTR(GPIO_OC_GP9_VSYNC_BYTE_ADDR )
+#define GPIO_OC_GP10_I2S_BYTE_REG REG8_PTR(GPIO_OC_GP10_I2S_BYTE_ADDR )
+#define GPIO_OC_GP11_I2S_BYTE_REG REG8_PTR(GPIO_OC_GP11_I2S_BYTE_ADDR )
+#define GPIO_OC_GP12_SPI_BYTE_REG REG8_PTR(GPIO_OC_GP12_SPI_BYTE_ADDR )
+#define GPIO_OC_GP13_SD0_BYTE_REG REG8_PTR(GPIO_OC_GP13_SD0_BYTE_ADDR )
+#define GPIO_OC_GP14_NAND_SD1_BYTE_REG REG8_PTR(GPIO_OC_GP14_NAND_SD1_BYTE_ADDR )
+#define GPIO_OC_GP15_NAND_BYTE_REG REG8_PTR(GPIO_OC_GP15_NAND_BYTE_ADDR )
+#define GPIO_OC_GP16_NAND_SD1_BYTE_REG REG8_PTR(GPIO_OC_GP16_NAND_SD1_BYTE_ADDR )
+#define GPIO_OC_GP17_I2C_BYTE_REG REG8_PTR(GPIO_OC_GP17_I2C_BYTE_ADDR )
+#define GPIO_OC_GP18_UART_BYTE_REG REG8_PTR(GPIO_OC_GP18_UART_BYTE_ADDR )
+#define GPIO_OC_GP19_SD2_BYTE_REG REG8_PTR(GPIO_OC_GP19_SD2_BYTE_ADDR )
+#define GPIO_OC_GP20_PWM0_BYTE_REG REG8_PTR(GPIO_OC_GP20_PWM0_BYTE_ADDR )
+#define GPIO_OC_GP21_HDMI_BYTE_REG REG8_PTR(GPIO_OC_GP21_HDMI_BYTE_ADDR )
+#define GPIO_OC_GP22_I2C3_BYTE_REG REG8_PTR(GPIO_OC_GP22_I2C3_BYTE_ADDR )
+#define GPIO_OC_GP24_SF_BYTE_REG REG8_PTR(GPIO_OC_GP24_SF_BYTE_ADDR )
+#define GPIO_OC_GP26_PCM_BYTE_REG REG8_PTR(GPIO_OC_GP26_PCM_BYTE_ADDR )
+#define GPIO_OC_GP60_USB_BYTE_REG REG8_PTR(GPIO_OC_GP60_USB_BYTE_ADDR )
+#define GPIO_OC_GP62_WAKEUP_SUS_BYTE_REG REG8_PTR(GPIO_OC_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define GPIO_OC_GP63_SD02CD_BYTE_REG REG8_PTR(GPIO_OC_GP63_SD02CD_BYTE_ADDR )
+#define GPIO_OD_GP0_BYTE_REG REG8_PTR(GPIO_OD_GP0_BYTE_ADDR )
+#define GPIO_OD_GP1_BYTE_REG REG8_PTR(GPIO_OD_GP1_BYTE_ADDR )
+#define GPIO_OD_GP2_BYTE_REG REG8_PTR(GPIO_OD_GP2_BYTE_ADDR )
+#define GPIO_OD_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(GPIO_OD_GP4_VDOUT_7_0_BYTE_ADDR )
+#define GPIO_OD_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(GPIO_OD_GP5_VDOUT_15_8_BYTE_ADDR )
+#define GPIO_OD_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(GPIO_OD_GP6_VDOUT_23_16_BYTE_ADDR )
+#define GPIO_OD_GP7_VD_BYTE_REG REG8_PTR(GPIO_OD_GP7_VD_BYTE_ADDR )
+#define GPIO_OD_GP8_VDIN_BYTE_REG REG8_PTR(GPIO_OD_GP8_VDIN_BYTE_ADDR )
+#define GPIO_OD_GP9_VSYNC_BYTE_REG REG8_PTR(GPIO_OD_GP9_VSYNC_BYTE_ADDR )
+#define GPIO_OD_GP10_I2S_BYTE_REG REG8_PTR(GPIO_OD_GP10_I2S_BYTE_ADDR )
+#define GPIO_OD_GP11_I2S_BYTE_REG REG8_PTR(GPIO_OD_GP11_I2S_BYTE_ADDR )
+#define GPIO_OD_GP12_SPI_BYTE_REG REG8_PTR(GPIO_OD_GP12_SPI_BYTE_ADDR )
+#define GPIO_OD_GP13_SD0_BYTE_REG REG8_PTR(GPIO_OD_GP13_SD0_BYTE_ADDR )
+#define GPIO_OD_GP14_NAND_SD1_BYTE_REG REG8_PTR(GPIO_OD_GP14_NAND_SD1_BYTE_ADDR )
+#define GPIO_OD_GP15_NAND_BYTE_REG REG8_PTR(GPIO_OD_GP15_NAND_BYTE_ADDR )
+#define GPIO_OD_GP16_NAND_SD1_BYTE_REG REG8_PTR(GPIO_OD_GP16_NAND_SD1_BYTE_ADDR )
+#define GPIO_OD_GP17_I2C_BYTE_REG REG8_PTR(GPIO_OD_GP17_I2C_BYTE_ADDR )
+#define GPIO_OD_GP18_UART_BYTE_REG REG8_PTR(GPIO_OD_GP18_UART_BYTE_ADDR )
+#define GPIO_OD_GP19_SD2_BYTE_REG REG8_PTR(GPIO_OD_GP19_SD2_BYTE_ADDR )
+#define GPIO_OD_GP20_PWM0_BYTE_REG REG8_PTR(GPIO_OD_GP20_PWM0_BYTE_ADDR )
+#define GPIO_OD_GP21_HDMI_BYTE_REG REG8_PTR(GPIO_OD_GP21_HDMI_BYTE_ADDR )
+#define GPIO_OD_GP23_I2C3_BYTE_REG REG8_PTR(GPIO_OD_GP23_I2C3_BYTE_ADDR )
+#define GPIO_OD_GP24_SF_BYTE_REG REG8_PTR(GPIO_OD_GP24_SF_BYTE_ADDR )
+#define GPIO_OD_GP26_PCM_BYTE_REG REG8_PTR(GPIO_OD_GP26_PCM_BYTE_ADDR )
+#define GPIO_OD_GP60_USB_BYTE_REG REG8_PTR(GPIO_OD_GP60_USB_BYTE_ADDR )
+#define GPIO_OD_GP62_WAKEUP_SUS_BYTE_REG REG8_PTR(GPIO_OD_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define GPIO_OD_GP63_SD02CD_BYTE_REG REG8_PTR(GPIO_OD_GP63_SD02CD_BYTE_ADDR )
+#define STRAP_STATUS_REG REG32_PTR(STRAP_STATUS_ADDR )
+#define AHB_CTRL_4BYTE_REG REG32_PTR(AHB_CTRL_4BYTE_ADDR )
+#define USB_OP_CTRL_4BYTE_REG REG32_PTR(USB_OP_CTRL_4BYTE_ADDR )
+#define BONDING_OPTION_4BYTE_REG REG32_PTR(BONDING_OPTION_4BYTE_ADDR )
+#define PIN_SHARING_SEL_4BYTE_REG REG32_PTR(PIN_SHARING_SEL_4BYTE_ADDR )
+#define TPIU_CLK_DATA_4BYTE_REG REG32_PTR(TPIU_CLK_DATA_4BYTE_ADDR )
+#define GPIO0_INT_REQ_TYPE_REG REG8_PTR(GPIO0_INT_REQ_TYPE_ADDR )
+#define GPIO1_INT_REQ_TYPE_REG REG8_PTR(GPIO1_INT_REQ_TYPE_ADDR )
+#define GPIO2_INT_REQ_TYPE_REG REG8_PTR(GPIO2_INT_REQ_TYPE_ADDR )
+#define GPIO3_INT_REQ_TYPE_REG REG8_PTR(GPIO3_INT_REQ_TYPE_ADDR )
+#define GPIO4_INT_REQ_TYPE_REG REG8_PTR(GPIO4_INT_REQ_TYPE_ADDR )
+#define GPIO5_INT_REQ_TYPE_REG REG8_PTR(GPIO5_INT_REQ_TYPE_ADDR )
+#define GPIO6_INT_REQ_TYPE_REG REG8_PTR(GPIO6_INT_REQ_TYPE_ADDR )
+#define GPIO7_INT_REQ_TYPE_REG REG8_PTR(GPIO7_INT_REQ_TYPE_ADDR )
+#define GPIO8_INT_REQ_TYPE_REG REG8_PTR(GPIO8_INT_REQ_TYPE_ADDR )
+#define GPIO9_INT_REQ_TYPE_REG REG8_PTR(GPIO9_INT_REQ_TYPE_ADDR )
+#define GPIO10_INT_REQ_TYPE_REG REG8_PTR(GPIO10_INT_REQ_TYPE_ADDR )
+#define GPIO11_INT_REQ_TYPE_REG REG8_PTR(GPIO11_INT_REQ_TYPE_ADDR )
+#define GPIO12_INT_REQ_TYPE_REG REG8_PTR(GPIO12_INT_REQ_TYPE_ADDR )
+#define GPIO13_INT_REQ_TYPE_REG REG8_PTR(GPIO13_INT_REQ_TYPE_ADDR )
+#define GPIO18_INT_REQ_TYPE_REG REG8_PTR(GPIO18_INT_REQ_TYPE_ADDR )
+#define GPIO19_INT_REQ_TYPE_REG REG8_PTR(GPIO19_INT_REQ_TYPE_ADDR )
+#define VOUT20_INT_REQ_TYPE_REG REG8_PTR(VOUT20_INT_REQ_TYPE_ADDR )
+#define VOUT21_INT_REQ_TYPE_REG REG8_PTR(VOUT21_INT_REQ_TYPE_ADDR )
+#define VOUT22_INT_REQ_TYPE_REG REG8_PTR(VOUT22_INT_REQ_TYPE_ADDR )
+#define VOUT23_INT_REQ_TYPE_REG REG8_PTR(VOUT23_INT_REQ_TYPE_ADDR )
+#define GPIO20_INT_REQ_TYPE_REG REG8_PTR(GPIO20_INT_REQ_TYPE_ADDR )
+#define GPIO21_INT_REQ_TYPE_REG REG8_PTR(GPIO21_INT_REQ_TYPE_ADDR )
+#define GPIO22_INT_REQ_TYPE_REG REG8_PTR(GPIO22_INT_REQ_TYPE_ADDR )
+#define GPIO23_INT_REQ_TYPE_REG REG8_PTR(GPIO23_INT_REQ_TYPE_ADDR )
+#define GPIO24_INT_REQ_TYPE_REG REG8_PTR(GPIO24_INT_REQ_TYPE_ADDR )
+#define GPIO25_INT_REQ_TYPE_REG REG8_PTR(GPIO25_INT_REQ_TYPE_ADDR )
+#define GPIO0_INT_REQ_STS_REG REG8_PTR(GPIO0_INT_REQ_STS_ADDR )
+#define GPIO1_INT_REQ_STS_REG REG8_PTR(GPIO1_INT_REQ_STS_ADDR )
+#define GPIO2_INT_REQ_STS_REG REG8_PTR(GPIO2_INT_REQ_STS_ADDR )
+#define GPIO3_INT_REQ_STS_REG REG8_PTR(GPIO3_INT_REQ_STS_ADDR )
+#define DRV_DVO_CLK_BYTE_REG REG8_PTR(DRV_DVO_CLK_BYTE_ADDR )
+#define DRV_DVO_VDEN_BYTE_REG REG8_PTR(DRV_DVO_VDEN_BYTE_ADDR )
+#define SD0_DPCTL_4BYTE_REG REG32_PTR(SD0_DPCTL_4BYTE_ADDR )
+#define SD0_DNCTL_4BYTE_REG REG32_PTR(SD0_DNCTL_4BYTE_ADDR )
+#define DRV_SD0_USB_BYTE_REG REG8_PTR(DRV_SD0_USB_BYTE_ADDR )
+#define DRV_USB_SWOC0_BYTE_REG REG8_PTR(DRV_USB_SWOC0_BYTE_ADDR )
+#define DRV_USB_OC12_BYTE_REG REG8_PTR(DRV_USB_OC12_BYTE_ADDR )
+#define DRV_USBOC3_CIR_BYTE_REG REG8_PTR(DRV_USBOC3_CIR_BYTE_ADDR )
+#define DRV_PWREN_BYTE_REG REG8_PTR(DRV_PWREN_BYTE_ADDR )
+#define DRV_PWREN_WAKEUP0_BYTE_REG REG8_PTR(DRV_PWREN_WAKEUP0_BYTE_ADDR )
+#define DRV_SUSGP01_BYTE_REG REG8_PTR(DRV_SUSGP01_BYTE_ADDR )
+#define DRV_WAKEUP23_BYTE_REG REG8_PTR(DRV_WAKEUP23_BYTE_ADDR )
+#define DRV_WAKEUP45_BYTE_REG REG8_PTR(DRV_WAKEUP45_BYTE_ADDR )
+#define DRV_I2C_BYTE_REG REG8_PTR(DRV_I2C_BYTE_ADDR )
+#define DRV_HDMI_BYTE_REG REG8_PTR(DRV_HDMI_BYTE_ADDR )
+#define PULL_EN_GP0_BYTE_REG REG8_PTR(PULL_EN_GP0_BYTE_ADDR )
+#define PULL_EN_GP1_BYTE_REG REG8_PTR(PULL_EN_GP1_BYTE_ADDR )
+#define PULL_EN_GP2_BYTE_REG REG8_PTR(PULL_EN_GP2_BYTE_ADDR )
+#define PULL_EN_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(PULL_EN_GP4_VDOUT_7_0_BYTE_ADDR )
+#define PULL_EN_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(PULL_EN_GP5_VDOUT_15_8_BYTE_ADDR )
+#define PULL_EN_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(PULL_EN_GP6_VDOUT_23_16_BYTE_ADDR )
+#define PULL_EN_GP7_VD_BYTE_REG REG8_PTR(PULL_EN_GP7_VD_BYTE_ADDR )
+#define PULL_EN_GP8_VDIN_BYTE_REG REG8_PTR(PULL_EN_GP8_VDIN_BYTE_ADDR )
+#define PULL_EN_GP9_VSYNC_BYTE_REG REG8_PTR(PULL_EN_GP9_VSYNC_BYTE_ADDR )
+#define PULL_EN_GP10_I2S_BYTE_REG REG8_PTR(PULL_EN_GP10_I2S_BYTE_ADDR )
+#define PULL_EN_GP11_I2S_BYTE_REG REG8_PTR(PULL_EN_GP11_I2S_BYTE_ADDR )
+#define PULL_EN_GP12_SPI_BYTE_REG REG8_PTR(PULL_EN_GP12_SPI_BYTE_ADDR )
+#define PULL_EN_GP13_SD0_BYTE_REG REG8_PTR(PULL_EN_GP13_SD0_BYTE_ADDR )
+#define PULL_EN_GP14_NAND_BYTE_REG REG8_PTR(PULL_EN_GP14_NAND_BYTE_ADDR )
+#define PULL_EN_GP15_NAND_BYTE_REG REG8_PTR(PULL_EN_GP15_NAND_BYTE_ADDR )
+#define PULL_EN_GP16_NANDIO_BYTE_REG REG8_PTR(PULL_EN_GP16_NANDIO_BYTE_ADDR )
+#define PULL_EN_GP17_I2C_BYTE_REG REG8_PTR(PULL_EN_GP17_I2C_BYTE_ADDR )
+#define PULL_EN_GP18_UART_BYTE_REG REG8_PTR(PULL_EN_GP18_UART_BYTE_ADDR )
+#define PULL_EN_GP19_SD2_BYTE_REG REG8_PTR(PULL_EN_GP19_SD2_BYTE_ADDR )
+#define PULL_EN_GP20_PWM0_BYTE_REG REG8_PTR(PULL_EN_GP20_PWM0_BYTE_ADDR )
+#define PULL_EN_GP21_HDMI_BYTE_REG REG8_PTR(PULL_EN_GP21_HDMI_BYTE_ADDR )
+#define PULL_EN_GP23_I2C3_BYTE_REG REG8_PTR(PULL_EN_GP23_I2C3_BYTE_ADDR )
+#define PULL_EN_GP24_SF_BYTE_REG REG8_PTR(PULL_EN_GP24_SF_BYTE_ADDR )
+#define PULL_EN_GP26_PCM_BYTE_REG REG8_PTR(PULL_EN_GP26_PCM_BYTE_ADDR )
+#define PULL_EN_GP60_USB_BYTE_REG REG8_PTR(PULL_EN_GP60_USB_BYTE_ADDR )
+#define PULL_EN_GP62_WAKEUP_SUS_BYTE_REG REG8_PTR(PULL_EN_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define PULL_EN_GP63_SD02_BYTE_REG REG8_PTR(PULL_EN_GP63_SD02_BYTE_ADDR )
+#define PULL_CTRL_GP0_BYTE_REG REG8_PTR(PULL_CTRL_GP0_BYTE_ADDR )
+#define PULL_CTRL_GP1_BYTE_REG REG8_PTR(PULL_CTRL_GP1_BYTE_ADDR )
+#define PULL_CTRL_GP2_BYTE_REG REG8_PTR(PULL_CTRL_GP2_BYTE_ADDR )
+#define PULL_CTRL_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(PULL_CTRL_GP4_VDOUT_7_0_BYTE_ADDR )
+#define PULL_CTRL_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(PULL_CTRL_GP5_VDOUT_15_8_BYTE_ADDR )
+#define PULL_CTRL_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(PULL_CTRL_GP6_VDOUT_23_16_BYTE_ADDR )
+#define PULL_CTRL_GP7_VD_BYTE_REG REG8_PTR(PULL_CTRL_GP7_VD_BYTE_ADDR )
+#define PULL_CTRL_GP8_VDIN_BYTE_REG REG8_PTR(PULL_CTRL_GP8_VDIN_BYTE_ADDR )
+#define PULL_CTRL_GP9_VSYNC_BYTE_REG REG8_PTR(PULL_CTRL_GP9_VSYNC_BYTE_ADDR )
+#define PULL_CTRL_GP10_I2S_BYTE_REG REG8_PTR(PULL_CTRL_GP10_I2S_BYTE_ADDR )
+#define PULL_CTRL_GP11_I2S_BYTE_REG REG8_PTR(PULL_CTRL_GP11_I2S_BYTE_ADDR )
+#define PULL_CTRL_GP12_SPI_BYTE_REG REG8_PTR(PULL_CTRL_GP12_SPI_BYTE_ADDR )
+#define PULL_CTRL_GP13_SD0_BYTE_REG REG8_PTR(PULL_CTRL_GP13_SD0_BYTE_ADDR )
+#define PULL_CTRL_GP14_NAND_BYTE_REG REG8_PTR(PULL_CTRL_GP14_NAND_BYTE_ADDR )
+#define PULL_CTRL_GP15_NAND_BYTE_REG REG8_PTR(PULL_CTRL_GP15_NAND_BYTE_ADDR )
+#define PULL_CTRL_GP16_NANDIO_BYTE_REG REG8_PTR(PULL_CTRL_GP16_NANDIO_BYTE_ADDR )
+#define PULL_CTRL_GP17_I2C_BYTE_REG REG8_PTR(PULL_CTRL_GP17_I2C_BYTE_ADDR )
+#define PULL_CTRL_GP18_UART_BYTE_REG REG8_PTR(PULL_CTRL_GP18_UART_BYTE_ADDR )
+#define PULL_CTRL_GP19_SD2_BYTE_REG REG8_PTR(PULL_CTRL_GP19_SD2_BYTE_ADDR )
+#define PULL_CTRL_GP20_PWM0_BYTE_REG REG8_PTR(PULL_CTRL_GP20_PWM0_BYTE_ADDR )
+#define PULL_CTRL_GP21_HDMI_BYTE_REG REG8_PTR(PULL_CTRL_GP21_HDMI_BYTE_ADDR )
+#define PULL_CTRL_GP23_I2C3_BYTE_REG REG8_PTR(PULL_CTRL_GP23_I2C3_BYTE_ADDR )
+#define PULL_CTRL_GP24_SF_BYTE_REG REG8_PTR(PULL_CTRL_GP24_SF_BYTE_ADDR )
+#define PULL_CTRL_GP26_PCM_BYTE_REG REG8_PTR(PULL_CTRL_GP26_PCM_BYTE_ADDR )
+#define PULL_CTRL_GP27_SD0_BYTE_REG REG8_PTR(PULL_CTRL_GP27_SD0_BYTE_ADDR )
+#define PULL_CTRL_GP60_USB_BYTE_REG REG8_PTR(PULL_CTRL_GP60_USB_BYTE_ADDR )
+#define PULL_CTRL_GP62_WAKEUP_SUS_BYTE_REG REG8_PTR(PULL_CTRL_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define PULL_CTRL_GP63_SD02_BYTE_REG REG8_PTR(PULL_CTRL_GP63_SD02_BYTE_ADDR )
+#define DRV_GPIO_7_0_4BYTE_REG REG32_PTR(DRV_GPIO_7_0_4BYTE_ADDR )
+#define DRV_GPIO_13_8_4BYTE_REG REG32_PTR(DRV_GPIO_13_8_4BYTE_ADDR )
+#define DRV_GPIO_19_14_4BYTE_REG REG32_PTR(DRV_GPIO_19_14_4BYTE_ADDR )
+#define DRV_VDIN_3_0_4BYTE_REG REG32_PTR(DRV_VDIN_3_0_4BYTE_ADDR )
+#define DRV_VDIN_4_6_4BYTE_REG REG32_PTR(DRV_VDIN_3_0_4BYTE_ADDR )
+#define DRV_VDIN_SPI_4BYTE_REG REG32_PTR(DRV_VDIN_SPI_4BYTE_ADDR )
+#define DRV_SPI_NAND_4BYTE_REG REG32_PTR(DRV_SPI_NAND_4BYTE_ADDR )
+#define DRV_NAND_4BYTE_REG REG32_PTR(DRV_NAND_4BYTE_ADDR )
+#define DRV_NANDIO_4BYTE_REG REG32_PTR(DRV_NANDIO_4BYTE_ADDR )
+#define DRV_HDMI_I2C_4BYTE_REG REG32_PTR(DRV_HDMI_I2C_4BYTE_ADDR )
+#define DRV_I2C_SD0_4BYTE_REG REG32_PTR(DRV_I2C_SD0_4BYTE_ADDR )
+#define DRV_SD0_SD2_4BYTE_REG REG32_PTR(DRV_SD0_SD2_4BYTE_ADDR )
+#define DRV_SD2_I2S_4BYTE_REG REG32_PTR(DRV_SD2_I2S_4BYTE_ADDR )
+#define DRV_I2S_UART_4BYTE_REG REG32_PTR(DRV_I2S_UART_4BYTE_ADDR )
+#define DRV_UART_4BYTE_REG REG32_PTR(DRV_UART_4BYTE_ADDR )
+#define DRV_SF_JTAGT_4BYTE_REG REG32_PTR(DRV_SF_JTAGT_4BYTE_ADDR )
+#define DRV_JTAGT_PWM_4BYTE_REG REG32_PTR(DRV_JTAGT_PWM_4BYTE_ADDR )
+#define DRV_PCM_BYTE_REG REG8_PTR(DRV_PCM_BYTE_ADDR )
+#define DRV_SPI_BYTE_REG REG8_PTR(DRV_SPI_BYTE_ADDR )
+
+#define GPIO_ID_GP0_BYTE_VAL REG8_VAL(GPIO_ID_GP0_BYTE_ADDR )
+#define GPIO_ID_GP1_BYTE_VAL REG8_VAL(GPIO_ID_GP1_BYTE_ADDR )
+#define GPIO_ID_GP2_BYTE_VAL REG8_VAL(GPIO_ID_GP2_BYTE_ADDR )
+#define GPIO_ID_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(GPIO_ID_GP4_VDOUT_7_0_BYTE_ADDR )
+#define GPIO_ID_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(GPIO_ID_GP5_VDOUT_15_8_BYTE_ADDR )
+#define GPIO_ID_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(GPIO_ID_GP6_VDOUT_23_16_BYTE_ADDR )
+#define GPIO_ID_GP7_VD_BYTE_VAL REG8_VAL(GPIO_ID_GP7_VD_BYTE_ADDR )
+#define GPIO_ID_GP8_VDIN_BYTE_VAL REG8_VAL(GPIO_ID_GP8_VDIN_BYTE_ADDR )
+#define GPIO_ID_GP9_VSYNC_BYTE_VAL REG8_VAL(GPIO_ID_GP9_VSYNC_BYTE_ADDR )
+#define GPIO_ID_GP10_I2S_BYTE_VAL REG8_VAL(GPIO_ID_GP10_I2S_BYTE_ADDR )
+#define GPIO_ID_GP11_I2S_BYTE_VAL REG8_VAL(GPIO_ID_GP11_I2S_BYTE_ADDR )
+#define GPIO_ID_GP12_SPI_BYTE_VAL REG8_VAL(GPIO_ID_GP12_SPI_BYTE_ADDR )
+#define GPIO_ID_GP13_SD0_BYTE_VAL REG8_VAL(GPIO_ID_GP13_SD0_BYTE_ADDR )
+#define GPIO_ID_GP14_NAND_SD1_BYTE_VAL REG8_VAL(GPIO_ID_GP14_NAND_SD1_BYTE_ADDR )
+#define GPIO_ID_GP15_NAND_BYTE_VAL REG8_VAL(GPIO_ID_GP15_NAND_BYTE_ADDR )
+#define GPIO_ID_GP16_NAND_SD1_BYTE_VAL REG8_VAL(GPIO_ID_GP16_NAND_SD1_BYTE_ADDR )
+#define GPIO_ID_GP17_I2C_BYTE_VAL REG8_VAL(GPIO_ID_GP17_I2C_BYTE_ADDR )
+#define GPIO_ID_GP18_UART_BYTE_VAL REG8_VAL(GPIO_ID_GP18_UART_BYTE_ADDR )
+#define GPIO_ID_GP19_SD2_BYTE_VAL REG8_VAL(GPIO_ID_GP19_SD2_BYTE_ADDR )
+#define GPIO_ID_GP20_PWM0_BYTE_VAL REG8_VAL(GPIO_ID_GP20_PWM0_BYTE_ADDR )
+#define GPIO_ID_GP21_HDMI_BYTE_VAL REG8_VAL(GPIO_ID_GP21_HDMI_BYTE_ADDR )
+#define GPIO_ID_GP23_I2C3_BYTE_VAL REG8_VAL(GPIO_ID_GP23_I2C3_BYTE_ADDR )
+#define GPIO_ID_GP24_SF_BYTE_VAL REG8_VAL(GPIO_ID_GP24_SF_BYTE_ADDR )
+#define GPIO_ID_GP26_PCM_BYTE_VAL REG8_VAL(GPIO_ID_GP26_PCM_BYTE_ADDR )
+#define GPIO_ID_GP60_USB_BYTE_VAL REG8_VAL(GPIO_ID_GP60_USB_BYTE_ADDR )
+#define GPIO_ID_GP62_WAKEUP_SUS_BYTE_VAL REG8_VAL(GPIO_ID_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define GPIO_ID_GP63_SD02CD_BYTE_VAL REG8_VAL(GPIO_ID_GP63_SD02CD_BYTE_ADDR )
+#define GPIO_CTRL_GP0_BYTE_VAL REG8_VAL(GPIO_CTRL_GP0_BYTE_ADDR )
+#define GPIO_CTRL_GP1_BYTE_VAL REG8_VAL(GPIO_CTRL_GP1_BYTE_ADDR )
+#define GPIO_CTRL_GP2_BYTE_VAL REG8_VAL(GPIO_CTRL_GP2_BYTE_ADDR )
+#define GPIO_CTRL_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(GPIO_CTRL_GP4_VDOUT_7_0_BYTE_ADDR )
+#define GPIO_CTRL_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(GPIO_CTRL_GP5_VDOUT_15_8_BYTE_ADDR )
+#define GPIO_CTRL_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(GPIO_CTRL_GP6_VDOUT_23_16_BYTE_ADDR )
+#define GPIO_CTRL_GP7_VD_BYTE_VAL REG8_VAL(GPIO_CTRL_GP7_VD_BYTE_ADDR )
+#define GPIO_CTRL_GP8_VDIN_BYTE_VAL REG8_VAL(GPIO_CTRL_GP8_VDIN_BYTE_ADDR )
+#define GPIO_CTRL_GP9_VSYNC_BYTE_VAL REG8_VAL(GPIO_CTRL_GP9_VSYNC_BYTE_ADDR )
+#define GPIO_CTRL_GP10_I2S_BYTE_VAL REG8_VAL(GPIO_CTRL_GP10_I2S_BYTE_ADDR )
+#define GPIO_CTRL_GP11_I2S_BYTE_VAL REG8_VAL(GPIO_CTRL_GP11_I2S_BYTE_ADDR )
+#define GPIO_CTRL_GP12_SPI_BYTE_VAL REG8_VAL(GPIO_CTRL_GP12_SPI_BYTE_ADDR )
+#define GPIO_CTRL_GP13_SD0_BYTE_VAL REG8_VAL(GPIO_CTRL_GP13_SD0_BYTE_ADDR )
+#define GPIO_CTRL_GP14_NAND_SD1_BYTE_VAL REG8_VAL(GPIO_CTRL_GP14_NAND_SD1_BYTE_ADDR )
+#define GPIO_CTRL_GP15_NAND_BYTE_VAL REG8_VAL(GPIO_CTRL_GP15_NAND_BYTE_ADDR )
+#define GPIO_CTRL_GP16_NAND_SD1_BYTE_VAL REG8_VAL(GPIO_CTRL_GP16_NAND_SD1_BYTE_ADDR )
+#define GPIO_CTRL_GP17_I2C_BYTE_VAL REG8_VAL(GPIO_CTRL_GP17_I2C_BYTE_ADDR )
+#define GPIO_CTRL_GP18_UART_BYTE_VAL REG8_VAL(GPIO_CTRL_GP18_UART_BYTE_ADDR )
+#define GPIO_CTRL_GP19_SD2_BYTE_VAL REG8_VAL(GPIO_CTRL_GP19_SD2_BYTE_ADDR )
+#define GPIO_CTRL_GP20_PWM0_BYTE_VAL REG8_VAL(GPIO_CTRL_GP20_PWM0_BYTE_ADDR )
+#define GPIO_CTRL_GP21_HDMI_BYTE_VAL REG8_VAL(GPIO_CTRL_GP21_HDMI_BYTE_ADDR )
+#define GPIO_CTRL_GP23_I2C3_BYTE_VAL REG8_VAL(GPIO_CTRL_GP23_I2C3_BYTE_ADDR )
+#define GPIO_CTRL_GP24_SF_BYTE_VAL REG8_VAL(GPIO_CTRL_GP24_SF_BYTE_ADDR )
+#define GPIO_CTRL_GP26_PCM_BYTE_VAL REG8_VAL(GPIO_CTRL_GP26_PCM_BYTE_ADDR )
+#define GPIO_CTRL_GP60_USB_BYTE_VAL REG8_VAL(GPIO_CTRL_GP60_USB_BYTE_ADDR )
+#define GPIO_CTRL_GP62_WAKEUP_SUS_BYTE_VAL REG8_VAL(GPIO_CTRL_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define GPIO_CTRL_GP63_SD02CD_BYTE_VAL REG8_VAL(GPIO_CTRL_GP63_SD02CD_BYTE_ADDR )
+#define GPIO_OC_GP0_BYTE_VAL REG8_VAL(GPIO_OC_GP0_BYTE_ADDR )
+#define GPIO_OC_GP1_BYTE_VAL REG8_VAL(GPIO_OC_GP1_BYTE_ADDR )
+#define GPIO_OC_GP2_BYTE_VAL REG8_VAL(GPIO_OC_GP2_BYTE_ADDR )
+#define GPIO_OC_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(GPIO_OC_GP4_VDOUT_7_0_BYTE_ADDR )
+#define GPIO_OC_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(GPIO_OC_GP5_VDOUT_15_8_BYTE_ADDR )
+#define GPIO_OC_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(GPIO_OC_GP6_VDOUT_23_16_BYTE_ADDR )
+#define GPIO_OC_GP7_VD_BYTE_VAL REG8_VAL(GPIO_OC_GP7_VD_BYTE_ADDR )
+#define GPIO_OC_GP8_VDIN_BYTE_VAL REG8_VAL(GPIO_OC_GP8_VDIN_BYTE_ADDR )
+#define GPIO_OC_GP9_VSYNC_BYTE_VAL REG8_VAL(GPIO_OC_GP9_VSYNC_BYTE_ADDR )
+#define GPIO_OC_GP10_I2S_BYTE_VAL REG8_VAL(GPIO_OC_GP10_I2S_BYTE_ADDR )
+#define GPIO_OC_GP11_I2S_BYTE_VAL REG8_VAL(GPIO_OC_GP11_I2S_BYTE_ADDR )
+#define GPIO_OC_GP12_SPI_BYTE_VAL REG8_VAL(GPIO_OC_GP12_SPI_BYTE_ADDR )
+#define GPIO_OC_GP13_SD0_BYTE_VAL REG8_VAL(GPIO_OC_GP13_SD0_BYTE_ADDR )
+#define GPIO_OC_GP14_NAND_SD1_BYTE_VAL REG8_VAL(GPIO_OC_GP14_NAND_SD1_BYTE_ADDR )
+#define GPIO_OC_GP15_NAND_BYTE_VAL REG8_VAL(GPIO_OC_GP15_NAND_BYTE_ADDR )
+#define GPIO_OC_GP16_NAND_SD1_BYTE_VAL REG8_VAL(GPIO_OC_GP16_NAND_SD1_BYTE_ADDR )
+#define GPIO_OC_GP17_I2C_BYTE_VAL REG8_VAL(GPIO_OC_GP17_I2C_BYTE_ADDR )
+#define GPIO_OC_GP18_UART_BYTE_VAL REG8_VAL(GPIO_OC_GP18_UART_BYTE_ADDR )
+#define GPIO_OC_GP19_SD2_BYTE_VAL REG8_VAL(GPIO_OC_GP19_SD2_BYTE_ADDR )
+#define GPIO_OC_GP20_PWM0_BYTE_VAL REG8_VAL(GPIO_OC_GP20_PWM0_BYTE_ADDR )
+#define GPIO_OC_GP21_HDMI_BYTE_VAL REG8_VAL(GPIO_OC_GP21_HDMI_BYTE_ADDR )
+#define GPIO_OC_GP22_I2C3_BYTE_VAL REG8_VAL(GPIO_OC_GP22_I2C3_BYTE_ADDR )
+#define GPIO_OC_GP24_SF_BYTE_VAL REG8_VAL(GPIO_OC_GP24_SF_BYTE_ADDR )
+#define GPIO_OC_GP26_PCM_BYTE_VAL REG8_VAL(GPIO_OC_GP26_PCM_BYTE_ADDR )
+#define GPIO_OC_GP60_USB_BYTE_VAL REG8_VAL(GPIO_OC_GP60_USB_BYTE_ADDR )
+#define GPIO_OC_GP62_WAKEUP_SUS_BYTE_VAL REG8_VAL(GPIO_OC_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define GPIO_OC_GP63_SD02CD_BYTE_VAL REG8_VAL(GPIO_OC_GP63_SD02CD_BYTE_ADDR )
+#define GPIO_OD_GP0_BYTE_VAL REG8_VAL(GPIO_OD_GP0_BYTE_ADDR )
+#define GPIO_OD_GP1_BYTE_VAL REG8_VAL(GPIO_OD_GP1_BYTE_ADDR )
+#define GPIO_OD_GP2_BYTE_VAL REG8_VAL(GPIO_OD_GP2_BYTE_ADDR )
+#define GPIO_OD_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(GPIO_OD_GP4_VDOUT_7_0_BYTE_ADDR )
+#define GPIO_OD_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(GPIO_OD_GP5_VDOUT_15_8_BYTE_ADDR )
+#define GPIO_OD_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(GPIO_OD_GP6_VDOUT_23_16_BYTE_ADDR )
+#define GPIO_OD_GP7_VD_BYTE_VAL REG8_VAL(GPIO_OD_GP7_VD_BYTE_ADDR )
+#define GPIO_OD_GP8_VDIN_BYTE_VAL REG8_VAL(GPIO_OD_GP8_VDIN_BYTE_ADDR )
+#define GPIO_OD_GP9_VSYNC_BYTE_VAL REG8_VAL(GPIO_OD_GP9_VSYNC_BYTE_ADDR )
+#define GPIO_OD_GP10_I2S_BYTE_VAL REG8_VAL(GPIO_OD_GP10_I2S_BYTE_ADDR )
+#define GPIO_OD_GP11_I2S_BYTE_VAL REG8_VAL(GPIO_OD_GP11_I2S_BYTE_ADDR )
+#define GPIO_OD_GP12_SPI_BYTE_VAL REG8_VAL(GPIO_OD_GP12_SPI_BYTE_ADDR )
+#define GPIO_OD_GP13_SD0_BYTE_VAL REG8_VAL(GPIO_OD_GP13_SD0_BYTE_ADDR )
+#define GPIO_OD_GP14_NAND_SD1_BYTE_VAL REG8_VAL(GPIO_OD_GP14_NAND_SD1_BYTE_ADDR )
+#define GPIO_OD_GP15_NAND_BYTE_VAL REG8_VAL(GPIO_OD_GP15_NAND_BYTE_ADDR )
+#define GPIO_OD_GP16_NAND_SD1_BYTE_VAL REG8_VAL(GPIO_OD_GP16_NAND_SD1_BYTE_ADDR )
+#define GPIO_OD_GP17_I2C_BYTE_VAL REG8_VAL(GPIO_OD_GP17_I2C_BYTE_ADDR )
+#define GPIO_OD_GP18_UART_BYTE_VAL REG8_VAL(GPIO_OD_GP18_UART_BYTE_ADDR )
+#define GPIO_OD_GP19_SD2_BYTE_VAL REG8_VAL(GPIO_OD_GP19_SD2_BYTE_ADDR )
+#define GPIO_OD_GP20_PWM0_BYTE_VAL REG8_VAL(GPIO_OD_GP20_PWM0_BYTE_ADDR )
+#define GPIO_OD_GP21_HDMI_BYTE_VAL REG8_VAL(GPIO_OD_GP21_HDMI_BYTE_ADDR )
+#define GPIO_OD_GP23_I2C3_BYTE_VAL REG8_VAL(GPIO_OD_GP23_I2C3_BYTE_ADDR )
+#define GPIO_OD_GP24_SF_BYTE_VAL REG8_VAL(GPIO_OD_GP24_SF_BYTE_ADDR )
+#define GPIO_OD_GP26_PCM_BYTE_VAL REG8_VAL(GPIO_OD_GP26_PCM_BYTE_ADDR )
+#define GPIO_OD_GP60_USB_BYTE_VAL REG8_VAL(GPIO_OD_GP60_USB_BYTE_ADDR )
+#define GPIO_OD_GP62_WAKEUP_SUS_BYTE_VAL REG8_VAL(GPIO_OD_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define GPIO_OD_GP63_SD02CD_BYTE_VAL REG8_VAL(GPIO_OD_GP63_SD02CD_BYTE_ADDR )
+#define STRAP_STATUS_VAL REG32_VAL(STRAP_STATUS_ADDR )
+#define AHB_CTRL_4BYTE_VAL REG32_VAL(AHB_CTRL_4BYTE_ADDR )
+#define USB_OP_CTRL_4BYTE_VAL REG32_VAL(USB_OP_CTRL_4BYTE_ADDR )
+#define BONDING_OPTION_4BYTE_VAL REG32_VAL(BONDING_OPTION_4BYTE_ADDR )
+#define PIN_SHARING_SEL_4BYTE_VAL REG32_VAL(PIN_SHARING_SEL_4BYTE_ADDR )
+#define TPIU_CLK_DATA_4BYTE_VAL REG32_VAL(TPIU_CLK_DATA_4BYTE_ADDR )
+#define GPIO0_INT_REQ_TYPE_VAL REG8_VAL(GPIO0_INT_REQ_TYPE_ADDR )
+#define GPIO1_INT_REQ_TYPE_VAL REG8_VAL(GPIO1_INT_REQ_TYPE_ADDR )
+#define GPIO2_INT_REQ_TYPE_VAL REG8_VAL(GPIO2_INT_REQ_TYPE_ADDR )
+#define GPIO3_INT_REQ_TYPE_VAL REG8_VAL(GPIO3_INT_REQ_TYPE_ADDR )
+#define GPIO4_INT_REQ_TYPE_VAL REG8_VAL(GPIO4_INT_REQ_TYPE_ADDR )
+#define GPIO5_INT_REQ_TYPE_VAL REG8_VAL(GPIO5_INT_REQ_TYPE_ADDR )
+#define GPIO6_INT_REQ_TYPE_VAL REG8_VAL(GPIO6_INT_REQ_TYPE_ADDR )
+#define GPIO7_INT_REQ_TYPE_VAL REG8_VAL(GPIO7_INT_REQ_TYPE_ADDR )
+#define GPIO8_INT_REQ_TYPE_VAL REG8_VAL(GPIO8_INT_REQ_TYPE_ADDR )
+#define GPIO9_INT_REQ_TYPE_VAL REG8_VAL(GPIO9_INT_REQ_TYPE_ADDR )
+#define GPIO10_INT_REQ_TYPE_VAL REG8_VAL(GPIO10_INT_REQ_TYPE_ADDR )
+#define GPIO11_INT_REQ_TYPE_VAL REG8_VAL(GPIO11_INT_REQ_TYPE_ADDR )
+#define GPIO12_INT_REQ_TYPE_VAL REG8_VAL(GPIO12_INT_REQ_TYPE_ADDR )
+#define GPIO13_INT_REQ_TYPE_VAL REG8_VAL(GPIO13_INT_REQ_TYPE_ADDR )
+#define GPIO18_INT_REQ_TYPE_VAL REG8_VAL(GPIO18_INT_REQ_TYPE_ADDR )
+#define GPIO19_INT_REQ_TYPE_VAL REG8_VAL(GPIO19_INT_REQ_TYPE_ADDR )
+#define VOUT20_INT_REQ_TYPE_VAL REG8_VAL(VOUT20_INT_REQ_TYPE_ADDR )
+#define VOUT21_INT_REQ_TYPE_VAL REG8_VAL(VOUT21_INT_REQ_TYPE_ADDR )
+#define VOUT22_INT_REQ_TYPE_VAL REG8_VAL(VOUT22_INT_REQ_TYPE_ADDR )
+#define VOUT23_INT_REQ_TYPE_VAL REG8_VAL(VOUT23_INT_REQ_TYPE_ADDR )
+#define GPIO20_INT_REQ_TYPE_VAL REG8_VAL(GPIO20_INT_REQ_TYPE_ADDR )
+#define GPIO21_INT_REQ_TYPE_VAL REG8_VAL(GPIO21_INT_REQ_TYPE_ADDR )
+#define GPIO22_INT_REQ_TYPE_VAL REG8_VAL(GPIO22_INT_REQ_TYPE_ADDR )
+#define GPIO23_INT_REQ_TYPE_VAL REG8_VAL(GPIO23_INT_REQ_TYPE_ADDR )
+#define GPIO24_INT_REQ_TYPE_VAL REG8_VAL(GPIO24_INT_REQ_TYPE_ADDR )
+#define GPIO25_INT_REQ_TYPE_VAL REG8_VAL(GPIO25_INT_REQ_TYPE_ADDR )
+#define GPIO0_INT_REQ_STS_VAL REG8_VAL(GPIO0_INT_REQ_STS_ADDR )
+#define GPIO1_INT_REQ_STS_VAL REG8_VAL(GPIO1_INT_REQ_STS_ADDR )
+#define GPIO2_INT_REQ_STS_VAL REG8_VAL(GPIO2_INT_REQ_STS_ADDR )
+#define GPIO3_INT_REQ_STS_VAL REG8_VAL(GPIO3_INT_REQ_STS_ADDR )
+#define DRV_DVO_CLK_BYTE_VAL REG8_VAL(DRV_DVO_CLK_BYTE_ADDR )
+#define DRV_DVO_VDEN_BYTE_VAL REG8_VAL(DRV_DVO_VDEN_BYTE_ADDR )
+#define SD0_DPCTL_4BYTE_VAL REG32_VAL(SD0_DPCTL_4BYTE_ADDR )
+#define SD0_DNCTL_4BYTE_VAL REG32_VAL(SD0_DNCTL_4BYTE_ADDR )
+#define DRV_SD0_USB_BYTE_VAL REG8_VAL(DRV_SD0_USB_BYTE_ADDR )
+#define DRV_USB_SWOC0_BYTE_VAL REG8_VAL(DRV_USB_SWOC0_BYTE_ADDR )
+#define DRV_USB_OC12_BYTE_VAL REG8_VAL(DRV_USB_OC12_BYTE_ADDR )
+#define DRV_USBOC3_CIR_BYTE_VAL REG8_VAL(DRV_USBOC3_CIR_BYTE_ADDR )
+#define DRV_PWREN_BYTE_VAL REG8_VAL(DRV_PWREN_BYTE_ADDR )
+#define DRV_PWREN_WAKEUP0_BYTE_VAL REG8_VAL(DRV_PWREN_WAKEUP0_BYTE_ADDR )
+#define DRV_SUSGP01_BYTE_VAL REG8_VAL(DRV_SUSGP01_BYTE_ADDR )
+#define DRV_WAKEUP23_BYTE_VAL REG8_VAL(DRV_WAKEUP23_BYTE_ADDR )
+#define DRV_WAKEUP45_BYTE_VAL REG8_VAL(DRV_WAKEUP45_BYTE_ADDR )
+#define DRV_I2C_BYTE_VAL REG8_VAL(DRV_I2C_BYTE_ADDR )
+#define DRV_HDMI_BYTE_VAL REG8_VAL(DRV_HDMI_BYTE_ADDR )
+#define PULL_EN_GP0_BYTE_VAL REG8_VAL(PULL_EN_GP0_BYTE_ADDR )
+#define PULL_EN_GP1_BYTE_VAL REG8_VAL(PULL_EN_GP1_BYTE_ADDR )
+#define PULL_EN_GP2_BYTE_VAL REG8_VAL(PULL_EN_GP2_BYTE_ADDR )
+#define PULL_EN_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(PULL_EN_GP4_VDOUT_7_0_BYTE_ADDR )
+#define PULL_EN_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(PULL_EN_GP5_VDOUT_15_8_BYTE_ADDR )
+#define PULL_EN_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(PULL_EN_GP6_VDOUT_23_16_BYTE_ADDR )
+#define PULL_EN_GP7_VD_BYTE_VAL REG8_VAL(PULL_EN_GP7_VD_BYTE_ADDR )
+#define PULL_EN_GP8_VDIN_BYTE_VAL REG8_VAL(PULL_EN_GP8_VDIN_BYTE_ADDR )
+#define PULL_EN_GP9_VSYNC_BYTE_VAL REG8_VAL(PULL_EN_GP9_VSYNC_BYTE_ADDR )
+#define PULL_EN_GP10_I2S_BYTE_VAL REG8_VAL(PULL_EN_GP10_I2S_BYTE_ADDR )
+#define PULL_EN_GP11_I2S_BYTE_VAL REG8_VAL(PULL_EN_GP11_I2S_BYTE_ADDR )
+#define PULL_EN_GP12_SPI_BYTE_VAL REG8_VAL(PULL_EN_GP12_SPI_BYTE_ADDR )
+#define PULL_EN_GP13_SD0_BYTE_VAL REG8_VAL(PULL_EN_GP13_SD0_BYTE_ADDR )
+#define PULL_EN_GP14_NAND_BYTE_VAL REG8_VAL(PULL_EN_GP14_NAND_BYTE_ADDR )
+#define PULL_EN_GP15_NAND_BYTE_VAL REG8_VAL(PULL_EN_GP15_NAND_BYTE_ADDR )
+#define PULL_EN_GP16_NANDIO_BYTE_VAL REG8_VAL(PULL_EN_GP16_NANDIO_BYTE_ADDR )
+#define PULL_EN_GP17_I2C_BYTE_VAL REG8_VAL(PULL_EN_GP17_I2C_BYTE_ADDR )
+#define PULL_EN_GP18_UART_BYTE_VAL REG8_VAL(PULL_EN_GP18_UART_BYTE_ADDR )
+#define PULL_EN_GP19_SD2_BYTE_VAL REG8_VAL(PULL_EN_GP19_SD2_BYTE_ADDR )
+#define PULL_EN_GP20_PWM0_BYTE_VAL REG8_VAL(PULL_EN_GP20_PWM0_BYTE_ADDR )
+#define PULL_EN_GP21_HDMI_BYTE_VAL REG8_VAL(PULL_EN_GP21_HDMI_BYTE_ADDR )
+#define PULL_EN_GP23_I2C3_BYTE_VAL REG8_VAL(PULL_EN_GP23_I2C3_BYTE_ADDR )
+#define PULL_EN_GP24_SF_BYTE_VAL REG8_VAL(PULL_EN_GP24_SF_BYTE_ADDR )
+#define PULL_EN_GP26_PCM_BYTE_VAL REG8_VAL(PULL_EN_GP26_PCM_BYTE_ADDR )
+#define PULL_EN_GP60_USB_BYTE_VAL REG8_VAL(PULL_EN_GP60_USB_BYTE_ADDR )
+#define PULL_EN_GP62_WAKEUP_SUS_BYTE_VAL REG8_VAL(PULL_EN_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define PULL_EN_GP63_SD02_BYTE_VAL REG8_VAL(PULL_EN_GP63_SD02_BYTE_ADDR )
+#define PULL_CTRL_GP0_BYTE_VAL REG8_VAL(PULL_CTRL_GP0_BYTE_ADDR )
+#define PULL_CTRL_GP1_BYTE_VAL REG8_VAL(PULL_CTRL_GP1_BYTE_ADDR )
+#define PULL_CTRL_GP2_BYTE_VAL REG8_VAL(PULL_CTRL_GP2_BYTE_ADDR )
+#define PULL_CTRL_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(PULL_CTRL_GP4_VDOUT_7_0_BYTE_ADDR )
+#define PULL_CTRL_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(PULL_CTRL_GP5_VDOUT_15_8_BYTE_ADDR )
+#define PULL_CTRL_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(PULL_CTRL_GP6_VDOUT_23_16_BYTE_ADDR )
+#define PULL_CTRL_GP7_VD_BYTE_VAL REG8_VAL(PULL_CTRL_GP7_VD_BYTE_ADDR )
+#define PULL_CTRL_GP8_VDIN_BYTE_VAL REG8_VAL(PULL_CTRL_GP8_VDIN_BYTE_ADDR )
+#define PULL_CTRL_GP9_VSYNC_BYTE_VAL REG8_VAL(PULL_CTRL_GP9_VSYNC_BYTE_ADDR )
+#define PULL_CTRL_GP10_I2S_BYTE_VAL REG8_VAL(PULL_CTRL_GP10_I2S_BYTE_ADDR )
+#define PULL_CTRL_GP11_I2S_BYTE_VAL REG8_VAL(PULL_CTRL_GP11_I2S_BYTE_ADDR )
+#define PULL_CTRL_GP12_SPI_BYTE_VAL REG8_VAL(PULL_CTRL_GP12_SPI_BYTE_ADDR )
+#define PULL_CTRL_GP13_SD0_BYTE_VAL REG8_VAL(PULL_CTRL_GP13_SD0_BYTE_ADDR )
+#define PULL_CTRL_GP14_NAND_BYTE_VAL REG8_VAL(PULL_CTRL_GP14_NAND_BYTE_ADDR )
+#define PULL_CTRL_GP15_NAND_BYTE_VAL REG8_VAL(PULL_CTRL_GP15_NAND_BYTE_ADDR )
+#define PULL_CTRL_GP16_NANDIO_BYTE_VAL REG8_VAL(PULL_CTRL_GP16_NANDIO_BYTE_ADDR )
+#define PULL_CTRL_GP17_I2C_BYTE_VAL REG8_VAL(PULL_CTRL_GP17_I2C_BYTE_ADDR )
+#define PULL_CTRL_GP18_UART_BYTE_VAL REG8_VAL(PULL_CTRL_GP18_UART_BYTE_ADDR )
+#define PULL_CTRL_GP19_SD2_BYTE_VAL REG8_VAL(PULL_CTRL_GP19_SD2_BYTE_ADDR )
+#define PULL_CTRL_GP20_PWM0_BYTE_VAL REG8_VAL(PULL_CTRL_GP20_PWM0_BYTE_ADDR )
+#define PULL_CTRL_GP21_HDMI_BYTE_VAL REG8_VAL(PULL_CTRL_GP21_HDMI_BYTE_ADDR )
+#define PULL_CTRL_GP23_I2C3_BYTE_VAL REG8_VAL(PULL_CTRL_GP23_I2C3_BYTE_ADDR )
+#define PULL_CTRL_GP24_SF_BYTE_VAL REG8_VAL(PULL_CTRL_GP24_SF_BYTE_ADDR )
+#define PULL_CTRL_GP26_PCM_BYTE_VAL REG8_VAL(PULL_CTRL_GP26_PCM_BYTE_ADDR )
+#define PULL_CTRL_GP27_SD0_BYTE_VAL REG8_VAL(PULL_CTRL_GP27_SD0_BYTE_ADDR )
+#define PULL_CTRL_GP60_USB_BYTE_VAL REG8_VAL(PULL_CTRL_GP60_USB_BYTE_ADDR )
+#define PULL_CTRL_GP62_WAKEUP_SUS_BYTE_VAL REG8_VAL(PULL_CTRL_GP62_WAKEUP_SUS_BYTE_ADDR )
+#define PULL_CTRL_GP63_SD02_BYTE_VAL REG8_VAL(PULL_CTRL_GP63_SD02_BYTE_ADDR )
+#define DRV_GPIO_7_0_4BYTE_VAL REG32_VAL(DRV_GPIO_7_0_4BYTE_ADDR )
+#define DRV_GPIO_13_8_4BYTE_VAL REG32_VAL(DRV_GPIO_13_8_4BYTE_ADDR )
+#define DRV_GPIO_19_14_4BYTE_VAL REG32_VAL(DRV_GPIO_19_14_4BYTE_ADDR )
+#define DRV_VDIN_3_0_4BYTE_VAL REG32_VAL(DRV_VDIN_3_0_4BYTE_ADDR )
+#define DRV_VDIN_4_6_4BYTE_VAL REG32_VAL(DRV_VDIN_3_0_4BYTE_ADDR )
+#define DRV_VDIN_SPI_4BYTE_VAL REG32_VAL(DRV_VDIN_SPI_4BYTE_ADDR )
+#define DRV_SPI_NAND_4BYTE_VAL REG32_VAL(DRV_SPI_NAND_4BYTE_ADDR )
+#define DRV_NAND_4BYTE_VAL REG32_VAL(DRV_NAND_4BYTE_ADDR )
+#define DRV_NANDIO_4BYTE_VAL REG32_VAL(DRV_NANDIO_4BYTE_ADDR )
+#define DRV_HDMI_I2C_4BYTE_VAL REG32_VAL(DRV_HDMI_I2C_4BYTE_ADDR )
+#define DRV_I2C_SD0_4BYTE_VAL REG32_VAL(DRV_I2C_SD0_4BYTE_ADDR )
+#define DRV_SD0_SD2_4BYTE_VAL REG32_VAL(DRV_SD0_SD2_4BYTE_ADDR )
+#define DRV_SD2_I2S_4BYTE_VAL REG32_VAL(DRV_SD2_I2S_4BYTE_ADDR )
+#define DRV_I2S_UART_4BYTE_VAL REG32_VAL(DRV_I2S_UART_4BYTE_ADDR )
+#define DRV_UART_4BYTE_VAL REG32_VAL(DRV_UART_4BYTE_ADDR )
+#define DRV_SF_JTAGT_4BYTE_VAL REG32_VAL(DRV_SF_JTAGT_4BYTE_ADDR )
+#define DRV_JTAGT_PWM_4BYTE_VAL REG32_VAL(DRV_JTAGT_PWM_4BYTE_ADDR )
+#define DRV_PCM_BYTE_VAL REG8_VAL(DRV_PCM_BYTE_ADDR )
+#define DRV_SPI_BYTE_VAL REG8_VAL(DRV_SPI_BYTE_ADDR )
+
+#define GPIO_STRAP_STS_VAL REG32_VAL(0x0100+BA_GPIO)
+
+/* [Rx300] GPIO Interrupt Request Type Register */
+#define GPIO_IRQT_LOW 0
+#define GPIO_IRQT_HIGH BIT0
+#define GPIO_IRQT_FALLING BIT1
+#define GPIO_IRQT_RISING (BIT1 | BIT0)
+#define GPIO_IRQT_DOUBLE BIT2
+
+/* GPIO Control Register for I2C */
+#define GPIO_I2C0_SCL BIT0
+#define GPIO_I2C0_SDA BIT1
+#define GPIO_I2C1_SCL BIT2
+#define GPIO_I2C1_SDA BIT3
+#define GPIO_I2C2_SCL BIT4
+#define GPIO_I2C2_SDA BIT5
+#define GPIO_I2C3_SCL BIT0
+#define GPIO_I2C3_SDA BIT1
+#define GPIO_I2C0_SCL_PULL_EN BIT0
+#define GPIO_I2C0_SDA_PULL_EN BIT1
+#define GPIO_I2C1_SCL_PULL_EN BIT2
+#define GPIO_I2C1_SDA_PULL_EN BIT3
+#define GPIO_I2C2_SCL_PULL_EN BIT4
+#define GPIO_I2C2_SDA_PULL_EN BIT5
+#define GPIO_I2C3_SCL_PULL_EN BIT0
+#define GPIO_I2C3_SDA_PULL_EN BIT1
+
+#endif
+/*=== END wmt_gpio.h ==========================================================*/
+
diff --git a/common/wmt_display/hw/wmt_i2c.h b/common/wmt_display/hw/wmt_i2c.h
new file mode 100755
index 0000000..9c5033e
--- /dev/null
+++ b/common/wmt_display/hw/wmt_i2c.h
@@ -0,0 +1,316 @@
+/*++
+ linux/include/asm-arm/arch-wmt/wmt_i2c.h
+
+ Copyright (c) 2008 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License along with
+ this program. If not, see <http://www.gnu.org/licenses/>.
+
+ WonderMedia Technologies, Inc.
+ 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+
+--*/
+/* Be sure that virtual mapping is defined right */
+
+
+#ifndef _WMT_I2C_H_
+#define _WMT_I2C_H_
+/*-------------------- MODULE DEPENDENCY -------------------------------------*/
+
+#include "wmt_mmap.h"
+/*
+ * Refer I2C 0.1 Module
+ *
+ */
+/*
+ i2c api address
+
+ Since i2c bus would probe all device which connect with it to add i2c adapter
+ ,but we dont make sure which would connect with it. In order to reduce probe time
+ ,we give a fake slave address for probing only.
+ Be carefully, the i2c api address must be different from real device address
+*/
+
+#define WMT_I2C_API_I2C_ADDR 0x59 /*API address*/
+
+/*
+ * Address
+ */
+#define I2C_CR_ADDR (0x0000+I2C_BASE_ADDR)
+#define I2C_TCR_ADDR (0x0002+I2C_BASE_ADDR)
+#define I2C_CSR_ADDR (0x0004+I2C_BASE_ADDR)
+#define I2C_ISR_ADDR (0x0006+I2C_BASE_ADDR)
+#define I2C_IMR_ADDR (0x0008+I2C_BASE_ADDR)
+#define I2C_CDR_ADDR (0x000A+I2C_BASE_ADDR)
+#define I2C_TR_ADDR (0x000C+I2C_BASE_ADDR)
+#define I2C_DIV_ADDR (0x000E+I2C_BASE_ADDR)
+
+#define I2C1_CR_ADDR (0x0000+I2C1_BASE_ADDR)
+#define I2C1_TCR_ADDR (0x0002+I2C1_BASE_ADDR)
+#define I2C1_CSR_ADDR (0x0004+I2C1_BASE_ADDR)
+#define I2C1_ISR_ADDR (0x0006+I2C1_BASE_ADDR)
+#define I2C1_IMR_ADDR (0x0008+I2C1_BASE_ADDR)
+#define I2C1_CDR_ADDR (0x000A+I2C1_BASE_ADDR)
+#define I2C1_TR_ADDR (0x000C+I2C1_BASE_ADDR)
+#define I2C1_DIV_ADDR (0x000E+I2C1_BASE_ADDR)
+/* Slave Address*/
+#define I2C_SCR_ADDR (0x0010+I2C_BASE_ADDR)
+#define I2C_SSR_ADDR (0x0012+I2C_BASE_ADDR)
+#define I2C_SISR_ADDR (0x0014+I2C_BASE_ADDR)
+#define I2C_SIMR_ADDR (0x0016+I2C_BASE_ADDR)
+#define I2C_SDR_ADDR (0x0018+I2C_BASE_ADDR)
+#define I2C_STR_ADDR (0x001A+I2C_BASE_ADDR)
+
+/*
+ * Registers
+ */
+#define I2C_CR_REG REG16_PTR(0x0000+I2C_BASE_ADDR)
+#define I2C_TCR_REG REG16_PTR(0x0002+I2C_BASE_ADDR)
+#define I2C_CSR_REG REG16_PTR(0x0004+I2C_BASE_ADDR)
+#define I2C_ISR_REG REG16_PTR(0x0006+I2C_BASE_ADDR)
+#define I2C_IMR_REG REG16_PTR(0x0008+I2C_BASE_ADDR)
+#define I2C_CDR_REG REG16_PTR(0x000A+I2C_BASE_ADDR)
+#define I2C_TR_REG REG16_PTR(0x000C+I2C_BASE_ADDR)
+#define I2C_DIV_REG REG16_PTR(0x000E+I2C_BASE_ADDR)
+
+#define I2C1_CR_REG REG16_PTR(0x0000+I2C1_BASE_ADDR)
+#define I2C1_TCR_REG REG16_PTR(0x0002+I2C1_BASE_ADDR)
+#define I2C1_CSR_REG REG16_PTR(0x0004+I2C1_BASE_ADDR)
+#define I2C1_ISR_REG REG16_PTR(0x0006+I2C1_BASE_ADDR)
+#define I2C1_IMR_REG REG16_PTR(0x0008+I2C1_BASE_ADDR)
+#define I2C1_CDR_REG REG16_PTR(0x000A+I2C1_BASE_ADDR)
+#define I2C1_TR_REG REG16_PTR(0x000C+I2C1_BASE_ADDR)
+#define I2C1_DIV_REG REG16_PTR(0x000E+I2C1_BASE_ADDR)
+/* Slave Registers*/
+#define I2C_SCR_REG REG16_PTR(0x0010+I2C_BASE_ADDR)
+#define I2C_SSR_REG REG16_PTR(0x0012+I2C_BASE_ADDR)
+#define I2C_SISR_REG REG16_PTR(0x0014+I2C_BASE_ADDR)
+#define I2C_SIMR_REG REG16_PTR(0x0016+I2C_BASE_ADDR)
+#define I2C_SDR_REG REG16_PTR(0x0018+I2C_BASE_ADDR)
+#define I2C_STR_REG REG16_PTR(0x001A+I2C_BASE_ADDR)
+
+/*
+ * Val Registers
+ */
+#define I2C_CR_VAL REG16_VAL(0x0000+I2C_BASE_ADDR)
+#define I2C_TCR_VAL REG16_VAL(0x0002+I2C_BASE_ADDR)
+#define I2C_CSR_VAL REG16_VAL(0x0004+I2C_BASE_ADDR)
+#define I2C_ISR_VAL REG16_VAL(0x0006+I2C_BASE_ADDR)
+#define I2C_IMR_VAL REG16_VAL(0x0008+I2C_BASE_ADDR)
+#define I2C_CDR_VAL REG16_VAL(0x000A+I2C_BASE_ADDR)
+#define I2C_TR_VAL REG16_VAL(0x000C+I2C_BASE_ADDR)
+#define I2C_DIV_VAL REG16_VAL(0x000E+I2C_BASE_ADDR)
+
+#define I2C1_CR_VAL REG16_VAL(0x0000+I2C1_BASE_ADDR)
+#define I2C1_TCR_VAL REG16_VAL(0x0002+I2C1_BASE_ADDR)
+#define I2C1_CSR_VAL REG16_VAL(0x0004+I2C1_BASE_ADDR)
+#define I2C1_ISR_VAL REG16_VAL(0x0006+I2C1_BASE_ADDR)
+#define I2C1_IMR_VAL REG16_VAL(0x0008+I2C1_BASE_ADDR)
+#define I2C1_CDR_VAL REG16_VAL(0x000A+I2C1_BASE_ADDR)
+#define I2C1_TR_VAL REG16_VAL(0x000C+I2C1_BASE_ADDR)
+#define I2C1_DIV_VAL REG16_VAL(0x000E+I2C1_BASE_ADDR)
+/* Slave Val Registers*/
+#define I2C_SCR_VAL REG16_VAL(0x0010+I2C_BASE_ADDR)
+#define I2C_SSR_VAL REG16_VAL(0x0012+I2C_BASE_ADDR)
+#define I2C_SISR_VAL REG16_VAL(0x0014+I2C_BASE_ADDR)
+#define I2C_SIMR_VAL REG16_VAL(0x0016+I2C_BASE_ADDR)
+#define I2C_SDR_VAL REG16_VAL(0x0018+I2C_BASE_ADDR)
+#define I2C_STR_VAL REG16_VAL(0x001A+I2C_BASE_ADDR)
+
+/*
+ * I2C_CR_REG
+ * I2C Controller Control
+ */
+/* Reserved [15:05] */
+/* [04:04] -- PCLK_SLE tied to Zero */
+#define I2C_CR_CPU_RDY 0x0008
+#define I2C_CR_TX_END 0x0004
+#define I2C_CR_TX_NEXT_NO_ACK 0x0002
+#define I2C_CR_TX_NEXT_ACK 0x0000
+#define I2C_CR_ENABLE 0x0001
+#define I2C_SLAV_MODE_SEL 0x8000
+/*
+ * I2C_TCR_REG
+ * I2C Transfer Control
+ *
+ */
+#define I2C_TCR_HS_MODE 0x2000 /* [13:13] */
+#define I2C_TCR_STANDARD_MODE 0x0000 /* [15:15] */
+#define I2C_TCR_FAST_MODE 0x8000
+#define I2C_TCR_MASTER_WRITE 0x0000 /* [14:14] */
+#define I2C_TCR_MASTER_READ 0x4000
+/* Reserved [13:07] */
+#define I2C_TCR_SLAVE_ADDR_MASK 0x007F /* [06:00] */
+
+/*
+ * I2C_CSR_REG
+ * I2C Status
+ *
+ */
+/* Reserved [15:02] */
+#define I2C_READY 0x0002 /* [01:01] R */
+#define I2C_BUSY 0x0000
+#define I2C_STATUS_MASK 0x0002
+#define I2C_CSR_RCV_ACK 0x0000 /* [00:00] R */
+#define I2C_CSR_RCV_NOT_ACK 0x0001
+#define I2C_CSR_RCV_ACK_MASK 0x0001
+
+/*
+ * I2C_ISR_REG
+ * I2C Interrupt Status
+ *
+ */
+/* Reserved [15:03] */
+#define I2C_ISR_SCL_TIME_OUT 0x0004 /* [02:02] R */
+#define I2C_ISR_SCL_TIME_OUT_WRITE_CLEAR 0x0004
+#define I2C_ISR_BYTE_END 0x0002 /* [01:01] R */
+#define I2C_ISR_BYTE_END_WRITE_CLEAR 0x0002
+#define I2C_ISR_NACK_ADDR 0x0001 /* [00:00] R */
+#define I2C_ISR_NACK_ADDR_WRITE_CLEAR 0x0001
+
+#define I2C_ISR_ALL_WRITE_CLEAR 0x0007
+/*
+ * I2C_IMR_REG
+ * I2C Interrupt Mask
+ *
+ */
+/* Reserved [15:03] */
+#define I2C_IMR_SCL_TIME_OUT_MASK 0x0004 /* [02:02] */
+#define I2C_IMR_BYTE_END_MASK 0x0002 /* [01:01] */
+#define I2C_IMR_NACK_ADDR_MASK 0x0001 /* [00:00] */
+
+#define I2C_IMR_ALL_ENABLE 0x0007
+/*
+ * I2C_CDR_REG
+ * I2C Data IO
+ *
+ */
+#define I2C_CDR_DATA_READ_MASK 0xFF00 /* [15:08] */
+#define I2C_CDR_DATA_WRITE_MASK 0x00FF /* [07:00] */
+
+
+/*
+ * I2C_TR_REG
+ * I2C Timer Parameters
+ *
+ */
+#define I2C_TR_SCL_TIME_OUT_MASK 0xFF00 /* [15:08] */
+#define I2C_TR_FSTP_MASK 0x00FF /* [07:00] */
+
+#define I2C_TR_STD_VALUE 0xFF64 /* standard mode*/
+#define I2C_TR_FAST_VALUE 0xFF19 /* fast mode*/
+
+
+/*
+ * I2C_DIV_REG
+ * I2C DIV
+ *
+ */
+#define APB_96M_I2C_DIV 7 /*Dean revised 2007/9/11 */
+#define APB_166M_I2C_DIV 12 /*Dean revised 2008/5/9 */
+
+
+
+/*
+ * I2C slave registers setting
+ *
+ */
+#define HS_MASTER_CODE 0x0800
+
+#define I2C_SLAVE_ADDR 0x59
+#define I2C_SLAVE_MASK 0x007F
+#define I2C_SLAVE_NACK BIT12
+#define I2C_SLAVE_HS_MODE BIT14
+#define I2C_SLAVE_EN BIT15
+
+#define I2C_SISR_SCL_TIME_OUT 0x0004 /* [02:02] R */
+#define I2C_SISR_SCL_TIME_OUT_WRITE_CLEAR 0x0004
+#define I2C_SISR_BYTE_END 0x0002 /* [01:01] R */
+#define I2C_SISR_BYTE_END_WRITE_CLEAR 0x0002
+#define I2C_SISR_DAT_REQ 0x0001 /* [00:00] R */
+#define I2C_SISR_DAT_REQ_WRITE_CLEAR 0x0001
+
+#define I2C_SISR_ALL_WRITE_CLEAR 0x0007
+
+#define I2C_SIMR_SCL_TIME_OUT_MASK 0x0004 /* [02:02] */
+#define I2C_SIMR_BYTE_END_MASK 0x0002 /* [01:01] */
+#define I2C_SIMR_NACK_ADDR_MASK 0x0001 /* [00:00] */
+
+#define I2C_SIMR_ALL_ENABLE 0x0007
+
+#define I2C_SRCV_NACK BIT0
+#define I2C_SREAD BIT1
+#define I2C_SACT BIT2
+
+#define I2C_SLAVE_WRITE_DATA_SHIFT 0
+#define I2C_SLAVE_READ_DATA_SHIFT 8
+#define I2C_SLAVE_READ_DATA_MASK 0xFF00
+#define I2C_SLAVE_WRITE_DATA_MASK 0x00FF
+
+enum i2c_mode_e {
+ I2C_STANDARD_MODE = 0 ,
+ I2C_FAST_MODE = 1,
+ I2C_HS_MODE = 2,
+};
+
+struct i2c_regs_s {
+ volatile unsigned short cr_reg; /* IIC controller control register*/
+ volatile unsigned short tcr_reg; /* IIC controller transfer control register*/
+ volatile unsigned short csr_reg; /* IIC controller status register*/
+ volatile unsigned short isr_reg; /* IIC controller interrupt status register*/
+ volatile unsigned short imr_reg; /* IIC controller interrupt mask register*/
+ volatile unsigned short cdr_reg; /* IIC controller data I/O buffer register*/
+ volatile unsigned short tr_reg; /* IIC controller time parameter register*/
+ volatile unsigned short div_reg; /* IIC controller clock divider register*/
+ volatile unsigned short scr_reg; /* IIC slave controller control register*/
+ volatile unsigned short cssr_reg; /* IIC slave controller status register*/
+ volatile unsigned short sisr_reg; /* IIC slave controller interrupt status register*/
+ volatile unsigned short simr_reg; /* IIC slave controller interrupt mask register*/
+ volatile unsigned short csdr_reg; /* IIC slave controller data I/O buffer register*/
+ volatile unsigned short str_reg; /* IIC slave controller time parameter register*/
+};
+
+#define SUSPEND_NOTIFY 0
+#define SUSPEND_SAVE_STATE 1
+#define SUSPEND_DISABLE 2
+#define SUSPEND_POWER_DOWN 3
+#define RESUME_POWER_ON 0
+#define RESUME_RESTORE_STATE 1
+#define RESUME_ENABLE 2
+
+#define I2C_ALGO_WMT 0x00900000 /* via WMT on-chip i2c algo*/
+
+#define I2C_ADAPTER_RETRIES 3
+#define I2C_ALGO_UDELAY 10
+#define I2C_ALGO_TIMEOUT 500
+
+#define MAX_MESSAGES 65536 /* maximum number of messages to send*/
+
+
+#define I2C_SET_STANDARD_MODE 0x07A0
+#define I2C_SET_FAST_MODE 0x07A1
+
+#if 0
+struct i2c_algo_wmt_data {
+ int (*write_msg)(unsigned int slave_addr, char *buf, unsigned int length , int restart, int last) ;
+ int (*read_msg)(unsigned int slave_addr, char *buf, unsigned int length , int restart, int last) ;
+ int (*send_request)(struct i2c_msg *msg, int msg_num, int non_block);
+#ifdef CONFIG_SND_SOC_VT1603
+ int (*vt1603_write_for_read)(unsigned int slave_addr, char *buf, unsigned int length , int restart, int last);
+#endif
+ int (*wait_bus_not_busy) (void);
+ void (*reset) (void);
+ void (*set_mode)(enum i2c_mode_e) ;
+ int udelay;
+ int timeout;
+};
+#endif
+
+#endif
diff --git a/common/wmt_display/hw/wmt_mmap.h b/common/wmt_display/hw/wmt_mmap.h
new file mode 100755
index 0000000..7e8214d
--- /dev/null
+++ b/common/wmt_display/hw/wmt_mmap.h
@@ -0,0 +1,190 @@
+/*++
+linux/include/asm-arm/arch-wmt/wmt_mmap.h
+
+Copyright (c) 2008 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with
+this program. If not, see <http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+
+#ifndef __WMT_MMAP_H
+#define __WMT_MMAP_H
+
+/**
+ * WMT Memory Map for Physical Address 0xD8000000 will be mapped to
+ * Virtual Address 0xFE000000
+ */
+#define WMT_MMAP_OFFSET 0
+
+#define EXTERNAL_AHB_BRIDGE_BASE_ADDR 0xB0000000
+#define INTERNAL_AHB_SLAVES_BASE_ADDR (0xD8000000 + WMT_MMAP_OFFSET)
+#define INTERNAL_APB_SLAVES_BASE_ADDR (0xD8100000 + WMT_MMAP_OFFSET)
+
+/**
+ * Internal AHB Slaves Memory Address Map
+ */
+#define MEMORY_CTRL_V3_CFG_BASE_ADDR (0xD8000000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define MEMORY_CTRL_V4_CFG_BASE_ADDR (0xD8000400 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define DMA_CTRL0_V3_CFG_BASE_ADDR (0xD8001000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define DMA_CTRL1_V3_CFG_BASE_ADDR (0xD8001400 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define DMA_CTRL_V4_CFG_BASE_ADDR (0xD8001800 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define PICTOR_DMA_CTRL_CFG_BASE_ADDR (0xD8001C00 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define SF_MEM_CTRL_CFG_BASE_ADDR (0xD8002000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define LPC_MEM_CTRL_CFG_BASE_ADDR (0xD8003000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define SPI_MEM_CTRL_CFG_BASE_ADDR (0xD8003000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+
+#define ETHERNET_MAC_0_CFG_BASE_ADDR (0xD8004000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+
+#define ETHERNET_MAC_1_CFG_BASE_ADDR (0xD8005000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+
+#define SECURITY_ENGINE_CFG_BASE_ADDR (0xD8006000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define SECURITY_ENGINE_CFG_EXTENT_BASE_ADDR (0xD8006400 + WMT_MMAP_OFFSET) /* 3K , 8/16/32 RW */
+#define USB20_HOST_CFG_BASE_ADDR (0xD8007000 + WMT_MMAP_OFFSET) /* 2K , 8/16/32 RW */
+#define USB20_HOST_DEVICE_CFG_BASE_ADDR (0xD8007800 + WMT_MMAP_OFFSET) /* 2K , 8/16/32 RW */
+#define PATA_CTRL_CFG_BASE_ADDR (0xD8008000 + WMT_MMAP_OFFSET) /* 2K , 8/16/32 RW */
+#define PS2_CFG_BASE_ADDR (0xD8008800 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define USB20_HOST_CFG_EXTENT_BASE_ADDR (0xD8008C00 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define NF_CTRL_CFG_BASE_ADDR (0xD8009000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define NOR_CTRL_CFG_BASE_ADDR (0xD8009400 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define USB20_DEVICE_CFG_BASE_ADDR (0xD8009800 + WMT_MMAP_OFFSET) /* 2K , 8/16/32 RW */
+#define SD0_SDIO_MMC_BASE_ADDR (0xD800A000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define SD1_SDIO_MMC_BASE_ADDR (0xD800A400 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+
+#define MS_CTRL_CFG_BASE_ADDR (0xD800B000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define XD_CTRL_CFG_BASE_ADDR (0xD800B400 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+
+#define CF_CTRL_CFG_BASE_ADDR (0xD800C000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+
+#define SATA_CTRL_CFG_BASE_ADDR (0xD800D000 + WMT_MMAP_OFFSET) /* 2K , 8/16/32 RW */
+
+#define XOR_CTRL_CFG_BASE_ADDR (0xD800E000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define LCD_CTRL_CFG_BASE_ADDR (0xD800E400 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+
+#define ASYNC_APB_BRIDGE_BASE_ADDR (0xD802FC00 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define LPC_TPM_CFG_BASE_ADDR (0xD8030000 + WMT_MMAP_OFFSET) /* 64K , 8/16/32 RW */
+#define LPC_SUPERIO_CFG_BASE_ADDR (0xD8040000 + WMT_MMAP_OFFSET) /* 64K , 8/16/32 RW */
+
+#define VPU_BASE_ADDR (0xD8050100 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define VPU_BASE2_ADDR (0xD8050200 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define SPU1_BASE_ADDR (0xD8050100 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define SPU2_BASE_ADDR (0xD8050200 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define GOVM_BASE_ADDR (0xD8050300 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define GE1_BASE_ADDR (0xD8050400 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define GE2_BASE_ADDR (0xD8050500 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define GE3_BASE_ADDR (0xD8050600 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define DISP_BASE_ADDR (0xD8050700 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define GOVRH_BASE1_ADDR (0xD8050800 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define GOVRH_BASE2_ADDR (0xD8050900 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define VID_BASE_ADDR (0xD8050A00 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define HDTV_CTRL_BASE_ADDR (0xD8050B00 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define GOVW_BASE_ADDR (0xD8050C00 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define SCL_BASE_ADDR (0xD8050D00 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define SCL_BASE2_ADDR (0xD8050000 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define DISP2_BASE_ADDR (0xD8050E00 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define VPP_BASE_ADDR (0xD8050F00 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define LVDS_BASE_ADDR (0xD8051000 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define GOVRH2_BASE1_ADDR (0xD8051700 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define GOVRH2_BASE2_ADDR (0xD8051800 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+#define HDMI_BASE2_ADDR (0xD8051F00 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+
+#define HDMI_TRANSMITTE_BASE_ADDR (0xD8060000 + WMT_MMAP_OFFSET) /* 64K , 8/16/32 RW */
+#define HDMI_CP_BASE_ADDR (0xD8070000 + WMT_MMAP_OFFSET) /* 64K , 8/16/32 RW */
+
+#define USB2_OTG_CFG_BASE_ADDR (0xD80E4000 + WMT_MMAP_OFFSET) /* 16K , 8/16/32 RW */
+
+#define AUDREGF_BASE_ADDR (0xD80ED800 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define PART_OF_AUDREGF_BASE_ADDR (0xD80EDC00 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define DSS_MBOX_BASE_ADDR (0xD80EE000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define DSS_PERM_BASE_ADDR (0xD80EE400 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+
+#define VDU_BASE_ADDR (0xD80F0000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define SCRCNT_BASE_ADDR (0xD80F0400 + WMT_MMAP_OFFSET) /* 256 , 8/16/32 RW */
+
+#define VLDBUF_BASE_ADDR (0xD80F1000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define IQ_BASE_ADDR (0xD80F1400 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define IDCT_BASE_ADDR (0xD80F1800 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+
+#define STREAMIN_BASE_ADDR (0xD80F2000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+
+#define MSVD_BASE_ADDR (0xD80F3000 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define AVBO_FIFO_BASE_ADDR (0xD80F3400 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+#define SPU_FIFO_BASE_ADDR (0xD80F3800 + WMT_MMAP_OFFSET) /* 1K , 8/16/32 RW */
+
+#define TSIN0_BASE_ADDR (0xD80F4000 + WMT_MMAP_OFFSET) /* 4K , 8/16/32 RW */
+#define TSIN1_BASE_ADDR (0xD80F5000 + WMT_MMAP_OFFSET) /* 4K , 8/16/32 RW */
+#define TSIN2_BASE_ADDR (0xD80F6000 + WMT_MMAP_OFFSET) /* 4K , 8/16/32 RW */
+#define TSOUT_BASE_ADDR (0xD80F7000 + WMT_MMAP_OFFSET) /* 4K , 8/16/32 RW */
+#define H264_DECODER_BASE_ADDR (0xD80F8000 + WMT_MMAP_OFFSET) /* 16K , 8/16/32 RW */
+
+#define CNM_BIT_BASE_ADDR (0xD80FC000 + WMT_MMAP_OFFSET) /* 4K , 8/16/32 RW */
+
+#define JPEG_DECODER_BASE_ADDR (0xD80FE000 + WMT_MMAP_OFFSET) /* 4K , 8/16/32 RW */
+#define JPEG_ENCODER_BASE_ADDR (0xD80FF000 + WMT_MMAP_OFFSET) /* 4K , 8/16/32 RW */
+
+/**
+ * Internal APB Slaves Memory Address Map
+ */
+#define RTC_BASE_ADDR (0xD8100000 + WMT_MMAP_OFFSET) /* 64K */
+#define GPIO_BASE_ADDR (0xD8110000 + WMT_MMAP_OFFSET) /* 64K */
+#define SYSTEM_CFG_CTRL_BASE_ADDR (0xD8120000 + WMT_MMAP_OFFSET) /* 64K */
+#define PM_CTRL_BASE_ADDR (0xD8130000 + WMT_MMAP_OFFSET) /* 64K */
+#define INTERRUPT0_CTRL_BASE_ADDR (0xD8140000 + WMT_MMAP_OFFSET) /* 64K */
+#define INTERRUPT1_CTRL_BASE_ADDR (0xD8150000 + WMT_MMAP_OFFSET) /* 64K */
+
+#define AUDIO_CODEC_BASE_ADDR (0xD81F0000 + WMT_MMAP_OFFSET) /* 64K */
+#define UART0_BASE_ADDR (0xD8200000 + WMT_MMAP_OFFSET) /* 64K */
+#define UART1_BASE_ADDR (0xD82b0000 + WMT_MMAP_OFFSET) /* 64K */
+#define UART2_BASE_ADDR (0xD8210000 + WMT_MMAP_OFFSET) /* 64K */
+#define UART3_BASE_ADDR (0xD82c0000 + WMT_MMAP_OFFSET) /* 64K */
+#define UART4_BASE_ADDR (0xD8370000 + WMT_MMAP_OFFSET) /* 64K */
+#define UART5_BASE_ADDR (0xD8380000 + WMT_MMAP_OFFSET) /* 64K */
+#define PWM0_BASE_ADDR (0xD8220000 + WMT_MMAP_OFFSET) /* 64K */
+
+#define SPI0_BASE_ADDR (0xD8240000 + WMT_MMAP_OFFSET) /* 64K */
+#define SPI1_BASE_ADDR (0xD8250000 + WMT_MMAP_OFFSET) /* 64K */
+#define SPI2_BASE_ADDR (0xD82A0000 + WMT_MMAP_OFFSET) /* 64K */
+#define KPAD_BASE_ADDR (0xD8260000 + WMT_MMAP_OFFSET) /* 64K */
+#define CIR_BASE_ADDR (0xD8270000 + WMT_MMAP_OFFSET) /* 64K */
+#define I2C0_BASE_ADDR (0xD8280000 + WMT_MMAP_OFFSET) /* 64K */
+#define I2C1_BASE_ADDR (0xD8320000 + WMT_MMAP_OFFSET) /* 64K */
+#define PCM_BASE_ADDR (0xD82D0000 + WMT_MMAP_OFFSET) /* 64K */
+#define AC97_BASE_ADDR (0xD8290000 + WMT_MMAP_OFFSET) /* 64K */
+
+#define AHB_ACCESS_MONITOR0_BASE_ADDR (0xD82E0000 + WMT_MMAP_OFFSET)
+#define AHB_ACCESS_MONITOR1_BASE_ADDR (0xD82F0000 + WMT_MMAP_OFFSET)
+#define AHB_ACCESS_MONITOR2_BASE_ADDR (0xD8300000 + WMT_MMAP_OFFSET)
+#define AHB_ACCESS_MONITOR3_BASE_ADDR (0xD8310000 + WMT_MMAP_OFFSET)
+
+#define ADC_BASE_ADDR (0xD8340000 + WMT_MMAP_OFFSET) /* 64K */
+#define ROTARY_DETECTOR_BASE_ADDR (0xD8350000 + WMT_MMAP_OFFSET) /* 64K */
+#define SMART_CARD_INTERFACE_BASE_ADDR (0xD8360000 + WMT_MMAP_OFFSET) /* 64K */
+#define POWER_MOS_BASE_ADDR (0xD8390000 + WMT_MMAP_OFFSET) /* 64K */
+// check
+#define MEMORY_CTRL_CFG_BASE_ADDR MEMORY_CTRL_V3_CFG_BASE_ADDR
+#define DMA_CTRL_CFG_BASE_ADDR DMA_CTRL_V4_CFG_BASE_ADDR
+#define LPC_CTRL_CFG_BASE_ADDR LPC_SUPERIO_CFG_BASE_ADDR
+#define HDMI1_BASE_ADDR (0xD806C000 + WMT_MMAP_OFFSET)
+#define HDMI2_BASE_ADDR (0xD8070000 + WMT_MMAP_OFFSET)
+#define GOVR_BASE_ADDR (0xD8050B00 + WMT_MMAP_OFFSET)
+#define INTERRUPT_CTRL_BASE_ADDR INTERRUPT0_CTRL_BASE_ADDR
+#define SPI_BASE_ADDR SPI0_BASE_ADDR
+#define I2C_BASE_ADDR I2C0_BASE_ADDR
+#define I2S_BASE_ADDR AUDREGF_BASE_ADDR
+
+
+/* WMT Memory Map for Physical Address*/
+#define UART0_PHY_BASE_ADDR 0xD8200000 /* 64K */
+#define UART1_PHY_BASE_ADDR 0xD82b0000 /* 64K */
+
+#endif /* __WMT_MMAP_H */
diff --git a/common/wmt_display/hw_devices.h b/common/wmt_display/hw_devices.h
new file mode 100755
index 0000000..7ba39c8
--- /dev/null
+++ b/common/wmt_display/hw_devices.h
@@ -0,0 +1,38 @@
+/*++
+ * linux/drivers/video/wmt/govm.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2010 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef HW_DEVICES_H
+#define HW_DEVICES_H
+
+int sil902x_module_init(void);
+int vt1632_module_init(void);
+int vt1625_module_init(void);
+int lcd_module_init(void);
+int lcd_oem_init(void);
+int lcd_at070tn83_init(void);
+int lcd_a080sn01_init(void);
+int lcd_lw700at9003_init(void);
+int lcd_ek08009_init(void);
+int lcd_HSD101PFW2_init(void);
+int lcd_LVDS_1024x600_init(void);
+#endif
diff --git a/common/wmt_display/lcd.h b/common/wmt_display/lcd.h
new file mode 100755
index 0000000..09acea0
--- /dev/null
+++ b/common/wmt_display/lcd.h
@@ -0,0 +1,105 @@
+/*++
+ * linux/drivers/video/wmt/lcd.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef LCD_H
+/* To assert that only one occurrence is included */
+#define LCD_H
+/*-------------------- MODULE DEPENDENCY -------------------------------------*/
+#include "vpp.h"
+
+/* following is the C++ header */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------- EXPORTED PRIVATE CONSTANTS ----------------------------*/
+/* #define LCD_XXXX 1 *//*Example*/
+
+/*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/
+/* typedef void lcd_xxx_t; *//*Example*/
+enum lcd_panel_t {
+ LCD_WMT_OEM,
+ LCD_CHILIN_LW0700AT9003,
+ LCD_INNOLUX_AT070TN83,
+ LCD_AUO_A080SN01,
+ LCD_EKING_EK08009,
+ LCD_HANNSTAR_HSD101PFW2,
+ LCD_LVDS_1024x600,
+ LCD_B079XAN01,
+ LCD_TPO_TJ015NC02AA,
+ LCD_BP080WX7,
+ LCD_PANEL_MAX
+};
+
+#define LCD_CAP_CLK_HI BIT(0)
+#define LCD_CAP_HSYNC_HI BIT(1)
+#define LCD_CAP_VSYNC_HI BIT(2)
+#define LCD_CAP_DE_LO BIT(3)
+struct lcd_parm_t {
+ int bits_per_pixel;
+ unsigned int capability;
+ struct fb_videomode vmode;
+ int width; /* width of picture in mm */
+ int height; /* height of picture in mm */
+
+ void (*initial)(void);
+ void (*uninitial)(void);
+};
+
+/*-------------------- EXPORTED PRIVATE VARIABLES ---------------------------*/
+#ifdef LCD_C /* allocate memory for variables only in vout.c */
+#define EXTERN
+#else
+#define EXTERN extern
+#endif /* ifdef LCD_C */
+
+/* EXTERN int lcd_xxx; *//*Example*/
+
+EXTERN struct lcd_parm_t *p_lcd;
+#undef EXTERN
+
+/*--------------------- EXPORTED PRIVATE MACROS ------------------------------*/
+/* #define LCD_XXX_YYY xxxx *//*Example*/
+/*--------------------- EXPORTED PRIVATE FUNCTIONS --------------------------*/
+/* extern void lcd_xxx(void); *//*Example*/
+
+int lcd_panel_register(int no, void (*get_parm)(int mode));
+struct lcd_parm_t *lcd_get_parm(enum lcd_panel_t id, unsigned int arg);
+void lcd_set_parm(int id, int bpp);
+struct lcd_parm_t *lcd_get_oem_parm(int resx, int resy);
+void lcd_set_lvds_id(int id);
+int lcd_get_lvds_id(void);
+void lcd_set_type(int type);
+int lcd_get_type(void);
+void lcd_set_enable(int enable);
+void lcd_enable_signal(int enable);
+
+#ifdef CONFIG_VPP_SHENZHEN
+void lcd_backlight_power_on(int on);
+#endif
+
+/* LCD back light */
+#ifdef __cplusplus
+}
+#endif
+#endif /* ifndef LCD_H */
diff --git a/common/wmt_display/lvds.c b/common/wmt_display/lvds.c
new file mode 100755
index 0000000..2516d78
--- /dev/null
+++ b/common/wmt_display/lvds.c
@@ -0,0 +1,202 @@
+/*++
+ * linux/drivers/video/wmt/lvds.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define LVDS_C
+#undef DEBUG
+/* #define DEBUG */
+/* #define DEBUG_DETAIL */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "lvds.h"
+
+#ifdef WMT_FTBLK_LVDS
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define LVDS_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx lvds_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in lvds.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int lvds_xxx; *//*Example*/
+struct lvds_base_regs *lvds_regs = (void *) LVDS_BASE_ADDR;
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void lvds_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+void lvds_set_power_down(int pwrdn)
+{
+ DBG_DETAIL("(%d)\n", pwrdn);
+
+ lvds_regs->test.b.pd = pwrdn;
+ mdelay(1);
+ lvds_regs->test2.b.pd_l2ha = pwrdn;
+}
+
+void lvds_set_enable(vpp_flag_t enable)
+{
+ DBG_DETAIL("(%d)\n", enable);
+ lvds_regs->test.b.tre_en = (enable) ? 0 : 1;
+ lvds_regs->test2.b.mode = (enable) ? 1 : 0;
+ lvds_regs->test2.b.resa_en = (enable) ? 0 : 1;
+#ifdef CONFIG_UBOOT
+ if ((enable) && (lcd_get_lvds_id() == LCD_LVDS_1024x600)) {
+ /* GPIO10 VDD_EN->CLK delay 16->38ms */
+ outl(inl(GPIO_BASE_ADDR + 0x80) | BIT10, GPIO_BASE_ADDR + 0x80);
+ outl(inl(GPIO_BASE_ADDR + 0xC0) | BIT10, GPIO_BASE_ADDR + 0xC0);
+ mdelay(16);
+ }
+#endif
+}
+
+int lvds_get_enable(void)
+{
+ return lvds_regs->test2.b.mode;
+}
+
+void lvds_set_rgb_type(int bpp)
+{
+ int mode;
+ int mode_change = 0x2;
+
+ DBG_DETAIL("(%d)\n", bpp);
+
+ /* 0:888, 1-555, 2-666, 3-565 */
+ switch (bpp) {
+ case 15:
+ mode = 1;
+ break;
+ case 16:
+ mode = 3;
+ break;
+ case 18:
+ mode = 2;
+ break;
+ case 24:
+ default:
+ mode = 0;
+ mode_change = 0x0;
+ break;
+ }
+#if 1 /* IGS default */
+ mode = 4;
+#endif
+ lvds_regs->status.b.test = mode_change;
+ lvds_regs->igs.b.bpp_type = mode;
+}
+
+vdo_color_fmt lvds_get_colfmt(void)
+{
+ return VDO_COL_FMT_ARGB;
+}
+
+void lvds_set_sync_polar(int h_lo, int v_lo)
+{
+ DBG_DETAIL("(%d,%d)\n", h_lo, v_lo);
+ lvds_regs->set.b.hsync_polar_lo = h_lo;
+ lvds_regs->set.b.vsync_polar_lo = v_lo;
+}
+
+void lvds_get_sync_polar(int *hsync_hi, int *vsync_hi)
+{
+ *hsync_hi = (lvds_regs->set.b.hsync_polar_lo) ? 0 : 1;
+ *vsync_hi = (lvds_regs->set.b.vsync_polar_lo) ? 0 : 1;
+}
+
+/*----------------------- Module API --------------------------------------*/
+void lvds_reg_dump(void)
+{
+ DPRINT("========== LVDS register dump ==========\n");
+ vpp_reg_dump(REG_LVDS_BEGIN, REG_LVDS_END-REG_LVDS_BEGIN);
+
+ DPRINT("---------- LVDS common ----------\n");
+ DPRINT("test %d,dual chan %d,inv clk %d\n", lvds_regs->status.b.test,
+ lvds_regs->status.b.dual_channel, lvds_regs->status.b.inv_clk);
+ DPRINT("ldi shift left %d,IGS bpp type %d\n",
+ lvds_regs->igs.b.ldi_shift_left, lvds_regs->igs.b.bpp_type);
+ DPRINT("rsen %d,pll ready %d\n", lvds_regs->detect.b.rsen,
+ lvds_regs->detect.b.pll_ready);
+ DPRINT("pwr dn %d\n", lvds_regs->test.b.pd);
+}
+
+#ifdef CONFIG_PM
+static unsigned int *lvds_pm_bk;
+static unsigned int lvds_pd_bk;
+void lvds_suspend(int sts)
+{
+ switch (sts) {
+ case 0: /* disable module */
+ break;
+ case 1: /* disable tg */
+ break;
+ case 2: /* backup register */
+ lvds_pd_bk = lvds_regs->test.b.pd;
+ lvds_set_power_down(1);
+ lvds_pm_bk = vpp_backup_reg(REG_LVDS_BEGIN,
+ (REG_LVDS_END-REG_LVDS_BEGIN));
+ break;
+ default:
+ break;
+ }
+}
+
+void lvds_resume(int sts)
+{
+ switch (sts) {
+ case 0: /* restore register */
+ vpp_restore_reg(REG_LVDS_BEGIN,
+ (REG_LVDS_END-REG_LVDS_BEGIN), lvds_pm_bk);
+ lvds_pm_bk = 0;
+ if (lcd_get_lvds_id() != LCD_LVDS_1024x600)
+ lvds_set_power_down(lvds_pd_bk);
+ break;
+ case 1: /* enable module */
+ break;
+ case 2: /* enable tg */
+ break;
+ default:
+ break;
+ }
+}
+#else
+#define lvds_suspend NULL
+#define lvds_resume NULL
+#endif
+
+void lvds_init(void)
+{
+ lvds_regs->level.b.level = 1;
+ lvds_regs->level.b.update = 1;
+ lvds_regs->test.b.pll_r_f = 1;
+ lvds_regs->test.b.pll_cpset = 1;
+ lvds_regs->test.b.tre_en = 0;
+ lvds_regs->test.b.vbg_sel = 2;
+ lvds_regs->test.b.drv_pdmode = 0;
+ lvds_regs->igs.b.ldi_shift_left = 1;
+ lvds_regs->test2.val = 0x31432;
+}
+
+#endif /* WMT_FTBLK_LVDS */
+
diff --git a/common/wmt_display/lvds.h b/common/wmt_display/lvds.h
new file mode 100755
index 0000000..9821a66
--- /dev/null
+++ b/common/wmt_display/lvds.h
@@ -0,0 +1,73 @@
+/*++
+ * linux/drivers/video/wmt/lvds.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#include "vpp.h"
+
+#ifndef LVDS_H
+/* To assert that only one occurrence is included */
+#define LVDS_H
+/*-------------------- MODULE DEPENDENCY -------------------------------------*/
+
+/* following is the C++ header */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------- EXPORTED PRIVATE CONSTANTS ----------------------------*/
+/* #define LVDS_XXXX 1 *//*Example*/
+
+/*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/
+/* typedef void lvds_xxx_t; *//*Example*/
+
+/*-------------------- EXPORTED PRIVATE VARIABLES ----------------------------*/
+#ifdef LVDS_C
+#define EXTERN
+#else
+#define EXTERN extern
+#endif /* ifdef LVDS_C */
+
+/* EXTERN int lvds_xxx; *//*Example*/
+
+#undef EXTERN
+
+/*--------------------- EXPORTED PRIVATE MACROS ------------------------------*/
+/* #define LVDS_XXX_YYY xxxx *//*Example*/
+/*--------------------- EXPORTED PRIVATE FUNCTIONS --------------------------*/
+/* extern void lvds_xxx(void); *//*Example*/
+void lvds_set_enable(vpp_flag_t enable);
+int lvds_get_enable(void);
+void lvds_set_rgb_type(int bpp);
+vdo_color_fmt lvds_get_colfmt(void);
+void lvds_reg_dump(void);
+void lvds_suspend(int sts);
+void lvds_resume(int sts);
+void lvds_init(void);
+void lvds_set_power_down(int pwrdn);
+void lvds_set_sync_polar(int h_lo, int v_lo);
+void lvds_get_sync_polar(int *hsync_hi, int *vsync_hi);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ifndef LVDS_H */
+
diff --git a/common/wmt_display/minivgui.c b/common/wmt_display/minivgui.c
new file mode 100755
index 0000000..54820dd
--- /dev/null
+++ b/common/wmt_display/minivgui.c
@@ -0,0 +1,1949 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+should have received a copy of the GNU General Public License along with this
+program. If not, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <version.h>
+#include <stdarg.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <linux/stddef.h>
+#include <asm/byteorder.h>
+#include <bmp_layout.h>
+
+#include "wmt_display.h"
+#include "minivgui.h"
+
+#define CHARGEANIM_PIC_NUM 7 // 1 big picture include 7 small pictures
+
+static char *sp_free_addr = (char *)5000000;
+
+static int s_display_percent;
+static int s_percent_val = -1;
+
+int g_tf_boot; // system boot from tf card. If set to 1, it means boot from eMMC. Otherwise, boot from Nand Flash
+
+typedef unsigned short GlyphScatter;
+
+#define Memcpy(dest, src, n) memcpy(dest, src, n)
+
+extern void *arm_memcpy(void *dest, const void *src, size_t n);
+extern void *arm_memset(void *s, int c, size_t count);
+extern void lcd_blt_enable(int no, int enable);
+
+typedef struct {
+ unsigned short ucs2Start;
+ unsigned short ucs2End;
+} GlyphRange;
+
+//
+// ×ÖÌåÎļþ²¼¾Ö
+// ----------------
+// | ÎļþÍ· | // FontFileHead
+// ---------------|
+// | Çø¼äÐÅÏ¢Êý×é | // Á¬ÐøÇø¼äÊý¾Ý GlyphRange[]
+// ----------------
+// | ÀëÉ¢ÐÅÏ¢Êý×é | // ÀëÉ¢µãÊý¾Ý GlyphScatter[] ÒѾ­ÅÅÐò
+// ---------------|
+// | missingµãÕó | // missing glyph µãÕ󣬶îÍâµÄÒ»¸öµãÕóÓÃÓÚÏÔʾÎÞ·¨ÕÒµ½µÄ×Ö·û
+// ----------------
+// | Çø¼ä1µãÕó | // Á¬ÐøÇø¼äµãÕóÊý¾Ý
+// | Çø¼ä2µãÕó | // Á¬ÐøÇø¼äµãÕóÊý¾Ý
+// | Çø¼ä... | // Á¬ÐøÇø¼äµãÕóÊý¾Ý
+// ----------------
+// | ÀëÉ¢1µãÕó | // ÀëÉ¢µÄµãÕó
+// | ÀëÉ¢2µãÕó | // ÀëÉ¢µÄµãÕó
+// | ÀëÉ¢... | // ÀëÉ¢µÄµãÕó
+// ----------------
+
+static const unsigned char s_fontData[] = {
+ 0x46, 0x54, 0x02, 0x10, 0x46, 0x6F, 0x6E, 0x74, 0x20, 0x31, 0x32, 0x78, 0x32, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0C, 0x16, 0x2C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x80, 0x10, 0x80, 0x10,
+ 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xC0, 0x39, 0xC0,
+ 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x04, 0x80, 0x04, 0x80, 0x09, 0x00,
+ 0x09, 0x00, 0x3F, 0xC0, 0x09, 0x00, 0x09, 0x00, 0x3F, 0xC0, 0x09, 0x00, 0x09, 0x00, 0x12, 0x00,
+ 0x12, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0F, 0x80, 0x10, 0x80, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,
+ 0x1E, 0x00, 0x01, 0x80, 0x00, 0x80, 0x20, 0x80, 0x21, 0x80, 0x3F, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1C, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x01, 0x80, 0x0E, 0x00, 0x30, 0x00,
+ 0x07, 0x00, 0x08, 0x80, 0x08, 0x80, 0x08, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x3F, 0x80, 0x04, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x7F, 0xC0, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x18, 0x00,
+ 0x18, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00,
+ 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00,
+ 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x10, 0x80, 0x10, 0x80, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40,
+ 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x80, 0x10, 0x80, 0x0F, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x3A, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x10, 0x80,
+ 0x20, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00,
+ 0x10, 0x00, 0x20, 0x40, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x30, 0x80, 0x00, 0x40, 0x00, 0x40,
+ 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x20, 0x80,
+ 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x05, 0x00, 0x09, 0x00, 0x09, 0x00,
+ 0x11, 0x00, 0x11, 0x00, 0x21, 0x00, 0x3F, 0x80, 0x01, 0x00, 0x01, 0x00, 0x07, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x80, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x17, 0x00, 0x18, 0x80, 0x00, 0x40,
+ 0x00, 0x40, 0x00, 0x40, 0x20, 0x40, 0x10, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x06, 0x00,
+ 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x27, 0x80, 0x28, 0x40, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x10, 0x20, 0x08, 0x40, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x20, 0x40, 0x00, 0x40, 0x00, 0x80,
+ 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x11, 0x00, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x11, 0x00,
+ 0x0F, 0x00, 0x11, 0x00, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x11, 0x00, 0x0E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0E, 0x00, 0x11, 0x80, 0x20, 0x80, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x10, 0xC0, 0x0F, 0x40,
+ 0x00, 0x40, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0C, 0x00, 0x18, 0x00,
+ 0x18, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x80, 0x03, 0x00, 0x0C, 0x00,
+ 0x10, 0x00, 0x60, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x00, 0x80, 0x00, 0x60, 0x00, 0x80, 0x03, 0x00,
+ 0x0C, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x10, 0x80, 0x10, 0x40,
+ 0x00, 0x40, 0x00, 0x40, 0x01, 0x80, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x18, 0x80, 0x20, 0x40, 0x20, 0x40, 0x21, 0xC0, 0x22, 0x40,
+ 0x24, 0x40, 0x24, 0x40, 0x24, 0x40, 0x23, 0xC0, 0x20, 0x00, 0x20, 0x00, 0x10, 0x80, 0x0F, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3E, 0x00, 0x06, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x10, 0x80, 0x10, 0x80,
+ 0x3F, 0xC0, 0x20, 0x40, 0x20, 0x40, 0x40, 0x20, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80,
+ 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x80, 0x1F, 0x80, 0x10, 0x40, 0x10, 0x20, 0x10, 0x20,
+ 0x10, 0x20, 0x10, 0x40, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x20, 0x10, 0xE0, 0x20, 0x20,
+ 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x20, 0x10, 0x40,
+ 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x10, 0x40, 0x10, 0x40, 0x10, 0x20, 0x10, 0x20,
+ 0x10, 0x20, 0x10, 0x20, 0x10, 0x20, 0x10, 0x20, 0x10, 0x40, 0x10, 0x40, 0x3F, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7F, 0xE0, 0x10, 0x20, 0x10, 0x20, 0x11, 0x00, 0x11, 0x00, 0x1F, 0x00, 0x11, 0x00,
+ 0x11, 0x00, 0x10, 0x20, 0x10, 0x20, 0x10, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0,
+ 0x10, 0x20, 0x10, 0x20, 0x11, 0x00, 0x11, 0x00, 0x1F, 0x00, 0x11, 0x00, 0x11, 0x00, 0x10, 0x00,
+ 0x10, 0x00, 0x10, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x40, 0x10, 0xC0, 0x20, 0x40,
+ 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x43, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x20, 0x40, 0x10, 0x40,
+ 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xF0, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40,
+ 0x3F, 0xC0, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0xF9, 0xF0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3F, 0x80, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0,
+ 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80,
+ 0x20, 0x80, 0x11, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xF0, 0x10, 0x40, 0x10, 0x80,
+ 0x11, 0x00, 0x12, 0x00, 0x14, 0x00, 0x1E, 0x00, 0x11, 0x00, 0x10, 0x80, 0x10, 0x80, 0x10, 0x40,
+ 0x78, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
+ 0x08, 0x00, 0x08, 0x00, 0x08, 0x20, 0x08, 0x20, 0x08, 0x20, 0x08, 0x20, 0x3F, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xE0, 0xE0, 0x60, 0xC0, 0x51, 0x40, 0x51, 0x40, 0x51, 0x40, 0x4A, 0x40, 0x4A, 0x40,
+ 0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xE0,
+ 0x30, 0x40, 0x28, 0x40, 0x28, 0x40, 0x24, 0x40, 0x24, 0x40, 0x22, 0x40, 0x22, 0x40, 0x21, 0x40,
+ 0x21, 0x40, 0x20, 0xC0, 0x70, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x10, 0x80, 0x20, 0x40,
+ 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x20, 0x40, 0x10, 0x80,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x10, 0x80, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40,
+ 0x10, 0x80, 0x1F, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x7E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0F, 0x00, 0x10, 0x80, 0x20, 0x40, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20,
+ 0x40, 0x20, 0x40, 0x20, 0x20, 0x40, 0x10, 0x80, 0x0F, 0x00, 0x04, 0x00, 0x0F, 0x20, 0x18, 0xC0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00,
+ 0x10, 0x80, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x80, 0x1F, 0x00, 0x10, 0x80, 0x10, 0x40,
+ 0x10, 0x40, 0x10, 0x20, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x40, 0x10, 0xC0, 0x20, 0x40,
+ 0x20, 0x00, 0x30, 0x00, 0x0F, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x20, 0x40, 0x30, 0x80,
+ 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC0, 0x44, 0x40, 0x44, 0x40, 0x44, 0x40, 0x04, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x1F, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0xE0, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40,
+ 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x10, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0,
+ 0x20, 0x40, 0x20, 0x40, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00,
+ 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xF0, 0x40, 0x40, 0x40, 0x40,
+ 0x44, 0x40, 0x44, 0x40, 0x24, 0x80, 0x2A, 0x80, 0x2A, 0x80, 0x2A, 0x80, 0x2A, 0x80, 0x2A, 0x80,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xE0, 0x20, 0x80, 0x11, 0x00, 0x11, 0x00, 0x0A, 0x00,
+ 0x04, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x10, 0x80, 0x20, 0x80, 0x40, 0x40, 0xF1, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0xF0, 0x20, 0x20, 0x10, 0x40, 0x08, 0x80, 0x05, 0x00, 0x05, 0x00, 0x02, 0x00,
+ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0,
+ 0x20, 0x40, 0x20, 0x80, 0x21, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x40,
+ 0x10, 0x40, 0x20, 0x40, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x80,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3C, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x3C, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x10, 0x80, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x10, 0x40, 0x00, 0x40, 0x00, 0x40,
+ 0x0F, 0xC0, 0x10, 0x40, 0x20, 0x40, 0x20, 0xC0, 0x1F, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x20, 0x00,
+ 0x20, 0x00, 0x20, 0x00, 0x27, 0x80, 0x28, 0x40, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x30, 0x20, 0x28, 0x40, 0x67, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0F, 0xA0, 0x10, 0x60, 0x20, 0x20, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x20, 0x10, 0x40,
+ 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x1E, 0x40, 0x21, 0xC0,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x21, 0xC0, 0x1E, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x10, 0x80, 0x20, 0x40, 0x20, 0x40,
+ 0x3F, 0xC0, 0x20, 0x00, 0x20, 0x00, 0x10, 0x40, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x08, 0x00,
+ 0x08, 0x00, 0x08, 0x00, 0x3F, 0x80, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
+ 0x08, 0x00, 0x08, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0E, 0xC0, 0x11, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x11, 0x80,
+ 0x0E, 0x80, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x17, 0x00, 0x18, 0x80,
+ 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x38, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x3E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00,
+ 0x11, 0xE0, 0x10, 0x80, 0x13, 0x00, 0x14, 0x00, 0x1C, 0x00, 0x12, 0x00, 0x11, 0x00, 0x10, 0x80,
+ 0x31, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x3F, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xC0, 0x33, 0x20, 0x22, 0x20, 0x22, 0x20,
+ 0x22, 0x20, 0x22, 0x20, 0x22, 0x20, 0x22, 0x20, 0x73, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x18, 0x80, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40,
+ 0x10, 0x40, 0x10, 0x40, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0F, 0x80, 0x10, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x40,
+ 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x80, 0x28, 0x40,
+ 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x20, 0x28, 0x40, 0x27, 0x80, 0x20, 0x00,
+ 0x20, 0x00, 0x20, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x60, 0x21, 0x40, 0x40, 0xC0, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x21, 0xC0, 0x1E, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
+ 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x19, 0xC0, 0x0A, 0x20, 0x0C, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
+ 0x08, 0x00, 0x08, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x40, 0x20, 0xC0, 0x20, 0x40, 0x1F, 0x00, 0x00, 0x80, 0x00, 0x40, 0x20, 0x40, 0x30, 0x80,
+ 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x3F, 0xC0, 0x08, 0x00,
+ 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x60, 0x07, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xC0, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40,
+ 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0xC0, 0x1F, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x20, 0x40, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x09, 0x00,
+ 0x09, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE0, 0xF0, 0x40, 0x40, 0x44, 0x40, 0x44, 0x40, 0x24, 0x80, 0x2A, 0x80, 0x2A, 0x80, 0x2A, 0x80,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xE0, 0x20, 0x40,
+ 0x10, 0x80, 0x09, 0x00, 0x06, 0x00, 0x09, 0x00, 0x10, 0x80, 0x20, 0x40, 0x79, 0xE0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x20, 0x40, 0x20, 0x80, 0x10, 0x80,
+ 0x10, 0x80, 0x09, 0x00, 0x09, 0x00, 0x06, 0x00, 0x06, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00,
+ 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x20, 0x80, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00,
+ 0x10, 0x00, 0x20, 0x40, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x02, 0x00, 0x02, 0x00,
+ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x0C, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x18, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x26, 0x40, 0x01, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/**
+ * the VGUI private Font file version 1.0 head struct, internally used only.
+ */
+typedef struct {
+ char magic[2]; // "FT"
+ unsigned short version; // 0x1001 (1.01)
+
+ char name[32]; // description
+
+ unsigned char charWidth;
+ unsigned char charHeight;
+ unsigned short glyphBytes;
+
+ unsigned short rangeCount;
+ unsigned short scatterCount;
+} FontFileHeadV1;
+
+
+static mv_surface s_surface[5];
+
+unsigned int (*rgb2color)(unsigned char r, unsigned char g, unsigned char b);
+void (*putcolor2fb)(const mv_surface *s, int x, int y, unsigned int color);
+void (*putcolor2mem)(const mv_surface *s, int x, int y, unsigned int color);
+
+static unsigned char *m_fileStart;
+static unsigned char *m_glyphStart;
+static FontFileHeadV1 *m_fh;
+int bitsPerPixel;
+
+//Display Direction definition:
+// 0: portrait, the back button under the screen ( ÊúÆÁ, back ¼üÔÚÏÂ)
+// 1: landscape, the back button on the right of the screnn ( ºáÆÁ, back¼üÔÚÓÒ)
+// 2: portrait, the back button above the screen ( ÊúÆÁ, back¼üÔÚÉÏ)
+// 3: landscape, the back button on the left of the screen ( ºáÆÁ, back¼üÔÚ×ó)
+int g_display_direction = 1;
+
+// for mem aligment
+extern void byte1_alig_mem_copy(char *src, char *des, unsigned int len);
+extern void byte2_alig_mem_copy(char *src, char *des, unsigned int len);
+extern void byte3_alig_mem_copy(char *src, char *des, unsigned int len);
+extern void mem_copy(char *src, char *des, unsigned int len);
+extern void byte1_less_bundle_copy(char *src, char *des, unsigned int len);
+extern void byte2_less_bundle_copy(char *src, char *des, unsigned int len);
+extern void byte3_less_bundle_copy(char *src, char *des, unsigned int len);
+extern void less_mem_copy(char *src, char *des, unsigned int len);
+
+// 24bits bitmap -> 146bits frame buffer
+extern void bit24_to_bit16_ali24(char *src, char *des, unsigned int len);
+extern void bit24_to_bit16_ali32(char *src, char *des, unsigned int len);
+
+static int setFontFileDat(const unsigned char *dat);
+
+static unsigned int rgb2color565(unsigned char r, unsigned char g, unsigned char b)
+{
+ unsigned int ret = 0;
+ ret = (unsigned int)(((r) >> 3) << 11 | ((g) >> 2) << 5 | ((b) >> 3));
+ return ret;
+}
+/*
+static unsigned int rgb2color555(unsigned char r, unsigned char g, unsigned char b)
+{
+ unsigned int ret = 0;
+ ret = (unsigned int)((((r) >> 3) << 10 | ((g) >> 3) << 5 | ((b) >> 3)) & 0x7fff);
+ return ret;
+}
+*/
+static unsigned int rgb2color888(unsigned char r, unsigned char g, unsigned char b)
+{
+ unsigned int ret = 0;
+ ret = (unsigned int)(((r) << 16 | (g) << 8 | (b)) & 0x00FFFFFF);
+ return ret;
+}
+/*
+static unsigned int rgb2color666(unsigned char r, unsigned char g, unsigned char b)
+{
+ unsigned int ret = 0;
+ ret = (unsigned int)(((r) >> 2) << 12 | ((g) >> 2) << 6 | ((b) >> 2));
+ return ret;
+}
+*/
+
+static void putcolor2fb16(const mv_surface *s, int x, int y, unsigned int color)
+{
+ if(g_display_direction == 1) {
+ if((g_logo_scale != LOGO_NOT_SCALE) || (x >= 0 && x < s->width && y >= 0 && y < s->height))
+ *(unsigned short *)(s->startAddr + (x * 2) + (s->lineBytes * y)) = (unsigned short)color;
+ } else { //circumrotate the font
+ int new_x, new_y;
+
+ new_x = x;
+ new_y = y;
+
+ switch(g_display_direction) {
+ case 0:
+ new_x = y;
+ new_y = (s->height - 1 - x);
+ break;
+
+ case 2:
+ new_x = (s->width - 1 - y);
+ new_y = x;
+ break;
+
+ case 3:
+ new_x = (s->width - 1 - x);
+ new_y = (s->height - 1 - y);
+ break;
+ }
+
+ if((g_logo_scale != LOGO_NOT_SCALE) || (new_x >= 0 && new_x < s->width && new_y >= 0 && new_y < s->height))
+ *(unsigned short *)(s->startAddr + (new_x * 2) + (s->lineBytes * new_y)) = (unsigned short)color;
+ }
+}
+
+static void putcolor2fb32(const mv_surface *s, int x, int y, unsigned int color)
+{
+ if(g_display_direction == 1) {
+ if((g_logo_scale != LOGO_NOT_SCALE) || (x >= 0 && x < s->width && y >= 0 && y < s->height))
+ *(unsigned int *)(s->startAddr + (x * 4) + (s->lineBytes * y)) = (unsigned int)color;
+ } else { //circumrotate the font
+ int new_x, new_y;
+
+ new_x = x;
+ new_y = y;
+
+ switch(g_display_direction) {
+ case 0:
+ new_x = y;
+ new_y = (s->height - 1 - x);
+ break;
+
+ case 2:
+ new_x = (s->width - 1 - y);
+ new_y = x;
+ break;
+
+ case 3:
+ new_x = (s->width - 1 - x);
+ new_y = (s->height - 1 - y);
+ break;
+ }
+
+ if((g_logo_scale != LOGO_NOT_SCALE) || (new_x >= 0 && new_x < s->width && new_y >= 0 && new_y < s->height))
+ *(unsigned int *)(s->startAddr + (new_x * 4) + (s->lineBytes * new_y)) = (unsigned int)color;
+ }
+}
+
+mv_surface *mv_getSurface(int no)
+{
+ return &s_surface[no];
+}
+
+static void putcolor2mem16(const mv_surface *s, int x, int y, unsigned int color)
+{
+ if(g_display_direction == 1) {
+ if((g_logo_scale != LOGO_NOT_SCALE) || (x >= 0 && x < s->width && y >= 0 && y < s->height))
+ *(unsigned short *)(sp_free_addr + (x * 2) + (s->lineBytes * y)) = (unsigned short)color;
+ } else { //circumrotate the font
+ int new_x, new_y;
+
+ new_x = x;
+ new_y = y;
+
+ switch(g_display_direction) {
+ case 0:
+ new_x = y;
+ new_y = (s->height - 1 - x);
+ break;
+
+ case 2:
+ new_x = (s->width - 1 - y);
+ new_y = x;
+ break;
+
+ case 3:
+ new_x = (s->width - 1 - x);
+ new_y = (s->height - 1 - y);
+ break;
+ }
+
+ if((g_logo_scale != LOGO_NOT_SCALE) || (new_x >= 0 && new_x < s->width && new_y >= 0 && new_y < s->height))
+ *(unsigned short *)(sp_free_addr + (new_x * 2) + (s->lineBytes * new_y)) = (unsigned short)color;
+ }
+}
+
+static void putcolor2mem32(const mv_surface *s, int x, int y, unsigned int color)
+{
+ if(g_display_direction == 1) {
+ if((g_logo_scale != LOGO_NOT_SCALE) || (x >= 0 && x < s->width && y >= 0 && y < s->height))
+ *(unsigned int *)(sp_free_addr + (x * 4) + (s->lineBytes * y)) = (unsigned int)color;
+ } else { //circumrotate the font
+ int new_x, new_y;
+
+ new_x = x;
+ new_y = y;
+
+ switch(g_display_direction) {
+ case 0:
+ new_x = y;
+ new_y = (s->height - 1 - x);
+ break;
+
+ case 2:
+ new_x = (s->width - 1 - y);
+ new_y = x;
+ break;
+
+ case 3:
+ new_x = (s->width - 1 - x);
+ new_y = (s->height - 1 - y);
+ break;
+ }
+
+ if((g_logo_scale != LOGO_NOT_SCALE) || (new_x >= 0 && new_x < s->width && new_y >= 0 && new_y < s->height))
+ *(unsigned int *)(sp_free_addr + (new_x * 4) + (s->lineBytes * new_y)) = (unsigned int)color;
+ }
+}
+
+static int get_fb_offset(const mv_surface *s, int img_width, int img_height, int xpos, int ypos)
+{
+ int x, y;
+ int bytes_per_pixel;
+
+ bytes_per_pixel = (s->bits_per_pixel >> 3);
+
+ switch(g_display_direction) {
+ case 0:
+ x = ypos;
+ y = s->height - xpos - img_width;
+ break;
+
+ case 2:
+ x = s->width - ypos - img_height;
+ y = xpos;
+ break;
+
+ case 3:
+ x = s->width - xpos - img_width;
+ y = s->height - ypos - img_height;
+ break;
+
+ case 1:
+ default:
+ x = xpos;
+ y = ypos;
+ break;
+ }
+
+ return (x * bytes_per_pixel + s->lineBytes * y);
+}
+
+static void mem2fb(const mv_surface *s, int width, int height, int xpos, int ypos)
+{
+ int new_width, new_height, new_xpos, new_ypos;
+ int i, bytes_per_pixel, fb_offset;
+ char *dest, *src;
+
+ new_width = width;
+ new_height = height;
+ new_xpos = xpos;
+ new_ypos = ypos;
+ bytes_per_pixel = (s->bits_per_pixel >> 3);
+
+ switch(g_display_direction) {
+ case 0: // the screen is portrait
+ case 2:
+ new_width = height;
+ new_height = width;
+ new_xpos = ypos;
+ new_ypos = xpos;
+ break;
+ }
+
+ fb_offset = get_fb_offset(s, width, height, xpos, ypos);
+ dest = s->startAddr + fb_offset;
+ src = sp_free_addr + fb_offset;
+
+ for (i = 0; i < new_height; i++) {
+ arm_memcpy(dest, src, new_width * bytes_per_pixel);
+ dest += s->lineBytes;
+ src += s->lineBytes;
+ }
+}
+
+void mv_clearFB(void)
+{
+ int no;
+ mv_surface *s;
+
+ for(no = 0; no < VPP_VOUT_INFO_NUM; no++) {
+ s = &s_surface[no];
+ if(s->startAddr)
+ arm_memset(s->startAddr, 0, s->height * s->lineBytes);
+ }
+}
+
+void mv_initSurface(int no, const mv_surface *s)
+{
+ static int flag = 0;
+ unsigned int free_addr;
+
+ Memcpy(&s_surface[no], s, sizeof(mv_surface));
+ if (flag == 0) {
+ setFontFileDat(s_fontData); //defined in "fontdata.h"
+ if (s->bits_per_pixel == 16) {
+ rgb2color = rgb2color565;
+ putcolor2fb = putcolor2fb16;
+ putcolor2mem = putcolor2mem16;
+ bitsPerPixel = 16;
+ } else {
+ rgb2color = rgb2color888;
+ putcolor2fb = putcolor2fb32;
+ putcolor2mem = putcolor2mem32;
+ }
+
+ free_addr = (unsigned int)s->startAddr - (1920 * 1080 * 4) * 2;
+ if(free_addr < 0)
+ free_addr = 0;
+
+ sp_free_addr = (char *)free_addr;
+
+ flag = 1;
+ }
+}
+
+void check_display_direction(void)
+{
+ char *env;
+
+ env = getenv("wmt.org.direction");
+ if (!env) {
+ g_display_direction = 1;
+ } else {
+ g_display_direction = simple_strtoul(env, NULL, 10);
+ if(g_display_direction < 0 || g_display_direction > 3)
+ g_display_direction = 1;
+ }
+
+ //printf("display direction %d\n", g_display_direction);
+}
+
+void check_tf_boot(void)
+{
+ char *env;
+
+ env = getenv("wmt.boot.dev");
+ if (env && !strnicmp(env, "TF", 2))
+ g_tf_boot = 1;
+}
+
+void mv_dumpSurface(void)
+{
+ printf("s_surface[0]: width = %d, height = %d, lineBytes = %d, bits_per_pixel = %d, startAddr = 0x%p\n",
+ s_surface[0].width, s_surface[0].height, s_surface[0].lineBytes, s_surface[0].bits_per_pixel, s_surface[0].startAddr);
+
+ printf("s_surface[1]: width = %d, height = %d, lineBytes = %d, bits_per_pixel = %d, startAddr = 0x%p\n",
+ s_surface[1].width, s_surface[1].height, s_surface[1].lineBytes, s_surface[1].bits_per_pixel, s_surface[1].startAddr);
+}
+
+void mv_drawLine(int no, int x1, int y1, int x2, int y2, unsigned int color)
+{
+ int i;
+ //mv_color* p;
+ const mv_surface *s = &s_surface[no];
+
+ if ( y1 == y2 ) {
+ if (x1 > x2) {
+ int tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ }
+#if 0
+ // horz line
+ p = getXYData(s, x1, y1);
+ for (i = x1; i < x2; ++i)
+ *p++ = color;
+#else
+ for (i = x1; i < x2; ++i)
+ putcolor2fb(s, i, y1, color);
+#endif
+ } else if ( x1 == x2 ) {
+ if (y1 > y2) {
+ int tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ }
+#if 0
+ // vert line
+ p = getXYData(s, x1,y1);
+ for (i = y1; i < y2; ++i) {
+ *p = color;
+ p = p + s->lineBytes;
+ }
+#else
+ for (i = y1; i < y2; ++i)
+ putcolor2fb(s, x1, i, color);
+#endif
+ }
+}
+
+void mv_drawRect(int no, const mv_Rect *rect, unsigned int color)
+{
+ mv_drawLine(no, rect->left, rect->top, rect->right, rect->top, color);
+ mv_drawLine(no, rect->left, rect->bottom, rect->right, rect->bottom, color);
+
+ mv_drawLine(no, rect->left, rect->top, rect->left, rect->bottom, color);
+ mv_drawLine(no, rect->right, rect->top, rect->right, rect->bottom, color);
+}
+
+void mv_fillRect(int no, const mv_Rect *rect, unsigned char r, unsigned char g, unsigned char b)
+{
+ int y;
+ unsigned int color = 0;
+
+ color = rgb2color(r, g, b);
+ for (y = rect->top; y < rect->bottom ; y++)
+ mv_drawLine(no, rect->left, y, rect->right, y, color);
+}
+
+int mv_le_to_cpu(char *buf, int size)
+{
+ int i;
+ int val = 0;
+
+ for(i = size - 1; i >= 0; i--) {
+ val = val << 8;
+ val |= buf[i];
+ }
+ return val;
+}
+
+int mv_loadBmp(int no, unsigned char *fileBuffer, int clearFB)
+{
+ unsigned char r, g, b;
+ int i, j, bytes;
+ int width, height, offset;
+ short colorBits;
+ unsigned char *colorMap;
+ mv_surface img;
+ bmp_header_t *header;
+ unsigned int dcolor = 0;
+ int xpos, ypos;
+ char *ptr;
+ int bits_per_pixel;
+ mv_surface *s;
+
+ char *source, *dst, *tmp_source, *tmp_dst;
+ int double_width, ali;
+
+ // for 32bits to 16bits
+ int bundle24, phase1, tmp_offset, tmp_phase1, tmp_bundle24, show_width, over_width, over_high;
+
+ s = &s_surface[no];
+ if(s->startAddr == 0)
+ return 0;
+
+ if (*fileBuffer != 'B') {
+ printf("fileBuffer : 0x%x = 0x%x \n", fileBuffer, *fileBuffer);
+ printf("Error : Not BMP Format\r\n");
+ return -1;
+ }
+
+ header = (bmp_header_t *)fileBuffer;
+ offset = mv_le_to_cpu((char *)&header->data_offset, 4);
+ width = mv_le_to_cpu((char *)&header->width, 4);
+ height = mv_le_to_cpu((char *)&header->height, 4);
+ colorBits = mv_le_to_cpu((char *)&header->bit_count, 2);
+
+ colorMap = (unsigned char *)(fileBuffer + 54); //ÑÕÉ«±íµØÖ·(8bitʱʹÓÃ)
+
+ show_width = width;
+ over_width = 0;
+ over_high = 0;
+
+ img.width = width;
+ img.height = height;
+ img.lineBytes = s->lineBytes;
+
+ i = 0;
+ j = 0;
+
+ if(g_display_direction == 0 || g_display_direction == 2) { // the screen is portrait
+ if (width != s->height) {
+ if (width > s->height) {
+ printf("Warning : BMP Width(%d) > LCD(%d)\r\n", width, s->height);
+ if(g_logo_scale == LOGO_NOT_SCALE) {
+ /* only surport 24bit or 32bit bmp exceed screen size */
+ if(colorBits == 24 || colorBits == 32) {
+ /* only show bmp center if bmp size exceed screen size*/
+ over_width = width - s->height;
+ width = s->height;
+ img.width = width;
+ }
+ }
+ }
+ else
+ i = (s->height - width) / 2;
+ }
+ if (height != s->width) {
+ if (height > s->width) {
+ printf("Warning : BMP Height(%d) > LCD(%d)\r\n", height, s->width);
+ if(g_logo_scale == LOGO_NOT_SCALE) {
+ if(colorBits == 24 || colorBits == 32) {
+ over_high = height - s->width;
+ height = s->width;
+ img.height = height;
+ }
+ }
+ }
+ else
+ j = (s->width - height) / 2;
+ }
+
+ if ((g_logo_x >= 0) && (g_logo_x < s->height)) i = g_logo_x;
+ if ((g_logo_y >= 0) && (g_logo_y < s->width)) j = g_logo_y;
+
+ } else { // the screen is landscape
+ if (width != s->width) {
+ if (width > s->width) {
+ printf("Warning : BMP Width(%d) > LCD(%d)\r\n", width, s->width);
+ if(g_logo_scale == LOGO_NOT_SCALE) {
+ if(colorBits == 24 || colorBits == 32) {
+ over_width = width - s->width;
+ width = s->width;
+ img.width = width;
+ }
+ }
+ }
+ else
+ i = (s->width - width) / 2;
+ }
+ if (height != s->height) {
+ if (height > s->height) {
+ printf("Warning : BMP Height(%d) > LCD(%d)\r\n", height, s->height);
+ if(g_logo_scale == LOGO_NOT_SCALE) {
+ if(colorBits == 24 || colorBits == 32) {
+ over_high = height - s->height;
+ height = s->height;
+ img.height = height;
+ }
+ }
+ }
+ else
+ j = (s->height - height) / 2;
+ }
+
+ if ((g_logo_x >= 0) && (g_logo_x < s->width)) i = g_logo_x;
+ if ((g_logo_y >= 0) && (g_logo_y < s->height)) j = g_logo_y;
+ }
+
+ img.startAddr = (s->startAddr + (i * (s->bits_per_pixel >> 3)) + (s->lineBytes * j));
+
+ /* add for logo scale */
+ //set wimg.startAddr = (char *)vpp_calc_align((int)img.startAddr, 64);
+
+ if(g_logo_scale != LOGO_NOT_SCALE) {
+ if (g_logo_scale == LOGO_MODE_MAX)
+ g_logo_scale = ((width == 1280 && height == 720) || (width > 1280 || height > 720)) ?
+ LOGO_ORI_SCALE_FULL : LOGO_720P_SCALE_FULL;
+
+ if(g_logo_scale == LOGO_720P_SCALE_FULL) {
+
+ s->img_width = 1280;
+ s->img_height = 720;
+ s->img_startAddr = s->startAddr;
+
+ i = (1280 - width) / 2;
+ j = (720 - height) / 2;
+
+ img.startAddr = (s->startAddr + (i * (s->bits_per_pixel >> 3)) + (s->lineBytes * j));
+ img.startAddr = (char *)vpp_calc_align((int)img.startAddr, 64);
+ arm_memset(s->startAddr, 0, 720 * s->lineBytes); //clean fb
+ } else {
+ s->img_width = width;
+ s->img_height = height;
+ s->img_startAddr = img.startAddr;
+ }
+ }
+ /* end of logo scale */
+
+ xpos = i;
+ ypos = j;
+
+ if(clearFB)
+ arm_memset(s->startAddr, 0, s->height * s->lineBytes); //clear fb
+
+ switch (colorBits) {
+ // AimarMa -- Add 32bit BMP support
+ case 32: // r,g,b,a
+ bits_per_pixel = s->bits_per_pixel;
+ if (bits_per_pixel != 16 && g_display_direction == 1) {
+ for (i = 0; i <= height - 1 ; i++) {
+ //source = (char *)(fileBuffer + offset + i * width * 4);
+ source = (char *)(fileBuffer + offset + i * show_width * 4 + (over_high/2)*show_width * 4 + (over_width/2) * 4);
+ dst = (char *)(img.startAddr + img.lineBytes * (height - 1 - i));
+ mem_cpy_alignment (dst, source, width * 4);
+ }
+ } else {
+ offset = offset + (over_high/2)*show_width * 4 + (over_width/2) * 4;
+ for (i = height - 1; i >= 0; i--) {
+ for (j = 0; j < width; j++) {
+ b = *(fileBuffer + offset);
+ g = *(fileBuffer + offset + 1);
+ r = *(fileBuffer + offset + 2);
+ //a = *(unsigned char*)(fileBuffer + offset + 3);
+ //*getXYData(&img, j, i) = mv_RGB2Color(r,g,b);
+ dcolor = rgb2color(r, g, b);
+ //putcolor2fb(&img, j, i, dcolor);
+ putcolor2mem(&s_surface[no], j + xpos, i + ypos, dcolor);
+ offset += 4;
+ }
+ offset += over_width * 4;
+ }
+ mem2fb(s, width, height, xpos, ypos);
+ }
+ break;
+
+ case 24: // r,g,b
+ if(g_display_direction == 1) {
+ bits_per_pixel = s->bits_per_pixel;
+ ptr = malloc(width * 3);
+ if (!ptr) {
+ printf("allocate fail!!\n");
+ return 0;
+ }
+ bytes = 4 - (show_width * 3) % 4;
+ if (bytes == 4)
+ bytes = 0;
+
+ // 24bits -> 16bits
+ bundle24 = (width * 3) % 24; // 8 bits
+ phase1 = width * 3 - bundle24; // 24 bits
+ for (i = 0; i <= height - 1 ; i++) {
+ source = (char *)(fileBuffer + offset + i*show_width * 3 + (over_high/2)*show_width * 3 + (over_width/2) * 3);
+ dst = (char *)(img.startAddr + img.lineBytes * (height - 1 - i));
+ tmp_source = source;
+ tmp_dst = dst;
+ tmp_phase1 = phase1;
+ tmp_bundle24 = bundle24;
+ ali = 0;
+
+ // dst not ali
+ if ((int)dst % 4 != 0) {
+ b = *(source);
+ g = *(source + 1);
+ r = *(source + 2);
+ dcolor = rgb2color(r, g, b);
+ *(unsigned short *)(dst) = (unsigned short)dcolor;
+ tmp_dst = dst + 2;
+
+ tmp_source = source + 3;
+ tmp_phase1 = phase1 - 3;
+ tmp_bundle24 = tmp_phase1 % 24;
+ tmp_phase1 = tmp_phase1 - tmp_bundle24;
+ ali = 1;
+ }
+
+ // src -> tmp_buffer
+ mem_cpy_alignment(ptr, tmp_source, (width - ali) * 3);
+ if (bits_per_pixel == 16)
+ bit24_to_bit16_ali24 (tmp_dst, ptr, tmp_phase1);
+ else
+ bit24_to_bit16_ali32 (tmp_dst, ptr, tmp_phase1);
+
+ if (tmp_bundle24) {
+ tmp_offset = 0;
+ source = (char *)(ptr + tmp_phase1);
+ for (j = 0; j < tmp_bundle24 / 3; j++) {
+ b = *(source + tmp_offset);
+ g = *(source + tmp_offset + 1);
+ r = *(source + tmp_offset + 2);
+ dcolor = rgb2color(r, g, b);
+ if (bits_per_pixel == 16) {
+ tmp_dst = dst + (tmp_phase1 / 3) * 2 + j * 2;
+ *(unsigned short *)(tmp_dst) = (unsigned short)dcolor;
+ } else {
+ tmp_dst = dst + (tmp_phase1 / 3) * 4 + j * 4;
+ *(unsigned int *)(tmp_dst) = (unsigned int)dcolor;
+ }
+ tmp_offset += 3;
+ }
+ }
+ offset += bytes;
+ }
+
+ if( NULL != ptr )
+ free(ptr);
+ } else {
+ bytes = 4 - (show_width * 3) % 4;
+ if (bytes == 4)
+ bytes = 0;
+
+ offset = offset + (over_high/2)*show_width * 3 + (over_width/2) * 3;
+
+ for (i = height - 1; i >= 0; i--) {
+ for (j = 0; j < width; j++) {
+ b = *(fileBuffer + offset);
+ g = *(fileBuffer + offset + 1);
+ r = *(fileBuffer + offset + 2);
+ //*getXYData(&img, j, i) = mv_RGB2Color(r,g,b);
+ dcolor = rgb2color(r, g, b);
+ //putcolor2fb(&img, j, i, dcolor);
+ putcolor2mem(s, j + xpos, i + ypos, dcolor);
+ offset += 3;
+ }
+ offset += bytes;
+ offset += over_width * 3;
+ }
+ mem2fb(s, width, height, xpos, ypos);
+ }
+ break;
+ case 16: { //16bit 555
+ double_width = width * 2;
+ bytes = 4 - width % 4;
+ if (bytes == 4)
+ bytes = 0;
+ if (bitsPerPixel == 16) {
+ for (i = 0; i <= height - 1 ; i++) {
+ // multicopy-----------------------------------------------
+ source = (char *)(fileBuffer + offset + i * double_width);
+ dst = (char *)(img.startAddr + img.lineBytes * (height - 1 - i));
+ mem_cpy_alignment (dst, source, double_width);
+ //--------------------------------------------------------
+ }
+ } else {
+ unsigned short color16;
+ bytes = 4 - (width * 2) % 4;
+ if (bytes == 4)
+ bytes = 0;
+ for (i = height - 1; i >= 0; i--) {
+ for (j = 0; j < width; j++) {
+ color16 = *(unsigned short *)(fileBuffer + offset);
+#if ( GUI_RGB_FORMAT == RGB_FORMAT_565)
+ //*getXYData(&img, j, i) = (color16<<1) & 0xFFC0 | (color16 & 0x1F);
+ dcolor = (unsigned int)((((color16 & 0xF800) << 8) & 0x00FF0000) | (((color16 & 0x7E0) << 5) & 0x0000FF00) | (((color16 & 0x1F) << 3) & 0x000000FF));
+ //putcolor2fb(&img, j, i, dcolor);
+ putcolor2mem(&s_surface[no], j + xpos, i + ypos, dcolor);
+#else
+ //*getXYData(&img, j, i) = mv_RGB2Color((color16 & 0x7C00) >> 7, (color16 & 0x03E0) >> 2, (color16 & 0x001F) << 3);
+ dcolor = rgb2color((color16 & 0x7C00) >> 7, (color16 & 0x03E0) >> 2, (color16 & 0x001F) << 3);
+ //putcolor2fb(&img, j, i, dcolor);
+ putcolor2mem(&s_surface[no], j + xpos, i + ypos, dcolor);
+#endif
+ offset += 2;
+ }
+ offset += bytes;
+ }
+ mem2fb(s, width, height, xpos, ypos);
+ }
+ }
+ break;
+ case 8: //256 colormap
+ bytes = 4 - width % 4;
+ if (bytes == 4)
+ bytes = 0;
+ for (i = height - 1; i >= 0; i--) {
+ for (j = 0; j < width; j++) {
+ int offSet = *(fileBuffer + offset) * 4;
+ b = colorMap[offSet];
+ g = colorMap[offSet + 1];
+ r = colorMap[offSet + 2];
+ //*getXYData(&img, j, i) = mv_RGB2Color(r,g,b);
+ dcolor = rgb2color(r, g, b);
+ //putcolor2fb(&img, j, i, dcolor);
+ putcolor2mem(&s_surface[no], j + xpos, i + ypos, dcolor);
+ offset ++;
+ }
+ offset += bytes;
+ }
+ mem2fb(s, width, height, xpos, ypos);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void get_display_postion(const mv_surface *s, int disp_width, int disp_height, int *p_x, int *p_y)
+{
+ int pos_x = 0, pos_y = 0;
+
+ if(g_display_direction == 0 || g_display_direction == 2) {
+ if (disp_width > s->height)
+ printf("Warning : disp_width(%d) > LCD(%d)\r\n", disp_width, s->height);
+ else
+ pos_x = (s->height - disp_width) / 2;
+
+ if (disp_height > s->width)
+ printf("Warning : disp_height(%d) > LCD(%d)\r\n", disp_height, s->width);
+ else
+ pos_y = (s->width - disp_height) / 2;
+
+ } else {
+ if (disp_width > s->width)
+ printf("Warning : disp_width(%d) > LCD(%d)\r\n", disp_width, s->width);
+ else
+ pos_x = (s->width - disp_width) / 2;
+
+ if (disp_height > s->height)
+ printf("Warning : disp_height(%d) > LCD(%d)\r\n", disp_height, s->height);
+ else
+ pos_y = (s->height - disp_height) / 2;
+ }
+
+ *p_x = pos_x;
+ *p_y = pos_y;
+}
+
+int init_charge_percent(void)
+{
+ char *s;
+
+ s = getenv("wmt.ui.uboot.charging_percent");
+ if(s && !strcmp(s, "1"))
+ s_display_percent = 1;
+ else
+ s_display_percent = 0;
+
+ s_percent_val = -1;
+
+ return 0;
+}
+
+int clear_charge_percent(unsigned char *fileBuffer)
+{
+ int blank_width, anim_height;
+ mv_Rect rect;
+ int pos_x, pos_y;
+ bmp_header_t *header;
+ unsigned int logo_size;
+ int no;
+ mv_surface *s;
+
+ if(s_display_percent == 0)
+ return -1;
+
+ for(no = 0; no < VPP_VOUT_INFO_NUM; no++) {
+ s = &s_surface[no];
+ if(s->startAddr == 0)
+ continue;
+
+ if (*fileBuffer != 'B') {
+ //printf("Error : logo is Not BMP Format. Couldn't clear charging percent\n");
+ //return -1;
+ anim_height = 168;
+ } else {
+ if(!g_tf_boot) {
+ logo_size = (*(unsigned short *)(fileBuffer + 4) << 16) + (*(unsigned short *)(fileBuffer + 2));
+
+ fileBuffer = fileBuffer + logo_size;
+
+ if (*fileBuffer != 'B') {
+ //printf("Error : charge-anim is Not BMP Format. Couldn't clear charging percent\n");
+ //return -1;
+ anim_height = 168;
+ } else {
+ header = (bmp_header_t *)fileBuffer;
+ anim_height = mv_le_to_cpu((char *)&header->height, 4);
+ anim_height = anim_height / CHARGEANIM_PIC_NUM;
+ }
+ } else {
+ header = (bmp_header_t *)fileBuffer;
+ anim_height = mv_le_to_cpu((char *)&header->height, 4);
+ anim_height = anim_height / CHARGEANIM_PIC_NUM;
+ }
+ }
+
+ blank_width = 4 * CHAR_WIDTH; // clear 4 char
+
+ get_display_postion(s, blank_width, anim_height, &pos_x, &pos_y);
+
+ pos_y = pos_y - CHAR_HEIGHT - CHAR_HEIGHT;
+ if(pos_y < 0)
+ pos_y = 0;
+
+ rect.left = pos_x;
+ rect.right = pos_x + blank_width;
+ rect.top = pos_y;
+ rect.bottom = pos_y + CHAR_HEIGHT;
+
+ mv_fillRect(no, &rect, 0, 0, 0);
+ }
+
+ return 0;
+}
+
+int display_charge_percent(unsigned char *fileBuffer, int percent)
+{
+ int ret, len;
+ int text_width, anim_height;
+ char tmpbuf[20];
+ unsigned int rgb = 0xFF00; //green
+ char r, g, b;
+ int pos_x, pos_y;
+ bmp_header_t *header;
+ unsigned int logo_size;
+ int no;
+ mv_surface *s;
+
+ if(s_display_percent == 0)
+ return -1;
+
+ if(percent < 0 || percent > 100)
+ return -1;
+
+ if(percent != s_percent_val) {
+ ret = clear_charge_percent(fileBuffer);
+ if(ret)
+ return ret;
+
+ s_percent_val = percent;
+ } else
+ return 0;
+
+ for(no = 0; no < VPP_VOUT_INFO_NUM; no++) {
+ s = &s_surface[no];
+ if(s->startAddr == 0)
+ continue;
+
+ if (*fileBuffer != 'B') {
+ //printf("Error : logo is Not BMP Format. Couldn't display charging percent\n");
+ //return -1;
+ anim_height = 168;
+ } else {
+ if(!g_tf_boot) {
+ logo_size = (*(unsigned short *)(fileBuffer + 4) << 16) + (*(unsigned short *)(fileBuffer + 2));
+
+ fileBuffer = fileBuffer + logo_size;
+
+ if (*fileBuffer != 'B') {
+ //printf("Error : charge-anim is Not BMP Format. Couldn't display charging percent\n");
+ //return -1;
+ anim_height = 168;
+ } else {
+ header = (bmp_header_t *)fileBuffer;
+ anim_height = mv_le_to_cpu((char *)&header->height, 4);
+ anim_height = anim_height / CHARGEANIM_PIC_NUM;
+ }
+ } else {
+ header = (bmp_header_t *)fileBuffer;
+ anim_height = mv_le_to_cpu((char *)&header->height, 4);
+ anim_height = anim_height / CHARGEANIM_PIC_NUM;
+ }
+ }
+
+ len = sprintf(tmpbuf, "%d%%", percent);
+ tmpbuf[len] = '\0';
+ text_width = len * CHAR_WIDTH;
+
+ get_display_postion(s, text_width, anim_height, &pos_x, &pos_y);
+
+ pos_y = pos_y - CHAR_HEIGHT - CHAR_HEIGHT;
+ if(pos_y < 0)
+ pos_y = 0;
+
+ r = (rgb >> 16) & 0xFF;
+ g = (rgb >> 8) & 0xFF;
+ b = rgb & 0xFF;
+
+ mv_textOut(no, pos_x, pos_y, tmpbuf, r, g, b);
+ }
+
+ return 0;
+}
+
+static void hint_text(char *p_text, unsigned int rgb)
+{
+ int xpos, ypos;
+ int len, text_width, text_height;
+ mv_Rect rect;
+ char r, g, b;
+ int no;
+ mv_surface *s;
+
+ for(no = 0; no < VPP_VOUT_INFO_NUM; no++) {
+ s = &s_surface[no];
+ if(s->startAddr == 0)
+ continue;
+
+ len = strlen(p_text);
+
+ text_width = len * CHAR_WIDTH;
+ text_height = CHAR_HEIGHT;
+
+ get_display_postion(s, text_width, text_height, &xpos, &ypos);
+
+ rect.left = xpos;
+ rect.right = xpos + text_width;
+ rect.top = ypos;
+ rect.bottom = ypos + CHAR_HEIGHT;
+ mv_fillRect(no, &rect, 0, 0, 0);
+
+ r = (rgb >> 16) & 0xFF;
+ g = (rgb >> 8) & 0xFF;
+ b = rgb & 0xFF;
+
+ mv_textOut(no, xpos, ypos, p_text, r, g, b);
+ }
+}
+
+void show_text_to_screen(char *p_text, unsigned int rgb)
+{
+ if(!(g_display_vaild & DISPLAY_ENABLE)) {
+ if(display_init(0, 0) == -1) {
+ printf("Display init fail. Don't show_text_to_screen\n");
+ return;
+ }
+ }
+
+ mv_clearFB();
+
+ hint_text(p_text, rgb);
+
+ if (g_display_param.vout == VPP_VOUT_LCD)
+ lcd_blt_enable(g_pwm_setting.pwm_no, 1);
+
+}
+
+void show_text_to_screen_no_backlight(char *p_text, unsigned int rgb)
+{
+ if(!(g_display_vaild & DISPLAY_ENABLE))
+ return;
+
+ mv_clearFB();
+
+ hint_text(p_text, rgb);
+}
+
+static void hint_2lines_text(char *p_text1, char *p_text2, unsigned int rgb)
+{
+ int xpos, ypos;
+ int len, text_width, text_height;
+ mv_Rect rect;
+ char r, g, b;
+ int no;
+ mv_surface *s;
+
+ for(no = 0; no < 2; no++) {
+ s = &s_surface[no];
+ if(s->startAddr == 0)
+ continue;
+
+ if(strlen(p_text1) >= strlen(p_text2))
+ len = strlen(p_text1);
+ else
+ len = strlen(p_text2);
+
+ text_width = len * CHAR_WIDTH;
+ text_height = 2 * CHAR_HEIGHT + 10;
+
+ get_display_postion(s, text_width, text_height, &xpos, &ypos);
+
+ rect.left = xpos;
+ rect.right = xpos + text_width;
+ rect.top = ypos;
+ rect.bottom = ypos + text_height;
+ mv_fillRect(no, &rect, 0, 0, 0);
+
+ r = (rgb >> 16) & 0xFF;
+ g = (rgb >> 8) & 0xFF;
+ b = rgb & 0xFF;
+
+ mv_textOut(no, xpos, ypos, p_text1, r, g, b);
+ mv_textOut(no, xpos, ypos + CHAR_HEIGHT + 10, p_text2, r, g, b);
+ }
+}
+
+void show_2lines_text_to_screen(char *p_text1, char *p_text2, unsigned int rgb)
+{
+ if(!(g_display_vaild & DISPLAY_ENABLE)) {
+ if(display_init(0, 0) == -1) {
+ printf("Display init fail. Don't show_text_to_screen\n");
+ return;
+ }
+ }
+
+ mv_clearFB();
+
+ hint_2lines_text(p_text1, p_text2, rgb);
+
+ if (g_display_param.vout == VPP_VOUT_LCD)
+ lcd_blt_enable(g_pwm_setting.pwm_no, 1);
+
+}
+
+void show_2lines_text_to_screen_no_backlight(char *p_text1, char *p_text2, unsigned int rgb)
+{
+ if(!(g_display_vaild & DISPLAY_ENABLE))
+ return;
+
+ mv_clearFB();
+
+ hint_2lines_text(p_text1, p_text2, rgb);
+}
+
+int show_charge_picture(unsigned char *fileBuffer, int picture_no)
+{
+ int i, j, bytes;
+ unsigned char r, g, b;
+ bmp_header_t *header;
+ int width, height, offset;
+ short colorBits;
+ //mv_surface img;
+ unsigned int dcolor = 0;
+ int xpos, ypos;
+ unsigned int logo_size;
+ int no;
+ mv_surface *s;
+ unsigned char *buffer;
+
+ if(!g_tf_boot) {
+ if (*fileBuffer != 'B') {
+ printf("Error : logo is Not BMP Format\n");
+ if(picture_no == CHARGEANIM_PIC_NUM - 1)
+ hint_text("Low Battery", 0xFFFF00);
+ else
+ hint_text("Charging now ...", 0xFF00);
+ return -1;
+ }
+
+ logo_size = (*(unsigned short *)(fileBuffer + 4) << 16) + (*(unsigned short *)(fileBuffer + 2));
+
+ fileBuffer = fileBuffer + logo_size;
+
+ if (*fileBuffer != 'B') {
+ printf("Error : charge-anim is Not BMP Format\n");
+ if(picture_no == CHARGEANIM_PIC_NUM - 1)
+ hint_text("Low Battery", 0xFFFF00);
+ else
+ hint_text("Charging now ...", 0xFF00);
+
+ return -1;
+ }
+ } else {
+ if (*fileBuffer != 'B') {
+ printf("Error : charge-anim is Not BMP Format\n");
+ if(picture_no == CHARGEANIM_PIC_NUM - 1)
+ hint_text("Low Battery", 0xFFFF00);
+ else
+ hint_text("Charging now ...", 0xFF00);
+
+ return -1;
+ }
+ }
+
+ if(picture_no < 0 || picture_no >= CHARGEANIM_PIC_NUM) {
+ printf("Error : picture no (%d) error\n", picture_no);
+ return -1;
+ }
+
+ for(no = 0; no < VPP_VOUT_INFO_NUM; no++) {
+ s = &s_surface[no];
+ if(s->startAddr == 0)
+ continue;
+
+ buffer = fileBuffer;
+
+ header = (bmp_header_t *)buffer;
+ colorBits = mv_le_to_cpu((char *)&header->bit_count, 2);
+ if(colorBits != 24) {
+ printf("Error : charge_animation colorBits = %d, current only support 24bits\n",
+ colorBits);
+ return -1;
+ }
+
+ offset = mv_le_to_cpu((char *)&header->data_offset, 4);
+ width = mv_le_to_cpu((char *)&header->width, 4);
+ height = mv_le_to_cpu((char *)&header->height, 4);
+
+ height = height / CHARGEANIM_PIC_NUM;
+
+ get_display_postion(s, width, height, &xpos, &ypos);
+
+ buffer += (width * height * 3) * (6 - picture_no);
+
+ switch (colorBits) {
+ case 24: // r,g,b
+ bytes = 4 - (width * 3) % 4;
+ if (bytes == 4)
+ bytes = 0;
+ for (i = height - 1; i >= 0; i--) {
+ for (j = 0; j < width; j++) {
+ b = *(buffer + offset);
+ g = *(buffer + offset + 1);
+ r = *(buffer + offset + 2);
+ dcolor = rgb2color(r, g, b);
+
+ putcolor2mem(s, j + xpos, i + ypos, dcolor);
+ offset += 3;
+ }
+ offset += bytes;
+ }
+
+ mem2fb(s, width, height, xpos, ypos);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int getGlyphIndex(unsigned short unicode)
+{
+ int i;
+ GlyphRange *const range = (GlyphRange *)(m_fh + 1);
+ GlyphScatter *start;
+ GlyphScatter *scatter;
+ int low;
+ int high;
+ int mid;
+ int glyphIndex = 1; // == 1 to skip missing lattice
+
+ for (i = 0 ; i < m_fh->rangeCount; i++) {
+ if ( unicode >= range[i].ucs2Start && unicode <= range[i].ucs2End) {
+ glyphIndex += (unicode - range[i].ucs2Start);
+ return glyphIndex;
+ }
+ glyphIndex += range[i].ucs2End - range[i].ucs2Start + 1;
+ }
+
+ start = (GlyphScatter *)(range + m_fh->rangeCount);
+ low = 0;
+ high = m_fh->scatterCount - 1;
+
+ while (low <= high) {
+ mid = (low + high) / 2;
+ scatter = start + mid;
+ if ( *scatter < unicode)
+ low = mid + 1;
+ else if ( *scatter > unicode)
+ high = mid - 1;
+ else
+ return(glyphIndex + mid);
+ }
+ return 0; // the missing glyph
+}
+
+
+static unsigned char *getLattice(int glyphIndex)
+{
+ return m_glyphStart + glyphIndex * m_fh->glyphBytes;
+}
+
+static int setFontFileDat(const unsigned char *dat)
+{
+ FontFileHeadV1 *fh = (FontFileHeadV1 *)dat;
+ if ( fh->magic[0] != 'F' || fh->magic[1] != 'T') {
+ return -1;
+ }
+
+ m_fileStart = (unsigned char * )dat;
+ m_fh = (FontFileHeadV1 *)m_fileStart;
+
+ m_glyphStart = m_fileStart + sizeof(FontFileHeadV1)
+ + m_fh->rangeCount * sizeof(GlyphRange)
+ + m_fh->scatterCount * sizeof(GlyphScatter);
+ return 0;
+}
+
+static void loadFontImage(int code, mv_surface *img)
+{
+ int idx = getGlyphIndex((unsigned short)code);
+
+ img->width = m_fh->charWidth;
+ img->height = m_fh->charHeight;
+ img->startAddr = (char *)getLattice(idx);
+}
+
+void mv_textOut(int no, int x, int y, const char *string, unsigned char r, unsigned char g, unsigned char b)
+{
+ mv_surface img;
+ const char *p;
+ const unsigned char *lattice;
+ int h, w;
+ unsigned int textColor = 0;
+ const mv_surface *s = &s_surface[no];
+
+ for (p = string; *p != '\0'; p++) {
+ loadFontImage(*p, &img);
+ lattice = (const unsigned char * )img.startAddr;
+ if (!lattice)
+ continue;
+
+ for ( h = 0 ; h < img.height; ++h) {
+ unsigned char mask = 0x80;
+ for ( w = 0 ; w < img.width; ++w) {
+ if (*lattice & mask) {
+ //*(getXYData(&s_primary, x + w, y + h)) = textColor;
+ textColor = rgb2color(r, g, b);
+ putcolor2fb(s, x + w, y + h, textColor);
+ }
+ mask >>= 1;
+ if ( mask == 0 ) {
+ mask = 0x80;
+ ++lattice; // next byte
+ }
+ }
+ if (mask != 0x80) {
+ ++lattice; // next byte
+ }
+ }
+
+ x += img.width;
+ }
+}
+
+void mem_cpy_alignment(char *des, char *src, int len)
+{
+ char *copy_some_src, *copy_some_dst;
+ int dst_alignment = (int)des % 4;
+ int src_alignment = (int)src % 4;
+ int i, tmp_len, len_less, len_less_4_byte;
+
+ int phase1, phase2;
+
+ // check dst, src ali
+ // all ali
+ if (!dst_alignment && !src_alignment) {
+ // check len 32bytes ali
+ phase1 = len_less = len % 32;
+ // len ali
+ if(!phase1 && len >= 32) {
+ mem_copy(src, des, len);
+ return;
+ } else {
+ // trans 32bytes ali data first
+ tmp_len = len - len_less;
+ if(len >= 32)
+ mem_copy(src, des, tmp_len);
+ // check len_less 4 bytes ali
+ phase2 = len_less % 4;
+ if(!phase2 && phase2 >= 4) {
+ less_mem_copy(src + tmp_len, des + tmp_len, len_less);
+ return;
+ } else {
+ // trans 4bytes ali data first
+ len_less = len_less - phase2;
+ if(len_less >= 4)
+ less_mem_copy(src + tmp_len, des + tmp_len, len_less);
+ // trans least bytes
+ for (i = 0; i < phase2; i++)
+ *(des + tmp_len + len_less + i) = *(src + tmp_len + len_less + i);
+ return;
+ }
+ }
+ }
+ tmp_len = len;
+ // dst not aligment, let dst alignment first
+ // ====================================================
+ copy_some_src = (char *)(src);
+ copy_some_dst = (char *)(des);
+ if (dst_alignment != 0) {
+ for (i = 0; i < 4 - dst_alignment; i++) {
+ *(des + i) = *(src + i);
+
+ // copy len
+ tmp_len = tmp_len - 1;
+
+ // copy complete
+ if (tmp_len <= 0)
+ return;
+ }
+
+ // src + bytes of already copy
+ copy_some_src = (char *)(src + ( 4 - dst_alignment)) ;
+ copy_some_dst = (char *)(des + ( 4 - dst_alignment)) ;
+ }
+ src_alignment = (int)copy_some_src % 4;
+
+ // ====================================================
+ // handle data len < 32bytes
+ if (tmp_len < 32) {
+ phase1 = len_less = tmp_len % 4;
+ // tmp_len 4bytes ali
+ if (!phase1 && tmp_len >= 4) {
+ switch (src_alignment) {
+ case 1:
+ byte1_less_bundle_copy (copy_some_src - src_alignment, copy_some_dst, tmp_len);
+ break;
+
+ case 2:
+ byte2_less_bundle_copy (copy_some_src - src_alignment, copy_some_dst, tmp_len);
+ break;
+
+ case 3:
+ byte3_less_bundle_copy (copy_some_src - src_alignment, copy_some_dst, tmp_len);
+ break;
+
+ default:
+ less_mem_copy (copy_some_src - src_alignment, copy_some_dst, tmp_len);
+ break;
+ }
+ return;
+ } else {
+ // trans 4bytes ali data first
+ len_less = tmp_len - phase1;
+ if(len_less >= 4)
+ switch (src_alignment) {
+ case 1:
+ byte1_less_bundle_copy (copy_some_src - src_alignment, copy_some_dst, len_less);
+ break;
+
+ case 2:
+ byte2_less_bundle_copy (copy_some_src - src_alignment, copy_some_dst, len_less);
+ break;
+
+ case 3:
+ byte3_less_bundle_copy (copy_some_src - src_alignment, copy_some_dst, len_less);
+ break;
+
+ default:
+ less_mem_copy (copy_some_src - src_alignment, copy_some_dst, len_less);
+ break;
+ }
+ // trans least bytes
+ for (i = 0; i < phase1; i++)
+ *(copy_some_dst + len_less + i) = *(copy_some_src + len_less + i);
+ return;
+ }
+ }
+ // ====================================================
+ phase1 = tmp_len % 32;
+ // data_len 32bytes ali
+ if (!phase1) {
+ switch (src_alignment) {
+ case 1:
+ byte1_alig_mem_copy (copy_some_src - src_alignment, copy_some_dst, tmp_len);
+ break;
+
+ case 2:
+ byte2_alig_mem_copy (copy_some_src - src_alignment, copy_some_dst, tmp_len);
+ break;
+
+ case 3:
+ byte3_alig_mem_copy (copy_some_src - src_alignment, copy_some_dst, tmp_len);
+ break;
+
+ default:
+ mem_copy (copy_some_src - src_alignment, copy_some_dst, tmp_len);
+ break;
+ }
+ return;
+ } else {
+ len_less = tmp_len - phase1;
+ // trans 32bytes ali data first
+ switch (src_alignment) {
+ case 1:
+ byte1_alig_mem_copy (copy_some_src - src_alignment, copy_some_dst, len_less);
+ break;
+
+ case 2:
+ byte2_alig_mem_copy (copy_some_src - src_alignment, copy_some_dst, len_less);
+ break;
+
+ case 3:
+ byte3_alig_mem_copy (copy_some_src - src_alignment, copy_some_dst, len_less);
+ break;
+
+ default:
+ mem_copy (copy_some_src - src_alignment, copy_some_dst, len_less);
+ break;
+ }
+ phase2 = phase1 % 4;
+ len_less_4_byte = phase1 - phase2;
+ // data_len 4bytes ali
+ if (!phase2) {
+ switch (src_alignment) {
+ case 1:
+ byte1_less_bundle_copy (copy_some_src - src_alignment + len_less, copy_some_dst + len_less, len_less_4_byte);
+ break;
+
+ case 2:
+ byte2_less_bundle_copy (copy_some_src - src_alignment + len_less, copy_some_dst + len_less, len_less_4_byte);
+ break;
+
+ case 3:
+ byte3_less_bundle_copy (copy_some_src - src_alignment + len_less, copy_some_dst + len_less, len_less_4_byte);
+ break;
+
+ default:
+ less_mem_copy (copy_some_src - src_alignment + len_less, copy_some_dst + len_less, len_less_4_byte);
+ break;
+ }
+ return;
+ } else {
+ // trans 4bytes ali data first
+ if(len_less_4_byte >= 4) {
+ switch (src_alignment) {
+ case 1:
+ byte1_less_bundle_copy (copy_some_src - src_alignment + len_less, copy_some_dst + len_less, len_less_4_byte);
+ break;
+
+ case 2:
+ byte2_less_bundle_copy (copy_some_src - src_alignment + len_less, copy_some_dst + len_less, len_less_4_byte);
+ break;
+
+ case 3:
+ byte3_less_bundle_copy (copy_some_src - src_alignment + len_less, copy_some_dst + len_less, len_less_4_byte);
+ break;
+
+ default:
+ less_mem_copy (copy_some_src - src_alignment + len_less, copy_some_dst + len_less, len_less_4_byte);
+ break;
+ }
+ }
+
+ // trans least bytes
+ for (i = 0; i < phase2; i++)
+ *(copy_some_dst + len_less + len_less_4_byte + i) = *(copy_some_src + len_less + len_less_4_byte + i);
+ return;
+ }
+ }
+}
+
diff --git a/common/wmt_display/minivgui.h b/common/wmt_display/minivgui.h
new file mode 100755
index 0000000..89f124a
--- /dev/null
+++ b/common/wmt_display/minivgui.h
@@ -0,0 +1,116 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+should have received a copy of the GNU General Public License along with this
+program. If not, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+/**
+ * A mini gui implementation (copied some code from VGUI)
+ * functions:
+ * 1. draw line (horz or vert only)
+ * 2. draw rectangle, fill rectangle,
+ * 3. draw bitmap ( Windows bmp format)
+ * 4. draw text ( note, ascii only and the text font was gererated by
+ * vgui's FontGen 1.0 tool)
+ *
+ * Usage:
+ * first maybe you want to change this line to fit your rgb format
+ #define mv_RGB_FORMAT mv_RGB_FORMAT_565
+ * in the source code firstly you need to prepare all HW related jobs,
+ * such as turn on panel backlight/init LCDC
+ * after that the first function you need to invoked is mv_initPrimary.
+ * You need to set the correct member in mv_surface argument.
+ * After that you can call all functions
+ *
+ * Here is a example:
+ *
+ *
+ mv_surface s;
+ s.width = 800;
+ s.height = 480;
+ s.lineBytes = 800 * 2;
+ // if the panel is 16bit
+ s.startAddr = 0x7C000000;
+ // the frame buffer address
+
+ mv_initPrimary(&s);
+
+ mv_Rect r;
+ r.left = 0;
+ r.right = s.width;
+ r.top = 0;
+ r.bottom = s.height;
+ //fill whole screen with red color
+ mv_fillRect(&r, mv_RGB2Color(255, 0, 0));
+
+ //draw some text on the screen (build-in font size is 12x24)
+ mv_textOut(0, 0, "Hello,world!", mv_RGB2Color(0, 0, 0));
+ mv_textOut(0, 25, "Hello, mini VGUI!", mv_RGB2Color(0, 0, 0));
+ *
+ */
+#ifndef MINIVGUI_H_INCLUDED
+#define MINIVGUI_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "wmt_display.h"
+
+extern int g_display_direction;
+
+/**
+ * init minivgui primary screen. this is the first function need be called
+ */
+void mv_initSurface(int no,const mv_surface * s);
+mv_surface *mv_getSurface(int no);
+void mv_dumpSurface(void);
+
+void mv_drawLine(int no, int x1, int y1, int x2, int y2, unsigned int color);
+void mv_drawRect(int no, const mv_Rect* rect, unsigned int color);
+void mv_fillRect(int no, const mv_Rect* rect, unsigned char r, unsigned char g, unsigned char b);
+
+void check_display_direction(void);
+void mv_clearFB(void);
+int show_charge_picture(unsigned char* fileBuffer, int picture_no);
+
+void check_tf_boot(void);
+
+/**
+ * draw text on the screen (Note: only acsii supported)
+ */
+void mv_textOut(int no, int x, int y, const char * string, unsigned char r, unsigned char g, unsigned char b);
+int mv_loadBmp(int no, unsigned char* fileBuffer, int clearFB);
+void show_text_to_screen(char *p_text, unsigned int rgb);
+void show_text_to_screen_no_backlight(char *p_text, unsigned int rgb);
+void show_2lines_text_to_screen(char *p_text1, char *p_text2, unsigned int rgb);
+void show_2lines_text_to_screen_no_backlight(char *p_text1, char *p_text2, unsigned int rgb);
+
+/**
+* display charging percent
+**/
+int init_charge_percent(void);
+int clear_charge_percent(unsigned char* fileBuffer);
+int display_charge_percent(unsigned char* fileBuffer, int percent);
+
+// for mem copy
+void mem_cpy_alignment(char *des, char *src, int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MINIVGUI_H_INCLUDED
+
+
diff --git a/common/wmt_display/parse-edid.c b/common/wmt_display/parse-edid.c
new file mode 100755
index 0000000..8bf8da7
--- /dev/null
+++ b/common/wmt_display/parse-edid.c
@@ -0,0 +1,1069 @@
+/*++
+ * linux/drivers/video/wmt/parse-edid.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define PARSE_EDID_C
+#undef DEBUG
+/* #define DEBUG */
+/* #define DEBUG_DETAIL */
+
+#include "vpp.h"
+#include "edid.h"
+#include "hdmi.h"
+
+const char edid_v1_header[] = {
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
+
+const char edid_v1_descriptor_flag[] = { 0x00, 0x00 };
+
+#define COMBINE_HI_8LO(hi, lo) \
+ ((((unsigned)hi) << 8) | (unsigned)lo)
+
+#define COMBINE_HI_4LO(hi, lo) \
+ ((((unsigned)hi) << 4) | (unsigned)lo)
+
+#define UPPER_NIBBLE(x) \
+ (((128|64|32|16) & (x)) >> 4)
+
+#define LOWER_NIBBLE(x) \
+ ((1|2|4|8) & (x))
+
+#define MONITOR_NAME 0xfc
+#define MONITOR_LIMITS 0xfd
+#define UNKNOWN_DESCRIPTOR -1
+#define DETAILED_TIMING_BLOCK -2
+
+struct edid_timing_t edid_establish_timing[] = {
+ { 800, 600, 60 }, { 800, 600, 56 }, { 640, 480, 75 }, { 640, 480, 72 },
+ { 640, 480, 67 }, { 640, 480, 60 }, { 720, 400, 88 }, { 720, 400, 70 },
+ { 1280, 1024, 75 }, { 1024, 768, 75 }, { 1024, 768, 70 },
+ { 1024, 768, 60 }, { 1024, 768, 87 }, { 832, 624, 75 },
+ { 800, 600, 75 }, { 800, 600, 72 }, { 1152, 870, 75 }
+};
+int edid_msg_enable;
+int edid_disable;
+struct edid_parsed_t edid_parsed;
+
+#undef DBGMSG
+#define DBGMSG(fmt, args...) if (edid_msg_enable) \
+ DPRINT(fmt, ## args)
+
+static int block_type(char *block)
+{
+ if (!memcmp(edid_v1_descriptor_flag, block, 2)) {
+ /* descriptor */
+ if (block[2] != 0)
+ return UNKNOWN_DESCRIPTOR;
+ return block[3];
+ }
+ /* detailed timing block */
+ return DETAILED_TIMING_BLOCK;
+} /* End of block_type() */
+
+static char *get_vendor_sign(char *block, char *sign)
+{
+ unsigned short h;
+
+ /*
+ 08h WORD big-endian manufacturer ID (see #00136)
+ bits 14-10: first letter (01h='A', 02h='B', etc.)
+ bits 9-5: second letter
+ bits 4-0: third letter
+ */
+ h = COMBINE_HI_8LO(block[0], block[1]);
+ sign[0] = ((h >> 10) & 0x1f) + 'A' - 1;
+ sign[1] = ((h >> 5) & 0x1f) + 'A' - 1;
+ sign[2] = (h & 0x1f) + 'A' - 1;
+ sign[3] = 0;
+ return sign;
+} /* End of get_vendor_sign() */
+
+static char *get_monitor_name(char *block, char *name)
+{
+#define DESCRIPTOR_DATA 5
+
+ char *ptr = block + DESCRIPTOR_DATA;
+ unsigned i;
+
+ for (i = 0; i < 13; i++, ptr++) {
+ if (*ptr == 0xa) {
+ name[i] = 0;
+ return name;
+ }
+ name[i] = *ptr;
+ }
+ return name;
+} /* End of get_monitor_name() */
+
+static int parse_timing_description(char *dtd, struct edid_info_t *info)
+{
+#define PIXEL_CLOCK_LO ((unsigned)dtd[0])
+#define PIXEL_CLOCK_HI ((unsigned)dtd[1])
+#define PIXEL_CLOCK (COMBINE_HI_8LO(PIXEL_CLOCK_HI, PIXEL_CLOCK_LO) * 10000)
+#define H_ACTIVE_LO ((unsigned)dtd[2])
+#define H_BLANKING_LO ((unsigned)dtd[3])
+#define H_ACTIVE_HI UPPER_NIBBLE((unsigned)dtd[4])
+#define H_ACTIVE COMBINE_HI_8LO(H_ACTIVE_HI, H_ACTIVE_LO)
+#define H_BLANKING_HI LOWER_NIBBLE((unsigned)dtd[4])
+#define H_BLANKING COMBINE_HI_8LO(H_BLANKING_HI, H_BLANKING_LO)
+#define V_ACTIVE_LO ((unsigned)dtd[5])
+#define V_BLANKING_LO ((unsigned)dtd[6])
+#define V_ACTIVE_HI UPPER_NIBBLE((unsigned)dtd[7])
+#define V_ACTIVE COMBINE_HI_8LO(V_ACTIVE_HI, V_ACTIVE_LO)
+#define V_BLANKING_HI LOWER_NIBBLE((unsigned)dtd[7])
+#define V_BLANKING COMBINE_HI_8LO(V_BLANKING_HI, V_BLANKING_LO)
+#define H_SYNC_OFFSET_LO ((unsigned)dtd[8])
+#define H_SYNC_WIDTH_LO ((unsigned)dtd[9])
+#define V_SYNC_OFFSET_LO UPPER_NIBBLE((unsigned)dtd[10])
+#define V_SYNC_WIDTH_LO LOWER_NIBBLE((unsigned)dtd[10])
+#define V_SYNC_WIDTH_HI ((unsigned)dtd[11] & (1|2))
+#define V_SYNC_OFFSET_HI (((unsigned)dtd[11] & (4|8)) >> 2)
+#define H_SYNC_WIDTH_HI (((unsigned)dtd[11] & (16|32)) >> 4)
+#define H_SYNC_OFFSET_HI (((unsigned)dtd[11] & (64|128)) >> 6)
+#define V_SYNC_WIDTH COMBINE_HI_4LO(V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO)
+#define V_SYNC_OFFSET COMBINE_HI_4LO(V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO)
+#define H_SYNC_WIDTH COMBINE_HI_4LO(H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO)
+#define H_SYNC_OFFSET COMBINE_HI_4LO(H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO)
+#define H_SIZE_LO ((unsigned)dtd[12])
+#define V_SIZE_LO ((unsigned)dtd[13])
+#define H_SIZE_HI UPPER_NIBBLE((unsigned)dtd[14])
+#define V_SIZE_HI LOWER_NIBBLE((unsigned)dtd[14])
+#define H_SIZE COMBINE_HI_8LO(H_SIZE_HI, H_SIZE_LO)
+#define V_SIZE COMBINE_HI_8LO(V_SIZE_HI, V_SIZE_LO)
+#define H_BORDER ((unsigned)dtd[15])
+#define V_BORDER ((unsigned)dtd[16])
+#define FLAGS ((unsigned) dtd[17])
+#define INTERLACED (FLAGS & 128)
+#define SYNC_TYPE (FLAGS & 3 << 3) /* bits 4,3 */
+#define SYNC_SEPARATE (3 << 3)
+#define HSYNC_POSITIVE (FLAGS & 4)
+#define VSYNC_POSITIVE (FLAGS & 2)
+
+ int htotal, vtotal;
+ int i;
+ struct fb_videomode *t;
+ int fps;
+ int vmul;
+
+ htotal = H_ACTIVE + H_BLANKING;
+ vtotal = V_ACTIVE + V_BLANKING;
+
+ DBGMSG("Detail Timing: \"%dx%d\"\n", H_ACTIVE, V_ACTIVE);
+ DBGMSG("\tVfreq %dHz, Hfreq %dkHz\n",
+ PIXEL_CLOCK / (vtotal * htotal),
+ PIXEL_CLOCK / (htotal * 1000));
+ DBGMSG("\tDotClock\t%d\n", PIXEL_CLOCK / 1000000);
+ DBGMSG("\tHTimings\t%u %u %u %u\n", H_ACTIVE,
+ H_ACTIVE + H_SYNC_OFFSET,
+ H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH,
+ htotal);
+
+ DBGMSG("\tVTimings\t%u %u %u %u\n", V_ACTIVE,
+ V_ACTIVE + V_SYNC_OFFSET,
+ V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH,
+ vtotal);
+
+ if (INTERLACED || (SYNC_TYPE == SYNC_SEPARATE)) {
+ DBGMSG("\tFlags\t%s\"%sHSync\" \"%sVSync\"\n",
+ INTERLACED ? "\"Interlace\" " : "",
+ HSYNC_POSITIVE ? "+" : "-",
+ VSYNC_POSITIVE ? "+" : "-");
+ }
+
+ for (i = 0; i < 4; i++) {
+ t = &info->detail_timing[i];
+ if (t->pixclock == 0)
+ break;
+ }
+
+ if (i >= 4) {
+ DBGMSG("*W* slot full\n");
+ return 0;
+ }
+
+ t->pixclock = KHZ2PICOS(PIXEL_CLOCK / 1000);
+ t->right_margin = H_SYNC_OFFSET;
+ t->hsync_len = H_SYNC_WIDTH;
+ t->xres = H_ACTIVE;
+ t->left_margin = H_BLANKING - (H_SYNC_WIDTH + H_SYNC_OFFSET);
+ t->vmode = INTERLACED ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
+ vmul = (INTERLACED) ? 2 : 1;
+ t->lower_margin = V_SYNC_OFFSET * vmul;
+ t->vsync_len = V_SYNC_WIDTH * vmul;
+ t->yres = V_ACTIVE * vmul;
+ t->upper_margin = V_BLANKING - (V_SYNC_WIDTH + V_SYNC_OFFSET);
+
+ fps = vpp_calc_refresh(PIXEL_CLOCK, htotal, vtotal);
+ t->refresh = fps;
+ t->sync = HSYNC_POSITIVE ? (FB_SYNC_HOR_HIGH_ACT) : 0;
+ t->sync |= VSYNC_POSITIVE ? (FB_SYNC_VERT_HIGH_ACT) : 0;
+
+ if (vout_check_ratio_16_9(H_ACTIVE, V_ACTIVE))
+ info->option |= EDID_OPT_16_9;
+#if 0
+ DBGMSG("%dx%d,%d,%s\n", H_ACTIVE, V_ACTIVE, t->pixel_clock,
+ (info->option & EDID_OPT_16_9) ? "16:9" : "4:3");
+#endif
+ return 0;
+} /* End of parse_timing_description() */
+
+static int parse_dpms_capabilities(char flags)
+{
+#define DPMS_ACTIVE_OFF (1 << 5)
+#define DPMS_SUSPEND (1 << 6)
+#define DPMS_STANDBY (1 << 7)
+
+ DBGMSG("# DPMS capabilities: Active off:%s Suspend:%s Standby:%s\n\n",
+ (flags & DPMS_ACTIVE_OFF) ? "yes" : "no",
+ (flags & DPMS_SUSPEND) ? "yes" : "no",
+ (flags & DPMS_STANDBY) ? "yes" : "no");
+ return 0;
+} /* End of parse_dpms_capabilities() */
+
+static int parse_monitor_limits(char *block, struct edid_info_t *info)
+{
+#define V_MIN_RATE block[5]
+#define V_MAX_RATE block[6]
+#define H_MIN_RATE block[7]
+#define H_MAX_RATE block[8]
+#define MAX_PIXEL_CLOCK (((int)block[9]) * 10)
+#define GTF_SUPPORT block[10]
+
+ DBGMSG("Monitor limit\n");
+ DBGMSG("\tHorizontal Frequency: %u-%u Hz\n", H_MIN_RATE, H_MAX_RATE);
+ DBGMSG("\tVertical Frequency: %u-%u kHz\n", V_MIN_RATE, V_MAX_RATE);
+ if (MAX_PIXEL_CLOCK == 10 * 0xff) {
+ DBGMSG("\tMax dot clock not given\n");
+ } else {
+ DBGMSG("\tMax dot clock (video bandwidth) %u MHz\n",
+ (int)MAX_PIXEL_CLOCK);
+ info->pixel_clock_limit = MAX_PIXEL_CLOCK;
+ }
+
+ if (GTF_SUPPORT)
+ DBGMSG("\tEDID version 3 GTF given: contact author\n");
+ return 0;
+} /* End of parse_monitor_limits() */
+
+static int get_established_timing(char *edid, struct edid_info_t *info)
+{
+ char time_1, time_2;
+
+ time_1 = edid[ESTABLISHED_TIMING_I];
+ time_2 = edid[ESTABLISHED_TIMING_II];
+ info->establish_timing = time_1 + (time_2 << 8);
+
+ /*---------------------------------------------------------------------
+ 35: ESTABLISHED TIMING I
+ bit 7-0: 720x400@70 Hz, 720x400@88 Hz, 640x480@60 Hz, 640x480@67 Hz,
+ 640x480@72 Hz, 640x480@75 Hz, 800x600@56 Hz, 800x600@60 Hz
+ ---------------------------------------------------------------------*/
+ DBGMSG("Established Timimgs I: 0x%x\n", time_1);
+ if (time_1 & 0x80)
+ DBGMSG("\t%dx%d@%dHz\n", 720, 400, 70);
+ if (time_1 & 0x40)
+ DBGMSG("\t%dx%d@%dHz\n", 720, 400, 88);
+ if (time_1 & 0x20)
+ DBGMSG("\t%dx%d@%dHz\n", 640, 480, 60);
+ if (time_1 & 0x10)
+ DBGMSG("\t%dx%d@%dHz\n", 640, 480, 67);
+ if (time_1 & 0x08)
+ DBGMSG("\t%dx%d@%dHz\n", 640, 480, 72);
+ if (time_1 & 0x04)
+ DBGMSG("\t%dx%d@%dHz\n", 640, 480, 75);
+ if (time_1 & 0x02)
+ DBGMSG("\t%dx%d@%dHz\n", 800, 600, 56);
+ if (time_1 & 0x01)
+ DBGMSG("\t%dx%d@%dHz\n", 800, 600, 60);
+
+ /*---------------------------------------------------------------------
+ 36: ESTABLISHED TIMING II
+ bit 7-0: 800x600@72 Hz, 800x600@75 Hz, 832x624@75 Hz,
+ 1024x768@87 Hz (Interlaced), 1024x768@60 Hz, 1024x768@70 Hz,
+ 1024x768@75 Hz, 1280x1024@75 Hz
+ ---------------------------------------------------------------------*/
+ DBGMSG("Established Timimgs II: 0x%x\n", time_2);
+ if (time_2 & 0x80)
+ DBGMSG("\t%dx%d@%dHz\n", 800, 600, 72);
+ if (time_2 & 0x40)
+ DBGMSG("\t%dx%d@%dHz\n", 800, 600, 75);
+ if (time_2 & 0x20)
+ DBGMSG("\t%dx%d@%dHz\n", 832, 624, 75);
+ if (time_2 & 0x10)
+ DBGMSG("\t%dx%d@%dHz (Interlace)\n", 1024, 768, 87);
+ if (time_2 & 0x08)
+ DBGMSG("\t%dx%d@%dHz\n", 1024, 768, 60);
+ if (time_2 & 0x04)
+ DBGMSG("\t%dx%d@%dHz\n", 1024, 768, 70);
+ if (time_2 & 0x02)
+ DBGMSG("\t%dx%d@%dHz\n", 1024, 768, 75);
+ if (time_2 & 0x01)
+ DBGMSG("\t%dx%d@%dHz\n", 1280, 1024, 75);
+ return 0;
+} /* End of get_established_timing() */
+
+static int get_standard_timing(char *edid, struct edid_info_t *info)
+{
+ char *ptr = edid + STANDARD_TIMING_IDENTIFICATION_START;
+ int h_res, v_res, v_freq;
+ int byte_1, byte_2, aspect, i;
+
+ /*---------------------------------------------------------------------
+ First byte
+ Horizontal resolution. Multiply by 8, then add 248 for actual value.
+ Second byte
+ bit 7-6: Aspect ratio. Actual vertical resolution depends on horizontal
+ resolution.
+ 00=16:10, 01=4:3, 10=5:4, 11=16:9 (00=1:1 prior to v1.3)
+ bit 5-0: Vertical frequency. Add 60 to get actual value.
+ ---------------------------------------------------------------------*/
+ DBGMSG("Standard Timing Identification\n");
+ for (i = 0; i < STANDARD_TIMING_IDENTIFICATION_SIZE / 2; i++) {
+ byte_1 = *ptr++;
+ byte_2 = *ptr++;
+ if ((byte_1 == 0x01) && (byte_2 == 0x01))
+ break;
+ h_res = (byte_1 * 8) + 248;
+ aspect = byte_2 & 0xC0;
+ switch (aspect) {
+ default:
+ case 0x00:
+ v_res = h_res * 10/16;
+ break;
+ case 0x40:
+ v_res = h_res * 3/4;
+ break;
+ case 0x80:
+ v_res = h_res * 4/5;
+ break;
+ case 0xC0:
+ v_res = h_res * 9/16;
+ break;
+ }
+ v_freq = (byte_2 & 0x1F) + 60;
+ DBGMSG("\t%dx%d@%dHz\n", h_res, v_res, v_freq);
+ info->standard_timing[i].resx = h_res;
+ info->standard_timing[i].resy = v_res;
+ info->standard_timing[i].freq = v_freq;
+ }
+ return 0;
+} /* End of get_standard_timing() */
+
+static int edid_parse_v1(char *edid, struct edid_info_t *info)
+{
+ char *block;
+ char *monitor_name = 0;
+ char monitor_alt_name[100];
+ char vendor_sign[4];
+ int i, ret = 0;
+
+ if (edid_checksum(edid, EDID_LENGTH)) {
+ DBG_ERR("checksum failed\n");
+ ret = -1;
+ goto parse_end;
+ }
+
+ if (memcmp(edid+EDID_HEADER, edid_v1_header, EDID_HEADER_END+1)) {
+ DBGMSG("*E* first bytes don't match EDID version 1 header\n");
+ ret = -1;
+ goto parse_end;
+ }
+
+ if(edid_msg_enable)
+ edid_dump(edid);
+
+ DBGMSG("[EDID] EDID version: %d.%d\n",
+ (int)edid[EDID_STRUCT_VERSION],
+ (int)edid[EDID_STRUCT_REVISION]);
+
+ get_vendor_sign(edid + ID_MANUFACTURER_NAME, (char *) &vendor_sign);
+
+ info->width = edid[EDID_MAX_HOR_IMAGE_SIZE] * 10;
+ info->height = edid[EDID_MAX_VER_IMAGE_SIZE] * 10;
+ DBGMSG("[EDID] max hor %d cm ver %d cm\n", info->width, info->height);
+
+ /*---------------------------------------------------------------------
+ Parse Monitor name
+ ---------------------------------------------------------------------*/
+ block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
+ for (i = 0; i < NO_DETAILED_TIMING_DESCRIPTIONS; i++,
+ block += DETAILED_TIMING_DESCRIPTION_SIZE) {
+ if (block_type(block) == MONITOR_NAME) {
+ monitor_name =
+ get_monitor_name(block, monitor_alt_name);
+ break;
+ }
+ }
+
+ if (!monitor_name) {
+ /* Stupid djgpp hasn't snDBGMSG so we have to
+ hack something together */
+ if (strlen(vendor_sign) + 10 > sizeof(monitor_alt_name))
+ vendor_sign[3] = 0;
+
+ sprintf(monitor_alt_name, "%s:%02x%02x",
+ vendor_sign, edid[ID_MODEL], edid[ID_MODEL+1]);
+ monitor_name = monitor_alt_name;
+ }
+
+ DBGMSG("Identifier \"%s\"\n", monitor_name);
+ DBGMSG("VendorName \"%s\"\n", vendor_sign);
+ DBGMSG("ModelName \"%s\"\n", monitor_name);
+
+ memset(edid_parsed.tv_name.vendor_name, 0, sizeof(edid_parsed.tv_name.vendor_name));
+ strcpy(edid_parsed.tv_name.vendor_name, vendor_sign);
+
+ memset(edid_parsed.tv_name.monitor_name, 0, sizeof(edid_parsed.tv_name.monitor_name));
+ if (strlen(monitor_name) < MONITOR_NAME_LEN)
+ strcpy(edid_parsed.tv_name.monitor_name, monitor_name);
+ else
+ strncpy(edid_parsed.tv_name.monitor_name, monitor_name, MONITOR_NAME_LEN - 1);
+
+ parse_dpms_capabilities(edid[DPMS_FLAGS]);
+
+ /*---------------------------------------------------------------------
+ Parse ESTABLISHED TIMING I and II
+ ---------------------------------------------------------------------*/
+ get_established_timing(edid, info);
+
+ /*---------------------------------------------------------------------
+ Parse STANDARD TIMING IDENTIFICATION
+ ---------------------------------------------------------------------*/
+ get_standard_timing(edid, info);
+
+ block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
+ for (i = 0; i < NO_DETAILED_TIMING_DESCRIPTIONS; i++,
+ block += DETAILED_TIMING_DESCRIPTION_SIZE) {
+ if (block_type(block) == MONITOR_LIMITS)
+ parse_monitor_limits(block, info);
+ }
+
+ block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
+ for (i = 0; i < NO_DETAILED_TIMING_DESCRIPTIONS; i++,
+ block += DETAILED_TIMING_DESCRIPTION_SIZE) {
+ if (block_type(block) == DETAILED_TIMING_BLOCK)
+ parse_timing_description(block, info);
+ }
+parse_end:
+ return ret;
+}
+
+void edid_parse_CEA_VendorSpecDataBlock(char *block, int len,
+ struct edid_info_t *info)
+{
+ int index;
+ char temp;
+
+ DBGMSG("Vendor Spec Data Block\n");
+ if (len < 5) /* min size */
+ return;
+ /* IEEE Registration Identifier 0x000C03 */
+ if ((block[1] == 0x03) && (block[2] == 0x0C) &&
+ (block[3] == 0x0)) {
+ info->option |= EDID_OPT_HDMI;
+ DBGMSG("\t support HDMI\n");
+ }
+ DBGMSG("\t Source Physical Addr %d.%d.%d.%d\n",
+ (block[4] & 0xF0) >> 4, block[4] & 0x0F,
+ (block[5] & 0xF0) >> 4, block[5] & 0x0F);
+ info->hdmi_phy_addr = (block[4] << 8) + block[5];
+
+ /* extersion fields */
+ if (len < 8)
+ return;
+ DBGMSG("\t%s support AI\n",
+ (block[6] & 0x80) ? "" : "no");
+ DBGMSG("\t%s support 30 bits/pixel(10 bits/color)\n",
+ (block[6] & 0x40) ? "" : "no");
+ DBGMSG("\t%s support 36 bits/pixel(12 bits/color)\n",
+ (block[6] & 0x20) ? "" : "no");
+ DBGMSG("\t%s support 48 bits/pixel(16 bits/color)\n",
+ (block[6] & 0x10) ? "" : "no");
+ DBGMSG("\t%s support YUV444 in Deep Color mode\n",
+ (block[6] & 0x08) ? "" : "no");
+ DBGMSG("\t%s support DVI dual-link\n",
+ (block[6] & 0x01) ? "" : "no");
+ DBGMSG("\tMax TMDS Clock %d MHz\n", block[7] * 5);
+ temp = block[8];
+ index = 9;
+
+ if (temp & BIT(7)) {
+ DBGMSG("\tVideo Latency %d,Audio Latency %d\n",
+ block[index], block[index+1]);
+ index += 2;
+ }
+
+ if (temp & BIT(6)) {
+ DBGMSG("\tInterlaced Video Latency %d,Audio Latency %d\n",
+ block[index], block[index+1]);
+ index += 2;
+ }
+
+ if (temp & BIT(5)) {
+ int hdmi_xx_len, hdmi_3d_len;
+
+ DBGMSG("\tHDMI Video present\n");
+ temp = block[index];
+ if (temp & 0x80)
+ DBGMSG("\t\t3D present support Mandatory formats\n");
+ if (temp & 0x60)
+ DBGMSG("\t\t3D Multi present %d\n", (temp & 0x60) >> 5);
+ DBGMSG("\t\tImage size %d\n", (temp & 0x18) >> 3);
+ hdmi_xx_len = (block[index + 1] & 0xE0) >> 5;
+ hdmi_3d_len = block[index + 1] & 0x1F;
+ DBGMSG("\t\thdmi_xx_len %d,hdmi_3d_len %d\n",
+ hdmi_xx_len, hdmi_3d_len);
+ index += 2;
+
+ if (hdmi_xx_len) {
+ /* Refer to HDMI Spec Ver 1.4a */
+ index += hdmi_xx_len;
+ }
+
+ if (hdmi_3d_len) {
+ int struct_all_3d = 0;
+ int mask_3d = 0xFF;
+ int vic_order_2d;
+ char struct_3d, detail_3d;
+ int i;
+
+ hdmi_3d_len += index;
+ switch (temp & 0x60) {
+ case 0x40:
+ struct_all_3d = (block[index] << 8) +
+ block[index + 1];
+ mask_3d = (block[index + 2] << 8) +
+ block[index + 3]; /* 3D support mask */
+ DBGMSG("\t\t3D struct 0x%x,mask 0x%x\n",
+ struct_all_3d, mask_3d);
+ index += 4;
+ break;
+ case 0x20:
+ struct_all_3d = (block[index] << 8) +
+ block[index + 1];
+ DBGMSG("\t\t3D struct 0x%x\n", struct_all_3d);
+ index += 2;
+ break;
+ default:
+ break;
+ }
+ /* 3D support type */
+ if (struct_all_3d & BIT0)
+ DBGMSG("\t\tSupport Frame packing\n");
+ if (struct_all_3d & BIT6)
+ DBGMSG("\t\tSupport Top and Bottom\n");
+ if (struct_all_3d & BIT8)
+ DBGMSG("\t\tSupport Side by Side\n");
+
+ for (i = 0; i < 16; i++) {
+ if (mask_3d & (0x1 << i))
+ info->vic_3d[i].mask = struct_all_3d;
+ }
+
+ DBGMSG("\t\t[3D Structure type 0-Frame packing");
+ DBGMSG(",6-Top and Bottom,8-Side by Side]\n");
+ while (index < hdmi_3d_len) {
+ vic_order_2d = (block[index] & 0xF0) >> 4;
+ struct_3d = block[index] & 0x0F;
+ index++;
+ if (struct_3d & 0x8) {
+ detail_3d = (block[index] & 0xF0) >> 4;
+ index++;
+ } else {
+ detail_3d = 0;
+ }
+ info->vic_3d[vic_order_2d].mask |=
+ (0x1 << struct_3d);
+ DBGMSG("\t\tVIC %d,3D struct %d,detail %d\n",
+ vic_order_2d, struct_3d, detail_3d);
+ }
+ }
+ }
+}
+
+static int edid_parse_CEA(char *edid, struct edid_info_t *info)
+{
+ char *block, *block_end;
+ char checksum = 0;
+ int i, len;
+ char audio_format;
+ int num = 0, sadcnt_in_block;
+
+ memset(edid_parsed.sad, 0, sizeof(edid_parsed.sad));
+
+ if (edid[0] != 0x2)
+ return -1;
+
+ for (i = 0; i < EDID_LENGTH; i++)
+ checksum += edid[i];
+
+ if (checksum != 0) {
+ DPRINT("*E* CEA EDID checksum (0x%02x) - data is corrupt\n",
+ checksum);
+ info->option |= (EDID_OPT_HDMI + EDID_OPT_AUDIO);
+ edid_dump(edid);
+ return -1;
+ }
+
+ if(edid_msg_enable)
+ edid_dump(edid);
+
+ DBGMSG("[EDID] CEA EDID Version %d.%d\n", edid[0], edid[1]);
+
+ if (edid[1] >= 2) {
+ info->option |= (edid[3] & 0xF0);
+ DBGMSG("\t%s support 422\n", (edid[3] & 0x10) ? "" : "no");
+ DBGMSG("\t%s support 444\n", (edid[3] & 0x20) ? "" : "no");
+ DBGMSG("\t%s support audio\n", (edid[3] & 0x40) ? "" : "no");
+ DBGMSG("\t%s support underscan\n",
+ (edid[3] & 0x80) ? "" : "no");
+ }
+
+ block_end = edid + edid[2];
+ block = edid + 4;
+ do {
+ len = block[0] & 0x1F;
+ switch (((block[0] & 0xE0) >> 5)) {
+ case 1: /* Audio Data Block */
+ DBGMSG("Audio Data Block (0x%02X)\n", block[0]);
+ info->option |= EDID_OPT_AUDIO;
+ sadcnt_in_block = len / 3;
+
+ for (i = 0; i < sadcnt_in_block; i++) {
+ if (num < AUD_SAD_NUM) {
+ edid_parsed.sad[num].flag = 1;
+ edid_parsed.sad[num].sad_byte[0] =
+ block[i * 3 + 1];
+ edid_parsed.sad[num].sad_byte[1] =
+ block[i * 3 + 2];
+ edid_parsed.sad[num].sad_byte[2] =
+ block[i * 3 + 3];
+ num++;
+ } else {
+ DPRINT("Lose SAD info:%02X %02X %02X\n",
+ block[i * 3 + 1],
+ block[i * 3 + 2],
+ block[i * 3 + 3]);
+ }
+
+ DBGMSG("\t ======== SDA %d ========\n", i);
+ DBGMSG("\t SDA Data: 0x%02X 0x%02X 0x%02X\n",
+ block[i * 3 + 1],
+ block[i * 3 + 2],
+ block[i * 3 + 3]);
+
+ audio_format = (block[i * 3 + 1] & 0x78) >> 3;
+ switch (audio_format) {
+ default:
+ case 0: /* reserved */
+ case 15:/* reserved */
+ DBGMSG("\t Reserved Audio Fmt\n");
+ break;
+ case 1: /* LPCM */
+ DBGMSG("\t Audio Fmt: LPCM\n");
+ break;
+ case 2: /* AC3 */
+ DBGMSG("\t Audio Fmt: AC3\n");
+ break;
+ case 3: /* MPEG1 */
+ DBGMSG("\t Audio Fmt: MPEG1\n");
+ break;
+ case 4: /* MP3 */
+ DBGMSG("\t Audio Fmt: MP3\n");
+ break;
+ case 5: /* MPEG2 */
+ DBGMSG("\t Audio Fmt: MPEG2\n");
+ break;
+ case 6: /* AAC */
+ DBGMSG("\t Audio Fmt: AAC\n");
+ break;
+ case 7: /* DTS */
+ DBGMSG("\t Audio Fmt: DTS\n");
+ break;
+ case 8: /* ATRAC */
+ DBGMSG("\t Audio Fmt: ATRAC\n");
+ break;
+ case 9: /* One bit audio */
+ DBGMSG("\t Audio Fmt: ONE BIT AUDIO\n");
+ break;
+ case 10:/* Dolby */
+ DBGMSG("\t Audio Fmt: DOLBY\n");
+ break;
+ case 11:/* DTS-HD */
+ DBGMSG("\t Audio Fmt: DTS-HD\n");
+ break;
+ case 12:/* MAT (MLP) */
+ DBGMSG("\t Audio Fmt: MAT\n");
+ break;
+ case 13:/* DST */
+ DBGMSG("\t Audio Fmt: DST\n");
+ break;
+ case 14:/* WMA Pro */
+ DBGMSG("\t Audio Fmt: WMA Pro\n");
+ break;
+ }
+
+ DBGMSG("\t Max channel: %d\n",
+ (block[i * 3 + 1] & 0x7) + 1);
+ DBGMSG("\t %s support 32 KHz\n",
+ (block[i * 3 + 2] & 0x1) ? "" : "no");
+ DBGMSG("\t %s support 44 KHz\n",
+ (block[i * 3 + 2] & 0x2) ? "" : "no");
+ DBGMSG("\t %s support 48 KHz\n",
+ (block[i * 3 + 2] & 0x4) ? "" : "no");
+ DBGMSG("\t %s support 88 KHz\n",
+ (block[i * 3 + 2] & 0x8) ? "" : "no");
+ DBGMSG("\t %s support 96 KHz\n",
+ (block[i * 3 + 2] & 0x10) ? "" : "no");
+ DBGMSG("\t %s support 176 KHz\n",
+ (block[i * 3 + 2] & 0x20) ? "" : "no");
+ DBGMSG("\t %s support 192 KHz\n",
+ (block[i * 3 + 2] & 0x40) ? "" : "no");
+ if (audio_format == 1) { /* For LPCM */
+ DBGMSG("\t %s support 16 bit\n",
+ (block[i * 3 + 3] & 0x1) ?
+ "" : "no");
+ DBGMSG("\t %s support 20 bit\n",
+ (block[i * 3 + 3] & 0x2) ?
+ "" : "no");
+ DBGMSG("\t %s support 24 bit\n",
+ (block[i * 3 + 3] & 0x4) ?
+ "" : "no");
+ } else if (audio_format >= 2 &&
+ audio_format <= 8) {
+ /* From AC3 to ATRAC */
+ DBGMSG("\t Max bitrate: %d kbit/s\n",
+ block[i * 3 + 3] * 8);
+ } else if (audio_format >= 9 &&
+ audio_format <= 14) {
+ /* From One-bit-audio to WMA Pro*/
+ DBGMSG("\t Audio Format Code:0x%02X\n",
+ block[i * 3 + 3]);
+ }
+ DBGMSG("\t ========================\n");
+ }
+ break;
+ case 2: /* Video Data Block */
+ DBGMSG("Video Data Block\n");
+ for (i = 0; i < len; i++) {
+ unsigned int vic;
+
+ vic = block[1 + i] & 0x7F;
+ info->cea_vic[vic / 8] |= (0x1 << (vic % 8));
+ if (i < 16)
+ info->vic_3d[i].vic = vic;
+ DBGMSG("\t %2d : VIC %2d %dx%d@%d%s %s\n", i,
+ vic, hdmi_vic_info[vic].resx,
+ hdmi_vic_info[vic].resy,
+ hdmi_vic_info[vic].freq,
+ (hdmi_vic_info[vic].option
+ & HDMI_VIC_INTERLACE) ? "I" : "P",
+ (hdmi_vic_info[vic].option
+ & HDMI_VIC_4x3) ? "4:3" : "16:9");
+ }
+ break;
+ case 3: /* Vendor Spec Data Block */
+ edid_parse_CEA_VendorSpecDataBlock(block, len, info);
+ break;
+ case 4: /* Speaker Allocation Data Block */
+ DBGMSG("Speaker Allocation Data Block\n");
+ break;
+ case 5: /* VESA DTC Data Block */
+ DBGMSG("VESA DTC Data Block\n");
+ break;
+ case 7: /* Use Extended Tag */
+ DBGMSG("Use Extended Tag\n");
+ break;
+ case 0: /* Reserved */
+ default:
+ len = 0;
+ break;
+ }
+ block += (1 + len);
+ } while (block < block_end);
+
+ {
+ struct fb_videomode *p;
+ unsigned int fps;
+
+ DBGMSG("Detail Timing\n");
+ block = edid + edid[2];
+ len = (128 - edid[2]) / 18;
+ for (i = 0; i < len; i++, block += 18) {
+ p = &info->cea_timing[i];
+ p->pixclock = ((block[1] << 8) + block[0]) * 10000;
+ if (p->pixclock == 0)
+ break;
+ p->xres = ((block[4] & 0xF0) << 4) + block[2];
+ p->left_margin = ((block[4] & 0x0F) << 8) + block[3];
+ p->yres = ((block[7] & 0xF0) << 4) + block[5];
+ p->upper_margin = ((block[7] & 0x0F) << 8) + block[6];
+ fps = vpp_calc_refresh(p->pixclock, p->xres + p->left_margin,
+ p->yres + p->upper_margin);
+ p->right_margin = ((block[11] & 0xC0) << 2) + block[8];
+ p->hsync_len = ((block[11] & 0x30) << 4) + block[9];
+ p->left_margin = p->left_margin -
+ p->right_margin - p->hsync_len;
+ p->lower_margin = ((block[11] & 0x0C) << 2) +
+ ((block[10] & 0xF0) >> 4);
+ p->vsync_len = ((block[11] & 0x03) << 4) + (block[10] & 0x0F);
+ p->upper_margin = p->upper_margin -
+ p->lower_margin - p->vsync_len;
+ p->refresh = fps;
+ p->vmode = (block[17] & 0x80) ?
+ FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
+ p->sync = (block[17] & 0x04) ? FB_SYNC_VERT_HIGH_ACT : 0;
+ p->sync |= (block[17] & 0x02) ? FB_SYNC_HOR_HIGH_ACT : 0;
+ if (p->vmode & FB_VMODE_INTERLACED) {
+ p->yres *= 2;
+ p->upper_margin *= 2;
+ p->lower_margin *= 2;
+ p->vsync_len *= 2;
+ }
+ DBGMSG("\t%dx%d%s@%d,clk %d\n", p->xres, p->yres,
+ (block[17] & 0x80) ? "I" : "P", fps, p->pixclock);
+ DBGMSG("\t\tH bp %d,sync %d,fp %d\n",
+ p->left_margin, p->hsync_len, p->right_margin);
+ DBGMSG("\t\tV bp %d,sync %d,fp %d\n",
+ p->upper_margin, p->vsync_len, p->lower_margin);
+ DBGMSG("\t\thsync %d,vsync %d\n",
+ (p->sync & FB_SYNC_HOR_HIGH_ACT) ? 1 : 0,
+ (p->sync & FB_SYNC_VERT_HIGH_ACT) ? 1 : 0);
+ p->pixclock = KHZ2PICOS(p->pixclock / 1000);
+ }
+ }
+ return 0;
+}
+
+void edid_dump(char *edid)
+{
+ int i;
+
+ DPRINT("===================== EDID BlOCK =====================");
+ for (i = 0; i < 128; i++) {
+ if ((i % 16) == 0)
+ DPRINT("\n");
+ DPRINT("%02x ", edid[i]);
+ }
+ DPRINT("\n");
+ DPRINT("======================================================\n");
+}
+
+int edid_checksum(char *edid, int len)
+{
+ char checksum = 0;
+ int i;
+
+ for (i = 0; i < len; i++)
+ checksum += edid[i];
+
+ if (checksum) {
+#ifdef DEBUG
+ edid_dump(edid);
+#endif
+ }
+ return checksum;
+}
+
+int edid_parse(char *edid, struct edid_info_t *info)
+{
+ int ext_cnt = 0;
+
+ if (edid == 0)
+ return 0;
+
+ if (info->option & EDID_OPT_VALID) {
+ DBG_MSG("[EDID] parse exist\n");
+ return info->option;
+ }
+
+ DBG_MSG("[EDID] Enter\n");
+
+ memset(info, 0, sizeof(struct edid_info_t));
+ info->option = EDID_OPT_VALID;
+ if (edid_parse_v1(edid, info) == 0) {
+ ext_cnt = edid[0x7E];
+ if (ext_cnt >= EDID_BLOCK_MAX) {
+ DPRINT("[EDID] *W* ext block cnt %d\n", ext_cnt);
+ ext_cnt = EDID_BLOCK_MAX - 1;
+ }
+ } else {
+ info->option = 0;
+ return 0;
+ }
+
+ while (ext_cnt) {
+ edid += 128;
+ ext_cnt--;
+ if (edid_parse_CEA(edid, info) == 0)
+ continue;
+
+ DPRINT("*W* not support EDID\n");
+ edid_dump(edid);
+ }
+ return info->option;
+}
+
+int edid_find_support(struct edid_info_t *info, unsigned int resx,
+ unsigned int resy, int freq, struct fb_videomode **vmode)
+{
+ struct fb_videomode *p;
+ int temp;
+ int ret;
+ int i;
+
+ ret = 0;
+ *vmode = 0;
+
+ if (!info)
+ return 0;
+
+ /* find detail timing */
+ for (i = 0; i < 4; i++) {
+ p = &info->detail_timing[i];
+ if (p->pixclock == 0)
+ continue;
+ if (resx != p->xres)
+ continue;
+ if (resy != p->yres)
+ continue;
+
+ temp = p->refresh;
+ temp |= (p->vmode & FB_VMODE_INTERLACED) ?
+ EDID_TMR_INTERLACE : 0;
+ if (freq != temp)
+ continue;
+ *vmode = p;
+ ret = 3;
+ goto find_end;
+ }
+
+ /* find cea timing */
+ for (i = 0; i < 6; i++) {
+ p = &info->cea_timing[i];
+
+ if (p->pixclock == 0)
+ continue;
+ if (resx != p->xres)
+ continue;
+ if (resy != p->yres)
+ continue;
+
+ temp = p->refresh;
+ temp |= (p->vmode & FB_VMODE_INTERLACED) ?
+ EDID_TMR_INTERLACE : 0;
+ if (freq != temp)
+ continue;
+
+ *vmode = p;
+ ret = 4;
+ goto find_end;
+ }
+
+ /* find vic timing */
+ for (i = 0; i < 64; i++) {
+ if ((info->cea_vic[i / 8] & (0x1 << (i % 8))) == 0)
+ continue;
+
+ if (i >= HDMI_VIDEO_CODE_MAX)
+ continue;
+
+ if (resx != hdmi_vic_info[i].resx)
+ continue;
+ if (resy != hdmi_vic_info[i].resy)
+ continue;
+ temp = hdmi_vic_info[i].freq;
+ temp |= (hdmi_vic_info[i].option & HDMI_VIC_INTERLACE) ?
+ EDID_TMR_INTERLACE : 0;
+ if (freq != temp)
+ continue;
+ ret = 5;
+ goto find_end;
+ }
+
+ /* find established timing */
+ if (info->establish_timing) {
+ for (i = 0; i < 17; i++) {
+ if (info->establish_timing & (0x1 << i)) {
+ if ((resx == edid_establish_timing[i].resx) &&
+ (resy == edid_establish_timing[i].resy)) {
+ if (freq ==
+ edid_establish_timing[i].freq) {
+ ret = 1;
+ goto find_end;
+ }
+ }
+ }
+ }
+ }
+
+ /* find standard timing */
+ for (i = 0; i < 8; i++) {
+ if (info->standard_timing[i].resx == 0)
+ continue;
+ if ((resx == info->standard_timing[i].resx) &&
+ (resy == info->standard_timing[i].resy)) {
+ if (freq == info->standard_timing[i].freq) {
+ ret = 2;
+ goto find_end;
+ }
+ }
+ }
+
+find_end:
+#if 0
+ if ((resx == 1920) && (resy == 1080) && !(freq & EDID_TMR_INTERLACE))
+ ret = 0;
+#endif
+#if 0
+ if (!(freq & EDID_TMR_INTERLACE))
+ ret = 0;
+#endif
+#if 0
+ DPRINT("[EDID] %s support %dx%d@%d%s(ret %d)\n",
+ (ret) ? "" : "No", resx, resy, freq & EDID_TMR_FREQ,
+ (freq & EDID_TMR_INTERLACE) ? "I" : "P", ret);
+#endif
+ return ret;
+}
+
+unsigned int edid_get_hdmi_phy_addr(void)
+{
+ struct vout_t *vo;
+
+ vo = vout_get_entry(VPP_VOUT_NUM_HDMI);
+ return vo->edid_info.hdmi_phy_addr;
+}
+
+unsigned int edid_get_hdmi_3d_mask(struct edid_info_t *info, int vic)
+{
+ int i;
+
+ if (!info)
+ return 0;
+ for (i = 0; i < 16; i++) {
+ if (info->vic_3d[i].vic == vic)
+ return info->vic_3d[i].mask;
+ }
+ return 0;
+}
+
diff --git a/common/wmt_display/pwm.c b/common/wmt_display/pwm.c
new file mode 100755
index 0000000..d19cd50
--- /dev/null
+++ b/common/wmt_display/pwm.c
@@ -0,0 +1,306 @@
+/*++
+ * linux/drivers/video/wmt/lcd.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2010 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+/*
+ * ChangeLog
+ *
+ * 2010-08-05 Sam Shen <samshen@wondermedia.com.tw>
+ * * Add License declaration and ChangeLog
+ */
+
+
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "vpp.h"
+#include "wmt_display.h"
+/*----------------------- Backlight --------------------------------------*/
+#ifdef CONFIG_VPP_SHENZHEN
+#include "../../board/wmt/include/wmt_iomux.h"
+
+#define ENV_LOGO_LED "wmt.logo.led"
+
+static void logo_led_power_on(int on);
+#endif
+
+#define pwm_write_reg(addr,val,wait) \
+ REG32_VAL(addr) = val; \
+ while(REG32_VAL(0xd8220040)&=wait);
+
+#define UBOOT_PWM_INVERT 0x10
+void lcd_blt_enable(int no,int enable)
+{
+#ifdef CONFIG_VPP_SHENZHEN
+ lcd_backlight_power_on(enable != 0);
+#endif
+ pwm_set_enable(no,enable);
+
+#ifdef CONFIG_VPP_SHENZHEN
+ logo_led_power_on(enable);
+#endif
+
+} /* End of vt8430_blt_enable */
+
+void lcd_blt_set_level(int no,int level)
+{
+ return;
+}
+
+void lcd_blt_set_freq(int no,unsigned int freq)
+{
+ return;
+}
+
+void lcd_blt_set_pwm(int no, int level, int freq)
+{
+ int clock = auto_pll_divisor(DEV_PWM,GET_FREQ, 0, 0);
+ int period, duty, scalar;
+
+ clock = clock / freq;
+ scalar = 0;
+ period = 2000;
+
+ while(period > 1023) {
+ scalar++;
+ period = clock / scalar;
+ }
+
+ duty = (period*level)/100;
+ duty = (duty)? (duty-1):0;
+ scalar = scalar-1;
+ period = period -1;
+
+ pwm_set_period(no,period);
+ pwm_set_duty(no,duty);
+ pwm_set_scalar(no,scalar);
+ if ((g_pwm_setting.config&UBOOT_PWM_INVERT) != 0)
+ pwm_set_control(no,(level)? 0x37:0x8);
+ else
+ pwm_set_control(no,(level)? 0x35:0x8);
+ pwm_set_gpio(no,level);
+}
+
+void pwm_set_enable(int no,int enable)
+{
+ unsigned int addr,reg,reg1;
+
+ addr = PWM_CTRL_REG_ADDR + (0x10 * no);
+ reg = REG32_VAL(addr);
+ if( enable ){
+ reg |= PWM_ENABLE;
+ }
+ else {
+ reg &= ~PWM_ENABLE;
+ }
+
+ pwm_write_reg(addr,reg,PWM_CTRL_UPDATE << (4*no));
+ reg1 = REG32_VAL(addr);
+ pwm_set_gpio(no,enable);
+}
+
+void pwm_set_control(int no,unsigned int ctrl)
+{
+ unsigned int addr;
+
+ addr = PWM_CTRL_REG_ADDR + (0x10 * no);
+ pwm_write_reg(addr,ctrl,PWM_CTRL_UPDATE << (8*no));
+} /* End of pwm_proc */
+
+void pwm_set_scalar(int no,unsigned int scalar)
+{
+ unsigned int addr;
+
+ addr = PWM_SCALAR_REG_ADDR + (0x10 * no);
+ pwm_write_reg(addr,scalar,PWM_SCALAR_UPDATE << (8*no));
+}
+
+void pwm_set_period(int no,unsigned int period)
+{
+ unsigned int addr;
+
+ addr = PWM_PERIOD_REG_ADDR + (0x10 * no);
+ pwm_write_reg(addr,period,PWM_PERIOD_UPDATE << (8*no));
+}
+
+void pwm_set_duty(int no,unsigned int duty)
+{
+ unsigned int addr;
+
+ addr = PWM_DUTY_REG_ADDR + (0x10 * no);
+ pwm_write_reg(addr,duty,PWM_DUTY_UPDATE << (8*no));
+}
+
+unsigned int pwm_get_period(int no)
+{
+ unsigned int addr;
+
+ addr = PWM_PERIOD_REG_ADDR + (0x10 * no);
+ return (REG32_VAL(addr) & 0xFFF);
+}
+
+unsigned int pwm_get_duty(int no)
+{
+ unsigned int addr;
+
+ addr = PWM_DUTY_REG_ADDR + (0x10 * no);
+ return (REG32_VAL(addr) & 0xFFF);
+}
+
+unsigned int pwm_get_enable(int no)
+{
+ unsigned int addr,reg;
+
+ addr = PWM_CTRL_REG_ADDR + (0x10 * no);
+ reg = REG32_VAL(addr);
+ reg &= PWM_ENABLE;
+ return reg;
+}
+
+void set_lcd_power(int on)
+{
+ unsigned int val;
+
+ if ((g_lcd_pw_pin.ctl == 0) || (g_lcd_pw_pin.oc == 0) || (g_lcd_pw_pin.od == 0)) {
+ printf("lcd power ping not define\n");
+ return;
+ }
+ val = 1<<g_lcd_pw_pin.bitmap;
+ if (g_lcd_pw_pin.act == 0)
+ on = ~on;
+ REG32_VAL(g_lcd_pw_pin.ctl) |= val;
+ REG32_VAL(g_lcd_pw_pin.oc) |= val;
+ if (on) {
+ REG32_VAL(g_lcd_pw_pin.od) |= val;
+ } else {
+ REG32_VAL(g_lcd_pw_pin.od) &= ~val;
+ }
+}
+
+void pwm_set_gpio(int no,int enable)
+{
+ /* unsigned int pwm_pin; */
+
+ if( enable ) {
+ if((g_pwm_setting.config&UBOOT_PWM_INVERT) != 0)
+ REG8_VAL(GPIO_OD_GP20_PWM0_BYTE_ADDR) &= 0xFE;
+ else
+ REG8_VAL(GPIO_OD_GP20_PWM0_BYTE_ADDR) |= 0x01;
+
+ REG8_VAL(GPIO_OC_GP20_PWM0_BYTE_ADDR) &= 0xFE;
+ REG8_VAL(GPIO_CTRL_GP20_PWM0_BYTE_ADDR) &= 0xFE;
+ } else {
+ if((g_pwm_setting.config&UBOOT_PWM_INVERT) != 0)
+ REG8_VAL(GPIO_OD_GP20_PWM0_BYTE_ADDR) |= 0x01;
+ else
+ REG8_VAL(GPIO_OD_GP20_PWM0_BYTE_ADDR) &= 0xFE;
+
+ REG8_VAL(GPIO_OC_GP20_PWM0_BYTE_ADDR) |= 0x01;
+ REG8_VAL(GPIO_CTRL_GP20_PWM0_BYTE_ADDR) |= 0x01;
+ }
+ /* set to PWM mode */
+ if ( no == 0 )
+ REG32_VAL(PIN_SHARING_SEL_4BYTE_ADDR) &= ~0x1000;
+ else if( no == 1 )
+ REG32_VAL(PIN_SHARING_SEL_4BYTE_ADDR) &= ~0x80;
+ /* do not control back-light power in pwm */
+ /*
+ pwm_pin = REG32_VAL(PWM_CTRL_REG_ADDR + (0x10 * no));
+ if (((pwm_pin&PWM_ENABLE) != 0)&&(enable == 1))
+ set_lcd_power(1);
+ if (((pwm_pin&PWM_ENABLE) == 0)&&(enable == 0))
+ set_lcd_power(0);
+ */
+}
+
+#ifdef CONFIG_VPP_SHENZHEN
+
+static void logo_led_set_pwm(int no, int level, int freq, int active, int init)
+{
+ int clock;
+ int period, duty, scalar;
+
+ if(init) {
+ clock = auto_pll_divisor(DEV_PWM,GET_FREQ, 0, 0);
+ clock = clock / freq;
+ scalar = 0;
+ period = 2000;
+
+ while(period > 1023) {
+ scalar++;
+ period = clock / scalar;
+ }
+
+ duty = (period*level)/100;
+ duty = (duty)? (duty-1):0;
+ scalar = scalar-1;
+ period = period -1;
+
+ pwm_set_period(no,period);
+ pwm_set_duty(no,duty);
+ pwm_set_scalar(no,scalar);
+ REG32_VAL(PIN_SHARING_SEL_4BYTE_ADDR) &= ~0x80;
+ }
+
+ if (active == 0)
+ pwm_set_control(no,(level)? 0x37:0x8);
+ else
+ pwm_set_control(no,(level)? 0x35:0x8);
+}
+
+#define PWM2_GPIO_NO 200
+
+static void logo_led_power_on(int on)
+{
+ int ret;
+ static int led_init;
+ static struct gpio_param_t led_control_pin;
+
+ if(led_init == -1)
+ return;
+
+ if(led_init == 0) {
+ ret = parse_gpio_param(ENV_LOGO_LED, &led_control_pin);
+ if(ret) {
+ led_init = -1;
+ return;
+ }
+
+ led_init = 1;
+ }
+
+ switch (led_control_pin.gpiono) {
+ case PWM2_GPIO_NO:
+ if(on)
+ logo_led_set_pwm(2, 100, 220000, led_control_pin.act, 1);
+ else
+ logo_led_set_pwm(2, 100, 220000, !led_control_pin.act, 1);
+ break;
+
+ default:
+ if(on)
+ gpio_direction_output(led_control_pin.gpiono, led_control_pin.act);
+ else
+ gpio_direction_output(led_control_pin.gpiono, !led_control_pin.act);
+ break;
+ }
+}
+#endif
+
diff --git a/common/wmt_display/scl.c b/common/wmt_display/scl.c
new file mode 100755
index 0000000..f367a0d
--- /dev/null
+++ b/common/wmt_display/scl.c
@@ -0,0 +1,1556 @@
+/*++
+ * linux/drivers/video/wmt/scl.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define SCL_C
+#undef DEBUG
+/* #define DEBUG */
+/* #define DEBUG_DETAIL */
+
+#include "scl.h"
+
+HW_REG struct scl_base1_regs *scl_regs1 = (void *) SCL_BASE_ADDR;
+HW_REG struct scl_base2_regs *scl_regs2 = (void *) SCL_BASE2_ADDR;
+
+#ifdef WMT_FTBLK_SCL
+void scl_reg_dump(void)
+{
+ vpp_set_clock_enable(DEV_SCL444U, 1, 0);
+
+ DPRINT("========== SCL register dump ==========\n");
+ vpp_reg_dump(REG_SCL_BASE1_BEGIN,
+ REG_SCL_BASE1_END - REG_SCL_BASE1_BEGIN);
+ vpp_reg_dump(REG_SCL_BASE2_BEGIN,
+ REG_SCL_BASE2_END - REG_SCL_BASE2_BEGIN);
+
+ DPRINT("---------- SCL scale ----------\n");
+ DPRINT("scale enable %d\n", scl_regs1->en.b.alu_enable);
+ DPRINT("mode bilinear(H %d,V %d),recursive(H %d,V %d)\n",
+ scl_regs1->true_bilinear.b.h, scl_regs1->true_bilinear.b.v,
+ scl_regs2->recursive_mode.b.h, scl_regs2->recursive_mode.b.v);
+ DPRINT("src(%d,%d),dst(%d,%d)\n",
+ scl_regs1->r_h_size.b.pix_w, scl_regs1->vxwidth.b.vxwidth,
+ scl_regs1->hscale1.b.thr, scl_regs1->vscale1.b.thr);
+ DPRINT("scale width H %d,V %d\n",
+ scl_regs1->hxwidth.b.hxwidth, scl_regs1->vxwidth.b.vxwidth);
+ DPRINT("H scale up %d,V scale up %d\n",
+ scl_regs1->sclup_en.b.h, scl_regs1->sclup_en.b.v);
+ DPRINT("H sub step %d,thr %d,step %d,sub step cnt %d,i step cnt %d\n",
+ scl_regs1->hscale1.b.substep, scl_regs1->hscale1.b.thr,
+ scl_regs1->hscale2.b.step, scl_regs1->hscale2.b.substepcnt,
+ scl_regs1->hscale3.b.stepcnt);
+ DPRINT("V sub step %d,thr %d,step %d,sub step cnt %d,i step cnt %d\n",
+ scl_regs1->vscale1.b.substep, scl_regs1->vscale1.b.thr,
+ scl_regs1->vscale2.b.step, scl_regs1->vscale2.b.substepcnt,
+ scl_regs1->vscale3.b.stepcnt);
+
+ DPRINT("---------- SCL filter ----------\n");
+ DPRINT("DEBLOCK %d,boundary 1st 0x%x,2nd 0x%x\n,",
+ scl_regs2->field_mode.b.deblock,
+ scl_regs2->dblk_threshold.b.layer1_boundary,
+ scl_regs2->dblk_threshold.b.layer2_boundary);
+ DPRINT("FIELD DEFLICKER %d,up %s down,thr Y %d,C %d\n",
+ scl_regs2->field_mode.b.field_deflicker,
+ (scl_regs2->field_mode.b.field_deflicker) ? "&" : "or",
+ scl_regs2->field_flicker.b.y_thd,
+ scl_regs2->field_flicker.b.c_thd);
+ DPRINT("FRAME DEFLICKER %d,%s,2^%d,scene chg %d\n",
+ scl_regs2->field_mode.b.frame_deflicker,
+ (scl_regs2->frame_flicker.b.rgb) ? "RGB" : "Y",
+ scl_regs2->frame_flicker.b.sampler,
+ scl_regs2->frame_flicker.b.scene_chg_thd);
+ DPRINT("CSC enable %d,CSC clamp %d\n",
+ scl_regs2->csc_ctl.b.enable,
+ scl_regs2->csc_ctl.b.clamp_enable);
+ DPRINT("---------- SCL TG ----------\n");
+ DPRINT("TG source : %s\n",
+ (scl_regs1->tg_govw.b.enable) ? "GOVW" : "SCL");
+ DPRINT("TG enable %d, wait ready enable %d\n",
+ scl_regs1->tg_ctl.b.enable,
+ scl_regs1->tg_ctl.b.watchdog_enable);
+ DPRINT("clk %d,Read cyc %d,1T %d\n",
+ vpp_get_base_clock(VPP_MOD_SCL),
+ scl_regs1->tg_ctl.b.rdcyc, scl_regs2->readcyc_1t.b.rdcyc_1t);
+ DPRINT("H total %d, beg %d, end %d\n",
+ scl_regs1->tg_total.b.h_allpixel,
+ scl_regs1->tg_h_active.b.h_actbg,
+ scl_regs1->tg_h_active.b.h_actend);
+ DPRINT("V total %d, beg %d, end %d\n",
+ scl_regs1->tg_total.b.v_allline,
+ scl_regs1->tg_v_active.b.v_actbg,
+ scl_regs1->tg_v_active.b.v_actend);
+ DPRINT("VBIE %d,PVBI %d\n",
+ scl_regs1->tg_vbi.b.vbie, scl_regs1->tg_vbi.b.pvbi);
+ DPRINT("Watch dog 0x%x\n",
+ scl_regs1->tg_watchdog);
+ DPRINT("---------- SCLR FB ----------\n");
+ DPRINT("SCLR MIF enable %d\n",
+ scl_regs1->r_ctl.b.mif_enable);
+ DPRINT("color format %s\n", vpp_colfmt_str[sclr_get_color_format()]);
+ DPRINT("color bar enable %d,mode %d,inv %d\n",
+ scl_regs1->r_ctl.b.colorbar_enable,
+ scl_regs1->r_ctl.b.colorbar_mode,
+ scl_regs1->r_ctl.b.colorbar_inv);
+ DPRINT("sourc mode : %s,H264 %d\n",
+ (scl_regs1->r_ctl.b.field) ? "field" : "frame",
+ scl_regs1->r_ctl.b.h264);
+ DPRINT("Y addr 0x%x, C addr 0x%x\n",
+ scl_regs1->r_ysa, scl_regs1->r_csa);
+ DPRINT("width %d, fb width %d\n",
+ scl_regs1->r_h_size.b.pix_w, scl_regs1->r_h_size.b.fb_w);
+ DPRINT("H crop %d, V crop %d\n",
+ scl_regs1->r_crop.b.hcrop, scl_regs1->r_crop.b.vcrop);
+ DPRINT("---------- SCLW FB ----------\n");
+ DPRINT("SCLW MIF enable %d\n", scl_regs1->w_ctl.b.mif_enable);
+ DPRINT("color format %s\n", vpp_colfmt_str[sclw_get_color_format()]);
+ DPRINT("Y addr 0x%x, C addr 0x%x\n",
+ scl_regs1->w_ysa, scl_regs1->w_csa);
+ DPRINT("Y width %d, fb width %d\n",
+ scl_regs1->w_y_time.b.pxl_w, scl_regs1->w_y_time.b.fb_w);
+ DPRINT("C width %d, fb width %d\n",
+ scl_regs1->w_c_time.b.pxl_w, scl_regs1->w_c_time.b.fb_w);
+ DPRINT("Y err %d, C err %d\n",
+ scl_regs1->w_ff_ctl.b.mif_y_err,
+ scl_regs1->w_ff_ctl.b.mif_c_err);
+ DPRINT("---------- SCLR2 FB ----------\n");
+ DPRINT("MIF enable %d\n", scl_regs1->r2_ctl.b.mif_en);
+ DPRINT("color format %s\n", vpp_colfmt_str[scl_R2_get_color_format()]);
+ DPRINT("color bar enable %d,mode %d,inv %d\n",
+ scl_regs1->r2_ctl.b.color_en,
+ scl_regs1->r2_ctl.b.color_wide,
+ scl_regs1->r2_ctl.b.color_inv);
+ DPRINT("sourc mode : %s,H264 %d\n",
+ (scl_regs1->r2_ctl.b.iofmt) ? "field" : "frame",
+ scl_regs1->r2_ctl.b.h264_fmt);
+ DPRINT("Y addr 0x%x, C addr 0x%x\n",
+ scl_regs1->r2_ysa, scl_regs1->r2_csa);
+ DPRINT("width %d, fb width %d\n",
+ scl_regs1->r2_h_size.b.lnsize, scl_regs1->r2_h_size.b.fbw);
+ DPRINT("H crop %d, V crop %d\n",
+ scl_regs1->r2_crop.b.hcrop, scl_regs1->r2_crop.b.vcrop);
+ DPRINT("---------- ALPHA ----------\n");
+ DPRINT("src alpha %d,dst alpha %d,swap %d\n",
+ scl_regs1->alpha_md.b.src,
+ scl_regs1->alpha_md.b.dst,
+ scl_regs1->alpha_md.b.swap);
+ DPRINT("src fix 0x%x,dst fix 0x%x\n",
+ scl_regs1->alpha_fxd.b.src_fixed,
+ scl_regs1->alpha_fxd.b.dst_fixed);
+ DPRINT("---------- ColorKey ----------\n");
+ DPRINT("enable %d\n", scl_regs1->alpha_colorkey.b.enable);
+ DPRINT("from %s,comp %d,mode %d\n",
+ (scl_regs1->alpha_colorkey.b.from) ? "mif2" : "mif1",
+ scl_regs1->alpha_colorkey.b.comp,
+ scl_regs1->alpha_colorkey.b.mode);
+ DPRINT("R 0x%x,G 0x%x,B 0x%x\n",
+ scl_regs1->alpha_colorkey_rgb.b.r,
+ scl_regs1->alpha_colorkey_rgb.b.g,
+ scl_regs1->alpha_colorkey_rgb.b.b);
+ DPRINT("---------- sw status ----------\n");
+ DPRINT("complete %d\n", p_scl->scale_complete);
+
+ vpp_set_clock_enable(DEV_SCL444U, 0, 0);
+}
+
+void scl_set_enable(vpp_flag_t enable)
+{
+ scl_regs1->en.b.alu_enable = enable;
+}
+
+void scl_set_reg_update(vpp_flag_t enable)
+{
+ scl_regs1->upd.b.reg_update = enable;
+}
+
+void scl_set_reg_level(vpp_reglevel_t level)
+{
+ scl_regs1->sel.b.reg_level = level;
+}
+
+void scl_set_int_enable(vpp_flag_t enable, enum vpp_int_t int_bit)
+{
+ /* clean status first before enable/disable interrupt */
+ scl_clean_int_status(int_bit);
+
+ if (int_bit & VPP_INT_ERR_SCL_TG)
+ scl_regs1->w_int_en.b.tg_err = enable;
+ if (int_bit & VPP_INT_ERR_SCLR1_MIF)
+ scl_regs1->w_int_en.b.r1_mif_enable = enable;
+ if (int_bit & VPP_INT_ERR_SCLR2_MIF)
+ scl_regs1->w_int_en.b.r2_mif_enable = enable;
+ if (int_bit & VPP_INT_ERR_SCLW_MIFRGB)
+ scl_regs1->w_int_en.b.mif_rgb_err = enable;
+ if (int_bit & VPP_INT_ERR_SCLW_MIFY)
+ scl_regs1->w_int_en.b.mif_y_err = enable;
+ if (int_bit & VPP_INT_ERR_SCLW_MIFC)
+ scl_regs1->w_int_en.b.mif_c_err = enable;
+}
+
+enum vpp_int_err_t scl_get_int_status(void)
+{
+ enum vpp_int_err_t int_sts;
+
+ int_sts = 0;
+ if (scl_regs1->tg_sts.b.tgerr)
+ int_sts |= VPP_INT_ERR_SCL_TG;
+ if (scl_regs1->r_fifo_ctl.b.r1_mif_err)
+ int_sts |= VPP_INT_ERR_SCLR1_MIF;
+ if (scl_regs1->r_fifo_ctl.b.r2_mif_err)
+ int_sts |= VPP_INT_ERR_SCLR2_MIF;
+ if (scl_regs1->w_ff_ctl.b.mif_rgb_err)
+ int_sts |= VPP_INT_ERR_SCLW_MIFRGB;
+ if (scl_regs1->w_ff_ctl.b.mif_y_err)
+ int_sts |= VPP_INT_ERR_SCLW_MIFY;
+ if (scl_regs1->w_ff_ctl.b.mif_c_err)
+ int_sts |= VPP_INT_ERR_SCLW_MIFC;
+ return int_sts;
+}
+
+void scl_clean_int_status(enum vpp_int_err_t int_sts)
+{
+ if (int_sts & VPP_INT_ERR_SCL_TG)
+ scl_regs1->tg_sts.val = BIT0;
+ if (int_sts & VPP_INT_ERR_SCLR1_MIF)
+ scl_regs1->r_fifo_ctl.val =
+ (scl_regs1->r_fifo_ctl.val & ~0x300) | BIT8;
+ if (int_sts & VPP_INT_ERR_SCLR2_MIF)
+ scl_regs1->r_fifo_ctl.val =
+ (scl_regs1->r_fifo_ctl.val & ~0x300) | BIT9;
+ if (int_sts & VPP_INT_ERR_SCLW_MIFRGB)
+ scl_regs1->w_ff_ctl.val = BIT16;
+ if (int_sts & VPP_INT_ERR_SCLW_MIFY)
+ scl_regs1->w_ff_ctl.val = BIT8;
+ if (int_sts & VPP_INT_ERR_SCLW_MIFC)
+ scl_regs1->w_ff_ctl.val = BIT0;
+}
+
+void scl_set_csc_mode(vpp_csc_t mode)
+{
+ vdo_color_fmt src_fmt, dst_fmt;
+
+ src_fmt = sclr_get_color_format();
+ dst_fmt = sclw_get_color_format();
+ mode = vpp_check_csc_mode(mode, src_fmt, dst_fmt, 0);
+ if (p_scl->abgr_mode) {
+ unsigned int parm[5];
+
+ parm[0] = (vpp_csc_parm[mode][1] & 0xFFFF) |
+ (vpp_csc_parm[mode][0] & 0xFFFF0000); /* C3,C2 */
+ parm[1] = (vpp_csc_parm[mode][0] & 0xFFFF) |
+ (vpp_csc_parm[mode][2] & 0xFFFF0000); /* C1,C6 */
+ parm[2] = (vpp_csc_parm[mode][2] & 0xFFFF) |
+ (vpp_csc_parm[mode][1] & 0xFFFF0000); /* C5,C4 */
+ parm[3] = (vpp_csc_parm[mode][4] & 0xFFFF) |
+ (vpp_csc_parm[mode][3] & 0xFFFF0000); /* C9,C8 */
+ parm[4] = (vpp_csc_parm[mode][3] & 0xFFFF) |
+ (vpp_csc_parm[mode][4] & 0xFFFF0000); /* C7,I */
+
+ scl_regs2->csc1 = parm[0];
+ scl_regs2->csc2 = parm[1];
+ scl_regs2->csc3 = parm[2];
+ scl_regs2->csc4 = parm[3];
+ scl_regs2->csc5 = parm[4];
+ } else {
+ scl_regs2->csc1 = vpp_csc_parm[mode][0];
+ scl_regs2->csc2 = vpp_csc_parm[mode][1];
+ scl_regs2->csc3 = vpp_csc_parm[mode][2];
+ scl_regs2->csc4 = vpp_csc_parm[mode][3];
+ scl_regs2->csc5 = vpp_csc_parm[mode][4];
+ }
+ scl_regs2->csc6 = vpp_csc_parm[mode][5];
+ scl_regs2->csc_ctl.val = vpp_csc_parm[mode][6];
+ scl_regs2->csc_ctl.b.enable = (mode >= VPP_CSC_MAX) ? 0 : 1;
+}
+
+void scl_set_scale_enable(vpp_flag_t vscl_enable, vpp_flag_t hscl_enable)
+{
+ DBGMSG("V %d,H %d\n", vscl_enable, hscl_enable);
+ scl_regs1->sclup_en.b.v = vscl_enable;
+ scl_regs1->sclup_en.b.h = hscl_enable;
+}
+
+void scl_set_V_scale(int A, int B) /* A dst,B src */
+{
+ unsigned int V_STEP;
+ unsigned int V_SUB_STEP;
+ unsigned int V_THR_DIV2;
+
+ DBG_DETAIL("scl_set_V_scale(%d,%d)\r\n", A, B);
+ if (A > B) {
+ V_STEP = (B - 1) * 16 / A;
+ V_SUB_STEP = (B - 1) * 16 % A;
+ } else {
+ V_STEP = (16 * B / A);
+ V_SUB_STEP = ((16 * B) % A);
+ }
+ V_THR_DIV2 = A;
+
+ DBG_DETAIL("V step %d,sub step %d, div2 %d\r\n",
+ V_STEP, V_SUB_STEP, V_THR_DIV2);
+
+ scl_regs1->vxwidth.b.dst_vxwidth = (A > B) ? A : B;
+ scl_regs1->vxwidth.b.vxwidth = B;
+ scl_regs1->vscale2.b.step = V_STEP;
+ scl_regs1->vscale1.b.substep = V_SUB_STEP;
+ scl_regs1->vscale1.b.thr = V_THR_DIV2;
+ scl_regs1->vscale2.b.substepcnt = 0;
+}
+
+void scl_set_H_scale(int A, int B) /* A dst,B src */
+{
+ unsigned int H_STEP;
+ unsigned int H_SUB_STEP;
+ unsigned int H_THR_DIV2;
+
+ DBG_DETAIL("scl_set_H_scale(%d,%d)\r\n", A, B);
+ if (A > B) {
+ H_STEP = (B - 1) * 16 / A;
+ H_SUB_STEP = (B - 1) * 16 % A;
+ } else {
+ H_STEP = (16 * B / A);
+ H_SUB_STEP = ((16 * B) % A);
+ }
+ H_THR_DIV2 = A;
+ DBG_DETAIL("H step %d,sub step %d, div2 %d\r\n",
+ H_STEP, H_SUB_STEP, H_THR_DIV2);
+ scl_regs1->hxwidth.b.hxwidth = ((A > B) ? A : B);
+ scl_regs1->hscale2.b.step = H_STEP;
+ scl_regs1->hscale1.b.substep = H_SUB_STEP;
+ scl_regs1->hscale1.b.thr = H_THR_DIV2;
+ scl_regs1->hscale2.b.substepcnt = 0;
+}
+
+void scl_set_crop(int offset_x, int offset_y)
+{
+ /* offset_x &= VPU_CROP_ALIGN_MASK; */ /* ~0x7 */
+ offset_x &= ~0xf;
+
+ scl_regs1->hscale3.b.stepcnt = offset_x * 16;
+ scl_regs1->vscale3.b.stepcnt = offset_y * 16;
+ DBGMSG("[VPU] crop - x : 0x%x, y : 0x%x \r\n",
+ offset_x * 16, offset_y * 16);
+}
+
+void scl_set_tg_enable(vpp_flag_t enable)
+{
+ scl_regs1->tg_ctl.b.enable = enable;
+}
+
+unsigned int scl_set_clock(unsigned int pixel_clock)
+{
+ unsigned int rd_cyc;
+ rd_cyc = vpp_get_base_clock(VPP_MOD_SCL) / pixel_clock;
+ return rd_cyc;
+}
+
+void scl_set_timing(vpp_clock_t *timing, unsigned int pixel_clock)
+{
+#if 1
+ timing->read_cycle = WMT_SCL_RCYC_MIN;
+#else
+ timing->read_cycle = scl_set_clock(pixel_clock * 2) - 1;
+ timing->read_cycle = (timing->read_cycle < WMT_SCL_RCYC_MIN) ?
+ WMT_SCL_RCYC_MIN : timing->read_cycle;
+ timing->read_cycle = (timing->read_cycle > 255) ?
+ 0xFF : timing->read_cycle;
+#endif
+ scl_regs1->tg_ctl.b.rdcyc = timing->read_cycle;
+ scl_regs2->readcyc_1t.b.rdcyc_1t = (timing->read_cycle) ? 0 : 1;
+ scl_regs1->tg_total.b.h_allpixel = timing->total_pixel_of_line;
+ scl_regs1->tg_h_active.b.h_actbg = timing->begin_pixel_of_active;
+ scl_regs1->tg_h_active.b.h_actend = timing->end_pixel_of_active;
+ scl_regs1->tg_total.b.v_allline = timing->total_line_of_frame;
+ scl_regs1->tg_v_active.b.v_actbg = timing->begin_line_of_active;
+ scl_regs1->tg_v_active.b.v_actend = timing->end_line_of_active;
+ scl_regs1->tg_vbi.b.vbie = timing->line_number_between_VBIS_VBIE;
+ scl_regs1->tg_vbi.b.pvbi = timing->line_number_between_PVBI_VBIS;
+#ifdef DEBUG_DETAIL
+ vpp_show_timing("scl set timing", 0, timing);
+#endif
+}
+
+void scl_get_timing(vpp_clock_t *p_timing)
+{
+ p_timing->read_cycle = scl_regs1->tg_ctl.b.rdcyc;
+ p_timing->total_pixel_of_line = scl_regs1->tg_total.b.h_allpixel;
+ p_timing->begin_pixel_of_active = scl_regs1->tg_h_active.b.h_actbg;
+ p_timing->end_pixel_of_active = scl_regs1->tg_h_active.b.h_actend;
+ p_timing->total_line_of_frame = scl_regs1->tg_total.b.v_allline;
+ p_timing->begin_line_of_active = scl_regs1->tg_v_active.b.v_actbg;
+ p_timing->end_line_of_active = scl_regs1->tg_v_active.b.v_actend;
+ p_timing->line_number_between_VBIS_VBIE = scl_regs1->tg_vbi.b.vbie;
+ p_timing->line_number_between_PVBI_VBIS = scl_regs1->tg_vbi.b.pvbi;
+}
+
+void scl_set_watchdog(U32 count)
+{
+ if (0 != count) {
+ scl_regs1->tg_watchdog = count;
+ scl_regs1->tg_ctl.b.watchdog_enable = 1;
+ } else
+ scl_regs1->tg_ctl.b.watchdog_enable = 0;
+}
+
+void scl_set_timing_master(vpp_mod_t mod_bit)
+{
+ scl_regs1->tg_govw.b.enable = (mod_bit == VPP_MOD_GOVW) ? 1 : 0;
+}
+
+vpp_mod_t scl_get_timing_master(void)
+{
+ return (scl_regs1->tg_govw.b.enable) ? VPP_MOD_GOVW : VPP_MOD_SCL;
+}
+
+void scl_set_drop_line(vpp_flag_t enable)
+{
+ scl_regs1->scldw = enable;
+}
+
+/* only one feature can work, other should be disable */
+void scl_set_filter_mode(enum vpp_filter_mode_t mode, int enable)
+{
+ DBG_DETAIL("(%d,%d)\n", mode, enable);
+ if (mode != VPP_FILTER_SCALE) {
+ if (scl_regs1->sclup_en.b.v || scl_regs1->sclup_en.b.h)
+ DPRINT("[SCL] *W* filter can't work w scale\n");
+ }
+ scl_regs2->field_mode.b.deblock = 0;
+ scl_regs2->field_mode.b.field_deflicker = 0;
+ scl_regs2->field_mode.b.frame_deflicker = 0;
+ switch (mode) {
+ default:
+ case VPP_FILTER_SCALE: /* scale mode */
+ break;
+ case VPP_FILTER_DEBLOCK: /* deblock */
+ scl_regs2->field_mode.b.deblock = enable;
+ break;
+ case VPP_FILTER_FIELD_DEFLICKER: /* field deflicker */
+ scl_regs2->field_mode.b.field_deflicker = enable;
+ break;
+ case VPP_FILTER_FRAME_DEFLICKER: /* frame deflicker */
+ scl_regs2->field_mode.b.frame_deflicker = enable;
+ break;
+ }
+}
+
+enum vpp_filter_mode_t scl_get_filter_mode(void)
+{
+ if (scl_regs1->sclup_en.b.v || scl_regs1->sclup_en.b.h)
+ return VPP_FILTER_SCALE;
+
+ if (scl_regs2->field_mode.b.deblock)
+ return VPP_FILTER_DEBLOCK;
+
+ if (scl_regs2->field_mode.b.field_deflicker)
+ return VPP_FILTER_FIELD_DEFLICKER;
+
+ if (scl_regs2->field_mode.b.frame_deflicker)
+ return VPP_FILTER_FRAME_DEFLICKER;
+ return VPP_FILTER_SCALE;
+}
+
+void sclr_set_mif_enable(vpp_flag_t enable)
+{
+ scl_regs1->r_ctl.b.mif_enable = enable;
+}
+
+void sclr_set_mif2_enable(vpp_flag_t enable)
+{
+
+}
+
+void sclr_set_colorbar(vpp_flag_t enable, int width, int inverse)
+{
+ scl_regs1->r_ctl.b.colorbar_mode = width;
+ scl_regs1->r_ctl.b.colorbar_inv = inverse;
+ scl_regs1->r_ctl.b.colorbar_enable = enable;
+}
+
+void sclr_set_field_mode(vpp_display_format_t fmt)
+{
+ scl_regs1->r_ctl.b.src_disp_fmt = fmt;
+}
+
+void sclr_set_display_format(vpp_display_format_t source,
+ vpp_display_format_t target)
+{
+ scl_regs1->r_ctl.b.src_disp_fmt =
+ (source == VPP_DISP_FMT_FIELD) ? 1 : 0;
+ scl_regs1->r_ctl.b.field = (target == VPP_DISP_FMT_FIELD) ? 1 : 0;
+}
+
+void sclr_set_color_format(vdo_color_fmt format)
+{
+ p_scl->abgr_mode = 0;
+ if (format >= VDO_COL_FMT_ARGB) {
+ scl_regs1->r_ctl.b.rgb_mode =
+ (format == VDO_COL_FMT_RGB_565) ? 0x1 : 0x3;
+ if (format == VDO_COL_FMT_ABGR)
+ p_scl->abgr_mode = 1;
+ return;
+ }
+ scl_regs1->r_ctl.b.rgb_mode = 0;
+ scl_regs1->r_ctl.b.rgb = 0x0;
+ switch (format) {
+ case VDO_COL_FMT_YUV444:
+ scl_regs1->r_ctl.b.yuv = 0x2;
+ break;
+ case VDO_COL_FMT_YUV422H:
+ scl_regs1->r_ctl.b.yuv = 0x0;
+ break;
+ case VDO_COL_FMT_YUV420:
+ scl_regs1->r_ctl.b.yuv = 0x1;
+ break;
+ default:
+ DBG_ERR("color fmt %d\n", format);
+ return;
+ }
+}
+
+vdo_color_fmt sclr_get_color_format(void)
+{
+ switch (scl_regs1->r_ctl.b.rgb_mode) {
+ case 0x1:
+ return VDO_COL_FMT_RGB_565;
+ case 0x3:
+ return VDO_COL_FMT_ARGB;
+ default:
+ break;
+ }
+ switch (scl_regs1->r_ctl.b.yuv) {
+ case 0:
+ return VDO_COL_FMT_YUV422H;
+ case 1:
+ return VDO_COL_FMT_YUV420;
+ case 2:
+ return VDO_COL_FMT_YUV444;
+ default:
+ break;
+ }
+ return VDO_COL_FMT_YUV444;
+}
+
+void sclr_set_media_format(vpp_media_format_t format)
+{
+ scl_regs1->r_ctl.b.h264 = (format == VPP_MEDIA_FMT_H264) ? 1 : 0;
+}
+
+void sclr_set_fb_addr(U32 y_addr, U32 c_addr)
+{
+ unsigned int line_y, line_c;
+ unsigned int offset_y, offset_c;
+ unsigned int pre_y, pre_c;
+
+ DBGMSG("y_addr:0x%08x, c_addr:0x%08x\n", y_addr, c_addr);
+
+ offset_y = offset_c = 0;
+ line_y = line_c = scl_regs1->r_h_size.b.fb_w;
+ switch (sclr_get_color_format()) {
+ case VDO_COL_FMT_YUV420:
+ offset_c /= 2;
+ line_c = 0;
+ break;
+ case VDO_COL_FMT_YUV422H:
+ break;
+ case VDO_COL_FMT_ARGB:
+ offset_y *= 4;
+ line_y *= 4;
+ break;
+ case VDO_COL_FMT_RGB_565:
+ offset_y *= 2;
+ line_y *= 2;
+ break;
+ default:
+ offset_c *= 2;
+ line_c *= 2;
+ break;
+ }
+ pre_y = scl_regs1->r_ysa;
+ pre_c = scl_regs1->r_csa;
+ scl_regs1->r_ysa = y_addr + offset_y;
+ scl_regs1->r_csa = c_addr + offset_c;
+}
+
+void sclr_get_fb_addr(U32 *y_addr, U32 *c_addr)
+{
+ *y_addr = scl_regs1->r_ysa;
+ *c_addr = scl_regs1->r_csa;
+/* DBGMSG("y_addr:0x%08x, c_addr:0x%08x\n", *y_addr, *c_addr); */
+}
+
+void sclr_set_width(U32 y_pixel, U32 y_buffer)
+{
+ scl_regs1->r_h_size.b.pix_w = y_pixel;
+ scl_regs1->r_h_size.b.fb_w = y_buffer;
+}
+
+void sclr_get_width(U32 *p_y_pixel, U32 *p_y_buffer)
+{
+ *p_y_pixel = scl_regs1->r_h_size.b.pix_w;
+ *p_y_buffer = scl_regs1->r_h_size.b.fb_w;
+}
+
+void sclr_set_crop(U32 h_crop, U32 v_crop)
+{
+ scl_regs1->r_crop.b.hcrop = h_crop;
+ scl_regs1->r_crop.b.vcrop = v_crop;
+}
+
+void sclr_get_fb_info(U32 *width, U32 *act_width,
+ U32 *x_offset, U32 *y_offset)
+{
+ *width = scl_regs1->r_h_size.b.fb_w;
+ *act_width = scl_regs1->r_h_size.b.pix_w;
+ *x_offset = scl_regs1->r_crop.b.hcrop;
+ *y_offset = scl_regs1->r_crop.b.vcrop;
+}
+
+void sclr_set_threshold(U32 value)
+{
+ scl_regs1->r_fifo_ctl.b.thr = value;
+}
+
+void sclw_set_mif_enable(vpp_flag_t enable)
+{
+ scl_regs1->w_ctl.b.mif_enable = enable;
+}
+
+void sclw_set_color_format(vdo_color_fmt format)
+{
+ /* 0-888(4 byte), 1-5515(2 byte), 2-666(4 byte), 3-565(2 byte) */
+ switch (format) {
+ case VDO_COL_FMT_RGB_666:
+ scl_regs1->w_ctl.b.rgb = 1;
+ scl_regs2->igs.b.mode = 2;
+ break;
+ case VDO_COL_FMT_RGB_565:
+ scl_regs1->w_ctl.b.rgb = 1;
+ scl_regs2->igs.b.mode = 3;
+ break;
+ case VDO_COL_FMT_RGB_1555:
+ scl_regs1->w_ctl.b.rgb = 1;
+ scl_regs2->igs.b.mode = 1;
+ break;
+ case VDO_COL_FMT_ARGB:
+ scl_regs1->w_ctl.b.rgb = 1;
+ scl_regs2->igs.b.mode = 0;
+ break;
+ case VDO_COL_FMT_YUV444:
+ scl_regs1->w_ctl.b.rgb = 0;
+ scl_regs1->w_ctl.b.yuv = 0;
+ scl_regs2->igs.b.mode = 0;
+ break;
+ case VDO_COL_FMT_YUV422H:
+ case VDO_COL_FMT_YUV420:
+ scl_regs1->w_ctl.b.rgb = 0;
+ scl_regs1->w_ctl.b.yuv = 1;
+ scl_regs2->igs.b.mode = 0;
+ break;
+ default:
+ DBGMSG("*E* check the parameter.\n");
+ return;
+ }
+}
+
+vdo_color_fmt sclw_get_color_format(void)
+{
+ if (scl_regs1->w_ctl.b.rgb) {
+ switch (scl_regs2->igs.b.mode) {
+ case 0:
+ return VDO_COL_FMT_ARGB;
+ case 1:
+ return VDO_COL_FMT_RGB_1555;
+ case 2:
+ return VDO_COL_FMT_RGB_666;
+ case 3:
+ return VDO_COL_FMT_RGB_565;
+ }
+ }
+
+ if (scl_regs1->w_ctl.b.yuv)
+ return VDO_COL_FMT_YUV422H;
+ return VDO_COL_FMT_YUV444;
+}
+
+void sclw_set_alpha(int enable, char data)
+{
+ scl_regs2->argb_alpha.b.data = data;
+ scl_regs2->argb_alpha.b.enable = enable;
+}
+
+void sclw_set_field_mode(vpp_display_format_t fmt)
+{
+ scl_regs1->r_ctl.b.field = fmt;
+}
+
+void sclw_set_fb_addr(U32 y_addr, U32 c_addr)
+{
+ DBGMSG("y_addr:0x%08x, c_addr:0x%08x\n", y_addr, c_addr);
+/* if( (y_addr & 0x3f) || (c_addr & 0x3f) ){
+ DPRINT("[SCL] *E* addr should align 64\n");
+ } */
+ scl_regs1->w_ysa = y_addr;
+ scl_regs1->w_csa = c_addr;
+}
+
+void sclw_get_fb_addr(U32 *y_addr, U32 *c_addr)
+{
+ *y_addr = scl_regs1->w_ysa;
+ *c_addr = scl_regs1->w_csa;
+ DBGMSG("y_addr:0x%08x, c_addr:0x%08x\n", *y_addr, *c_addr);
+}
+
+void sclw_set_fb_width(U32 width, U32 buf_width)
+{
+ scl_regs1->w_y_time.b.pxl_w = width;
+ scl_regs1->w_y_time.b.fb_w = buf_width;
+ if (sclw_get_color_format() == VDO_COL_FMT_YUV444) {
+ scl_regs1->w_c_time.b.pxl_w = width;
+ scl_regs1->w_c_time.b.fb_w = buf_width * 2;
+ } else {
+ scl_regs1->w_c_time.b.pxl_w = width / 2;
+ scl_regs1->w_c_time.b.fb_w = buf_width;
+ }
+}
+
+void sclw_get_fb_width(U32 *width, U32 *buf_width)
+{
+ *width = scl_regs1->w_y_time.b.pxl_w;
+ *buf_width = scl_regs1->w_y_time.b.fb_w;
+}
+
+void scl_R2_set_mif_enable(int enable)
+{
+ scl_regs1->r2_ctl.b.mif_en = enable;
+}
+
+void scl_R2_set_colorbar(int enable, int wide, int inv)
+{
+ scl_regs1->r2_ctl.b.color_en = enable;
+ scl_regs1->r2_ctl.b.color_wide = wide;
+ scl_regs1->r2_ctl.b.color_inv = inv;
+}
+
+void scl_R2_set_color_format(vdo_color_fmt colfmt)
+{
+ if (colfmt >= VDO_COL_FMT_ARGB) {
+ scl_regs1->r2_ctl.b.rgb_mode =
+ (colfmt == VDO_COL_FMT_RGB_565) ? 0x1 : 0x3;
+ return;
+ }
+ scl_regs1->r2_ctl.b.rgb_mode = 0;
+ switch (colfmt) {
+ case VDO_COL_FMT_YUV444:
+ scl_regs1->r2_ctl.b.vfmt = 0x2;
+ break;
+ case VDO_COL_FMT_YUV422H:
+ scl_regs1->r2_ctl.b.vfmt = 0x0;
+ break;
+ case VDO_COL_FMT_YUV420:
+ scl_regs1->r2_ctl.b.vfmt = 0x1;
+ break;
+ default:
+ DBG_ERR("color fmt %d\n", colfmt);
+ return;
+ }
+}
+
+vdo_color_fmt scl_R2_get_color_format(void)
+{
+ switch (scl_regs1->r2_ctl.b.rgb_mode) {
+ case 0:
+ switch (scl_regs1->r2_ctl.b.vfmt) {
+ case 0:
+ return VDO_COL_FMT_YUV422H;
+ case 1:
+ return VDO_COL_FMT_YUV420;
+ case 2:
+ default:
+ return VDO_COL_FMT_YUV444;
+ }
+ break;
+ case 1:
+ return VDO_COL_FMT_RGB_565;
+ case 3:
+ default:
+ break;
+ }
+ return VDO_COL_FMT_ARGB;
+}
+
+void scl_R2_set_csc_mode(vpp_csc_t mode)
+{
+ vdo_color_fmt src_fmt, dst_fmt;
+
+ src_fmt = scl_R2_get_color_format();
+ dst_fmt = sclw_get_color_format();
+ mode = vpp_check_csc_mode(mode, src_fmt, dst_fmt, 0);
+
+ scl_regs2->r2_csc1 = vpp_csc_parm[mode][0];
+ scl_regs2->r2_csc2 = vpp_csc_parm[mode][1];
+ scl_regs2->r2_csc3 = vpp_csc_parm[mode][2];
+ scl_regs2->r2_csc4 = vpp_csc_parm[mode][3];
+ scl_regs2->r2_csc5 = vpp_csc_parm[mode][4];
+ scl_regs2->r2_csc6 = vpp_csc_parm[mode][5];
+ scl_regs2->r2_csc.val = vpp_csc_parm[mode][6];
+ scl_regs2->r2_csc.b.enable = (mode >= VPP_CSC_MAX) ? 0 : 1;
+}
+
+void scl_R2_set_framebuffer(vdo_framebuf_t *fb)
+{
+ scl_regs1->r2_ctl.b.iofmt = (fb->flag & VDO_FLAG_INTERLACE) ? 1 : 0;
+ scl_R2_set_color_format(fb->col_fmt);
+ scl_regs1->r2_ysa = fb->y_addr;
+ scl_regs1->r2_csa = fb->c_addr;
+ scl_regs1->r2_h_size.b.fbw = fb->fb_w;
+ scl_regs1->r2_h_size.b.lnsize = fb->img_w;
+ scl_regs1->r2_crop.b.hcrop = fb->h_crop;
+ scl_regs1->r2_crop.b.vcrop = fb->v_crop;
+ scl_R2_set_csc_mode(p_scl->fb_p->csc_mode);
+}
+
+void scl_ALPHA_set_enable(int enable)
+{
+ scl_regs1->alpha_colorkey.b.enable = enable;
+}
+
+void scl_ALPHA_set_swap(int enable)
+{
+ /* 0-(alpha,1-alpha),1:(1-alpha,alpha) */
+ scl_regs1->alpha_md.b.swap = enable;
+}
+
+void scl_ALPHA_set_src(int mode, int fixed)
+{
+ /* 0-RMIF1,1-RMIF2,2-Fixed ALPHA */
+ scl_regs1->alpha_md.b.src = mode;
+ scl_regs1->alpha_fxd.b.src_fixed = fixed;
+}
+
+void scl_ALPHA_set_dst(int mode, int fixed)
+{
+ /* 0-RMIF1,1-RMIF2,2-Fixed ALPHA */
+ scl_regs1->alpha_md.b.dst = mode;
+ scl_regs1->alpha_fxd.b.dst_fixed = fixed;
+}
+
+void scl_ALPHA_set_color_key(int rmif2, int comp, int mode, int colkey)
+{
+ /* 0-RMIF1,1-RMIF2 */
+ scl_regs1->alpha_colorkey.b.from = rmif2;
+ /* 0-888,1-777,2-666,3-555 */
+ scl_regs1->alpha_colorkey.b.comp = comp;
+ /* (Non-Hit,Hit):0/1-(alpha,alpha),
+ 2-(alpha,pix1),3-(pix1,alpha),4-(alpha,pix2),
+ 5-(pix2,alpha),6-(pix1,pix2),7-(pix2,pix1) */
+ scl_regs1->alpha_colorkey.b.mode = mode;
+ scl_regs1->alpha_colorkey_rgb.val = colkey;
+}
+
+void scl_set_overlap(vpp_overlap_t *p)
+{
+#if 0
+ DPRINT("alpha src %d,0x%x,dst %d,0x%x\n",
+ p->alpha_src_type, p->alpha_src,
+ p->alpha_dst_type, p->alpha_dst);
+ DPRINT("colkey from %d,comp %d,mode %d,0x%x\n",
+ p->color_key_from, p->color_key_comp,
+ p->color_key_mode, p->color_key);
+#endif
+ scl_ALPHA_set_src(p->alpha_src_type, p->alpha_src);
+ scl_ALPHA_set_dst(p->alpha_dst_type, p->alpha_dst);
+ scl_ALPHA_set_swap(p->alpha_swap);
+ scl_ALPHA_set_color_key(p->color_key_from, p->color_key_comp,
+ p->color_key_mode, p->color_key);
+}
+
+void scl_set_req_num(int ynum, int cnum)
+{
+ scl_regs1->r_req_num.b.y_req_num = ynum;
+ scl_regs1->r_req_num.b.c_req_num = cnum;
+}
+
+static void scl_set_scale_PP(unsigned int src, unsigned int dst,
+ int horizontal)
+{
+ int gcd;
+
+/* DBGMSG("scale PP(s %d,d %d,is H %d)\n",src,dst,horizontal); */
+
+ /* gcd = scl_get_gcd(src,dst); */
+ gcd = 1;
+ src /= gcd;
+ dst /= gcd;
+
+ if (horizontal)
+ scl_set_H_scale(dst, src);
+ else
+ scl_set_V_scale(dst, src);
+}
+
+void scl_set_scale(unsigned int SRC_W, unsigned int SRC_H,
+ unsigned int DST_W, unsigned int DST_H)
+{
+ int h_scale_up;
+ int v_scale_up;
+
+ DBGMSG("[SCL] src(%dx%d),dst(%dx%d)\n", SRC_W, SRC_H, DST_W, DST_H);
+
+ h_scale_up = (DST_W > SRC_W) ? 1 : 0;
+ v_scale_up = (DST_H > SRC_H) ? 1 : 0;
+
+ if (((DST_W / SRC_W) >= 32) || ((DST_W / SRC_W) < 1/32))
+ DBGMSG("*W* SCL H scale rate invalid\n");
+
+ if (((DST_H / SRC_H) >= 32) || ((DST_H / SRC_H) < 1/32))
+ DBGMSG("*W* SCL V scale rate invalid\n");
+
+/* DBGMSG("scale H %d,V %d\n",h_scale_up,v_scale_up); */
+
+ sclr_set_mif2_enable(VPP_FLAG_DISABLE);
+ scl_set_scale_PP(SRC_W, DST_W, 1);
+ scl_set_scale_PP(SRC_H, DST_H, 0);
+ scl_set_scale_enable(v_scale_up, h_scale_up);
+
+ {
+ int rec_h, rec_v;
+ int h, v;
+
+ h = rec_h = 0;
+ if (SRC_W > DST_W) { /* scale down */
+ switch (p_scl->scale_mode) {
+ case VPP_SCALE_MODE_ADAPTIVE:
+ if ((DST_W * 2) > SRC_W) /* 1 > mode(3) > 1/2 */
+ h = 1; /* bilinear mode */
+ else
+ rec_h = 1; /* recursive mode */
+ break;
+ case VPP_SCALE_MODE_BILINEAR:
+ h = 1; /* bilinear mode */
+ break;
+ case VPP_SCALE_MODE_RECURSIVE:
+ rec_h = 1; /* recursive mode */
+ break;
+ default:
+ break;
+ }
+ }
+
+ v = rec_v = 0;
+ if (SRC_H > DST_H) { /* scale down */
+ switch (p_scl->scale_mode) {
+ case VPP_SCALE_MODE_ADAPTIVE:
+ if ((DST_H * 2) > SRC_H) /* 1 > mode(3) > 1/2 */
+ v = 1; /* bilinear mode */
+ else
+ rec_v = 1; /* recursive mode */
+ break;
+ case VPP_SCALE_MODE_BILINEAR:
+ v = 1; /* bilinear mode */
+ break;
+ case VPP_SCALE_MODE_RECURSIVE:
+ rec_v = 1; /* recursive mode */
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (SRC_W == DST_W)
+ rec_h = 1;
+ if (SRC_H == DST_H)
+ rec_v = 1;
+ scl_regs1->true_bilinear.b.h = h;
+ scl_regs1->true_bilinear.b.v = v;
+ scl_regs2->recursive_mode.b.h = rec_h;
+ scl_regs2->recursive_mode.b.v = rec_v;
+ if (v) {
+ scl_regs1->vxwidth.b.vxwidth =
+ scl_regs1->vxwidth.b.vxwidth - 1;
+ scl_regs1->vxwidth.b.dst_vxwidth =
+ scl_regs1->vxwidth.b.vxwidth;
+ }
+ sclr_set_mif2_enable((v) ? VPP_FLAG_ENABLE : VPP_FLAG_DISABLE);
+ }
+}
+
+void sclr_set_framebuffer(vdo_framebuf_t *inbuf)
+{
+ sclr_set_color_format(inbuf->col_fmt);
+ sclr_set_crop(inbuf->h_crop, inbuf->v_crop);
+ sclr_set_width(inbuf->img_w, inbuf->fb_w);
+ sclr_set_fb_addr(inbuf->y_addr, inbuf->c_addr);
+ sclr_set_field_mode(vpp_get_fb_field(inbuf));
+}
+
+void scl_set_scale_timing(vdo_framebuf_t *s, vdo_framebuf_t *d)
+{
+ vpp_clock_t timing;
+ unsigned int pixel_clock;
+
+ /* scl TG */
+ timing.total_pixel_of_line = (d->img_w > s->img_w) ?
+ d->img_w : s->img_w;
+ timing.total_line_of_frame = (d->img_h > s->img_h) ?
+ d->img_h : s->img_h;
+ timing.begin_pixel_of_active = 60;
+ timing.end_pixel_of_active = timing.total_pixel_of_line + 60;
+ timing.total_pixel_of_line = timing.total_pixel_of_line + 120;
+ timing.begin_line_of_active = 8;
+ timing.end_line_of_active = timing.total_line_of_frame + 8;
+ timing.total_line_of_frame = timing.total_line_of_frame + 16;
+ timing.line_number_between_VBIS_VBIE = 4;
+ timing.line_number_between_PVBI_VBIS = 1;
+ pixel_clock = timing.total_pixel_of_line *
+ timing.total_line_of_frame * p_scl->fb_p->framerate;
+ scl_set_timing(&timing, pixel_clock);
+}
+
+void sclw_set_framebuffer(vdo_framebuf_t *fb)
+{
+ unsigned int yaddr, caddr;
+ int y_bpp, c_bpp;
+
+ vpp_get_colfmt_bpp(fb->col_fmt, &y_bpp, &c_bpp);
+ yaddr = fb->y_addr + ((fb->fb_w * fb->v_crop + fb->h_crop) * y_bpp / 8);
+ caddr = (c_bpp) ? (fb->c_addr + (((fb->fb_w * fb->v_crop +
+ fb->h_crop) / 2) * 2 * c_bpp / 8)) : 0;
+ sclw_set_fb_addr(yaddr, caddr);
+ sclw_set_color_format(fb->col_fmt);
+ sclw_set_fb_width(fb->img_w, fb->fb_w);
+ sclw_set_field_mode(vpp_get_fb_field(fb));
+ scl_set_csc_mode(p_scl->fb_p->csc_mode);
+}
+
+void scl_init(void *base)
+{
+ struct scl_mod_t *mod_p;
+ struct vpp_fb_base_t *fb_p;
+
+ mod_p = (struct scl_mod_t *) base;
+ fb_p = mod_p->fb_p;
+
+ scl_set_reg_level(VPP_REG_LEVEL_1);
+ scl_set_tg_enable(VPP_FLAG_DISABLE);
+ scl_set_enable(VPP_FLAG_DISABLE);
+ scl_set_int_enable(VPP_FLAG_DISABLE, VPP_INT_ALL);
+ sclr_set_mif_enable(VPP_FLAG_DISABLE);
+ sclr_set_mif2_enable(VPP_FLAG_DISABLE);
+ sclr_set_colorbar(VPP_FLAG_DISABLE, 0, 0);
+
+ scl_set_int_enable(VPP_FLAG_ENABLE, mod_p->int_catch);
+ scl_set_watchdog(fb_p->wait_ready);
+ scl_set_csc_mode(fb_p->csc_mode);
+ sclr_set_media_format(fb_p->media_fmt);
+ sclr_set_threshold(0xf);
+
+ /* filter default value */
+ scl_regs2->dblk_threshold.b.layer1_boundary = 48;
+ scl_regs2->dblk_threshold.b.layer2_boundary = 16;
+
+ scl_regs2->field_flicker.b.y_thd = 8;
+ scl_regs2->field_flicker.b.c_thd = 8;
+ scl_regs2->field_flicker.b.condition = 0;
+
+ scl_regs2->frame_flicker.b.rgb = 0;
+ scl_regs2->frame_flicker.b.sampler = 14;
+ scl_regs2->frame_flicker.b.scene_chg_thd = 32;
+ scl_set_reg_update(VPP_FLAG_ENABLE);
+ scl_set_tg_enable(VPP_FLAG_DISABLE);
+}
+
+void sclw_init(void *base)
+{
+ sclw_set_mif_enable(VPP_FLAG_DISABLE);
+ sclw_set_fb_width(VPP_HD_DISP_RESX, VPP_HD_MAX_RESX);
+/* vppif_reg32_write(SCL_SCLDW_METHOD,0x1); */ /* drop line enable */
+}
+
+#ifdef __KERNEL__
+/* static struct work_struct scl_proc_scale_wq; */
+DECLARE_WAIT_QUEUE_HEAD(scl_proc_scale_event);
+static void scl_proc_scale_complete_work(struct work_struct *work)
+#else
+static void scl_proc_scale_complete_work(int arg)
+#endif
+{
+/* DPRINT("[SCL] scl_proc_scale_complete_work\n"); */
+ p_scl->scale_complete = 1;
+#ifdef __KERNEL__
+ wake_up_interruptible(&scl_proc_scale_event);
+#endif
+#if 0 /* avoid mutex in irq */
+ vpp_mod_set_clock(VPP_MOD_SCL, VPP_FLAG_DISABLE, 0);
+#endif
+}
+
+#ifdef __KERNEL__
+struct timer_list scl_scale_timer;
+#endif
+int scl_proc_scale_complete(void *arg)
+{
+#ifdef __KERNEL__
+ del_timer(&scl_scale_timer);
+#endif
+/* DPRINT("[SCL] scl_proc_scale_complete\n"); */
+ if (scl_regs1->tg_sts.b.tgerr) {
+ DPRINT("[SCL] scale TG err 0x%x,0x%x\n",
+ scl_regs1->tg_sts.val, scl_regs1->w_ff_ctl.val);
+ scl_regs1->tg_sts.val = BIT0;
+ scl_regs1->w_ff_ctl.val = 0x10101;
+ }
+ scl_set_tg_enable(VPP_FLAG_DISABLE);
+#ifndef CONFIG_UBOOT
+ vppm_set_int_enable(VPP_FLAG_DISABLE, SCL_COMPLETE_INT);
+#endif
+ sclw_set_mif_enable(VPP_FLAG_DISABLE);
+ sclr_set_mif_enable(VPP_FLAG_DISABLE);
+ sclr_set_mif2_enable(VPP_FLAG_DISABLE);
+ scl_set_enable(VPP_FLAG_DISABLE);
+
+/* #ifdef __KERNEL__ */
+#if 0
+ INIT_WORK(&scl_proc_scale_wq, scl_proc_scale_complete_work);
+ schedule_work(&scl_proc_scale_wq);
+#else
+ scl_proc_scale_complete_work(0);
+#endif
+ return 0;
+}
+
+void scl_scale_timeout(int arg)
+{
+ DBG_ERR("scale timeout\n");
+#if 0
+ scl_reg_dump();
+ g_vpp.dbg_msg_level = VPP_DBGLVL_STREAM;
+ g_vpp.dbg_cnt = 1000;
+#endif
+ scl_proc_scale_complete(0);
+}
+
+void scl_set_scale_timer(int ms)
+{
+#ifdef __KERNEL__
+ if (scl_scale_timer.function)
+ del_timer(&scl_scale_timer);
+ init_timer(&scl_scale_timer);
+ scl_scale_timer.function = (void *) scl_scale_timeout;
+ scl_scale_timer.expires = jiffies + msecs_to_jiffies(ms);
+ add_timer(&scl_scale_timer);
+#endif
+}
+
+int scl_proc_scale_finish(void)
+{
+ int ret = 0;
+
+#ifdef __KERNEL__
+
+/* DPRINT("[SCL] scl_proc_scale_finish\n"); */
+ ret = wait_event_interruptible_timeout(scl_proc_scale_event,
+ (p_scl->scale_complete != 0), 3 * HZ);
+ if (ret == 0) { /* timeout */
+ DPRINT("[SCL] *E* wait scale timeout\n");
+ ret = -1;
+ } else {
+ ret = 0;
+ }
+#endif
+#if 1 /* avoid mutex in irq */
+ vpp_mod_set_clock(VPP_MOD_SCL, VPP_FLAG_DISABLE, 0);
+#endif
+ return ret;
+}
+
+void scl_check_framebuf(vdo_framebuf_t *s,
+ vdo_framebuf_t *in, vdo_framebuf_t *out)
+{
+ if (s) {
+ if (s->img_w > WMT_SCL_H_DIV_MAX)
+ DBG_ERR("src w %d over %d\n",
+ s->img_w, WMT_SCL_H_DIV_MAX);
+ if (s->img_h > WMT_SCL_V_DIV_MAX)
+ DBG_ERR("src h %d over %d\n",
+ s->img_h, WMT_SCL_V_DIV_MAX);
+ if (s->col_fmt >= VDO_COL_FMT_ARGB) {
+ if (s->y_addr % 4)
+ DBG_ERR("src addr 0x%x not align 4\n",
+ s->y_addr);
+ }
+ if (s->fb_w > WMT_SCL_H_DIV_MAX)
+ DBG_ERR("src fb w %d over %d\n",
+ s->fb_w, WMT_SCL_H_DIV_MAX);
+ if (s->y_addr % 64)
+ DBG_ERR("src fb addr 0x%x no align 64\n", s->y_addr);
+ } else {
+ DBG_ERR("src null\n");
+ }
+
+ if (in) {
+ if (in->img_w > WMT_SCL_H_DIV_MAX)
+ DBG_ERR("in w %d over %d\n",
+ in->img_w, WMT_SCL_H_DIV_MAX);
+ if (in->img_h > WMT_SCL_V_DIV_MAX)
+ DBG_ERR("in h %d over %d\n",
+ in->img_h, WMT_SCL_V_DIV_MAX);
+ if (in->col_fmt >= VDO_COL_FMT_ARGB) {
+ if (in->y_addr % 4)
+ DBG_ERR("in addr 0x%x not align 4\n",
+ in->y_addr);
+ }
+ if (in->fb_w > WMT_SCL_H_DIV_MAX)
+ DBG_ERR("in fb w %d over %d\n",
+ in->fb_w, WMT_SCL_H_DIV_MAX);
+ if (in->y_addr % 64)
+ DBG_ERR("in fb addr 0x%x no align 64\n", in->y_addr);
+ }
+
+ if (out) {
+ if (s && (s->img_w == out->img_w)) {
+ if (out->img_w > WMT_SCL_H_DIV_MAX)
+ DBG_ERR("out w %d over %d\n", out->img_w,
+ WMT_SCL_H_DIV_MAX);
+ } else {
+ if (out->img_w > WMT_SCL_SCALE_DST_H_MAX)
+ DBG_ERR("out w %d over %d\n", out->img_w,
+ WMT_SCL_SCALE_DST_H_MAX);
+
+ }
+ if (out->col_fmt >= VDO_COL_FMT_ARGB) {
+ if (out->y_addr % 4)
+ DBG_ERR("out addr 0x%x not align 4\n",
+ out->y_addr);
+ }
+ if (out->fb_w > WMT_SCL_H_DIV_MAX)
+ DBG_ERR("out fb w %d over %d\n",
+ out->fb_w, WMT_SCL_H_DIV_MAX);
+ if (out->y_addr % 64)
+ DBG_ERR("out fb addr 0x%x no align 64\n", out->y_addr);
+ } else {
+ DBG_ERR("out null\n");
+ }
+}
+
+#define CONFIG_VPP_CHECK_SCL_STATUS
+int scl_set_scale_overlap(vdo_framebuf_t *s,
+ vdo_framebuf_t *in, vdo_framebuf_t *out)
+{
+ int ret = 0;
+
+ if (vpp_check_dbg_level(VPP_DBGLVL_SCALE)) {
+ scl_check_framebuf(s, in, out);
+
+ if (s)
+ vpp_show_framebuf("src1", s);
+ if (in)
+ vpp_show_framebuf("src2", in);
+ if (out)
+ vpp_show_framebuf("dst", out);
+ }
+
+ if (p_scl->scale_sync)
+ vpp_mod_set_clock(VPP_MOD_SCL, VPP_FLAG_ENABLE, 0);
+
+ scl_set_timing_master(VPP_MOD_SCL);
+
+ if (s) {
+ p_scl->fb_p->fb = *s;
+ sclr_set_framebuffer(s);
+ sclr_set_mif_enable(VPP_FLAG_ENABLE);
+ } else {
+ DPRINT("[SCL] *E* no source\n");
+ return -1;
+ }
+
+ if (in && (in->y_addr == 0))
+ in = 0;
+
+ scl_ALPHA_set_enable((in) ? VPP_FLAG_ENABLE : VPP_FLAG_DISABLE);
+ scl_R2_set_mif_enable((in) ? VPP_FLAG_ENABLE : VPP_FLAG_DISABLE);
+ if (in)
+ scl_R2_set_framebuffer(in);
+ if (out) {
+ p_sclw->fb_p->fb = *out;
+ sclw_set_framebuffer(out);
+ } else {
+ DPRINT("[SCL] *E* no dest\n");
+ return -1;
+ }
+
+ scl_set_scale(s->img_w, s->img_h, out->img_w, out->img_h);
+ scl_set_scale_timing(s, out);
+
+ /* scale process */
+ scl_set_enable(VPP_FLAG_ENABLE);
+ scl_regs1->tg_ctl.b.oneshot = 1;
+ sclw_set_mif_enable(VPP_FLAG_ENABLE);
+ scl_set_tg_enable(VPP_FLAG_ENABLE);
+#ifdef CONFIG_VPP_CHECK_SCL_STATUS
+ scl_regs1->tg_sts.val = BIT0;
+ scl_regs1->w_ff_ctl.val = 0x10101;
+#endif
+ p_scl->scale_complete = 0;
+#ifndef CONFIG_UBOOT
+ vppm_set_int_enable(VPP_FLAG_ENABLE, SCL_COMPLETE_INT);
+#endif
+#if 0 /* for debug scale */
+ scl_reg_dump();
+#endif
+#ifdef CONFIG_UBOOT
+ while (scl_regs1->tg_ctl.b.enable);
+ scl_proc_scale_complete(0);
+ scl_proc_scale_finish();
+#else
+ if (p_scl->scale_sync) {
+ ret = vpp_irqproc_work(SCL_COMPLETE_INT,
+ (void *)scl_proc_scale_complete, 0, 100, 1);
+ scl_proc_scale_finish();
+ } else {
+ vpp_irqproc_work(SCL_COMPLETE_INT,
+ (void *)scl_proc_scale_complete, 0, 0, 1);
+ scl_set_scale_timer(100);
+ }
+#endif
+ return ret;
+}
+
+int scl_proc_scale(vdo_framebuf_t *src_fb, vdo_framebuf_t *dst_fb)
+{
+ int ret = 0;
+
+ if (dst_fb->col_fmt == VDO_COL_FMT_YUV420) {
+ int size;
+ unsigned int buf;
+ vdo_framebuf_t dfb;
+
+ dfb = *dst_fb; /* backup dst fb */
+
+ /* alloc memory */
+ size = dst_fb->img_w * dst_fb->img_h + 64;
+ buf = (unsigned int) kmalloc(size, GFP_KERNEL);
+ if (!buf) {
+ DPRINT("[SCL] *E* malloc fail %d\n", size);
+ return -1;
+ }
+
+ if (buf % 64)
+ buf = buf + (64 - (buf % 64));
+
+ /* scale for Y */
+ dst_fb->c_addr = buf;
+ ret = scl_set_scale_overlap(src_fb, 0, dst_fb);
+ if (ret == 0) {
+ /* V 1/2 scale for C */
+ dst_fb->y_addr = buf;
+ dst_fb->c_addr = dfb.c_addr;
+ dst_fb->img_h = dfb.img_h / 2;
+ ret = scl_set_scale_overlap(src_fb, 0, dst_fb);
+ }
+ kfree((void *)buf);
+ *dst_fb = dfb; /* restore dst fb */
+ } else {
+ ret = scl_set_scale_overlap(src_fb, 0, dst_fb);
+ }
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static unsigned int *scl_pm_bk2;
+static unsigned int scl_pm_enable, scl_pm_tg;
+static unsigned int scl_pm_r_mif1, scl_pm_r_mif2, scl_pm_w_mif;
+void scl_suspend(int sts)
+{
+ switch (sts) {
+ case 0: /* disable module */
+ vpp_mod_set_clock(VPP_MOD_SCL, VPP_FLAG_ENABLE, 1);
+ scl_pm_enable = scl_regs1->en.b.alu_enable;
+ scl_regs1->en.b.alu_enable = 0;
+ scl_pm_r_mif1 = scl_regs1->r_ctl.b.mif_enable;
+ scl_pm_r_mif2 = scl_regs1->r2_ctl.b.mif_en;
+ scl_regs1->r2_ctl.b.mif_en = 0;
+ scl_regs1->r_ctl.b.mif_enable = 0;
+ scl_pm_w_mif = scl_regs1->w_ctl.b.mif_enable;
+ scl_regs1->w_ctl.b.mif_enable = 0;
+ break;
+ case 1: /* disable tg */
+ scl_pm_tg = scl_regs1->tg_ctl.b.enable;
+ scl_regs1->tg_ctl.b.enable = 0;
+ break;
+ case 2: /* backup register */
+ p_scl->reg_bk = vpp_backup_reg(REG_SCL_BASE1_BEGIN,
+ (REG_SCL_BASE1_END - REG_SCL_BASE1_BEGIN));
+ scl_pm_bk2 = vpp_backup_reg(REG_SCL_BASE2_BEGIN,
+ (REG_SCL_BASE2_END - REG_SCL_BASE2_BEGIN));
+ break;
+ default:
+ break;
+ }
+}
+
+void scl_resume(int sts)
+{
+ switch (sts) {
+ case 0: /* restore register */
+ vpp_restore_reg(REG_SCL_BASE1_BEGIN,
+ (REG_SCL_BASE1_END - REG_SCL_BASE1_BEGIN),
+ p_scl->reg_bk);
+ vpp_restore_reg(REG_SCL_BASE2_BEGIN,
+ (REG_SCL_BASE2_END - REG_SCL_BASE2_BEGIN), scl_pm_bk2);
+ p_scl->reg_bk = 0;
+ scl_pm_bk2 = 0;
+ break;
+ case 1: /* enable module */
+ scl_regs1->w_ctl.b.mif_enable = scl_pm_w_mif;
+ scl_regs1->r_ctl.b.mif_enable = scl_pm_r_mif1;
+ scl_regs1->r2_ctl.b.mif_en = scl_pm_r_mif2;
+ scl_regs1->en.b.alu_enable = scl_pm_enable;
+ break;
+ case 2: /* enable tg */
+ scl_regs1->tg_ctl.b.enable = scl_pm_tg;
+ vpp_mod_set_clock(VPP_MOD_SCL, VPP_FLAG_DISABLE, 1);
+ break;
+ default:
+ break;
+ }
+}
+#else
+#define scl_suspend NULL
+#define scl_resume NULL
+#endif
+
+int scl_mod_init(void)
+{
+ struct vpp_fb_base_t *mod_fb_p;
+ vdo_framebuf_t *fb_p;
+
+ /* -------------------- SCL module -------------------- */
+ {
+ struct scl_mod_t *scl_mod_p;
+
+ scl_mod_p = (struct scl_mod_t *) vpp_mod_register(VPP_MOD_SCL,
+ sizeof(struct scl_mod_t),
+ VPP_MOD_FLAG_FRAMEBUF);
+ if (!scl_mod_p) {
+ DPRINT("*E* SCL module register fail\n");
+ return -1;
+ }
+
+ /* module member variable */
+ scl_mod_p->int_catch = VPP_INT_NULL;
+ scl_mod_p->scale_mode = VPP_SCALE_MODE_ADAPTIVE;
+ scl_mod_p->pm = DEV_SCL444U;
+ scl_mod_p->filter_mode = VPP_FILTER_SCALE;
+
+ /* module member function */
+ scl_mod_p->init = scl_init;
+ scl_mod_p->set_enable = scl_set_enable;
+ scl_mod_p->set_colorbar = sclr_set_colorbar;
+ scl_mod_p->dump_reg = scl_reg_dump;
+ scl_mod_p->get_sts = scl_get_int_status;
+ scl_mod_p->clr_sts = scl_clean_int_status;
+ scl_mod_p->scale = scl_proc_scale;
+ scl_mod_p->scale_finish = scl_proc_scale_finish;
+ scl_mod_p->suspend = scl_suspend;
+ scl_mod_p->resume = scl_resume;
+
+ /* module frame buffer variable */
+ mod_fb_p = scl_mod_p->fb_p;
+ fb_p = &mod_fb_p->fb;
+
+ fb_p->y_addr = 0;
+ fb_p->c_addr = 0;
+ fb_p->col_fmt = VDO_COL_FMT_YUV422H;
+ fb_p->img_w = VPP_HD_DISP_RESX;
+ fb_p->img_h = VPP_HD_DISP_RESY;
+ fb_p->fb_w = VPP_HD_MAX_RESX;
+ fb_p->fb_h = VPP_HD_MAX_RESY;
+ fb_p->h_crop = 0;
+ fb_p->v_crop = 0;
+
+ /* module frame buffer member function */
+ mod_fb_p->csc_mode = VPP_CSC_RGB2YUV_SDTV_0_255;
+ mod_fb_p->set_framebuf = sclr_set_framebuffer;
+ mod_fb_p->set_addr = sclr_set_fb_addr;
+ mod_fb_p->get_addr = sclr_get_fb_addr;
+ mod_fb_p->set_csc = scl_set_csc_mode;
+ mod_fb_p->framerate = 0x7fffffff;
+ mod_fb_p->wait_ready = 0xffffffff;
+ mod_fb_p->capability = BIT(VDO_COL_FMT_YUV420)
+ | BIT(VDO_COL_FMT_YUV422H) | BIT(VDO_COL_FMT_YUV444)
+ | BIT(VDO_COL_FMT_ARGB) | BIT(VDO_COL_FMT_RGB_565)
+ | VPP_FB_FLAG_CSC | VPP_FB_FLAG_FIELD;
+ p_scl = scl_mod_p;
+ p_scl->scale_complete = 1;
+ p_scl->scale_sync = 1;
+ }
+
+ /* -------------------- SCLW module -------------------- */
+ {
+ struct sclw_mod_t *sclw_mod_p;
+
+ sclw_mod_p = (struct sclw_mod_t *) vpp_mod_register(VPP_MOD_SCLW,
+ sizeof(struct sclw_mod_t),
+ VPP_MOD_FLAG_FRAMEBUF);
+ if (!sclw_mod_p) {
+ DPRINT("*E* SCLW module register fail\n");
+ return -1;
+ }
+
+ /* module member variable */
+ sclw_mod_p->int_catch = VPP_INT_NULL;
+
+ /* module member function */
+ sclw_mod_p->init = sclw_init;
+ sclw_mod_p->set_enable = sclw_set_mif_enable;
+
+ /* module frame buffer */
+ mod_fb_p = sclw_mod_p->fb_p;
+ fb_p = &mod_fb_p->fb;
+
+ fb_p->y_addr = 0;
+ fb_p->c_addr = 0;
+ fb_p->col_fmt = VDO_COL_FMT_YUV422H;
+ fb_p->img_w = VPP_HD_DISP_RESX;
+ fb_p->img_h = VPP_HD_DISP_RESY;
+ fb_p->fb_w = VPP_HD_MAX_RESX;
+ fb_p->fb_h = VPP_HD_MAX_RESY;
+ fb_p->h_crop = 0;
+ fb_p->v_crop = 0;
+
+ /* module frame buffer member function */
+ mod_fb_p->csc_mode = VPP_CSC_RGB2YUV_SDTV_0_255;
+ mod_fb_p->set_framebuf = sclw_set_framebuffer;
+ mod_fb_p->set_addr = sclw_set_fb_addr;
+ mod_fb_p->get_addr = sclw_get_fb_addr;
+ mod_fb_p->set_csc = scl_set_csc_mode;
+ mod_fb_p->wait_ready = 0xffffffff;
+ mod_fb_p->capability = BIT(VDO_COL_FMT_YUV422H)
+ | BIT(VDO_COL_FMT_YUV444) | BIT(VDO_COL_FMT_ARGB)
+ | BIT(VDO_COL_FMT_RGB_565) | VPP_FB_FLAG_CSC
+ | BIT(VDO_COL_FMT_YUV420);
+ p_sclw = sclw_mod_p;
+ }
+ return 0;
+}
+module_init(scl_mod_init);
+#endif /* WMT_FTBLK_SCL */
diff --git a/common/wmt_display/scl.h b/common/wmt_display/scl.h
new file mode 100755
index 0000000..2d11b48
--- /dev/null
+++ b/common/wmt_display/scl.h
@@ -0,0 +1,128 @@
+/*++
+ * linux/drivers/video/wmt/scl.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#include "vpp.h"
+
+#ifndef SCL_H
+#define SCL_H
+
+#define SCL_COMPLETE_INT VPP_INT_SCL_PVBI
+
+struct scl_mod_t {
+ VPP_MOD_BASE;
+
+ int (*scale)(vdo_framebuf_t *src, vdo_framebuf_t *dst);
+ int (*scale_finish)(void);
+
+ enum vpp_scale_mode_t scale_mode;
+ enum vpp_scale_mode_t scale_sync;
+ int scale_complete;
+ enum vpp_filter_mode_t filter_mode;
+ int abgr_mode;
+
+ struct vpp_dbg_timer_t overlap_timer;
+ struct vpp_dbg_timer_t scale_timer;
+};
+
+struct sclw_mod_t {
+ VPP_MOD_BASE;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SCL_C
+#define EXTERN
+#else
+#define EXTERN extern
+#endif
+
+EXTERN struct scl_mod_t *p_scl;
+EXTERN struct sclw_mod_t *p_sclw;
+
+#ifdef WMT_FTBLK_SCL
+
+EXTERN void scl_reg_dump(void);
+EXTERN void sclr_set_framebuffer(vdo_framebuf_t *inbuf);
+EXTERN void sclw_set_framebuffer(vdo_framebuf_t *outbuf);
+
+EXTERN void scl_set_enable(vpp_flag_t enable);
+EXTERN void scl_set_reg_update(vpp_flag_t enable);
+EXTERN void scl_set_reg_level(vpp_reglevel_t level);
+EXTERN void scl_set_int_enable(vpp_flag_t enable, enum vpp_int_t int_bit);
+EXTERN enum vpp_int_err_t scl_get_int_status(void);
+EXTERN void scl_clean_int_status(enum vpp_int_err_t int_sts);
+EXTERN void scl_set_csc_mode(vpp_csc_t mode);
+EXTERN void scl_set_scale_enable(vpp_flag_t vscl_enable,
+ vpp_flag_t hscl_enable);
+EXTERN void scl_set_V_scale(int A, int B);
+EXTERN void scl_set_H_scale(int A, int B);
+EXTERN void scl_set_crop(int offset_x, int offset_y);
+EXTERN void scl_set_tg_enable(vpp_flag_t enable);
+EXTERN void scl_set_timing_master(vpp_mod_t mod_bit);
+EXTERN vpp_mod_t scl_get_timing_master(void);
+EXTERN void scl_set_drop_line(vpp_flag_t enable);
+EXTERN void sclr_get_fb_info(U32 *width, U32 *act_width,
+ U32 *x_offset, U32 *y_offset);
+EXTERN void sclr_set_mif_enable(vpp_flag_t enable);
+EXTERN void sclr_set_mif2_enable(vpp_flag_t enable);
+EXTERN void sclr_set_colorbar(vpp_flag_t enable, int width, int inverse);
+EXTERN void sclr_set_display_format(vpp_display_format_t source,
+ vpp_display_format_t target);
+EXTERN void sclr_set_field_mode(vpp_display_format_t fmt);
+EXTERN void sclr_set_color_format(vdo_color_fmt format);
+EXTERN vdo_color_fmt sclr_get_color_format(void);
+EXTERN void sclr_set_media_format(vpp_media_format_t format);
+EXTERN void sclr_set_fb_addr(U32 y_addr, U32 c_addr);
+EXTERN void sclr_get_fb_addr(U32 *y_addr, U32 *c_addr);
+EXTERN void sclr_set_width(U32 y_pixel, U32 y_buffer);
+EXTERN void sclr_get_width(U32 *p_y_pixel, U32 *p_y_buffer);
+EXTERN void sclr_set_crop(U32 h_crop, U32 v_crop);
+EXTERN void sclr_set_threshold(U32 value);
+EXTERN vdo_color_fmt scl_R2_get_color_format(void);
+EXTERN void sclw_set_mif_enable(vpp_flag_t enable);
+EXTERN void sclw_set_color_format(vdo_color_fmt format);
+EXTERN vdo_color_fmt sclw_get_color_format(void);
+EXTERN void sclw_set_field_mode(vpp_display_format_t fmt);
+EXTERN void sclw_set_fb_addr(U32 y_addr, U32 c_addr);
+EXTERN void sclw_get_fb_addr(U32 *y_addr, U32 *c_addr);
+EXTERN void sclw_set_fb_width(U32 y_pixel, U32 y_buffer);
+EXTERN void sclw_get_fb_width(U32 *width, U32 *buf_width);
+EXTERN void scl_set_scale(unsigned int SRC_W, unsigned int SRC_H,
+ unsigned int DST_W, unsigned int DST_H);
+EXTERN int scl_mod_init(void);
+EXTERN void scl_set_deblock_enable(int enable);
+EXTERN void scl_set_field_filter_enable(int enable);
+EXTERN void scl_set_frame_filter_enable(int enable);
+EXTERN int scl_set_scale_overlap(vdo_framebuf_t *s,
+ vdo_framebuf_t *in, vdo_framebuf_t *out);
+EXTERN void scl_set_overlap(vpp_overlap_t *p);
+EXTERN int scl_mod_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* WMT_FTBLK_SCL */
+#undef EXTERN
+#endif /* SCL_H */
diff --git a/common/wmt_display/sw_i2c.c b/common/wmt_display/sw_i2c.c
new file mode 100755
index 0000000..79acd96
--- /dev/null
+++ b/common/wmt_display/sw_i2c.c
@@ -0,0 +1,436 @@
+/*++
+ * linux/drivers/video/wmt/sw_i2c.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#include "vpp-osif.h"
+#include "sw_i2c.h"
+
+#define SPEED 50 /* 5000000 */
+
+#define delay_time 30
+
+struct swi2c_reg_bk_t {
+ unsigned int gpio_en;
+ unsigned int out_en;
+ unsigned int data_out;
+ unsigned int pull_en;
+};
+
+#ifdef __KERNEL__
+static DEFINE_SPINLOCK(swi2c_irqlock);
+unsigned long swi2c_irqlock_flags;
+#endif
+void wmt_swi2c_lock(int lock)
+{
+#ifdef __KERNEL__
+ if (lock)
+ spin_lock_irqsave(&swi2c_irqlock, swi2c_irqlock_flags);
+ else
+ spin_unlock_irqrestore(&swi2c_irqlock, swi2c_irqlock_flags);
+#endif
+}
+
+struct swi2c_reg_s *swi2c_scl, *swi2c_sda;
+
+void wmt_swi2c_delay(unsigned int time)
+{
+ udelay(time);
+}
+
+void wmt_swi2c_SetSDAInput(void)
+{
+ outw(inw(swi2c_sda->gpio_en) | swi2c_sda->bit_mask, swi2c_sda->gpio_en);
+ outw(inw(swi2c_sda->out_en) & ~swi2c_sda->bit_mask, swi2c_sda->out_en);
+}
+
+
+void wmt_swi2c_SetSDAOutput(void)
+{
+ outw(inw(swi2c_sda->gpio_en) | swi2c_sda->bit_mask, swi2c_sda->gpio_en);
+ outw(inw(swi2c_sda->out_en) | swi2c_sda->bit_mask, swi2c_sda->out_en);
+}
+
+bool wmt_swi2c_GetSDA(void) /* bit */
+{
+ if (inw(swi2c_sda->data_in) & swi2c_sda->bit_mask)
+#ifdef CFG_LOADER
+ return 1;
+ return 0;
+#else
+ return (HW_REG bool) 1;
+ return (HW_REG bool) 0;
+#endif
+}
+
+bool wmt_swi2c_GetSCL(void) /* bit */
+{
+ if (inw(swi2c_scl->data_in) & swi2c_scl->bit_mask)
+#ifdef CFG_LOADER
+ return 1;
+ return 0;
+#else
+ return (HW_REG bool) 1;
+ return (HW_REG bool) 0;
+#endif
+}
+
+void wmt_swi2c_SetSDA(int high)
+{
+ if (high) {
+ /* set to GPI and pull high */
+ outw(inw(swi2c_sda->gpio_en) | swi2c_sda->bit_mask,
+ swi2c_sda->gpio_en);
+ outw(inw(swi2c_sda->out_en) & ~swi2c_sda->bit_mask,
+ swi2c_sda->out_en);
+ if (swi2c_sda->pull_en)
+ outw(inw(swi2c_sda->pull_en) &
+ ~swi2c_sda->pull_en_bit_mask,
+ swi2c_sda->pull_en);
+ } else {
+ outw(inw(swi2c_sda->gpio_en) | swi2c_sda->bit_mask,
+ swi2c_sda->gpio_en);
+ outw(inw(swi2c_sda->out_en) | swi2c_sda->bit_mask,
+ swi2c_sda->out_en);
+ outw(inw(swi2c_sda->data_out) & ~swi2c_sda->bit_mask,
+ swi2c_sda->data_out);
+ }
+}
+
+void wmt_swi2c_SetSCL(int high)
+{
+ if (high) {
+ outw(inw(swi2c_scl->gpio_en) | swi2c_scl->bit_mask,
+ swi2c_scl->gpio_en);
+ outw(inw(swi2c_scl->out_en) & ~swi2c_scl->bit_mask,
+ swi2c_scl->out_en);
+ if (swi2c_scl->pull_en)
+ outw(inw(swi2c_scl->pull_en) &
+ ~swi2c_scl->pull_en_bit_mask,
+ swi2c_scl->pull_en);
+ } else {
+ outw(inw(swi2c_scl->gpio_en) | swi2c_scl->bit_mask,
+ swi2c_scl->gpio_en);
+ outw(inw(swi2c_scl->out_en) | swi2c_scl->bit_mask,
+ swi2c_scl->out_en);
+ outw(inw(swi2c_scl->data_out) & ~swi2c_scl->bit_mask,
+ swi2c_scl->data_out);
+ }
+}
+
+int wmt_swi2c_SetData(int high)
+{
+ unsigned int wait = 1;
+
+ wmt_swi2c_SetSDA(high);
+ do {
+ if (wmt_swi2c_GetSDA() == ((high) ? 1 : 0))
+ return 0;
+ } while (wait++ < SPEED);
+ return 1;
+}
+
+int wmt_swi2c_SetClock(int high)
+{
+ unsigned int wait = 1;
+
+ udelay(5); /* 3-100kHz, 5-80kHz */
+
+ wmt_swi2c_SetSCL(high);
+ do {
+ if (wmt_swi2c_GetSCL() == ((high) ? 1 : 0))
+ return 0;
+ } while (wait++ < SPEED);
+ return 1; /* fail */
+}
+
+int wmt_swi2c_StartI2C(void)
+{
+ if (wmt_swi2c_SetData(1))
+ return 1;
+ if (wmt_swi2c_SetClock(1))
+ return 2;
+ if (wmt_swi2c_SetData(0))
+ return 3;
+ wmt_swi2c_delay(0);
+ if (wmt_swi2c_SetClock(0))
+ return 4;
+ return 0; /* success */
+}
+
+int wmt_swi2c_StopI2C(void)
+{
+ if (wmt_swi2c_SetData(0))
+ return 1;
+ if (wmt_swi2c_SetClock(0))
+ return 1;
+ if (wmt_swi2c_SetClock(1))
+ return 1;
+ wmt_swi2c_delay(0);
+ if (wmt_swi2c_SetData(1))
+ return 1;
+ return 0; /* success */
+}
+
+int wmt_swi2c_WriteAck(unsigned char byte)
+{
+ int ret;
+ int bit;
+
+ for (bit = 7; bit >= 0; bit--) {
+ wmt_swi2c_SetData(byte & 0x80);
+ byte <<= 1;
+ if (wmt_swi2c_SetClock(1))
+ return 1;
+ if (wmt_swi2c_SetClock(0))
+ return 1;
+ }
+ ret = 0;
+ wmt_swi2c_SetSDAInput();
+ if (wmt_swi2c_SetClock(1))
+ ret = 1;
+ else if (wmt_swi2c_GetSDA())
+ ret = (wmt_swi2c_SetClock(0)) ? 1 : 0;
+ else if (wmt_swi2c_SetClock(0))
+ ret = 1;
+ wmt_swi2c_SetSDAOutput();
+ return ret;
+}
+
+int wmt_swi2c_ReadAck(unsigned char *byte, int last)
+{
+ unsigned char i;
+ unsigned char Data = 0;
+
+ wmt_swi2c_SetSDAInput();
+
+ for (i = 0; i < 8; i++) {
+ if (wmt_swi2c_SetClock(1)) {
+ wmt_swi2c_SetSDAOutput();
+ return 1;
+ }
+ Data <<= 1;
+ wmt_swi2c_delay(0);
+ Data |= wmt_swi2c_GetSDA();
+ if (wmt_swi2c_SetClock(0)) {
+ wmt_swi2c_SetSDAOutput();
+ return 1;
+ }
+ }
+
+ *byte = Data;
+ wmt_swi2c_SetSDAOutput();
+
+ wmt_swi2c_delay(0);
+ if (wmt_swi2c_SetData((last) ? 1 : 0))
+ return 1;
+ if (wmt_swi2c_SetClock(1))
+ return 1;
+ wmt_swi2c_delay(0);
+ if (wmt_swi2c_SetClock(0))
+ return 1;
+ wmt_swi2c_delay(0);
+ return 0;
+}
+
+int wmt_swi2c_tx(
+ char addr,
+ char *buf,
+ int cnt,
+ int *ret_cnt
+)
+{
+ int ret = 0;
+ unsigned char i;
+
+ wmt_swi2c_lock(1);
+
+ ret |= wmt_swi2c_StartI2C();
+ if (ret)
+ goto tx_end;
+ ret |= wmt_swi2c_WriteAck(addr);
+ if (ret)
+ goto tx_end;
+ for (i = 0; i < cnt; i++) {
+ ret |= wmt_swi2c_WriteAck(buf[i]);
+ if (ret)
+ goto tx_end;
+ }
+ ret |= wmt_swi2c_StopI2C();
+tx_end:
+ wmt_swi2c_lock(0);
+ return ret;
+}
+
+int wmt_swi2c_rx(
+ char addr,
+ char *buf,
+ int cnt,
+ int *ret_cnt
+)
+{
+ int ret = 0;
+ int i;
+
+ wmt_swi2c_lock(1);
+
+ ret |= wmt_swi2c_StartI2C();
+ if (ret)
+ goto rx_end;
+ ret |= wmt_swi2c_WriteAck(addr | 0x01);
+ if (ret)
+ goto rx_end;
+ for (i = 0; i < cnt; i++) {
+ ret |= wmt_swi2c_ReadAck((unsigned char *)&buf[i],
+ (i == (cnt - 1)));
+ if (ret)
+ goto rx_end;
+ }
+ ret |= wmt_swi2c_StopI2C();
+rx_end:
+ wmt_swi2c_lock(0);
+ return ret;
+}
+
+void wmt_swi2c_reg_bk(struct swi2c_reg_s *reg_p,
+ struct swi2c_reg_bk_t *reg_bk, int bk)
+{
+ if (bk) {
+ reg_bk->gpio_en = inw(reg_p->gpio_en);
+ reg_bk->out_en = inw(reg_p->out_en);
+ reg_bk->data_out = inw(reg_p->data_out);
+ reg_bk->pull_en = inw(reg_p->pull_en);
+ } else {
+ outw(reg_bk->gpio_en, reg_p->gpio_en);
+ outw(reg_bk->out_en, reg_p->out_en);
+ outw(reg_bk->data_out, reg_p->data_out);
+ outw(reg_bk->pull_en, reg_p->pull_en);
+ }
+}
+
+int wmt_swi2c_read(
+ struct swi2c_handle_s *handle,
+ char addr,
+ char index,
+ char *buf,
+ int cnt
+)
+{
+ int ret = 0;
+ char buffer[24];
+ int temp = 0;
+ struct swi2c_reg_bk_t scl_bk, sda_bk;
+
+ swi2c_scl = handle->scl_reg;
+ swi2c_sda = handle->sda_reg;
+
+ wmt_swi2c_reg_bk(swi2c_scl, &scl_bk, 1);
+ wmt_swi2c_reg_bk(swi2c_sda, &sda_bk, 1);
+
+ buffer[0] = index;
+ ret = wmt_swi2c_tx(addr, buffer, 1, &temp);
+ if (ret) {
+ DPRINT("[SWI2C] *E* tx fail\n");
+ goto exit;
+ }
+ ret = wmt_swi2c_rx(addr, buf, cnt, &temp);
+ if (ret) {
+ DPRINT("[SWI2C] *E* rx fail\n");
+ goto exit;
+ }
+exit:
+ wmt_swi2c_reg_bk(swi2c_scl, &scl_bk, 0);
+ wmt_swi2c_reg_bk(swi2c_sda, &sda_bk, 0);
+ return ret;
+}
+EXPORT_SYMBOL(wmt_swi2c_read);
+
+int wmt_swi2c_write(
+ struct swi2c_handle_s *handle,
+ char addr,
+ char index,
+ char *buf,
+ int cnt
+)
+{
+ int ret = 0;
+ char buffer[24];
+ int temp;
+ struct swi2c_reg_bk_t scl_bk, sda_bk;
+
+ swi2c_scl = handle->scl_reg;
+ swi2c_sda = handle->sda_reg;
+
+ wmt_swi2c_reg_bk(swi2c_scl, &scl_bk, 1);
+ wmt_swi2c_reg_bk(swi2c_sda, &sda_bk, 1);
+
+ buffer[0] = index;
+ buffer[1] = *buf;
+ ret = wmt_swi2c_tx(addr, buffer, cnt, &temp);
+ if (ret) {
+ DPRINT("[SWI2C] *E* tx fail\n");
+ goto exit;
+ }
+exit:
+ wmt_swi2c_reg_bk(swi2c_scl, &scl_bk, 0);
+ wmt_swi2c_reg_bk(swi2c_sda, &sda_bk, 0);
+ return ret;
+}
+EXPORT_SYMBOL(wmt_swi2c_write);
+
+int wmt_swi2c_check(struct swi2c_handle_s *handle)
+{
+ int ret = 0;
+#if 0
+ struct swi2c_reg_s *reg_p;
+ struct swi2c_reg_bk_t scl_bk, sda_bk;
+
+ swi2c_scl = handle->scl_reg;
+ swi2c_sda = handle->sda_reg;
+
+ wmt_swi2c_reg_bk(swi2c_scl, &scl_bk, 1);
+ wmt_swi2c_reg_bk(swi2c_sda, &sda_bk, 1);
+ reg_p = handle->scl_reg;
+ do {
+ outw(inw(reg_p->gpio_en) | reg_p->bit_mask, reg_p->gpio_en);
+ outw(inw(reg_p->out_en) | reg_p->bit_mask, reg_p->out_en);
+ outw(inw(reg_p->data_out) & ~reg_p->bit_mask, reg_p->data_out);
+
+ outw(inw(reg_p->out_en) & ~reg_p->bit_mask, reg_p->out_en);
+ if (reg_p->pull_en)
+ outw(inw(reg_p->pull_en) & ~reg_p->pull_en_bit_mask,
+ reg_p->pull_en);
+ if (inw(reg_p->data_in) & reg_p->bit_mask) {
+ if (reg_p == handle->sda_reg)
+ break;
+ reg_p = handle->sda_reg;
+ } else {
+ ret = 1;
+ break;
+ }
+ } while (1);
+ wmt_swi2c_reg_bk(swi2c_scl, &scl_bk, 0);
+ wmt_swi2c_reg_bk(swi2c_sda, &sda_bk, 0);
+ DPRINT("[SWI2C] %s exist\n", (ret) ? "not" : "");
+#endif
+ return ret;
+}
+EXPORT_SYMBOL(wmt_swi2c_check);
diff --git a/common/wmt_display/sw_i2c.h b/common/wmt_display/sw_i2c.h
new file mode 100755
index 0000000..593fd08
--- /dev/null
+++ b/common/wmt_display/sw_i2c.h
@@ -0,0 +1,63 @@
+/*++
+ * linux/drivers/video/wmt/sw_i2c.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef _SWI2C_H_
+#define _SWI2C_H_
+
+struct swi2c_reg_s {
+ unsigned int bit_mask;
+ unsigned int gpio_en;
+ unsigned int out_en;
+ unsigned int data_in;
+ unsigned int data_out;
+ unsigned int pull_en_bit_mask;
+ unsigned int pull_en;
+};
+#define swi2c_reg_t struct swi2c_reg_s
+
+struct swi2c_handle_s {
+ struct swi2c_reg_s *scl_reg;
+ struct swi2c_reg_s *sda_reg;
+};
+#define swi2c_handle_t struct swi2c_handle_s
+
+int wmt_swi2c_read(
+ struct swi2c_handle_s *handle,
+ char addr,
+ char index,
+ char *buf,
+ int cnt
+);
+
+int wmt_swi2c_write(
+ struct swi2c_handle_s *handle,
+ char addr,
+ char index,
+ char *buf,
+ int cnt
+);
+
+int wmt_swi2c_check(struct swi2c_handle_s *handle);
+
+#endif
+
diff --git a/common/wmt_display/uboot-vpp.c b/common/wmt_display/uboot-vpp.c
new file mode 100755
index 0000000..7343cae
--- /dev/null
+++ b/common/wmt_display/uboot-vpp.c
@@ -0,0 +1,298 @@
+/*++
+ * common/wmt_display/uboot-vpp.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <version.h>
+#include <stdarg.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <linux/stddef.h>
+#include <asm/byteorder.h>
+
+#define DEBUG
+
+#include "vpp.h"
+#include "vout.h"
+#include "minivgui.h"
+
+#define WMT_DISPLAY
+
+#include "../../board/wmt/include/wmt_clk.h"
+
+#include "hw_devices.h"
+#include "wmt_display.h"
+#include "vout.h"
+
+struct wmt_display_param_t g_display_param;
+struct wmt_display_param_t g_display_param2;
+struct wmt_pwm_setting_t g_pwm_setting;
+struct gpio_operation_t g_lcd_pw_pin;
+
+#ifdef CONFIG_VPP_SHENZHEN
+struct wmt_backlight_param_t g_backlight_param;
+#endif
+
+int g_display_vaild;
+unsigned int g_fb_phy;
+unsigned int g_img_phy;
+int g_logo_x;
+int g_logo_y;
+logo_scale_t g_logo_scale = LOGO_NOT_SCALE;
+
+char *video_str[] = {
+ "SDA", "SDD" , "LCD", "DVI" , "HDMI", "DVO2HDMI", "LVDS", "VGA"
+};
+
+extern int vo_dvi_initial(void);
+extern int vo_hdmi_initial(void);
+extern int vo_lvds_initial(void);
+extern int vo_virtual_initial(void);
+extern int vt1632_module_init(void);
+extern int sil902x_module_init(void);
+extern void vpp_init(void);
+extern struct vout_dev_t *lcd_get_dev(void);
+extern void vpp_config(struct vout_info_t *info);
+
+static unsigned int alignmentMemory(unsigned int memtotal)
+{
+ unsigned int memmax = 2;
+
+ while (memtotal > memmax) {
+ memmax *= 2;
+ }
+ return memmax;
+}
+
+static unsigned int wmt_get_fb(unsigned int memtotal, unsigned int mbsize)
+{
+ unsigned int addr;
+
+ addr = alignmentMemory(memtotal);
+ addr <<= 20;
+ addr -= 1920 * 1200 * 4; /* avoid kernel change resolution */
+ addr -= 1280; /* avoid govr prefetch 1280 byte over memory boundary */
+ return addr;
+}
+
+static int wmt_init_check(void)
+{
+ char *tmp;
+
+ check_tf_boot();
+ check_display_direction(); //added by howayhuo
+
+ g_fb_phy = 0;
+ if ((tmp = getenv (ENV_DIRECTFB)) != NULL)
+ g_fb_phy = (unsigned int)simple_strtoul(tmp, NULL, 16);
+
+ if (g_fb_phy == 0) {
+ unsigned int memtotal;
+ unsigned int mbsize;
+
+ /* we must check "memtotal" because we get framebuf from it */
+ if ((tmp = getenv (ENV_MEMTOTAL)) != NULL) {
+ memtotal = (unsigned int)simple_strtoul(tmp, NULL, 10);
+ } else {
+ printf("err:need %s to cal fb addr\n", ENV_MEMTOTAL);
+ return -1;
+ }
+
+ if ((tmp = getenv ("mbsize")) != NULL) {
+ mbsize = (unsigned int)simple_strtoul (tmp, NULL, 10);
+ } else {
+ printf("err:need %s to cal fb addr\n", "mbsize");
+ return -1;
+ }
+ g_fb_phy = wmt_get_fb(memtotal, mbsize);
+ }
+
+ if ((tmp = getenv (ENV_IMGADDR)) != NULL)
+ g_img_phy = (unsigned int)simple_strtoul (tmp, NULL, 16);
+ else {
+ printf("%s is not found,(display show) invaild\n", ENV_IMGADDR);
+ g_img_phy = 0xFFFF;
+ }
+ return 0;
+}
+
+#if 0
+int uboot_vpp_alloc_framebuffer(unsigned int resx, unsigned int resy)
+{
+ return 0;
+}
+#endif
+
+void vpp_mod_init(void)
+{
+#ifdef WMT_FTBLK_GOVRH
+ govrh_mod_init();
+#endif
+#ifdef WMT_FTBLK_SCL
+ scl_mod_init();
+#endif
+ /* register vout interface */
+ vo_dvi_initial();
+ vo_hdmi_initial();
+ vo_lvds_initial();
+}
+
+void vpp_device_init(void)
+{
+ auto_pll_divisor(DEV_PWM,CLK_ENABLE, 0, 0);
+ lcd_module_init();
+ lcd_oem_init();
+ lcd_lw700at9003_init();
+ lcd_at070tn83_init();
+ lcd_a080sn01_init();
+ lcd_ek08009_init();
+ lcd_HSD101PFW2_init();
+ lcd_LVDS_1024x600_init();
+
+ vt1632_module_init();
+ vt1625_module_init();
+ sil902x_module_init();
+}
+
+int wmt_graphic_init(void)
+{
+ struct vout_info_t *info;
+ int i;
+ int y_bpp, c_bpp;
+ struct vout_t *vo;
+
+ if (wmt_init_check())
+ return -1;
+
+ vpp_mod_init();
+ vpp_device_init();
+ vpp_init();
+ for (i = 0; i < VPP_VOUT_INFO_NUM; i++) {
+ struct fb_videomode vmode;
+ vdo_framebuf_t *fb;
+ unsigned int pixel_size, line_size;
+ mv_surface s;
+
+ info = vout_info[i];
+ if (!info)
+ break;
+
+ memset(&vmode, 0, sizeof(struct fb_videomode));
+ vmode.xres = info->resx;
+ vmode.yres = info->resy;
+ vmode.refresh = info->fps;
+ vmode.vmode = (info->option & VPP_OPT_INTERLACE) ?
+ FB_VMODE_INTERLACED : 0;
+ vout_find_match_mode(i, &vmode, 1);
+#if 0
+ printf("fb %d\n", i);
+ vpp_show_videomode("uboot", &vmode);
+#endif
+ info->resx = vmode.xres;
+ info->resy = vmode.yres;
+
+ /* get framebuffer parameter */
+ fb = &info->fb;
+ fb->col_fmt = g_vpp.mb_colfmt;
+ fb->img_w = info->resx;
+ fb->img_h = info->resy;
+ fb->fb_w = vpp_calc_fb_width(fb->col_fmt, info->resx);
+ fb->fb_h = info->resy;
+
+ info->resx_virtual = fb->fb_w;
+ info->resy_virtual = fb->fb_h;
+ vpp_get_colfmt_bpp(fb->col_fmt, &y_bpp, &c_bpp);
+ pixel_size = y_bpp / 8;
+ line_size = fb->fb_w * pixel_size;
+ g_fb_phy -= (fb->fb_h * line_size);
+ fb->y_addr = g_fb_phy;
+ fb->c_addr = 0;
+ /* init surface */
+ s.width = fb->img_w;
+ s.height = fb->img_h;
+ s.startAddr = (char *) fb->y_addr;
+ s.bits_per_pixel = pixel_size * 8;
+ s.lineBytes = line_size;
+ mv_initSurface(i,&s);
+
+ /* clear frame buffer */
+ memset((void *)fb->y_addr, 0, fb->fb_h * line_size);
+ vout_config(info, &vmode, &info->fb);
+#if 0
+ DBG_MSG("[UBOOT] fb%d(%dx%d)\n", i, vmode.xres, vmode.yres);
+ vpp_show_framebuf("uboot", fb);
+#endif
+ }
+
+ /* enable vout */
+ for (i = 0; i < VPP_VOUT_NUM; i++) {
+ int blank;
+
+ vo = vout_get_entry(i);
+ if (!vo)
+ continue;
+ blank = (vo->status & VPP_VOUT_STS_ACTIVE) ?
+ VOUT_BLANK_UNBLANK : VOUT_BLANK_POWERDOWN;
+ blank = (vo->status & VPP_VOUT_STS_BLANK) ?
+ VOUT_BLANK_NORMAL : blank;
+ vout_set_blank(i, blank);
+ }
+
+ /* set pwm for LCD backlight */
+ g_display_param.vout = VPP_VOUT_DVI;
+ if ( lcd_get_dev() || (lcd_get_lvds_id() != LCD_PANEL_MAX))
+ g_display_param.vout = VPP_VOUT_LCD;
+
+ if (g_display_param.vout == VPP_VOUT_LCD) {
+ parse_pwm_params(ENV_DISPLAY_PWM, NULL);
+ parse_gpio_operation(ENV_LCD_POWER);
+ if ((g_display_vaild&PWMDEFMASK) == PWMDEFTP)
+ lcd_blt_set_pwm(g_pwm_setting.pwm_no,
+ g_pwm_setting.duty, g_pwm_setting.period);
+ else {
+ /* fan : may need to check PWM power .. */
+ pwm_set_period(g_pwm_setting.pwm_no,
+ g_pwm_setting.period - 1);
+ pwm_set_duty(g_pwm_setting.pwm_no,
+ g_pwm_setting.duty - 1);
+ pwm_set_control(g_pwm_setting.pwm_no,
+ (g_pwm_setting.duty - 1) ? 0x34 : 0x8);
+ pwm_set_gpio(g_pwm_setting.pwm_no,
+ g_pwm_setting.duty - 1);
+ pwm_set_scalar(g_pwm_setting.pwm_no,
+ g_pwm_setting.scalar - 1);
+ }
+ lcd_set_enable(1);
+ }
+#if 0
+ p_govrh->dump_reg();
+ p_govrh2->dump_reg();
+// hdmi_reg_dump();
+// lvds_reg_dump();
+#endif
+ g_display_vaild |= DISPLAY_ENABLE;
+ return 0;
+}
+#undef WMT_DISPLAY
+
diff --git a/common/wmt_display/vout-wmt.c b/common/wmt_display/vout-wmt.c
new file mode 100755
index 0000000..2e2c71f
--- /dev/null
+++ b/common/wmt_display/vout-wmt.c
@@ -0,0 +1,1344 @@
+/*++
+ * linux/drivers/video/wmt/vout-wmt.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+#undef DEBUG
+/* #define DEBUG */
+/* #define DEBUG_DETAIL */
+
+#include "vpp.h"
+
+#ifndef CFG_LOADER
+static int vo_plug_flag;
+#endif
+int vo_plug_vout;
+int (*vo_plug_func)(int hotplug);
+enum vout_mode_t dvo_vout_mode;
+enum vout_mode_t int_vout_mode;
+int hdmi_cur_plugin;
+struct vout_t *vo_poll_vout;
+
+/* GPIO 10 & 11 */
+struct swi2c_reg_s vo_gpio_scl = {
+ .bit_mask = BIT10,
+ .gpio_en = (__GPIO_BASE + 0x40),
+ .out_en = (__GPIO_BASE + 0x80),
+ .data_in = (__GPIO_BASE + 0x00),
+ .data_out = (__GPIO_BASE + 0xC0),
+ .pull_en = (__GPIO_BASE + 0x480),
+ .pull_en_bit_mask = BIT10,
+};
+
+struct swi2c_reg_s vo_gpio_sda = {
+ .bit_mask = BIT11,
+ .gpio_en = (__GPIO_BASE + 0x40),
+ .out_en = (__GPIO_BASE + 0x80),
+ .data_in = (__GPIO_BASE + 0x00),
+ .data_out = (__GPIO_BASE + 0xC0),
+ .pull_en = (__GPIO_BASE + 0x480),
+ .pull_en_bit_mask = BIT11,
+};
+
+struct swi2c_handle_s vo_swi2c_dvi = {
+ .scl_reg = &vo_gpio_scl,
+ .sda_reg = &vo_gpio_sda,
+};
+
+#define DVI_POLL_TIME_MS 1000
+
+extern void hdmi_config_audio(struct vout_audio_t *info);
+
+/*---------------------------------- API ------------------------------------*/
+#ifdef DEBUG
+void vout_print_entry(struct vout_t *vo)
+{
+ if (vo == 0)
+ return;
+
+ MSG(" =============== vout %d ===============\n", vo->num);
+ MSG("fix 0x%x", vo->fix_cap);
+ MSG("(inf %d,bus %d,govr %d,ext dev %d,fix plug %d,aud %d,edid %d)\n",
+ (vo->fix_cap & VOUT_CAP_INTERFACE),
+ (vo->fix_cap & VOUT_CAP_BUS) >> 8,
+ (vo->fix_cap & VOUT_CAP_GOVR) >> 12,
+ (vo->fix_cap & VOUT_CAP_EXT_DEV) ? 1 : 0,
+ (vo->fix_cap & VOUT_CAP_FIX_PLUG) ? 1 : 0,
+ (vo->fix_cap & VOUT_CAP_AUDIO) ? 1 : 0,
+ (vo->fix_cap & VOUT_CAP_EDID) ? 1 : 0);
+ MSG("info %d,%s\n", vo->info->num, vpp_mod_str[vo->govr->mod]);
+ MSG("inf 0x%x,dev 0x%x\n", (int)vo->inf, (int)vo->dev);
+ MSG("resx %d,resy %d,fps %d\n", vo->resx, vo->resy, vo->fps);
+ MSG("pixclk %d,option %d,%d,%d,disable %d\n", vo->pixclk,
+ vo->option[0], vo->option[1], vo->option[2], vo->disable);
+ MSG("sts(reg %d,act %d,plug %d,edid %d,blank %d,pwrdn %d,cp %d)\n",
+ (vo->status & VPP_VOUT_STS_REGISTER) ? 1 : 0,
+ (vo->status & VPP_VOUT_STS_ACTIVE) ? 1 : 0,
+ (vo->status & VPP_VOUT_STS_PLUGIN) ? 1 : 0,
+ (vo->status & VPP_VOUT_STS_EDID) ? 1 : 0,
+ (vo->status & VPP_VOUT_STS_BLANK) ? 1 : 0,
+ (vo->status & VPP_VOUT_STS_POWERDN) ? 1 : 0,
+ (vo->status & VPP_VOUT_STS_CONTENT_PROTECT) ? 1 : 0);
+
+ if (vo->inf) {
+ MSG(" ===== inf entry =====\n");
+ MSG("mode %d, %s\n",
+ vo->inf->mode, vout_inf_str[vo->inf->mode]);
+ }
+
+ if (vo->dev) {
+ MSG(" ===== dev entry =====\n");
+ MSG("name %s,inf %d,%s\n", vo->dev->name,
+ vo->dev->mode, vout_inf_str[vo->dev->mode]);
+ MSG("vout 0x%x,capability 0x%x\n",
+ (int)vo->dev->vout, vo->dev->capability);
+ }
+}
+#endif
+
+int vo_i2c_proc(int id, unsigned int addr, unsigned int index,
+ char *pdata, int len)
+{
+ struct swi2c_handle_s *handle = 0;
+ int ret = 0;
+
+ switch (id) {
+ case 1: /* dvi */
+ if (lcd_get_type()) /* share pin with LVDS */
+ return -1;
+ handle = &vo_swi2c_dvi;
+ break;
+ default:
+ break;
+ }
+
+ if (handle) {
+ if (wmt_swi2c_check(handle))
+ return -1;
+ if (addr & 0x1) { /* read */
+ *pdata = 0xff;
+#ifdef CONFIG_WMT_EDID
+ ret = wmt_swi2c_read(handle, addr & ~0x1,
+ index, pdata, len);
+#else
+ ret = -1;
+#endif
+ } else { /* write */
+ DBG_ERR("not support sw i2c write\n");
+ }
+ }
+ return ret;
+}
+
+#ifndef CONFIG_UBOOT
+static void vo_do_plug(struct work_struct *ptr)
+{
+ struct vout_t *vo;
+ int plugin;
+
+ if (vo_plug_func == 0)
+ return;
+
+ vo = vout_get_entry(vo_plug_vout);
+ govrh_set_dvo_enable(vo->govr, 1);
+ plugin = vo_plug_func(1);
+/* govrh_set_dvo_enable(vo->govr, plugin); */
+ vout_change_status(vo, VPP_VOUT_STS_PLUGIN, plugin);
+ vo_plug_flag = 0;
+ DBG_DETAIL("vo_do_plug %d\n", plugin);
+ /* GPIO irq enable */
+ vppif_reg32_write(GPIO_BASE_ADDR + 0x300 + VPP_VOINT_NO, 0x80, 7, 1);
+ /* GPIO input mode */
+ vppif_reg32_write(GPIO_BASE_ADDR + 0x80, 0x1 << VPP_VOINT_NO,
+ VPP_VOINT_NO, 0x0);
+#ifdef __KERNEL__
+ vpp_netlink_notify_plug(VPP_VOUT_NUM_DVI, plugin);
+#endif
+ return;
+}
+
+DECLARE_DELAYED_WORK(vo_plug_work, vo_do_plug);
+
+static irqreturn_t vo_plug_interrupt_routine
+(
+ int irq, /*!<; // irq id */
+ void *dev_id /*!<; // device id */
+)
+{
+ DBG_DETAIL("Enter\n");
+ if ((inb(GPIO_BASE_ADDR + 0x360) &
+ (0x1 << VPP_VOINT_NO)) == 0)
+ return IRQ_NONE;
+
+ /* clear int status */
+ outb(0x1 << VPP_VOINT_NO, GPIO_BASE_ADDR + 0x360);
+#ifdef __KERNEL__
+ /* if (vo_plug_flag == 0) { */
+ /* GPIO irq disable */
+ vppif_reg32_write(GPIO_BASE_ADDR + 0x300 + VPP_VOINT_NO, 0x80, 7, 0);
+ schedule_delayed_work(&vo_plug_work, HZ/5);
+ vo_plug_flag = 1;
+ /* } */
+#else
+ if (vo_plug_func)
+ vo_do_plug(0);
+#endif
+ return IRQ_HANDLED;
+}
+
+#define CONFIG_VO_POLL_WORKQUEUE
+struct timer_list vo_poll_timer;
+#ifdef CONFIG_VO_POLL_WORKQUEUE
+static void vo_do_poll(struct work_struct *ptr)
+{
+ struct vout_t *vo;
+
+ vo = vo_poll_vout;
+ if (vo) {
+ if (vo->dev)
+ vo->dev->poll();
+ mod_timer(&vo_poll_timer,
+ jiffies + msecs_to_jiffies(vo_poll_timer.data));
+ }
+ return;
+}
+
+DECLARE_DELAYED_WORK(vo_poll_work, vo_do_poll);
+#else
+struct tasklet_struct vo_poll_tasklet;
+static void vo_do_poll_tasklet
+(
+ unsigned long data /*!<; // tasklet input data */
+)
+{
+ struct vout_t *vo;
+
+ vpp_lock();
+ vo = vo_poll_vout;
+ if (vo) {
+ if (vo->dev)
+ vo->dev->poll();
+ mod_timer(&vo_poll_timer,
+ jiffies + msecs_to_jiffies(vo_poll_timer.data));
+ }
+ vpp_unlock();
+}
+#endif
+
+void vo_do_poll_tmr(int ms)
+{
+#ifdef CONFIG_VO_POLL_WORKQUEUE
+ schedule_delayed_work(&vo_poll_work, msecs_to_jiffies(ms));
+#else
+ tasklet_schedule(&vo_poll_tasklet);
+#endif
+}
+
+static void vo_set_poll(struct vout_t *vo, int on, int ms)
+{
+ DMSG("%d\n", on);
+
+ if (on) {
+ vo_poll_vout = vo;
+ if (vo_poll_timer.function) {
+ vo_poll_timer.data = ms / 2;
+ mod_timer(&vo_poll_timer,
+ jiffies + msecs_to_jiffies(vo_poll_timer.data));
+ } else {
+ init_timer(&vo_poll_timer);
+ vo_poll_timer.data = ms / 2;
+ vo_poll_timer.function = (void *) vo_do_poll_tmr;
+ vo_poll_timer.expires = jiffies +
+ msecs_to_jiffies(vo_poll_timer.data);
+ add_timer(&vo_poll_timer);
+ }
+#ifndef CONFIG_VO_POLL_WORKQUEUE
+ tasklet_init(&vo_poll_tasklet, vo_do_poll_tasklet, 0);
+#endif
+ } else {
+ del_timer(&vo_poll_timer);
+#ifndef CONFIG_VO_POLL_WORKQUEUE
+ tasklet_kill(&vo_poll_tasklet);
+#endif
+ vo_poll_vout = 0;
+ }
+}
+#endif
+
+void vout_set_int_type(int type)
+{
+ unsigned char reg;
+
+ reg = inb(GPIO_BASE_ADDR + 0x300 + VPP_VOINT_NO);
+ reg &= ~0x7;
+ switch (type) {
+ case 0: /* low level */
+ case 1: /* high level */
+ case 2: /* falling edge */
+ case 3: /* rising edge */
+ case 4: /* rising edge or falling */
+ reg |= type;
+ break;
+ default:
+ break;
+ }
+ outb(reg, GPIO_BASE_ADDR + 0x300 + VPP_VOINT_NO);
+}
+EXPORT_SYMBOL(vout_set_int_type);
+
+void vout_set_int_enable(int enable)
+{
+ vppif_reg32_write(GPIO_BASE_ADDR + 0x300 +
+ VPP_VOINT_NO, 0x80, 7, enable); /* GPIO irq enable/disable */
+}
+EXPORT_SYMBOL(vout_set_int_enable);
+
+int vout_get_clr_int(void)
+{
+ if ((inb(GPIO_BASE_ADDR + 0x360) &
+ (0x1 << VPP_VOINT_NO)) == 0)
+ return 1;
+ /* clear int status */
+ outb(0x1 << VPP_VOINT_NO, GPIO_BASE_ADDR + 0x360);
+ return 0;
+}
+EXPORT_SYMBOL(vout_get_clr_int);
+
+static void vo_plug_enable(int enable, void *func, int no)
+{
+ struct vout_t *vo;
+
+ DBG_DETAIL("%d\n", enable);
+ vo_plug_vout = no;
+ vo = vout_get_entry(no);
+#ifdef CONFIG_WMT_EXT_DEV_PLUG_DISABLE
+ vo_plug_func = 0;
+ govrh_set_dvo_enable(vo->govr, enable);
+#else
+ vo_plug_func = func;
+ if (vo_plug_func == 0)
+ return;
+
+ if (enable) {
+ vppif_reg32_write(GPIO_BASE_ADDR + 0x40, 0x1 << VPP_VOINT_NO,
+ VPP_VOINT_NO, 0x0); /* GPIO disable */
+ vppif_reg32_write(GPIO_BASE_ADDR + 0x80, 0x1 << VPP_VOINT_NO,
+ VPP_VOINT_NO, 0x0); /* GPIO input mode */
+ vppif_reg32_write(GPIO_BASE_ADDR + 0x480, 0x1 << VPP_VOINT_NO,
+ VPP_VOINT_NO, 0x1); /* GPIO pull enable */
+ vppif_reg32_write(GPIO_BASE_ADDR + 0x4c0, 0x1 << VPP_VOINT_NO,
+ VPP_VOINT_NO, 0x1); /* GPIO pull-up */
+#ifndef CONFIG_UBOOT
+ vo_do_plug(0);
+ if (vpp_request_irq(IRQ_GPIO, vo_plug_interrupt_routine,
+ IRQF_SHARED, "vo plug", (void *) &vo_plug_vout))
+ DBG_ERR("request GPIO ISR fail\n");
+
+ vppif_reg32_write(GPIO_BASE_ADDR + 0x300 + VPP_VOINT_NO,
+ 0x80, 7, 1); /* GPIO irq enable */
+ } else {
+ vpp_free_irq(IRQ_GPIO, (void *) &vo_plug_vout);
+#endif
+ }
+#endif
+}
+
+/*--------------------------------- DVI ------------------------------------*/
+#ifdef WMT_FTBLK_VOUT_DVI
+static int vo_dvi_blank(struct vout_t *vo, enum vout_blank_t arg)
+{
+ DMSG("(%d, %d)\n", vo->pre_blank, arg);
+ if(vo->pre_blank == arg)
+ return 0;
+
+ if (vo->pre_blank == VOUT_BLANK_POWERDOWN) {
+ if (vo->dev) {
+#ifdef __KERNEL__
+ if (!g_vpp.dvi_int_disable && vo->dev->interrupt)
+ vo_plug_enable(VPP_FLAG_ENABLE,
+ vo->dev->interrupt, vo->num);
+ else if (vo->dev->poll)
+ vo_set_poll(vo, (vo->dev->poll) ? 1 : 0,
+ DVI_POLL_TIME_MS);
+#endif
+ }
+ }
+#ifdef __KERNEL__
+ if (arg == VOUT_BLANK_POWERDOWN)
+ vo_set_poll(vo, 0, 0);
+#endif
+ if (!lcd_get_dev()) /* enable DVO not contain LCD */
+ govrh_set_dvo_enable(vo->govr,
+ (arg == VOUT_BLANK_UNBLANK) ? 1 : 0);
+ vo->pre_blank = arg;
+ return 0;
+}
+
+static int vo_dvi_config(struct vout_t *vo, int arg)
+{
+ struct vout_info_t *vo_info;
+
+ DBG_DETAIL("Enter\n");
+
+ vo_info = (struct vout_info_t *) arg;
+ govrh_set_dvo_sync_polar(vo->govr,
+ (vo_info->option & VPP_DVO_SYNC_POLAR_HI) ? 0 : 1,
+ (vo_info->option & VPP_DVO_VSYNC_POLAR_HI) ? 0 : 1);
+ return 0;
+}
+
+static int vo_dvi_init(struct vout_t *vo, int arg)
+{
+ unsigned int clk_delay;
+
+ DBG_DETAIL("(%d)\n", arg);
+
+ vo->pre_blank = VOUT_BLANK_POWERDOWN;
+
+ lvds_set_enable(0);
+ govrh_set_dvo_color_format(vo->govr, vo->option[0]);
+ govrh_set_dvo_outdatw(vo->govr, vo->option[1] & WMT_DISP_FB_DVI_24BIT);
+ govrh_IGS_set_mode(vo->govr, 0, WMT_DISP_FB_GET_RGB_MODE(vo->option[1]),
+ (vo->option[1] & WMT_DISP_FB_MSB) ? 1 : 0);
+ govrh_IGS_set_RGB_swap(vo->govr, WMT_DISP_FB_RGB_SWAP(vo->option[1]));
+ clk_delay = (vo->option[1] & WMT_DISP_FB_DVI_24BIT) ?
+ VPP_GOVR_DVO_DELAY_24 : VPP_GOVR_DVO_DELAY_12;
+ govrh_set_dvo_clock_delay(vo->govr, ((clk_delay & BIT14) != 0x0),
+ clk_delay & 0x3FFF);
+ if (vo->dev) {
+ vo->dev->set_mode(&vo->option[0]);
+ vo->dev->set_power_down(VPP_FLAG_DISABLE);
+ if (!g_vpp.dvi_int_disable && vo->dev->interrupt)
+ vo_plug_enable(VPP_FLAG_ENABLE,
+ vo->dev->interrupt, vo->num);
+#ifdef __KERNEL__
+ else if (vo->dev->poll) {
+ vo_set_poll(vo, (vo->dev->poll) ? 1 : 0,
+ DVI_POLL_TIME_MS);
+ }
+#endif
+ vout_change_status(vo, VPP_VOUT_STS_PLUGIN,
+ vo->dev->check_plugin(0));
+ }
+ vo->govr->fb_p->set_csc(vo->govr->fb_p->csc_mode);
+ if (!lcd_get_dev()) {
+ govrh_set_dvo_enable(vo->govr,
+ (vo->status & VPP_VOUT_STS_BLANK) ? 0 : 1);
+ }
+ return 0;
+}
+
+static int vo_dvi_uninit(struct vout_t *vo, int arg)
+{
+ DBG_DETAIL("(%d)\n", arg);
+
+ vo_plug_enable(VPP_FLAG_DISABLE, 0, VPP_VOUT_NUM);
+ govrh_set_dvo_enable(vo->govr, VPP_FLAG_DISABLE);
+#ifdef __KERNEL__
+ vo_set_poll(vo, 0, DVI_POLL_TIME_MS);
+#endif
+ return 0;
+}
+
+static int vo_dvi_chkplug(struct vout_t *vo, int arg)
+{
+ int plugin = 1;
+
+ DBG_MSG("plugin %d\n", plugin);
+ return plugin;
+}
+
+static int vo_dvi_get_edid(struct vout_t *vo, int arg)
+{
+ char *buf;
+ int i, cnt;
+
+ DBG_DETAIL("Enter\n");
+
+ buf = (char *) arg;
+ memset(&buf[0], 0x0, 128 * EDID_BLOCK_MAX);
+ if (vpp_i2c_read(VPP_DVI_EDID_ID, 0xA0, 0, &buf[0], 128)) {
+ DBG_ERR("read edid\n");
+ return 1;
+ }
+
+ if (edid_checksum(buf, 128)) {
+ DBG_ERR("checksum\n");
+ return 1;
+ }
+
+ cnt = buf[0x7E];
+ if (cnt >= 3)
+ cnt = 3;
+ for (i = 1; i <= cnt; i++) {
+ vpp_i2c_read(VPP_DVI_EDID_ID, 0xA0, 0x80 * i,
+ &buf[128 * i], 128);
+ }
+ return 0;
+}
+
+struct vout_inf_t vo_dvi_inf = {
+ .mode = VOUT_INF_DVI,
+ .init = vo_dvi_init,
+ .uninit = vo_dvi_uninit,
+ .blank = vo_dvi_blank,
+ .config = vo_dvi_config,
+ .chkplug = vo_dvi_chkplug,
+ .get_edid = vo_dvi_get_edid,
+};
+
+int vo_dvi_initial(void)
+{
+ vout_inf_register(VOUT_INF_DVI, &vo_dvi_inf);
+ return 0;
+}
+module_init(vo_dvi_initial);
+
+#endif /* WMT_FTBLK_VOUT_DVI */
+
+/*---------------------------------- HDMI -----------------------------------*/
+void vo_hdmi_set_clock(int enable)
+{
+ DBG_DETAIL("(%d)\n", enable);
+
+ enable = (enable) ? CLK_ENABLE : CLK_DISABLE;
+ vpp_set_clock_enable(DEV_HDMII2C, enable, 0);
+ vpp_set_clock_enable(DEV_HDMI, enable, 0);
+ vpp_set_clock_enable(DEV_HDCE, enable, 0);
+}
+
+#ifdef WMT_FTBLK_VOUT_HDMI
+#ifdef __KERNEL__
+struct timer_list hdmi_cp_timer;
+static struct timer_list hdmi_plug_timer;
+#endif
+
+void vo_hdmi_cp_set_enable_tmr(int sec)
+{
+#ifdef __KERNEL__
+ int ms = sec * 1000;
+#endif
+
+ DBG_MSG("[HDMI] set enable tmr %d sec\n", sec);
+
+ if (sec == 0) {
+ hdmi_set_cp_enable(VPP_FLAG_ENABLE);
+ return ;
+ }
+#ifdef __KERNEL__
+ if (hdmi_cp_timer.function)
+ del_timer(&hdmi_cp_timer);
+ init_timer(&hdmi_cp_timer);
+ hdmi_cp_timer.data = VPP_FLAG_ENABLE;
+ hdmi_cp_timer.function = (void *) hdmi_set_cp_enable;
+ hdmi_cp_timer.expires = jiffies + msecs_to_jiffies(ms);
+ add_timer(&hdmi_cp_timer);
+#else
+ hdmi_set_cp_enable(VPP_FLAG_ENABLE);
+#endif
+}
+EXPORT_SYMBOL(vo_hdmi_cp_set_enable_tmr);
+
+static int vo_hdmi_blank(struct vout_t *vo, enum vout_blank_t arg)
+{
+ int enable;
+
+ DBG_DETAIL("(%d)\n", arg);
+
+ enable = (arg == VOUT_BLANK_UNBLANK) ? 1 : 0;
+ if (g_vpp.hdmi_cp_enable && enable)
+ vo_hdmi_cp_set_enable_tmr(2);
+ else
+ hdmi_set_cp_enable(VPP_FLAG_DISABLE);
+ hdmi_set_enable(enable);
+ hdmi_set_power_down((enable) ? 0 : 1);
+ return 0;
+}
+
+#ifndef CFG_LOADER
+static irqreturn_t vo_hdmi_cp_interrupt
+(
+ int irq, /*!<; // irq id */
+ void *dev_id /*!<; // device id */
+)
+{
+ struct vout_t *vo;
+
+ DBG_DETAIL("%d\n", irq);
+ vo = vout_get_entry(VPP_VOUT_NUM_HDMI);
+ switch (hdmi_check_cp_int()) {
+ case 1:
+ if (hdmi_cp)
+ hdmi_cp->enable(VPP_FLAG_DISABLE);
+ vo_hdmi_cp_set_enable_tmr(HDMI_CP_TIME);
+ vout_change_status(vo, VPP_VOUT_STS_CONTENT_PROTECT, 0);
+ vpp_netlink_notify_cp(0);
+ break;
+ case 0:
+ vout_change_status(vo, VPP_VOUT_STS_CONTENT_PROTECT, 1);
+ vpp_netlink_notify_cp(1);
+ break;
+ case 2:
+ hdmi_ri_tm_cnt = 3 * 30;
+ break;
+ default:
+ break;
+ }
+ return IRQ_HANDLED;
+}
+
+#ifdef __KERNEL__
+static void vo_hdmi_do_plug(struct work_struct *ptr)
+#else
+static void vo_hdmi_do_plug(void)
+#endif
+{
+ struct vout_t *vo;
+ int plugin;
+ int option = 0;
+
+ plugin = hdmi_check_plugin(1);
+ vo = vout_get_entry(VPP_VOUT_NUM_HDMI);
+ vout_change_status(vo, VPP_VOUT_STS_PLUGIN, plugin);
+ if (plugin) {
+ option = vout_get_edid_option(VPP_VOUT_NUM_HDMI);
+#ifdef CONFIG_VPP_DEMO
+ option |= (EDID_OPT_HDMI + EDID_OPT_AUDIO);
+#endif
+ hdmi_set_option(option);
+ } else {
+ g_vpp.hdmi_bksv[0] = g_vpp.hdmi_bksv[1] = 0;
+ }
+ vo_hdmi_blank(vo, (vo->status & VPP_VOUT_STS_BLANK) ? 1 : !(plugin));
+ if (!g_vpp.hdmi_certify_flag)
+ hdmi_hotplug_notify(plugin);
+ DBG_MSG("%d\n", plugin);
+ return;
+}
+DECLARE_WORK(vo_hdmi_plug_work, vo_hdmi_do_plug);
+
+static void hdmi_handle_plug(vpp_flag_t enable)
+{
+ schedule_work(&vo_hdmi_plug_work);
+}
+
+static void vo_hdmi_handle_plug_tmr(int ms)
+{
+ static int timer_init;
+
+ if (timer_init == 0) {
+ init_timer(&hdmi_plug_timer);
+ hdmi_plug_timer.data = VPP_FLAG_ENABLE;
+ hdmi_plug_timer.function = (void *) hdmi_handle_plug;
+ timer_init = 1;
+ }
+ hdmi_plug_timer.expires = jiffies + msecs_to_jiffies(ms);
+ mod_timer(&hdmi_plug_timer, hdmi_plug_timer.expires);
+}
+
+static irqreturn_t vo_hdmi_plug_interrupt
+(
+ int irq, /*!<; // irq id */
+ void *dev_id /*!<; // device id */
+)
+{
+ DBG_MSG("vo_hdmi_plug_interrupt %d\n", irq);
+ hdmi_clear_plug_status();
+ if (g_vpp.hdmi_certify_flag)
+ vo_hdmi_do_plug(0);
+ else
+ vo_hdmi_handle_plug_tmr(HDMI_PLUG_DELAY);
+ return IRQ_HANDLED;
+}
+#endif
+
+static int vo_hdmi_init(struct vout_t *vo, int arg)
+{
+ DBG_DETAIL("(%d)\n", arg);
+
+ vo_hdmi_set_clock(1);
+ vout_change_status(vout_get_entry(VPP_VOUT_NUM_HDMI),
+ VPP_VOUT_STS_PLUGIN, hdmi_check_plugin(0));
+ hdmi_enable_plugin(1);
+
+ if (g_vpp.hdmi_disable)
+ return 0;
+#ifndef CONFIG_UBOOT
+ if (vpp_request_irq(VPP_IRQ_HDMI_CP, vo_hdmi_cp_interrupt,
+ SA_INTERRUPT, "hdmi cp", (void *) 0)) {
+ DBG_ERR("*E* request HDMI ISR fail\n");
+ }
+ if (vpp_request_irq(VPP_IRQ_HDMI_HPDH, vo_hdmi_plug_interrupt,
+ SA_INTERRUPT, "hdmi plug", (void *) 0)) {
+ DBG_ERR("*E* request HDMI ISR fail\n");
+ }
+ if (vpp_request_irq(VPP_IRQ_HDMI_HPDL, vo_hdmi_plug_interrupt,
+ SA_INTERRUPT, "hdmi plug", (void *) 0)) {
+ DBG_ERR("*E* request HDMI ISR fail\n");
+ }
+#endif
+ hdmi_set_enable((vo->status & VPP_VOUT_STS_BLANK) ?
+ VPP_FLAG_DISABLE : VPP_FLAG_ENABLE);
+ return 0;
+}
+
+static int vo_hdmi_uninit(struct vout_t *vo, int arg)
+{
+ DBG_DETAIL("(%d)\n", arg);
+ hdmi_enable_plugin(0);
+ hdmi_set_cp_enable(VPP_FLAG_DISABLE);
+ hdmi_set_enable(VPP_FLAG_DISABLE);
+#ifndef CONFIG_UBOOT
+ vpp_free_irq(VPP_IRQ_HDMI_CP, (void *) 0);
+ vpp_free_irq(VPP_IRQ_HDMI_HPDH, (void *) 0);
+ vpp_free_irq(VPP_IRQ_HDMI_HPDL, (void *) 0);
+#endif
+ vo_hdmi_set_clock(0);
+ return 0;
+}
+
+static int vo_hdmi_config(struct vout_t *vo, int arg)
+{
+ struct vout_info_t *vo_info;
+ vdo_color_fmt colfmt;
+
+ hdmi_set_enable(0);
+ vo_info = (struct vout_info_t *) arg;
+
+ DBG_DETAIL("(%dx%d@%d)\n", vo_info->resx, vo_info->resy, vo_info->fps);
+
+ /* 1280x720@60, HDMI pixel clock 74250060 not 74500000 */
+ if ((vo_info->resx == 1280)
+ && (vo_info->resy == 720) && (vo_info->pixclk == 74500000))
+ vo_info->pixclk = 74250060;
+ colfmt = (vo->option[0] == VDO_COL_FMT_YUV422V) ?
+ VDO_COL_FMT_YUV422H : vo->option[0];
+ hdmi_cur_plugin = hdmi_check_plugin(0);
+ hdmi_info.option = (hdmi_cur_plugin) ?
+ vout_get_edid_option(VPP_VOUT_NUM_HDMI) : 0;
+ hdmi_info.outfmt = colfmt;
+ hdmi_info.vic = hdmi_get_vic(vo_info->resx, vo_info->resy,
+ vo_info->fps, (vo_info->option & VPP_OPT_INTERLACE) ? 1 : 0);
+
+ govrh_set_csc_mode(vo->govr, vo->govr->fb_p->csc_mode);
+ hdmi_set_sync_low_active((vo_info->option & VPP_DVO_SYNC_POLAR_HI) ?
+ 0 : 1, (vo_info->option & VPP_DVO_VSYNC_POLAR_HI) ? 0 : 1);
+ hdmi_config(&hdmi_info);
+#ifdef __KERNEL__
+ mdelay(200); /* patch for VIZIO change resolution issue */
+#endif
+ hdmi_cur_plugin = hdmi_check_plugin(0);
+ vo_hdmi_blank(vo, (vo->status & VPP_VOUT_STS_BLANK) ?
+ 1 : !(hdmi_cur_plugin));
+ return 0;
+}
+
+static int vo_hdmi_chkplug(struct vout_t *vo, int arg)
+{
+ int plugin;
+
+ if (g_vpp.hdmi_disable)
+ return 0;
+ plugin = hdmi_get_plugin();
+ DBG_DETAIL("%d\n", plugin);
+ return plugin;
+}
+
+static int vo_hdmi_get_edid(struct vout_t *vo, int arg)
+{
+ char *buf;
+#ifdef CONFIG_WMT_EDID
+ int i, cnt;
+#endif
+ DBG_DETAIL("Enter\n");
+ buf = (char *) arg;
+#ifdef CONFIG_WMT_EDID
+ memset(&buf[0], 0x0, 128*EDID_BLOCK_MAX);
+ if (!hdmi_get_plugin())
+ return 1;
+
+ if (hdmi_DDC_read(0xA0, 0x0, &buf[0], 128)) {
+ DBG_ERR("read edid\n");
+ return 1;
+ }
+
+ if (edid_checksum(buf, 128)) {
+ DBG_ERR("hdmi checksum\n");
+/* g_vpp.dbg_hdmi_ddc_crc_err++; */
+ return 1;
+ }
+
+ cnt = buf[0x7E];
+ if (cnt >= 3)
+ cnt = 3;
+ for (i = 1; i <= cnt; i++)
+ hdmi_DDC_read(0xA0, 0x80 * i, &buf[128 * i], 128);
+#endif
+ return 0;
+}
+
+struct vout_inf_t vo_hdmi_inf = {
+ .mode = VOUT_INF_HDMI,
+ .init = vo_hdmi_init,
+ .uninit = vo_hdmi_uninit,
+ .blank = vo_hdmi_blank,
+ .config = vo_hdmi_config,
+ .chkplug = vo_hdmi_chkplug,
+ .get_edid = vo_hdmi_get_edid,
+};
+
+int vo_hdmi_initial(void)
+{
+ vout_inf_register(VOUT_INF_HDMI, &vo_hdmi_inf);
+ return 0;
+}
+module_init(vo_hdmi_initial);
+
+#endif /* WMT_FTBLK_VOUT_HDMI */
+
+/*--------------------------------- LVDS ------------------------------------*/
+#ifdef WMT_FTBLK_VOUT_LVDS
+int vo_lvds_init_flag;
+static int vo_lvds_blank(struct vout_t *vo, enum vout_blank_t arg)
+{
+ DBG_DETAIL("(%d)\n", arg);
+ if (arg == VOUT_BLANK_POWERDOWN) {
+ lvds_regs->test.b.tre_en = 0;
+ } else { /* avoid suspend signal not clear */
+ lvds_set_enable((arg == VOUT_BLANK_UNBLANK) ? 1 : 0);
+ }
+
+ if (vo_lvds_init_flag)
+ lvds_set_power_down(arg);
+ return 0;
+}
+
+static int vo_lvds_config(struct vout_t *vo, int arg)
+{
+ DBG_DETAIL("(%d)\n", arg);
+ lvds_set_power_down(VPP_FLAG_DISABLE);
+ vo_lvds_init_flag = 1;
+ return 0;
+}
+
+static int vo_lvds_init(struct vout_t *vo, int arg)
+{
+ DBG_DETAIL("(%d)\n", arg);
+
+ vpp_set_clock_enable(DEV_LVDS, 1, 0);
+ if (vo->dev)
+ vo->dev->set_mode(&vo->option[0]);
+ govrh_set_dvo_enable(p_govrh2, 0);
+ govrh_set_csc_mode(vo->govr, vo->govr->fb_p->csc_mode);
+ lvds_set_enable((vo->status & VPP_VOUT_STS_BLANK) ?
+ VPP_FLAG_DISABLE : VPP_FLAG_ENABLE);
+ return 0;
+}
+
+static int vo_lvds_uninit(struct vout_t *vo, int arg)
+{
+ DBG_DETAIL("(%d)\n", arg);
+ lvds_set_enable(VPP_FLAG_DISABLE);
+ if (vo->dev)
+ vo->dev->set_mode(0);
+ lvds_set_power_down(VPP_FLAG_ENABLE);
+ vpp_set_clock_enable(DEV_LVDS, 0, 0);
+ vo_lvds_init_flag = 0;
+ return 0;
+}
+
+static int vo_lvds_chkplug(struct vout_t *vo, int arg)
+{
+ DBG_DETAIL("\n");
+#if 0
+ vo = vout_get_info(VOUT_LVDS);
+ if (vo->dev)
+ return vo->dev->check_plugin(0);
+#endif
+ return 1;
+}
+
+struct vout_inf_t vo_lvds_inf = {
+ .mode = VOUT_INF_LVDS,
+ .capability = VOUT_INF_CAP_FIX_PLUG,
+ .init = vo_lvds_init,
+ .uninit = vo_lvds_uninit,
+ .blank = vo_lvds_blank,
+ .config = vo_lvds_config,
+ .chkplug = vo_lvds_chkplug,
+#ifdef WMT_FTBLK_VOUT_HDMI
+ .get_edid = vo_hdmi_get_edid,
+#endif
+};
+
+int vo_lvds_initial(void)
+{
+ vout_inf_register(VOUT_INF_LVDS, &vo_lvds_inf);
+ return 0;
+}
+module_init(vo_lvds_initial);
+
+#endif /* WMT_FTBLK_VOUT_LVDS */
+/*---------------------------------- API ------------------------------------*/
+#ifndef CFG_LOADER
+int vout_set_audio(struct vout_audio_t *arg)
+{
+ struct vout_t *vout;
+ int ret = 0;
+
+#if 0
+ vout = vout_get_info(VPP_VOUT_DVO2HDMI);
+ if (vout && (vout->status & VPP_VOUT_STS_PLUGIN)) {
+ if (vout->dev->set_audio)
+ vout->dev->set_audio(arg);
+ }
+#endif
+
+#ifdef WMT_FTBLK_VOUT_HDMI
+ vout = vout_get_entry(VPP_VOUT_NUM_HDMI);
+ if (vout) {
+ g_vpp.hdmi_ch_change = 1;
+ hdmi_config_audio(arg);
+ g_vpp.hdmi_ch_change = 0;
+ ret = 1;
+ }
+#endif
+ return ret;
+}
+#endif
+
+/* 3445 port1 : DVI/SDD, port2 : VGA/SDA, port3 : HDMI/LVDS */
+/* 3481 port1 : HDMI/LVDS, port2 : DVI */
+/* 3498 port1 : HDMI, port2 : DVI/LVDS */
+struct vout_t vout_entry_0 = {
+ .fix_cap = BIT(VOUT_INF_HDMI),
+ .option[0] = VDO_COL_FMT_ARGB,
+ .option[1] = VPP_DATAWIDHT_24,
+ .option[2] = 0,
+};
+
+struct vout_t vout_entry_1 = {
+ .fix_cap = BIT(VOUT_INF_DVI) + BIT(VOUT_INF_LVDS) +
+ VOUT_CAP_EXT_DEV + 0x100, /* i2c bus 1,ext dev */
+ .option[0] = VDO_COL_FMT_ARGB,
+ .option[1] = VPP_DATAWIDHT_24,
+ .option[2] = 0,
+};
+
+int vout_add_display(int fb_no, unsigned int *parm)
+{
+ struct vout_info_t *info;
+ struct vout_t *vout;
+ int ret = 0;
+
+ info = vout_info[fb_no];
+ if (!info) {
+ info = kmalloc(sizeof(struct vout_info_t), GFP_KERNEL);
+ if (!info)
+ return 1;
+ memset(info, 0, sizeof(struct vout_info_t));
+ vout_info[fb_no] = info;
+ DBG_MSG("malloc vout_info %d,0x%x\n", fb_no, (int) info);
+#ifdef CONFIG_KERNEL
+ sema_init(&info->sem, 1);
+#endif
+ }
+
+ if (parm[0] == VOUT_BOOT) {
+ struct vout_t *vo_boot;
+
+ MSG("[VOUT] %s (%d:%d:%d)\n",
+ (fb_no == 0) ? "tvbox" : "virtual display",
+ parm[0], parm[1], parm[2]);
+ if (fb_no == 0) {
+ g_vpp.virtual_display = 1;
+ g_vpp.fb0_bitblit = 1;
+ } else {
+ g_vpp.stream_fb = fb_no;
+ }
+ vo_boot = kmalloc(sizeof(struct vout_t), GFP_KERNEL);
+ if (vo_boot == 0)
+ return 1;
+ memset(vo_boot, 0, sizeof(struct vout_t));
+ vo_boot->resx = parm[3];
+ vo_boot->resy = parm[4];
+ vo_boot->fps = parm[5];
+ vo_boot->num = VPP_VOUT_NUM;
+ vout_info_add_entry(fb_no, vo_boot);
+ kfree(vo_boot);
+ return 0;
+ }
+
+ vout = vout_get_entry_adapter(parm[0]);
+ vout->inf = vout_get_inf_entry_adapter(parm[0]);
+ vout->option[0] = parm[1];
+ vout->option[1] = parm[2];
+ vout->resx = parm[3];
+ vout->resy = parm[4];
+ vout->fps = parm[5];
+ vout->disable = (parm[2] & VOUT_OPT_BLANK) ? 1 : 0;
+ switch (parm[0]) {
+ case VOUT_LVDS:
+ {
+ struct fb_videomode *vmode = 0;
+
+ /* lvds auto detect edid */
+ if ((parm[1] == 0) && (parm[3] == 0) && (parm[4] == 0)) {
+ if (vout_get_edid_option(vout->num)) {
+ vmode = &vout->edid_info.detail_timing[0];
+ if (vmode->pixclock == 0) {
+ vmode = 0;
+ DBG_ERR("LVDS timing\n");
+ }
+ }
+
+ if (vout->inf->get_edid(vout, (int)vout->edid) == 0) {
+ if (edid_parse(vout->edid,
+ &vout->edid_info) == 0)
+ DBG_ERR("LVDS edid parse\n");
+ } else {
+ DBG_ERR("LVDS edid read\n");
+ }
+ }
+
+ if (vmode == 0) { /* use internal timing */
+ struct lcd_parm_t *p = 0;
+
+ if (parm[1]) {
+ p = lcd_get_parm(parm[1], parm[2]);
+ if (p)
+ lcd_set_lvds_id(parm[1]);
+ }
+
+ if (p == 0)
+ p = lcd_get_oem_parm(parm[3], parm[4]);
+ vmode = &p->vmode;
+ }
+ vout->option[2] = vmode->vmode;
+ info->resx = vmode->xres;
+ info->resy = vmode->yres;
+ info->fps = vmode->refresh;
+ vout_info_set_fixed_timing(fb_no, vmode);
+ lcd_set_type(1);
+ }
+ case VOUT_LCD:
+ {
+ struct vout_dev_t *dev;
+
+ lcd_set_parm(parm[1], parm[2] & 0xFF);
+ dev = lcd_get_dev();
+ vout->dev = dev;
+ dev->vout = vout;
+ vout->option[0] = VDO_COL_FMT_ARGB;
+ vout->option[1] &= ~0xFF;
+ vout->option[1] |= VPP_DATAWIDHT_24;
+ vout->dev->init(vout);
+ vout_info_set_fixed_timing(fb_no, &p_lcd->vmode);
+ }
+ break;
+ case VOUT_DVI:
+ {
+ struct vout_dev_t *dev = 0;
+
+ g_vpp.dvi_int_disable =
+ (parm[2] & WMT_DISP_FB_DISBALE_DVI_INT) ? 1 : 0;
+ g_vpp.dvi_int_no = (parm[2] & WMT_DISP_FB_DVI_INT) ?
+ ((parm[1] & 0xF000) >> 12) : VPP_DVI_INT_DEFAULT;
+ g_vpp.dvi_i2c_no = (parm[2] & WMT_DISP_FB_DVI_I2C) ?
+ ((parm[1] & 0xF00) >> 8) : VPP_DVI_I2C_DEFAULT;
+ g_vpp.dvi_i2c_no &= VPP_DVI_I2C_ID_MASK;
+
+ if (parm[2] & WMT_DISP_FB_DISABLE_EXTDEV)
+ vout->dev = 0;
+ else {
+ vpp_i2c_init(VPP_DVI_I2C_ID, 0xA0);
+ do {
+ dev = vout_get_device(dev);
+ if (dev == 0)
+ break;
+ if (vout->fix_cap & BIT(dev->mode)) {
+ vout->inf =
+ vout_inf_get_entry(dev->mode);
+ if (dev->init(vout) == 0) {
+ vout->dev = dev;
+ dev->vout = vout;
+ break;
+ }
+ }
+ } while (1);
+ }
+
+ DBG_MSG("DVI ext dev : %s\n",
+ (vout->dev) ? vout->dev->name : "NO");
+ }
+ info->option = (parm[2] & WMT_DISP_FB_INTERLACE) ?
+ VPP_OPT_INTERLACE : 0;
+ break;
+ case VOUT_HDMI:
+ info->option = (parm[2] & WMT_DISP_FB_INTERLACE) ?
+ VPP_OPT_INTERLACE : 0;
+#if 0 /* use old uboot param and wait next chip */
+ g_vpp.hdmi_disable =
+ (parm[2] & WMT_DISP_FB_HDMI_DISABLE) ? 1 : 0;
+
+ g_vpp.hdmi_sp_mode =
+ (parm[2] & WMT_DISP_FB_HDMI_SP_MODE) ? 1 : 0;
+#endif
+ break;
+ default:
+ break;
+ }
+
+ if (ret == 0)
+ vout_info_add_entry(fb_no, vout);
+ return ret;
+}
+
+int vout_check_display(void)
+{
+ #define BUF_LEN 100
+ char buf[BUF_LEN];
+ int varlen = BUF_LEN;
+ unsigned int parm[32];
+ int i, idx;
+
+ if (wmt_getsyspara("wmt.display.fb0", buf, &varlen)) {
+ /* default for no uboot parameter */
+ parm[0] = VOUT_HDMI;
+ parm[1] = VDO_COL_FMT_ARGB;
+ parm[2] = VPP_DATAWIDHT_24;
+ parm[3] = 1280;
+ parm[4] = 720;
+ parm[5] = 60;
+ vout_add_display(0, &parm[0]);
+ parm[0] = VOUT_DVI;
+ parm[1] = VDO_COL_FMT_ARGB;
+ parm[2] = VPP_DATAWIDHT_24;
+ parm[3] = 1024;
+ parm[4] = 768;
+ parm[5] = 60;
+ vout_add_display(0, &parm[0]);
+ return 1;
+ } else {
+ int fb_no = 0;
+ int num;
+
+ while (fb_no < VPP_VOUT_INFO_NUM) {
+ sprintf(buf, "wmt.display.fb%d", fb_no);
+ varlen = BUF_LEN;
+ if (wmt_getsyspara(buf, buf, &varlen))
+ break;
+
+ DBG_DETAIL("fb%d : %s\n", fb_no, buf);
+ varlen = vpp_parse_param(buf,
+ (unsigned int *)parm, 32, 0x1C1C1C1D);
+ DBG_DETAIL("op 0x%x\n", parm[0]);
+ num = (varlen - 1) / 7;
+ for (i = 0; i < num; i++) {
+ idx = 1 + 8 * i; /* [ + 6 + ] = 8 */
+ DBG_DETAIL("%d : %x, %x, %x (%dx%d@%d)\n", i,
+ parm[idx + 1], parm[idx + 2],
+ parm[idx + 3], parm[idx + 4],
+ parm[idx + 5], parm[idx + 6]);
+ vout_add_display(fb_no, &parm[idx + 1]);
+ }
+
+ vout_info[fb_no]->multi =
+ (parm[0] & WMT_DISP_FB_MULTI) ? 1 : 0;
+ vout_info[fb_no]->alloc_mode = (parm[0] & 0xF);
+ vout_info[fb_no]->hwc_mode = (parm[0] & 0xF0) >> 4;
+ if (parm[0] & WMT_DISP_FB_COLFMT)
+ vout_info[fb_no]->fb.col_fmt = ((parm[0] &
+ WMT_DISP_FB_COLFMT_MASK) >> 16);
+ fb_no++;
+ }
+ }
+
+ /* [uboot parameter] oem timing :
+ pixclk:option:hsync:hbp:hpixel:hfp:vsync:vbp:vpixel:vfp */
+ varlen = BUF_LEN;
+ if (wmt_getsyspara("wmt.display.tmr", buf, &varlen) == 0) {
+ struct fb_videomode *p;
+ int xres, yres;
+ struct fb_videomode vo_oem_vmode;
+
+ p = &vo_oem_vmode;
+ DBG_MSG("tmr %s\n", buf);
+ vpp_parse_param(buf, parm, 12, 0);
+ p->pixclock = parm[0];
+ p->vmode = parm[1];
+ p->hsync_len = parm[2];
+ p->left_margin = parm[3];
+ p->xres = parm[4];
+ p->right_margin = parm[5];
+ p->vsync_len = parm[6];
+ p->upper_margin = parm[7];
+ p->yres = parm[8];
+ p->lower_margin = parm[9];
+ p->pixclock *= 1000;
+ xres = p->hsync_len + p->left_margin + p->xres +
+ p->right_margin;
+ yres = p->vsync_len + p->upper_margin + p->yres +
+ p->lower_margin;
+ p->refresh = vpp_calc_refresh(p->pixclock, xres, yres);
+ if (p->refresh == 59)
+ p->refresh = 60;
+ p->vmode = (parm[1] & VPP_OPT_INTERLACE) ? FB_VMODE_INTERLACED : 0;
+ p->sync = (parm[1] & VPP_DVO_SYNC_POLAR_HI) ? FB_SYNC_HOR_HIGH_ACT : 0;
+ p->sync |= (parm[1] & VPP_DVO_VSYNC_POLAR_HI) ? FB_SYNC_VERT_HIGH_ACT : 0;
+ DBG_MSG("tmr pixclk %d,option 0x%x\n",
+ p->pixclock, p->vmode);
+ DBG_MSG("H sync %d,bp %d,pixel %d,fp %d\n", p->hsync_len,
+ p->left_margin, p->xres, p->right_margin);
+ DBG_MSG("V sync %d,bp %d,pixel %d,fp %d\n", p->vsync_len,
+ p->upper_margin, p->yres, p->lower_margin);
+ p->pixclock = KHZ2PICOS(p->pixclock / 1000);
+ vout_info_set_fixed_timing(0, &vo_oem_vmode);
+ vout_info[0]->fixed_width = parm[10];
+ vout_info[0]->fixed_height = parm[11];
+ vout_info[0]->resx = p->xres;
+ vout_info[0]->resy = p->yres;
+ vout_info[0]->fps = p->refresh;
+ vout_info[0]->vout[0]->resx = p->xres;
+ vout_info[0]->vout[0]->resy = p->yres;
+ vout_info[0]->vout[0]->fps = p->refresh;
+ }
+ return 0;
+}
+
+int vout_init(void)
+{
+ struct vout_info_t *info;
+ struct vout_t *vout;
+ int i, j;
+
+ DBG_DETAIL("Enter\n");
+
+ for(i = 0; i < VPP_VOUT_INFO_NUM; i++) {
+ if(vout_info[i] != NULL) {
+ kfree(vout_info[i]);
+ vout_info[i] = NULL;
+ }
+ }
+
+ /* register vout & set default */
+ vout_register(0, &vout_entry_0);
+ vout_entry_0.inf = vout_inf_get_entry(VOUT_INF_HDMI);
+ vout_entry_0.govr = p_govrh;
+ vout_register(1, &vout_entry_1);
+ vout_entry_1.inf = vout_inf_get_entry(VOUT_INF_DVI);
+ vout_entry_1.govr = p_govrh2;
+
+ /* check vout info */
+ DBG_DETAIL("check display\n");
+ vout_check_display();
+
+ /* initial vout */
+ DBG_DETAIL("init display\n");
+ for (i = 0; i < VPP_VOUT_INFO_NUM; i++) {
+ info = vout_info[i];
+ if (!info)
+ break;
+ for (j = 0; ; j++) {
+ vout = info->vout[j];
+ if (vout == 0)
+ break;
+ if (vout->inf)
+ vout->inf->init(vout, 0);
+ }
+ }
+
+ /* check monitor resolution */
+ DBG_DETAIL("check resolution\n");
+ for (i = 0; i < VPP_VOUT_INFO_NUM; i++) {
+ struct vout_t *vout_first = 0;
+ struct vout_t *vout_plug = 0;
+
+ info = vout_info[i];
+ if (!info)
+ break;
+ for (j = 0; ; j++) {
+ vout = info->vout[j];
+ if (vout == 0)
+ break;
+
+ if (vout_first == 0) /* first priority */
+ vout_first = vout;
+
+ if (vout_chkplug(vout->num)) {
+ struct fb_videomode vmode;
+
+ vmode.xres = vout->resx;
+ vmode.yres = vout->resy;
+ vmode.refresh = vout->fps;
+ vmode.vmode = 0;
+ vout_find_match_mode(i, &vmode, 1);
+ vout->resx = vmode.xres;
+ vout->resy = vmode.yres;
+ vout->fps = vmode.refresh;
+ if (vout_plug == 0) /* first plugin */
+ vout_plug = vout;
+ }
+
+ if (info->multi)
+ vout_change_status(vout,
+ VPP_VOUT_STS_ACTIVE, 1);
+ }
+
+ vout = (vout_plug) ? vout_plug : vout_first;
+ if (vout) {
+ vout_change_status(vout, VPP_VOUT_STS_ACTIVE, 1);
+ info->resx = vout->resx;
+ info->resy = vout->resy;
+ info->fps = vout->fps;
+ }
+ }
+
+#ifdef DEBUG
+ /* show display info */
+ for (i = 0; i < VPP_VOUT_INFO_NUM; i++) {
+ info = vout_info[i];
+ if (!info)
+ break;
+ MSG("-----------------------------------------------------\n");
+ MSG("fb%d, resx %d,resy %d,fps %d\n", i,
+ info->resx, info->resy, info->fps);
+ MSG("resx_vir %d,resy_vir %d,pixclk %d\n", info->resx_virtual,
+ info->resy_virtual, info->pixclk);
+ MSG("multi %d,alloc %d,option 0x%x\n", info->multi,
+ info->alloc_mode, info->option);
+
+ for (j = 0; ; j++) {
+ vout = info->vout[j];
+ if (vout == 0)
+ break;
+ vout_print_entry(vout);
+ }
+ }
+ MSG("-----------------------------------------------------\n");
+#endif
+ DBG_DETAIL("Leave\n");
+ return 0;
+}
+
+int vout_exit(void)
+{
+ return 0;
+}
diff --git a/common/wmt_display/vout.c b/common/wmt_display/vout.c
new file mode 100755
index 0000000..9291ac5
--- /dev/null
+++ b/common/wmt_display/vout.c
@@ -0,0 +1,941 @@
+/*++
+ * linux/drivers/video/wmt/vout.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define VOUT_C
+#undef DEBUG
+/* #define DEBUG */
+/* #define DEBUG_DETAIL */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "vout.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+/* #define VO_XXXX xxxx *//*Example*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define VO_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx vo_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in vout.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int vo_xxx; *//*Example*/
+struct vout_t *vout_array[VPP_VOUT_NUM];
+struct vout_inf_t *vout_inf_array[VOUT_INF_MODE_MAX];
+struct vout_dev_t *vout_dev_list;
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void vo_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+/*----------------------- vout API --------------------------------------*/
+void vout_register(int no, struct vout_t *vo)
+{
+ if (no >= VPP_VOUT_NUM)
+ return;
+
+ vo->num = no;
+ vo->govr = (void *) p_govrh;
+ vo->status = VPP_VOUT_STS_REGISTER;
+ vo->info = 0;
+ vout_array[no] = vo;
+}
+
+struct vout_t *vout_get_entry(int no)
+{
+ if (no >= VPP_VOUT_NUM)
+ return 0;
+ return vout_array[no];
+}
+EXPORT_SYMBOL(vout_get_entry);
+
+struct vout_info_t *vout_get_info_entry(int no)
+{
+ struct vout_info_t *info;
+ struct vout_t *vout;
+ int i, j;
+
+ if (no >= VPP_VOUT_NUM)
+ return 0;
+
+ for (i = 0; i < VPP_VOUT_INFO_NUM; i++) {
+ info = vout_info[i];
+ if (!info)
+ break;
+ for (j = 0; j < VPP_VOUT_NUM; j++) {
+ vout = info->vout[j];
+ if (vout == 0)
+ break;
+ if (vout->num == no)
+ return info;
+ }
+ }
+ return 0;
+}
+
+void vout_change_status(struct vout_t *vo, int mask, int sts)
+{
+ DBG_DETAIL("(0x%x,%d)\n", mask, sts);
+ if (sts)
+ vo->status |= mask;
+ else
+ vo->status &= ~mask;
+
+ switch (mask) {
+ case VPP_VOUT_STS_PLUGIN:
+ if (sts == 0) {
+ vo->status &= ~(VPP_VOUT_STS_EDID +
+ VPP_VOUT_STS_CONTENT_PROTECT);
+ vo->edid_info.option = 0;
+#ifdef __KERNEL__
+ vpp_netlink_notify_cp(0);
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+int vout_query_inf_support(int no, enum vout_inf_mode_t mode)
+{
+ struct vout_t *vo;
+
+ if (no >= VPP_VOUT_NUM)
+ return 0;
+
+ if (mode >= VOUT_INF_MODE_MAX)
+ return 0;
+
+ vo = vout_get_entry(no);
+ return (vo->fix_cap & BIT(mode)) ? 1 : 0;
+}
+
+/*----------------------- vout interface API --------------------------------*/
+int vout_inf_register(enum vout_inf_mode_t mode, struct vout_inf_t *inf)
+{
+ if (mode >= VOUT_INF_MODE_MAX) {
+ DBG_ERR("vout interface mode invalid %d\n", mode);
+ return -1;
+ }
+
+ if (vout_inf_array[mode])
+ DBG_ERR("vout interface register again %d\n", mode);
+
+ vout_inf_array[mode] = inf;
+ return 0;
+} /* End of vout_register */
+
+struct vout_inf_t *vout_inf_get_entry(enum vout_inf_mode_t mode)
+{
+ if (mode >= VOUT_INF_MODE_MAX) {
+ DBG_ERR("vout interface mode invalid %d\n", mode);
+ return 0;
+ }
+ return vout_inf_array[mode];
+}
+
+/*----------------------- vout device API -----------------------------------*/
+int vout_device_register(struct vout_dev_t *ops)
+{
+ struct vout_dev_t *list;
+
+ if (vout_dev_list == 0) {
+ vout_dev_list = ops;
+ list = ops;
+ } else {
+ list = vout_dev_list;
+ while (list->next != 0)
+ list = list->next;
+ list->next = ops;
+ }
+ ops->next = 0;
+ return 0;
+}
+
+struct vout_dev_t *vout_get_device(struct vout_dev_t *ops)
+{
+ if (ops == 0)
+ return vout_dev_list;
+ return ops->next;
+}
+
+struct vout_t *vout_get_entry_adapter(enum vout_mode_t mode)
+{
+ int no;
+
+ switch (mode) {
+ case VOUT_SD_DIGITAL:
+ case VOUT_DVI:
+ case VOUT_LCD:
+ case VOUT_DVO2HDMI:
+ case VOUT_SD_ANALOG:
+ case VOUT_VGA:
+ no = VPP_VOUT_NUM_DVI;
+ break;
+ case VOUT_HDMI:
+ no = VPP_VOUT_NUM_HDMI;
+ break;
+ case VOUT_LVDS:
+ no = VPP_VOUT_NUM_LVDS;
+ break;
+ default:
+ no = VPP_VOUT_NUM;
+ break;
+ }
+ return vout_get_entry(no);
+}
+
+struct vout_inf_t *vout_get_inf_entry_adapter(enum vout_mode_t mode)
+{
+ int no;
+
+ switch (mode) {
+ case VOUT_SD_DIGITAL:
+ case VOUT_SD_ANALOG:
+ case VOUT_DVI:
+ case VOUT_LCD:
+ case VOUT_DVO2HDMI:
+ case VOUT_VGA:
+ no = VOUT_INF_DVI;
+ break;
+ case VOUT_HDMI:
+ no = VOUT_INF_HDMI;
+ break;
+ case VOUT_LVDS:
+ no = VOUT_INF_LVDS;
+ break;
+ default:
+ no = VOUT_INF_MODE_MAX;
+ return 0;
+ }
+ return vout_inf_get_entry(no);
+}
+
+enum vpp_vout_s vout_get_mode_adapter(struct vout_t *vout)
+{
+ enum vpp_vout_s mode;
+
+ switch (vout->inf->mode) {
+ case VOUT_INF_DVI:
+ mode = VPP_VOUT_DVI;
+ if (vout->dev && (strcmp("LCD", vout->dev->name) == 0))
+ mode = VPP_VOUT_LCD;
+ break;
+ case VOUT_INF_HDMI:
+ mode = VPP_VOUT_HDMI;
+ break;
+ case VOUT_INF_LVDS:
+ mode = VPP_VOUT_LVDS;
+ break;
+ default:
+ mode = VPP_VOUT_NONE;
+ break;
+ }
+ return mode;
+}
+
+int vout_info_add_entry(int no, struct vout_t *vo)
+{
+ struct vout_info_t *info;
+ int i = 0;
+
+ if ((vo == 0) || (vo->info))
+ return 0;
+
+ info = vout_info[no];
+ info->num = no;
+ if (vo->num < VPP_VOUT_NUM) { /* not virtual vout */
+ for (i = 0; i < VPP_VOUT_NUM; i++) {
+ if (info->vout[i] == 0) {
+ info->vout[i] = vo;
+ vo->info = info;
+ break;
+ } else {
+ if (info->vout[i] == vo) /* exist */
+ break;
+ }
+ }
+ }
+
+ if (i == 0) { /* new */
+ info->resx = vo->resx;
+ info->resy = vo->resy;
+ info->resx_virtual = vpp_calc_align(info->resx, 4);
+ info->resy_virtual = info->resy;
+ info->fps = (int) vo->fps;
+ DBG_MSG("new %dx%d@%d\n", info->resx, info->resy, info->fps);
+ }
+
+ DBG_MSG("info %d,%dx%d@%d\n", no, info->resx, info->resy, info->fps);
+ return no;
+}
+
+struct vout_info_t *vout_info_get_entry(int no)
+{
+ if (no >= VPP_VOUT_INFO_NUM)
+ return 0;
+ return vout_info[no];
+}
+
+void vout_info_set_fixed_timing(int no, struct fb_videomode *vmode)
+{
+ struct vout_info_t *info;
+
+ DBG_MSG("(%d)\n", no);
+
+ info = vout_info_get_entry(no);
+ if (!info->fixed_vmode) {
+ info->fixed_vmode =
+ kmalloc(sizeof(struct fb_videomode), GFP_KERNEL);
+ if (!info->fixed_vmode)
+ return;
+ }
+ memcpy(info->fixed_vmode, vmode, sizeof(struct fb_videomode));
+}
+
+struct govrh_mod_t *vout_info_get_govr(int no)
+{
+ struct vout_info_t *info;
+ struct govrh_mod_t *govr = 0;
+ int i;
+
+ info = vout_info[no];
+ if (!info)
+ return 0;
+
+ for (i = 0; i < VPP_VOUT_NUM; i++) {
+ if (info->vout[i]) {
+ if (govr == 0)
+ govr = info->vout[i]->govr;
+ if (info->vout[i]->status & VPP_VOUT_STS_ACTIVE) {
+ govr = info->vout[i]->govr;
+ break;
+ }
+ }
+ }
+ return govr;
+}
+
+int vout_check_ratio_16_9(unsigned int resx, unsigned int resy)
+{
+ int val;
+
+ val = (resy) ? ((resx * 10) / resy) : 0;
+ return (val >= 15) ? 1 : 0;
+}
+
+struct fb_videomode *vout_get_video_mode(int vout_num,
+ struct fb_videomode *vmode, int option)
+{
+ int i;
+ struct fb_videomode *p, *best = NULL;
+ unsigned int diff = -1, diff_refresh = -1;
+ int d;
+ int resx, resy, fps;
+ unsigned int pixel_clock, diff_pixel_clock = -1;
+ struct vout_t *vo = 0;
+ char *edid = 0;
+
+ resx = vmode->xres;
+ resy = vmode->yres;
+ fps = vmode->refresh;
+#ifdef DEBUG
+ pixel_clock = (vmode->pixclock) ? PICOS2KHZ(vmode->pixclock) * 1000 : 0;
+ DBG_MSG("%d,%dx%d@%d,%d,0x%x\n", vout_num, resx, resy, fps,
+ pixel_clock, option);
+#endif
+ pixel_clock = vmode->pixclock;
+
+ /* EDID detail timing */
+ if (option & VOUT_MODE_OPTION_EDID) {
+ unsigned int opt;
+ struct fb_videomode *edid_vmode;
+
+ vo = vout_get_entry(vout_num);
+ if (vo == 0)
+ return 0;
+
+ edid = vout_get_edid(vout_num);
+ if (edid_parse(edid, &vo->edid_info)) {
+ opt = fps | ((option &
+ VOUT_MODE_OPTION_INTERLACE) ?
+ EDID_TMR_INTERLACE : 0);
+ if (edid_find_support(&vo->edid_info,
+ resx, resy, opt, &edid_vmode)) {
+ if (edid_vmode) {
+ DBG_MSG("EDID detail timing\n");
+ return edid_vmode;
+ }
+ }
+ }
+ }
+
+ /* video mode table */
+ for (i = 0; ; i++) {
+ p = (struct fb_videomode *) &vpp_videomode[i];
+ if (p->pixclock == 0)
+ break;
+
+ if (option & VOUT_MODE_OPTION_LESS) {
+ if ((p->xres > resx) || (p->yres > resy))
+ continue;
+ }
+ if (option & VOUT_MODE_OPTION_GREATER) {
+ if ((p->xres < resx) || (p->yres < resy))
+ continue;
+ }
+ if (option & VOUT_MODE_OPTION_INTERLACE) {
+ if (!(p->vmode & FB_VMODE_INTERLACED))
+ continue;
+ }
+ if (option & VOUT_MODE_OPTION_PROGRESS) {
+ if ((p->vmode & FB_VMODE_INTERLACED))
+ continue;
+ }
+ if ((option & VOUT_MODE_OPTION_EDID) &&
+ (edid_parse(edid, &vo->edid_info))) {
+ unsigned int opt;
+ struct fb_videomode *edid_vmode;
+
+ opt = p->refresh | ((option &
+ VOUT_MODE_OPTION_INTERLACE) ?
+ EDID_TMR_INTERLACE : 0);
+ if (edid_find_support(&vo->edid_info,
+ p->xres, p->yres, opt, &edid_vmode)) {
+ if (edid_vmode)
+ p = edid_vmode;
+ } else {
+ continue;
+ }
+ }
+ d = abs(p->xres - resx) + abs(p->yres - resy);
+ d = abs(d);
+ if (diff > d) {
+ diff = d;
+ diff_refresh = abs(p->refresh - fps);
+ diff_pixel_clock = abs(p->pixclock - pixel_clock);
+ best = p;
+ } else if (diff == d) {
+ d = abs(p->refresh - fps);
+ if (diff_refresh > d) {
+ diff_refresh = d;
+ diff_pixel_clock =
+ abs(p->pixclock - pixel_clock);
+ best = p;
+ } else if (diff_refresh == d) {
+ d = abs(p->pixclock - pixel_clock);
+ if (diff_pixel_clock > d) {
+ diff_pixel_clock = d;
+ best = p;
+ }
+ }
+ }
+ }
+ if (best)
+ DBG_MSG("%dx%d@%d\n", best->xres, best->yres, best->refresh);
+ return best;
+}
+
+int vout_get_width_height(int fbnum, int *width, int *height)
+{
+ struct vout_info_t *info;
+ int i;
+
+ info = vout_info_get_entry(fbnum);
+ *width = 0;
+ *height = 0;
+ for (i = 0; i < VPP_VOUT_NUM; i++) {
+ struct vout_t *vout;
+
+ vout = info->vout[i];
+ if (vout) {
+ if ((vout->inf->mode == VOUT_INF_DVI) && p_lcd) {
+ if (info->fixed_width != 0 && info->fixed_height != 0) {
+ *width = info->fixed_width;
+ *height = info->fixed_height;
+ } else {
+ *width = p_lcd->width;
+ *height = p_lcd->height;
+ }
+ break;
+ }
+ if (vout_chkplug(vout->num)) {
+ if (vout_get_edid_option(vout->num)
+ & EDID_OPT_VALID) {
+ *width = vout->edid_info.width;
+ *height = vout->edid_info.height;
+ break;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+#ifndef CONFIG_VPOST
+int vout_find_match_mode(int fbnum,
+ struct fb_videomode *vmode, int match)
+{
+ struct vout_info_t *info;
+ struct fb_videomode *p;
+ int no = VPP_VOUT_NUM;
+ unsigned int option;
+ int i;
+
+ DBG_DETAIL("(%d)\n", fbnum);
+
+ info = vout_info_get_entry(fbnum);
+ if (vmode->refresh == 59)
+ vmode->refresh = 60;
+
+ /* fixed timing */
+ if (info->fixed_vmode) {
+ if (info->fixed_vmode->xres != vmode->xres)
+ return -1;
+ if (info->fixed_vmode->yres != vmode->yres)
+ return -1;
+ if (info->fixed_vmode->refresh != vmode->refresh)
+ return -1;
+ p = info->fixed_vmode;
+ goto label_find_match;
+ }
+ for (i = 0; i < VPP_VOUT_NUM; i++) {
+ if (info->vout[i]) {
+ int vout_no = info->vout[i]->num;
+
+ if (no == VPP_VOUT_NUM)
+ no = vout_no; /* get first vo */
+ if (vout_chkplug(vout_no)) {
+ no = vout_no;
+ break;
+ }
+ }
+ }
+ /* resolution match and interlace match */
+ option = VOUT_MODE_OPTION_GREATER + VOUT_MODE_OPTION_LESS;
+ option |= (no == VPP_VOUT_NUM) ? 0 : VOUT_MODE_OPTION_EDID;
+ option |= (vmode->vmode & FB_VMODE_INTERLACED) ?
+ VOUT_MODE_OPTION_INTERLACE : VOUT_MODE_OPTION_PROGRESS;
+ p = vout_get_video_mode(no, vmode, option);
+ if (p)
+ goto label_find_match;
+
+ /* resolution match but interlace not match */
+ option = VOUT_MODE_OPTION_GREATER + VOUT_MODE_OPTION_LESS;
+ option |= (no == VPP_VOUT_NUM) ? 0 : VOUT_MODE_OPTION_EDID;
+ option |= (vmode->vmode & FB_VMODE_INTERLACED) ?
+ VOUT_MODE_OPTION_PROGRESS : VOUT_MODE_OPTION_INTERLACE;
+ p = vout_get_video_mode(no, vmode, option);
+ if (p)
+ goto label_find_match;
+
+/* if( !match ){ */
+ /* resolution less best mode */
+ option = VOUT_MODE_OPTION_LESS;
+ option |= (no == VPP_VOUT_NUM) ? 0 : VOUT_MODE_OPTION_EDID;
+ p = vout_get_video_mode(no, vmode, option);
+ if (p)
+ goto label_find_match;
+/* } */
+ DBG_ERR("no support mode\n");
+ return -1;
+label_find_match:
+ *vmode = *p;
+#ifdef CONFIG_UBOOT
+ info->p_vmode = p;
+#endif
+ return 0;
+}
+#endif
+
+int vout_find_edid_support_mode(
+ struct edid_info_t *info,
+ unsigned int *resx,
+ unsigned int *resy,
+ unsigned int *fps,
+ int r_16_9
+)
+{
+ /* check the EDID to find one that not large and same ratio mode*/
+#ifdef CONFIG_WMT_EDID
+ int i, cnt;
+ struct fb_videomode *p;
+ unsigned int w, h, f, option;
+
+ if ((*resx == 720) && (*resy == 480) && (*fps == 50))
+ *fps = 60;
+
+ for (i = 0, cnt = 0; ; i++) {
+ if (vpp_videomode[i].pixclock == 0)
+ break;
+ cnt++;
+ }
+
+ for (i = cnt - 1; i >= 0; i--) {
+ p = (struct fb_videomode *) &vpp_videomode[i];
+ h = p->yres;
+ if (h > *resy)
+ continue;
+
+ w = p->xres;
+ if (w > *resx)
+ continue;
+
+ f = p->refresh;
+ if (f > *fps)
+ continue;
+
+ if (r_16_9 != vout_check_ratio_16_9(w, h))
+ continue;
+
+ option = f & EDID_TMR_FREQ;
+ option |= (p->vmode & FB_VMODE_INTERLACED) ?
+ EDID_TMR_INTERLACE : 0;
+
+ if (edid_find_support(info, w, h, option, &p)) {
+ *resx = w;
+ *resy = h;
+ *fps = f;
+ DBG_MSG("(%dx%d@%d)\n", w, h, f);
+ return 1;
+ }
+ }
+#endif
+ return 0;
+}
+
+/*----------------------- vout control API ----------------------------------*/
+void vout_set_framebuffer(struct vout_info_t *info, vdo_framebuf_t *fb)
+{
+ int i;
+ struct vout_t *vo;
+
+ if (!info)
+ return;
+
+ for (i = 0; i < VPP_VOUT_NUM; i++) {
+ vo = info->vout[i];
+ if (vo == 0)
+ break;
+ if (vo->govr)
+ vo->govr->fb_p->set_framebuf(fb);
+ }
+}
+
+int vout_set_blank(int no, enum vout_blank_t arg)
+{
+ struct vout_t *vo;
+
+ DBG_DETAIL("(%d,%d)\n", no, arg);
+
+ vo = vout_get_entry(no);
+ if (vo && (vo->inf)) {
+ vout_change_status(vo, VPP_VOUT_STS_BLANK, arg);
+ vo->inf->blank(vo, arg);
+ if (vo->dev && vo->dev->set_power_down)
+ vo->dev->set_power_down(
+ (arg == VOUT_BLANK_POWERDOWN) ? 1 : 0);
+ if (vo->govr)
+ govrh_set_MIF_enable(vo->govr, (arg) ? 0 : 1);
+ }
+ return 0;
+}
+
+int vout_set_mode(int no, enum vout_inf_mode_t mode)
+{
+ struct vout_t *vo;
+
+ DBG_DETAIL("(%d,%d)\n", no, mode);
+
+ if (vout_query_inf_support(no, mode) == 0) {
+ DBG_ERR("not support this interface(%d,%d)\n", no, mode);
+ return -1;
+ }
+
+ vo = vout_get_entry(no);
+ if (vo->inf) {
+ if (vo->inf->mode == mode)
+ return 0;
+ vo->inf->uninit(vo, 0);
+ vout_change_status(vo, VPP_VOUT_STS_ACTIVE, 0);
+ if (vo->dev)
+ vo->dev->set_power_down(1);
+ }
+
+ vo->inf = vout_inf_get_entry(mode);
+ vo->inf->init(vo, 0);
+ vout_change_status(vo, VPP_VOUT_STS_ACTIVE, 1);
+ return 0;
+}
+
+int vout_config(struct vout_info_t *info, struct fb_videomode *vmode,
+ vdo_framebuf_t *fb)
+{
+ struct vout_t *vo;
+ int i;
+
+ DBG_DETAIL("\n");
+
+ if (!vmode && !fb)
+ return 0;
+
+ if (vmode) {
+ /* option for interface & device config */
+ info->resx = vmode->xres;
+ info->resy = vmode->yres;
+ info->fps = (vmode->refresh == 59) ? 60 : vmode->refresh;
+ info->option = (vmode->vmode & FB_VMODE_INTERLACED) ?
+ VPP_OPT_INTERLACE : 0;
+ info->option |= (vmode->sync & FB_SYNC_HOR_HIGH_ACT) ?
+ VPP_DVO_SYNC_POLAR_HI : 0;
+ info->option |= (vmode->sync & FB_SYNC_VERT_HIGH_ACT) ?
+ VPP_DVO_VSYNC_POLAR_HI : 0;
+ }
+
+ for (i = 0; i < VPP_VOUT_NUM; i++) {
+ vo = info->vout[i];
+ if (vo == 0)
+ break;
+
+ if (vo->govr == 0)
+ continue;
+
+ if (vmode) {
+ govrh_set_videomode(vo->govr, vmode);
+
+ if (vo->inf) {
+ vo->inf->config(vo, (int)info);
+ if (vo->dev)
+ vo->dev->config(info);
+ }
+ }
+
+ if (fb)
+ govrh_set_framebuffer(vo->govr, fb);
+ }
+ return 0;
+}
+
+int vout_chkplug(int no)
+{
+ struct vout_t *vo;
+ struct vout_inf_t *inf;
+ int ret = 0;
+
+ DBG_DETAIL("(%d)\n", no);
+
+ vo = vout_get_entry(no);
+ if (vo == 0)
+ return 0;
+
+ if (vo->inf == 0)
+ return 0;
+
+ inf = vout_inf_get_entry(vo->inf->mode);
+ if (inf == 0)
+ return 0;
+
+ if (vo->dev && vo->dev->check_plugin)
+ ret = vo->dev->check_plugin(0);
+ else
+ ret = inf->chkplug(vo, 0);
+ vout_change_status(vo, VPP_VOUT_STS_PLUGIN, ret);
+ return ret;
+}
+
+int vout_inf_chkplug(int no, enum vout_inf_mode_t mode)
+{
+ struct vout_t *vo;
+ struct vout_inf_t *inf;
+ int plugin = 0;
+
+ DBG_MSG("(%d,%d)\n", no, mode);
+ if (vout_query_inf_support(no, mode) == 0)
+ return 0;
+
+ vo = vout_get_entry(no);
+ inf = vout_inf_get_entry(mode);
+ if (inf) {
+ if (inf->chkplug)
+ plugin = inf->chkplug(vo, 0);
+ }
+ return plugin;
+}
+
+char *vout_get_edid(int no)
+{
+ struct vout_t *vo;
+ int ret;
+
+ DBG_DETAIL("(%d)\n", no);
+
+ if (edid_disable)
+ return 0;
+ vo = vout_get_entry(no);
+ if (vo == 0)
+ return 0;
+
+ if (vo->status & VPP_VOUT_STS_EDID) {
+ DBG_MSG("edid exist\n");
+ return vo->edid;
+ }
+
+ vout_change_status(vo, VPP_VOUT_STS_EDID, 0);
+#ifdef CONFIG_VOUT_EDID_ALLOC
+ if (vo->edid == 0) {
+ vo->edid = kmalloc(128 * EDID_BLOCK_MAX, GFP_KERNEL);
+ if (!vo->edid) {
+ DBG_ERR("edid buf alloc\n");
+ return 0;
+ }
+ }
+#endif
+
+ ret = 1;
+ if (vo->dev && vo->dev->get_edid) {
+ ret = vo->dev->get_edid(vo->edid);
+ } else {
+ if (vo->inf->get_edid)
+ ret = vo->inf->get_edid(vo, (int)vo->edid);
+ }
+
+ if (ret == 0) {
+ DBG_DETAIL("edid read\n");
+ vout_change_status(vo, VPP_VOUT_STS_EDID, 1);
+ return vo->edid;
+ } else {
+ DBG_MSG("read edid fail\n");
+ }
+
+#ifdef CONFIG_VOUT_EDID_ALLOC
+ kfree(vo->edid);
+ vo->edid = 0;
+#endif
+ return 0;
+}
+
+int vout_get_edid_option(int no)
+{
+ struct vout_t *vo;
+
+ DBG_DETAIL("(%d)\n", no);
+
+ vo = vout_get_entry(no);
+ if (vo == 0)
+ return 0;
+
+ if (vo->edid_info.option)
+ return vo->edid_info.option;
+
+ if (vout_get_edid(no) == 0) {
+ if (no == VPP_VOUT_NUM_HDMI) { /* HDMI wo EDID still can work */
+ vo->edid_info.option = (EDID_OPT_HDMI + EDID_OPT_AUDIO);
+ return vo->edid_info.option;
+ }
+ return 0;
+ }
+
+ edid_parse(vo->edid, &vo->edid_info);
+ return vo->edid_info.option;
+}
+
+unsigned int vout_get_mask(struct vout_info_t *vo_info)
+{
+ unsigned int mask;
+ int i;
+
+ if (g_vpp.virtual_display) {
+ if (vo_info->num == 0)
+ return 0;
+ return VPP_VOUT_ALL;
+ }
+
+ mask = 0;
+ for (i = 0; i <= VPP_VOUT_NUM; i++) {
+ if (vo_info->vout[i] == 0)
+ break;
+ mask |= (0x1 << vo_info->vout[i]->num);
+ }
+ return mask;
+}
+
+int vout_check_plugin(int clr_sts)
+{
+ struct vout_t *vo;
+ int i;
+ int plugin = 0;
+
+ for (i = 0; i <= VPP_VOUT_NUM; i++) {
+ vo = vout_get_entry(i);
+ if (vo == 0)
+ continue;
+ if (vo->inf == 0)
+ continue;
+
+ if (vo->dev) {
+ if (!(vo->dev->capability & VOUT_DEV_CAP_FIX_PLUG)) {
+ if (vout_chkplug(i)) {
+ plugin = 1;
+ if (clr_sts)
+ vout_change_status(vo,
+ VPP_VOUT_STS_PLUGIN, 0);
+ DBG_MSG("[VPP] ext dev plugin\n");
+ }
+ }
+ } else {
+ if (!(vo->inf->capability & VOUT_INF_CAP_FIX_PLUG)) {
+ if (vout_chkplug(i)) {
+ plugin = 1;
+ if (clr_sts)
+ vout_change_status(vo,
+ VPP_VOUT_STS_PLUGIN, 0);
+ DBG_MSG("[VPP] inf dev plugin\n");
+ }
+ }
+ }
+ }
+ return plugin;
+}
+
+enum vout_tvformat_t vout_get_tvformat(void)
+{
+ char buf[40] = {0};
+ int varlen = 40;
+ enum vout_tvformat_t s_tvformat = TV_MAX;
+
+ if (wmt_getsyspara("wmt.display.tvformat", buf, &varlen) == 0) {
+ if (!strnicmp(buf, "PAL", 3))
+ s_tvformat = TV_PAL;
+ else if (!strnicmp(buf, "NTSC", 4))
+ s_tvformat = TV_NTSC;
+ else
+ s_tvformat = TV_UNDEFINED;
+ } else
+ s_tvformat = TV_UNDEFINED;
+
+ return s_tvformat;
+}
+
+/*--------------------End of Function Body -----------------------------------*/
+#undef VOUT_C
diff --git a/common/wmt_display/vout.h b/common/wmt_display/vout.h
new file mode 100755
index 0000000..d6dbcb6
--- /dev/null
+++ b/common/wmt_display/vout.h
@@ -0,0 +1,391 @@
+/*++
+ * linux/drivers/video/wmt/vout.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef VOUT_H
+/* To assert that only one occurrence is included */
+#define VOUT_H
+/*-------------------- MODULE DEPENDENCY -------------------------------------*/
+#include "vpp.h"
+#include "sw_i2c.h"
+#include "edid.h"
+
+/* following is the C++ header */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------- EXPORTED PRIVATE CONSTANTS ----------------------------*/
+/* #define VO_XXXX 1 *//*Example*/
+/* #define CONFIG_VOUT_EDID_ALLOC */
+#define CONFIG_VOUT_REFACTORY
+
+#define VOUT_INFO_DEFAULT_RESX 1024
+#define VOUT_INFO_DEFAULT_RESY 768
+#define VOUT_INFO_DEFAULT_FPS 60
+
+/*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/
+/* typedef void vo_xxx_t; *//*Example*/
+
+enum vout_mode_t {
+ VOUT_SD_ANALOG,
+ VOUT_SD_DIGITAL,
+ VOUT_LCD,
+ VOUT_DVI,
+ VOUT_HDMI,
+ VOUT_DVO2HDMI,
+ VOUT_LVDS,
+ VOUT_VGA,
+ VOUT_BOOT,
+ VOUT_MODE_MAX,
+ VOUT_MODE_ALL = VOUT_MODE_MAX
+};
+
+enum vout_dev_mode_t {
+ VOUT_DEV_VGA,
+ VOUT_DEV_DVI,
+ VOUT_DEV_LCD,
+ VOUT_DEV_HDMI,
+ VOUT_DEV_SDD,
+ VOUT_DEV_LVDS,
+ VOUT_DEV_MODE_MAX
+};
+
+enum vout_inf_mode_t {
+ VOUT_INF_DVI,
+ VOUT_INF_HDMI,
+ VOUT_INF_LVDS,
+ VOUT_INF_MODE_MAX
+};
+
+enum vout_tvformat_t {
+ TV_PAL,
+ TV_NTSC,
+ TV_UNDEFINED,
+ TV_MAX
+};
+
+/* wmt.display.fb0 - op:[type:op1:op2:resx:resy:fps]:[...]:[...]
+<op>:[<type>:<op1>:<op2>:<resx>:<resy>:<fps>]:[...]...
+[H] <op>:=
+<op>.Bit[3:0] : fb type (0-GE,1-alloc & fix,2-dynamic alloc,3-GE overscan)
+<op>.Bit[7:4] : hwc type (0-normal,1-scale,2-overscan,3-virtual)
+<op>.Bit[8] : multi display
+<op>.Bit[9] : color format valid flag
+<op>.Bit[23:16] : color format
+
+[H] <type>:=
+1: SDA
+[H]<op1>:= mode (0-YCbCr,1-VGA,2-YPbPr,4-SVideo,5-CVBS)
+[H]<op2>
+2: LCD
+[H]<op1>:= lcd id (0-auto or OEM,1-Chilin,2-Innolux,3-AUO,4-Eking,5-Hannstar)
+[H]<op2>:=
+<op2>.Bit[7:0] : bit per pixel
+<op2>.Bit[10:8] : rgb mode (0-888,1-555,2-666,3-565)
+<op2>.Bit[11] : msb(0-lsb,1-msb)
+<op2>.Bit[13:12] : swap (0-RGB [7-0], 1-RGB [0-7], 2-BGR [7-0], 3-BGR [0-7])
+3: DVI
+[H]<op1> :=
+<op1>.Bit[7:0] : color format(6-ARGB)
+<op1>.Bit[11:8] : dvi i2c bus id
+<op1>.Bit[15:12] : dvi interrupt gpio no
+[H]<op2> :=
+<op2>.Bit[0] : (0-12bit,1-24bit)
+<op2>.Bit[1] : (1:interlace)
+<op2>.Bit[2] : disable external device
+<op2>.Bit[3] : disable external device interrupt
+<op2>.Bit[4] : dvi i2c bus id valid
+<op2>.Bit[5] : dvi interrupt gpio no valid
+<op2>.Bit[10:8] : rgb mode (0-888,1-555,2-666,3-565)
+<op2>.Bit[11] : (0-lsb,1-msb)
+<op2>.Bit[13:12] : swap (0-RGB [7-0], 1-RGB [0-7], 2-BGR [7-0], 3-BGR [0-7])
+4: HDMI
+[H]<op1> (1-422,3-444,6-ARGB)
+[H]<op2> :=
+<op2>.Bit[0] : (0-12bit,1-24bit)
+<op2>.Bit[1] : (1:interlace)
+<op2>.Bit[2] : (1:CEC)
+<op2>.Bit[3] : (1:disable)
+<op2>.Bit[4] : (1:sp mode)
+6:LVDS
+same as LCD
+8: virtual frame buffer
+[H]<op1> (0-disable,1-enable)
+
+[D] <resx> := horizontal resolution
+[D] <resy> := vertical resolution
+[D] <fps> := frame per second
+*/
+
+#define WMT_DISP_FB_MULTI BIT(8)
+#define WMT_DISP_FB_COLFMT BIT(9)
+#define WMT_DISP_FB_COLFMT_MASK 0xFF0000
+
+#define WMT_DISP_FB_GET_BPP(a) (a & 0xFF)
+#define WMT_DISP_FB_GET_RGB_MODE(a) ((a & 0x700) >> 8)
+#define WMT_DISP_FB_MSB BIT(11)
+#define WMT_DISP_FB_RGB_SWAP(a) ((a & 0x3000) >> 12)
+
+#define WMT_DISP_FB_DVI_24BIT BIT(0)
+#define WMT_DISP_FB_INTERLACE BIT(1)
+#define WMT_DISP_FB_DISABLE_EXTDEV BIT(2)
+#define WMT_DISP_FB_DISBALE_DVI_INT BIT(3)
+#define WMT_DISP_FB_DVI_I2C BIT(4)
+#define WMT_DISP_FB_DVI_INT BIT(5)
+
+#define WMT_DISP_FB_HDMI_CEC BIT(2)
+#define WMT_DISP_FB_HDMI_DISABLE BIT(3)
+#define WMT_DISP_FB_HDMI_SP_MODE BIT(4)
+
+enum vout_alloc_mode_t {
+ VOUT_ALLOC_GE,
+ VOUT_ALLOC_FIX_MB,
+ VOUT_ALLOC_DYNAMIC_MB,
+ VOUT_ALLOC_GE_OVERSCAN,
+ VOUT_ALLOC_MODE_MAX
+};
+
+enum vout_hwc_mode_t {
+ VOUT_HWC_NORMAL,
+ VOUT_HWC_SCALE,
+ VOUT_HWC_OVERSCAN,
+ VOUT_HWC_VIRTUAL,
+ VOUT_HWC_MODE_MAX
+};
+
+struct vout_info_t {
+ int num;
+ struct vout_t *vout[VPP_VOUT_NUM + 1];
+ int multi; /* multi display in same time */
+
+ /* frame buffer alloc */
+ enum vout_alloc_mode_t alloc_mode;
+ enum vout_hwc_mode_t hwc_mode;
+ void *fb_info_p; /* fb info pointer */
+#ifdef CONFIG_KERNEL
+ struct semaphore sem;
+#endif
+
+ int resx;
+ int resy;
+ int resx_virtual;
+ int resy_virtual;
+ int bpp;
+ int fps;
+ unsigned int pixclk;
+ unsigned int option;
+
+ struct fb_videomode *fixed_vmode;
+ int fixed_width;
+ int fixed_height;
+ vdo_framebuf_t fb;
+#ifdef CONFIG_UBOOT
+ struct fb_videomode *p_vmode;
+#endif
+ struct vpp_dbg_timer_t pandisp_timer;
+ unsigned int mb;
+ unsigned int mb_size;
+};
+
+struct vout_audio_t {
+ int fmt; /* sample bits */
+ int sample_rate; /* sample rate */
+ int channel; /* channel count */
+};
+
+struct vout_t;
+struct vout_inf_t;
+
+#define VOUT_DEV_CAP_FIX_RES 0x1
+#define VOUT_DEV_CAP_EDID 0x2
+#define VOUT_DEV_CAP_AUDIO 0x4
+#define VOUT_DEV_CAP_FIX_PLUG 0x8
+
+struct vout_dev_t {
+ struct vout_dev_t *next;
+ char name[10];
+ enum vout_inf_mode_t mode;
+ struct vout_t *vout;
+ unsigned int capability;
+
+ int (*init)(struct vout_t *vo);
+ void (*set_power_down)(int enable);
+ int (*set_mode)(unsigned int *option);
+ int (*config)(struct vout_info_t *info);
+ int (*check_plugin)(int hotplug);
+ int (*get_edid)(char *buf);
+ int (*set_audio)(struct vout_audio_t *arg);
+ int (*interrupt)(void);
+ void (*poll)(void);
+ int (*suspend)(void);
+ int (*resume)(void);
+};
+
+enum vout_blank_t {
+ VOUT_BLANK_UNBLANK, /* screen: unblanked, hsync: on, vsync: on */
+ VOUT_BLANK_NORMAL, /* screen: blanked, hsync: on, vsync: on */
+ VOUT_BLANK_VSYNC_SUSPEND,/* screen: blanked, hsync: on, vsync: off */
+ VOUT_BLANK_HSYNC_SUSPEND,/* screen: blanked, hsync: off, vsync: on */
+ VOUT_BLANK_POWERDOWN /* screen: blanked, hsync: off, vsync: off */
+};
+
+#define VOUT_CAP_INTERFACE 0x000000FF
+#define VOUT_CAP_BUS 0x00000F00
+#define VOUT_CAP_GOVR 0x0000F000
+#define VOUT_CAP_EXT_DEV 0x00010000
+#define VOUT_CAP_FIX_PLUG 0x00020000
+#define VOUT_CAP_AUDIO 0x00040000
+#define VOUT_CAP_EDID 0x00080000
+
+struct vout_t {
+ int num;
+ unsigned int fix_cap;
+ struct vout_info_t *info;
+ struct vout_inf_t *inf; /* interface ops */
+ struct vout_dev_t *dev; /* device ops */
+ struct govrh_mod_t *govr;
+ int resx;
+ int resy;
+ int fps;
+ int pixclk;
+ unsigned int status;
+#ifdef CONFIG_VOUT_EDID_ALLOC
+ char *edid;
+#else
+ char edid[128*EDID_BLOCK_MAX];
+#endif
+ struct edid_info_t edid_info;
+ unsigned int option[3];
+ enum vout_blank_t pre_blank;
+ int disable;
+};
+
+#define VOUT_INF_CAP_FIX_PLUG BIT(0)
+struct vout_inf_t {
+ enum vout_inf_mode_t mode;
+ unsigned int capability;
+
+ /* function */
+ int (*init)(struct vout_t *vo, int arg);
+ int (*uninit)(struct vout_t *vo, int arg);
+ int (*blank)(struct vout_t *vo, enum vout_blank_t arg);
+ int (*config)(struct vout_t *vo, int arg);
+ int (*chkplug)(struct vout_t *vo, int arg);
+ int (*get_edid)(struct vout_t *vo, int arg);
+/* int (*ioctl)(struct vout_t *vo,int arg); */
+};
+
+/*-------------------- EXPORTED PRIVATE VARIABLES ---------------------------*/
+#ifdef VOUT_C /* allocate memory for variables only in vout.c */
+#define EXTERN
+
+const char *vout_inf_str[] = {"DVI", "HDMI", "LVDS", "VGA", "SDA", "SDD"};
+const char *vout_adpt_str[] = {"SD_DIGITAL", "SD_DIGITAL", "LCD", "DVI",
+ "HDMI", "DVO2HDMI", "LVDS", "VGA", "BOOT"};
+
+#else
+#define EXTERN extern
+
+extern const char *vout_inf_str[];
+extern const char *vout_adpt_str[];
+
+#endif /* ifdef VOUT_C */
+
+EXTERN struct vout_info_t *vout_info[VPP_VOUT_INFO_NUM];
+
+/* EXTERN int vo_xxx; *//*Example*/
+EXTERN int (*vout_board_info)(int arg);
+
+#undef EXTERN
+
+/*--------------------- EXPORTED PRIVATE MACROS -----------------------------*/
+/* #define VO_XXX_YYY xxxx *//*Example*/
+/*--------------------- EXPORTED PRIVATE FUNCTIONS -------------------------*/
+/* extern void vo_xxx(void); *//*Example*/
+
+void vout_register(int no, struct vout_t *vo);
+struct vout_t *vout_get_entry(int no);
+struct vout_info_t *vout_get_info_entry(int no);
+void vout_change_status(struct vout_t *vo, int mask, int sts);
+int vout_query_inf_support(int no, enum vout_inf_mode_t mode);
+
+int vout_inf_register(enum vout_inf_mode_t mode, struct vout_inf_t *inf);
+struct vout_inf_t *vout_inf_get_entry(enum vout_inf_mode_t mode);
+
+int vout_device_register(struct vout_dev_t *ops);
+struct vout_dev_t *vout_get_device(struct vout_dev_t *ops);
+
+struct vout_t *vout_get_entry_adapter(enum vout_mode_t mode);
+struct vout_inf_t *vout_get_inf_entry_adapter(enum vout_mode_t mode);
+int vout_info_add_entry(int no, struct vout_t *vo);
+struct vout_info_t *vout_info_get_entry(int no);
+void vout_info_set_fixed_timing(int no, struct fb_videomode *vmode);
+struct govrh_mod_t *vout_info_get_govr(int no);
+enum vpp_vout_s vout_get_mode_adapter(struct vout_t *vout);
+
+int vout_config(struct vout_info_t *info, struct fb_videomode *vmode,
+ vdo_framebuf_t *fb);
+int vout_set_mode(int no, enum vout_inf_mode_t mode);
+int vout_set_blank(int no, enum vout_blank_t blank);
+void vout_set_framebuffer(struct vout_info_t *info, vdo_framebuf_t *fb);
+int vout_chkplug(int no);
+void vout_set_int_type(int type);
+char *vout_get_edid(int no);
+int vout_get_edid_option(int no);
+int vout_check_plugin(int clr_sts);
+void vout_print_entry(struct vout_t *vo);
+
+int vout_init(void);
+int vout_exit(void);
+int vo_i2c_proc(int id, unsigned int addr, unsigned int index,
+ char *pdata, int len);
+int vout_set_audio(struct vout_audio_t *arg);
+int vout_find_edid_support_mode(struct edid_info_t *info,
+ unsigned int *resx, unsigned int *resy, unsigned int *fps, int r_16_9);
+int vout_check_ratio_16_9(unsigned int resx, unsigned int resy);
+unsigned int vout_get_mask(struct vout_info_t *vo_info);
+void vout_set_int_enable(int enable);
+int vout_get_clr_int(void);
+void vo_hdmi_set_clock(int enable);
+enum vout_tvformat_t vout_get_tvformat(void);
+#ifndef CONFIG_VPOST
+int vout_find_match_mode(int fbnum,
+ struct fb_videomode *vmode, int match);
+#endif
+#define VOUT_MODE_OPTION_LESS BIT0
+#define VOUT_MODE_OPTION_GREATER BIT1
+#define VOUT_MODE_OPTION_EDID BIT2
+#define VOUT_MODE_OPTION_INTERLACE BIT3
+#define VOUT_MODE_OPTION_PROGRESS BIT4
+struct fb_videomode *vout_get_video_mode(int vout_num,
+ struct fb_videomode *vmode, int option);
+int vout_get_width_height(int fbnum, int *width, int *height);
+void vo_hdmi_cp_set_enable_tmr(int sec);
+struct vout_dev_t *lcd_get_dev(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ifndef VOUT_H */
+
+/*=== END vout.h ==========================================================*/
diff --git a/common/wmt_display/vpp-osif.c b/common/wmt_display/vpp-osif.c
new file mode 100755
index 0000000..f679946
--- /dev/null
+++ b/common/wmt_display/vpp-osif.c
@@ -0,0 +1,912 @@
+/*++
+ * linux/drivers/video/wmt/osif.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define VPP_OSIF_C
+#undef DEBUG
+/* #define DEBUG */
+/* #define DEBUG_DETAIL */
+/*----------------------- DEPENDENCE -----------------------------------------*/
+#include "vpp.h"
+
+/*----------------------- PRIVATE MACRO --------------------------------------*/
+
+/*----------------------- PRIVATE CONSTANTS ----------------------------------*/
+/* #define LVDS_XXXX 1 *//*Example*/
+
+/*----------------------- PRIVATE TYPE --------------------------------------*/
+/* typedef xxxx lvds_xxx_t; *//*Example*/
+
+/*----------EXPORTED PRIVATE VARIABLES are defined in lvds.h -------------*/
+/*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/
+/* int lvds_xxx; *//*Example*/
+#ifdef __KERNEL__
+static DEFINE_SPINLOCK(vpp_irqlock);
+static unsigned long vpp_lock_flags;
+#endif
+
+/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/
+/* void lvds_xxx(void); *//*Example*/
+
+/*----------------------- Function Body --------------------------------------*/
+#ifdef __KERNEL__
+#include <asm/io.h>
+#include <linux/proc_fs.h>
+#else
+inline unsigned int inl(unsigned int offset)
+{
+ return *(unsigned int *)(offset);
+}
+
+inline void outl(unsigned int val, unsigned int offset)
+{
+ (*(unsigned int *)(offset)) = val;
+}
+
+inline unsigned short inw(unsigned int offset)
+{
+ return *(unsigned short *)(offset);
+}
+
+inline void outw(unsigned short val, unsigned int offset)
+{
+ (*(unsigned short *)(offset)) = val;
+}
+
+inline unsigned char inb(unsigned int offset)
+{
+ return *(unsigned char *)(offset);
+}
+
+inline void outb(unsigned char val, unsigned int offset)
+{
+ (*(unsigned char *)(offset)) = val;
+}
+#ifndef CFG_LOADER
+int get_key(void)
+{
+ int key;
+
+ key = get_num(0, 256, "Input:", 5);
+ DPRINT("\n");
+ return key;
+}
+
+void udelay(int us)
+{
+ vpp_post_delay(us);
+}
+
+void mdelay(int ms)
+{
+ udelay(ms * 1000);
+}
+#endif
+#endif
+
+void vpp_udelay(unsigned int us)
+{
+#if 1
+ udelay(us);
+#else
+ unsigned int cur;
+ unsigned int cross;
+
+ if (us == 0)
+ return;
+
+ cur = wmt_read_oscr();
+ us = cur + us * 3;
+ cross = (us < cur) ? cur : 0; /* check overflow */
+ while (1) {
+ if (cross) {
+ if (cur < cross)
+ cross = 0;
+ } else {
+ if (us < cur)
+ break;
+ }
+ cur = wmt_read_oscr();
+ }
+#endif
+}
+
+/* Internal functions */
+U32 vppif_reg32_write(U32 offset, U32 mask, U32 shift, U32 val)
+{
+ U32 new_val;
+
+#if 0
+ if (val > (mask >> shift))
+ MSG("*E* check the parameter 0x%x 0x%x 0x%x 0x%x\n",
+ offset, mask, shift, val);
+#endif
+ new_val = (inl(offset) & ~(mask)) | (((val) << (shift)) & mask);
+ outl(new_val, offset);
+ return new_val;
+}
+EXPORT_SYMBOL(vppif_reg32_write);
+
+U32 vppif_reg32_read(U32 offset, U32 mask, U32 shift)
+{
+ return (inl(offset) & mask) >> shift;
+}
+EXPORT_SYMBOL(vppif_reg32_read);
+
+U32 vppif_reg32_mask(U32 offset, U32 mask, U32 shift)
+{
+ return mask;
+}
+
+int vpp_request_irq(unsigned int irq_no, void *routine,
+ unsigned int flags, char *name, void *arg)
+{
+#if 0 /* disable irq */
+ return 0;
+#endif
+
+#ifdef __KERNEL__
+ if (request_irq(irq_no, routine, flags, name, arg)) {
+ DPRINT("[VPP] *E* request irq %s fail\n", name);
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+void vpp_free_irq(unsigned int irq_no, void *arg)
+{
+#ifdef __KERNEL__
+ free_irq(irq_no, arg);
+#endif
+}
+
+#ifndef __KERNEL__
+int wmt_getsyspara(char *varname, char *varval, int *varlen)
+{
+#ifdef CONFIG_VPOST
+ struct env_para_def param;
+#endif
+ int i = 0;
+ char *p;
+
+#ifdef CONFIG_VPOST
+ p = 0;
+ if (env_read_para(varname, &param) == 0)
+ p = param.value;
+#else
+ p = getenv(varname);
+#endif
+ if (!p) {
+ /* printf("## Warning: %s not defined\n", varname); */
+ return -1;
+ }
+ while (p[i] != '\0') {
+ varval[i] = p[i];
+ i++;
+ }
+ varval[i] = '\0';
+ *varlen = i;
+ /* printf("getsyspara: %s,len %d\n", p, *varlen); */
+#ifdef CONFIG_VPOST
+ free(param.value);
+#endif
+ return 0;
+}
+#endif
+
+int vpp_parse_param(char *buf, unsigned int *param,
+ int cnt, unsigned int hex_mask)
+{
+ char *p;
+ char *endp;
+ int i = 0;
+
+ if (*buf == '\0')
+ return 0;
+
+ for (i = 0; i < cnt; i++)
+ param[i] = 0;
+
+ p = (char *)buf;
+ for (i = 0; i < cnt; i++) {
+#ifdef CONFIG_VPOST
+ param[i] = strtoul(p, &endp,
+ (hex_mask & (0x1 << i)) ? 16 : 0);
+#else
+ param[i] = simple_strtoul(p, &endp,
+ (hex_mask & (0x1 << i)) ? 16 : 0);
+#endif
+ if (*endp == '\0')
+ break;
+ p = endp + 1;
+
+ if (*p == '\0')
+ break;
+ }
+ return i + 1;
+}
+
+unsigned int vpp_lock_cnt;
+void vpp_lock_l(void)
+{
+#ifdef __KERNEL__
+#if 0
+ vpp_lock_cnt++;
+ DPRINT("vpp_lock(%d)\n", vpp_lock_cnt);
+#endif
+ spin_lock_irqsave(&vpp_irqlock, vpp_lock_flags);
+#else
+#endif
+}
+
+void vpp_unlock(void)
+{
+#ifdef __KERNEL__
+#if 0
+ vpp_lock_cnt--;
+ DPRINT("vpp_unlock(%d)\n", vpp_lock_cnt);
+#endif
+ spin_unlock_irqrestore(&vpp_irqlock, vpp_lock_flags);
+#else
+#endif
+}
+
+#ifdef __KERNEL__
+struct i2c_adapter *vpp_i2c_adapter;
+struct i2c_client *vpp_i2c_client;
+struct vpp_i2c_priv {
+ unsigned int var;
+};
+static int __devinit vpp_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct vpp_i2c_priv *vpp_i2c;
+ int ret = 0;
+
+ DBGMSG("\n");
+ if (vpp_i2c_client == 0)
+ return -ENODEV;
+
+ if (!i2c_check_functionality(vpp_i2c_client->adapter, I2C_FUNC_I2C)) {
+ DBG_ERR("need I2C_FUNC_I2C\n");
+ return -ENODEV;
+ }
+
+ vpp_i2c = kzalloc(sizeof(struct vpp_i2c_priv), GFP_KERNEL);
+ if (vpp_i2c == NULL) {
+ DBG_ERR("kzalloc fail\n");
+ return -ENOMEM;
+ }
+ i2c_set_clientdata(i2c, vpp_i2c);
+ return ret;
+}
+
+static int vpp_i2c_remove(struct i2c_client *client)
+{
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+static const struct i2c_device_id vpp_i2c_id[] = {
+ { "vpp_i2c", 0},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, vpp_i2c_id);
+
+static struct i2c_driver vpp_i2c_driver = {
+ .probe = vpp_i2c_probe,
+ .remove = vpp_i2c_remove,
+ .id_table = vpp_i2c_id,
+ .driver = { .name = "vpp_i2c", },
+};
+
+static struct i2c_board_info vpp_i2c_board_info = {
+ .type = "vpp_i2c",
+ .flags = 0x00,
+ .platform_data = NULL,
+ .archdata = NULL,
+ .irq = -1,
+};
+#endif
+#ifdef __KERNEL__
+int vpp_i2c_xfer(struct i2c_msg *msg, unsigned int num, int bus_id)
+#else
+int vpp_i2c_xfer(struct i2c_msg_s *msg, unsigned int num, int bus_id)
+#endif
+{
+ int ret = 1;
+
+#ifdef __KERNEL__
+ int i = 0;
+#if 0
+ if (bus_id == 1) {
+ ret = wmt_i2c_xfer_continue_if_4(msg, num, bus_id);
+ return ret;
+ }
+#endif
+
+ if (num > 1) {
+ for (i = 0; i < num - 1; ++i)
+ msg[i].flags |= I2C_M_NOSTART;
+ }
+ ret = i2c_transfer(vpp_i2c_adapter, msg, num);
+ if (ret <= 0) {
+ DBG_ERR("i2c fail\n");
+ return ret;
+ }
+#elif defined(CONFIG_VPOST)
+ ret = i2c_transfer(msg, num);
+#else
+ ret = wmt_i2c_transfer(msg, num, bus_id);
+#endif
+ return ret;
+}
+
+int vpp_i2c_init(int i2c_id, unsigned short addr)
+{
+#ifdef __KERNEL__
+ struct i2c_board_info *vpp_i2c_bi = &vpp_i2c_board_info;
+ int ret = 0;
+
+ DBGMSG("id %d,addr 0x%x\n", i2c_id, addr);
+
+ if (i2c_id & VPP_DVI_I2C_SW_BIT)
+ return 0;
+
+ i2c_id &= VPP_DVI_I2C_ID_MASK;
+ vpp_i2c_adapter = i2c_get_adapter(i2c_id);
+ if (vpp_i2c_adapter == NULL) {
+ DBG_ERR("can not get i2c adapter, client address error\n");
+ return -ENODEV;
+ }
+
+ vpp_i2c_bi->addr = addr >> 1;
+
+ vpp_i2c_client = i2c_new_device(vpp_i2c_adapter, vpp_i2c_bi);
+ if (vpp_i2c_client == NULL) {
+ DBG_ERR("allocate i2c client failed\n");
+ return -ENOMEM;
+ }
+ i2c_put_adapter(vpp_i2c_adapter);
+
+ ret = i2c_add_driver(&vpp_i2c_driver);
+ if (ret)
+ DBG_ERR("i2c_add_driver fail\n");
+ return ret;
+#else
+ return 0;
+#endif
+}
+
+int vpp_i2c_release(void)
+{
+#ifdef __KERNEL__
+ if (vpp_i2c_client) {
+ i2c_del_driver(&vpp_i2c_driver);
+ i2c_unregister_device(vpp_i2c_client);
+ vpp_i2c_remove(vpp_i2c_client);
+ vpp_i2c_client = 0;
+ }
+#else
+
+#endif
+ return 0;
+}
+
+#ifdef __KERNEL__
+static DEFINE_SEMAPHORE(vpp_i2c_sem);
+#endif
+void vpp_i2c_set_lock(int lock)
+{
+#ifdef __KERNEL__
+ if (lock)
+ down(&vpp_i2c_sem);
+ else
+ up(&vpp_i2c_sem);
+#endif
+}
+
+int vpp_i2c_lock;
+int vpp_i2c_enhanced_ddc_read(int id, unsigned int addr,
+ unsigned int index, char *pdata, int len)
+{
+#ifdef __KERNEL__
+ struct i2c_msg msg[3];
+#else
+ struct i2c_msg_s msg[3];
+#endif
+ unsigned char buf[len + 1];
+ unsigned char buf2[2];
+ int ret = 0;
+
+ vpp_i2c_set_lock(1);
+
+ if (vpp_i2c_lock)
+ DBG_ERR("in lock\n");
+
+ vpp_i2c_lock = 1;
+
+ id = id & VPP_DVI_I2C_ID_MASK;
+ buf2[0] = 0x1;
+ buf2[1] = 0x0;
+ msg[0].addr = (0x60 >> 1);
+ msg[0].flags = 0 ;
+ msg[0].flags &= ~(I2C_M_RD);
+ msg[0].len = 1;
+ msg[0].buf = buf2;
+
+ addr = (addr >> 1);
+ memset(buf, 0x55, len + 1);
+ buf[0] = index;
+ buf[1] = 0x0;
+
+ msg[1].addr = addr;
+ msg[1].flags = 0 ;
+ msg[1].flags &= ~(I2C_M_RD);
+ msg[1].len = 1;
+ msg[1].buf = buf;
+
+ msg[2].addr = addr;
+ msg[2].flags = 0 ;
+ msg[2].flags |= (I2C_M_RD);
+ msg[2].len = len;
+ msg[2].buf = buf;
+
+ ret = vpp_i2c_xfer(msg, 3, id);
+ memcpy(pdata, buf, len);
+ vpp_i2c_lock = 0;
+ vpp_i2c_set_lock(0);
+ return ret;
+} /* End of vpp_i2c_enhanced_ddc_read */
+EXPORT_SYMBOL(vpp_i2c_enhanced_ddc_read);
+
+int vpp_i2c_read(int id, unsigned int addr,
+ unsigned int index, char *pdata, int len)
+{
+ int ret = 0;
+
+ DBG_DETAIL("(%d,0x%x,%d,%d)\n", id, addr, index, len);
+ vpp_i2c_set_lock(1);
+ if (vpp_i2c_lock)
+ DBG_ERR("in lock\n");
+
+ vpp_i2c_lock = 1;
+
+ id = id & VPP_DVI_I2C_ID_MASK;
+ switch (id) {
+ case 0 ... 0xF: /* hw i2c */
+ {
+#ifdef CONFIG_KERNEL
+ struct i2c_msg msg[2];
+#else
+ struct i2c_msg_s msg[2] ;
+#endif
+ unsigned char buf[len + 1];
+
+ addr = (addr >> 1);
+
+ buf[0] = index;
+ buf[1] = 0x0;
+
+ msg[0].addr = addr; /* slave address */
+ msg[0].flags = 0 ;
+ msg[0].flags &= ~(I2C_M_RD);
+ msg[0].len = 1;
+ msg[0].buf = buf;
+
+ msg[1].addr = addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = len;
+ msg[1].buf = buf;
+ ret = vpp_i2c_xfer(msg, 2, id);
+ memcpy(pdata, buf, len);
+ }
+ break;
+ default:
+#ifdef CONFIG_KERNEL
+ ret = vo_i2c_proc((id & 0xF), (addr | BIT0), index, pdata, len);
+#endif
+ break;
+ }
+#ifdef DEBUG
+ {
+ int i;
+
+ DBGMSG("vpp_i2c_read(addr 0x%x,index 0x%x,len %d\n", addr, index, len);
+ for (i = 0; i < len; i += 8) {
+ DBGMSG("%d : 0x%02x 0x%02x 0x%02x 0x%02x",
+ i, pdata[i], pdata[i + 1], pdata[i + 2], pdata[i + 3]);
+ DBGMSG(" 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ pdata[i + 4], pdata[i + 5], pdata[i + 6], pdata[i + 7]);
+ }
+ }
+#endif
+ vpp_i2c_lock = 0;
+ vpp_i2c_set_lock(0);
+ return ret;
+}
+EXPORT_SYMBOL(vpp_i2c_read);
+
+int vpp_i2c_write(int id, unsigned int addr, unsigned int index,
+ char *pdata, int len)
+{
+ int ret = 0;
+
+ DBG_DETAIL("(%d,0x%x,%d,%d)\n", id, addr, index, len);
+ vpp_i2c_set_lock(1);
+ if (vpp_i2c_lock)
+ DBG_ERR("in lock\n");
+
+ vpp_i2c_lock = 1;
+
+ id = id & VPP_DVI_I2C_ID_MASK;
+ switch (id) {
+ case 0 ... 0xF: /* hw i2c */
+ {
+#ifdef CONFIG_KERNEL
+ struct i2c_msg msg[1];
+#else
+ struct i2c_msg_s msg[1] ;
+#endif
+ unsigned char buf[len + 1];
+
+ addr = (addr >> 1);
+ buf[0] = index;
+ memcpy(&buf[1], pdata, len);
+ msg[0].addr = addr; /* slave address */
+ msg[0].flags = 0 ;
+ msg[0].flags &= ~(I2C_M_RD);
+ msg[0].len = len + 1;
+ msg[0].buf = buf;
+ ret = vpp_i2c_xfer(msg, 1, id);
+ }
+ break;
+ default:
+#ifdef CONFIG_KERNEL
+ vo_i2c_proc((id & 0xF), (addr & ~BIT0), index, pdata, len);
+#endif
+ break;
+ }
+
+#ifdef DEBUG
+ {
+ int i;
+
+ DBGMSG("vpp_i2c_write(addr 0x%x,index 0x%x,len %d\n", addr, index, len);
+ for (i = 0; i < len; i += 8) {
+ DBGMSG("%d : 0x%02x 0x%02x 0x%02x 0x%02x",
+ i, pdata[i], pdata[i + 1], pdata[i + 2], pdata[i + 3]);
+ DBGMSG(" 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ pdata[i + 4], pdata[i + 5], pdata[i + 6], pdata[i + 7]);
+ }
+ }
+#endif
+ vpp_i2c_lock = 0;
+ vpp_i2c_set_lock(0);
+ return ret;
+}
+EXPORT_SYMBOL(vpp_i2c_write);
+
+void DelayMS(int ms)
+{
+ mdelay(ms);
+}
+EXPORT_SYMBOL(DelayMS);
+
+/*----------------------- VPP debug --------------------------------------*/
+#define VPP_DEBUG_FUNC
+#ifdef VPP_DEBUG_FUNC
+#define VPP_DBG_TMR_NUM 3
+/* #define VPP_DBG_DIAG_NUM 100 */
+#ifdef VPP_DBG_DIAG_NUM
+char vpp_dbg_diag_str[VPP_DBG_DIAG_NUM][100];
+int vpp_dbg_diag_index;
+int vpp_dbg_diag_delay;
+#endif
+
+int vpp_check_dbg_level(enum vpp_dbg_level_t level)
+{
+ if (level == VPP_DBGLVL_ALL)
+ return 1;
+
+ switch (g_vpp.dbg_msg_level) {
+ case VPP_DBGLVL_DISABLE:
+ break;
+ case VPP_DBGLVL_ALL:
+ return 1;
+ default:
+ if (g_vpp.dbg_msg_level == level)
+ return 1;
+ break;
+ }
+ return 0;
+}
+
+void vpp_dbg_show(int level, int tmr, char *str)
+{
+#ifdef __KERNEL__
+ static struct timeval pre_tv[VPP_DBG_TMR_NUM];
+ struct timeval tv;
+ unsigned int tm_usec = 0;
+
+ if (vpp_check_dbg_level(level) == 0)
+ return;
+
+ if (tmr && (tmr <= VPP_DBG_TMR_NUM)) {
+ do_gettimeofday(&tv);
+ if (pre_tv[tmr - 1].tv_sec)
+ tm_usec = (tv.tv_sec == pre_tv[tmr - 1].tv_sec) ?
+ (tv.tv_usec - pre_tv[tmr - 1].tv_usec) :
+ (1000000 + tv.tv_usec - pre_tv[tmr - 1].tv_usec);
+ pre_tv[tmr - 1] = tv;
+ }
+
+#ifdef VPP_DBG_DIAG_NUM
+ if (level == VPP_DBGLVL_DIAG) {
+ if (str) {
+ char *ptr = &vpp_dbg_diag_str[vpp_dbg_diag_index][0];
+ sprintf(ptr, "%s (%d,%d)(T%d %d usec)", str,
+ (int)tv.tv_sec, (int)tv.tv_usec, tmr,
+ (int) tm_usec);
+ vpp_dbg_diag_index = (vpp_dbg_diag_index + 1)
+ % VPP_DBG_DIAG_NUM;
+ }
+
+ if (vpp_dbg_diag_delay) {
+ vpp_dbg_diag_delay--;
+ if (vpp_dbg_diag_delay == 0) {
+ int i;
+
+ DPRINT("----- VPP DIAG -----\n");
+ for (i = 0; i < VPP_DBG_DIAG_NUM; i++) {
+ DPRINT("%02d : %s\n", i,
+ &vpp_dbg_diag_str[vpp_dbg_diag_index][0]);
+ vpp_dbg_diag_index = (vpp_dbg_diag_index + 1)
+ % VPP_DBG_DIAG_NUM;
+ }
+ }
+ }
+ return;
+ }
+#endif
+
+ if (str) {
+ if (tmr)
+ DPRINT("[VPP] %s (T%d period %d usec)\n", str,
+ tmr - 1, (int) tm_usec);
+ else
+ DPRINT("[VPP] %s\n", str);
+ }
+#else
+ if (vpp_check_dbg_level(level) == 0)
+ return;
+
+ if (str)
+ DPRINT("[VPP] %s\n", str);
+#endif
+} /* End of vpp_dbg_show */
+
+void vpp_dbg_show_val1(int level, int tmr, char *str, int val)
+{
+ if (vpp_check_dbg_level(level)) {
+ char buf[50];
+
+ sprintf(buf, "%s 0x%x", str, val);
+ vpp_dbg_show(level, tmr, buf);
+ }
+}
+
+#ifdef __KERNEL__
+static DECLARE_WAIT_QUEUE_HEAD(vpp_dbg_wq);
+void vpp_dbg_wait(char *str)
+{
+ DPRINT("[VPP] vpp_dbg_wait(%s)\n", str);
+ wait_event_interruptible(vpp_dbg_wq, (g_vpp.dbg_wait));
+ g_vpp.dbg_wait = 0;
+ DPRINT("[VPP] Exit vpp_dbg_wait\n");
+}
+
+void vpp_dbg_wake_up(void)
+{
+ wake_up(&vpp_dbg_wq);
+}
+
+int vpp_dbg_get_period_usec(struct vpp_dbg_period_t *p, int cmd)
+{
+ struct timeval tv;
+ int tm_usec = 0;
+
+ if (p == 0)
+ return 0;
+
+ do_gettimeofday(&tv);
+ if (p->pre_tv.tv_sec)
+ tm_usec = (tv.tv_sec == p->pre_tv.tv_sec) ?
+ (tv.tv_usec - p->pre_tv.tv_usec) :
+ (1000000 + tv.tv_usec - p->pre_tv.tv_usec);
+ p->pre_tv = tv;
+ if (cmd == 0) { /* reset */
+ p->index = 0;
+ memset(&p->period_us, 0, VPP_DBG_PERIOD_NUM);
+ } else if (p->index < VPP_DBG_PERIOD_NUM) {
+ p->period_us[p->index] = tm_usec;
+ p->index++;
+ }
+
+ if (cmd == 2) { /* show */
+ int i, sum = 0;
+
+ DPRINT("[VPP] period");
+ for (i = 0; i < VPP_DBG_PERIOD_NUM; i++) {
+ DPRINT(" %d", p->period_us[i]);
+ sum += p->period_us[i];
+ }
+ DPRINT(",sum %d\n", sum);
+ }
+ return tm_usec;
+}
+
+void vpp_dbg_timer(struct vpp_dbg_timer_t *p, char *str, int cmd)
+{
+ struct timeval tv;
+ int tm_usec = 0;
+ int initial = 0;
+
+ if (p == 0)
+ return;
+
+ if (p->reset == 0) { /* default */
+ p->reset = 150;
+ initial = 1;
+ }
+
+ do_gettimeofday(&tv);
+ if (p->pre_tv.tv_sec)
+ tm_usec = (tv.tv_sec == p->pre_tv.tv_sec) ?
+ (tv.tv_usec - p->pre_tv.tv_usec) :
+ (1000000 + tv.tv_usec - p->pre_tv.tv_usec);
+ p->pre_tv = tv;
+ switch (cmd) {
+ case 0: /* initial */
+ initial = 1;
+ break;
+ case 1: /* start */
+ break;
+ case 2: /* end */
+ p->cnt++;
+ p->sum += tm_usec;
+ if (p->min > tm_usec)
+ p->min = tm_usec;
+ if (p->max < tm_usec)
+ p->max = tm_usec;
+ if (p->threshold && (tm_usec >= p->threshold))
+ MSG("%s tmr %d over %d\n", str, tm_usec, p->threshold);
+ if (p->cnt >= p->reset) {
+ int us_1t;
+
+ us_1t = p->sum / p->cnt;
+ MSG("%s(Cnt %d)Sum %d us,Avg %d,Min %d,Max %d,",
+ str, p->cnt, p->sum, us_1t, p->min, p->max);
+ MSG("fps %d.%02d\n", 1000000 / us_1t,
+ (100000000 / us_1t) % 100);
+ initial = 1;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (initial) {
+ p->cnt = 0;
+ p->sum = 0;
+ p->min = ~0;
+ p->max = 0;
+ }
+}
+#endif
+#else
+void vpp_dbg_show(int level, int tmr, char *str) {}
+static void vpp_dbg_show_val1(int level, int tmr, char *str, int val) {}
+void vpp_dbg_wait(char *str) {}
+#endif
+
+#if 0
+static void load_regs(struct pt_regs *ptr)
+{
+ asm volatile(
+ "stmia %0, {r0 - r15}\n\t"
+ :
+ : "r" (ptr)
+ : "memory"
+ );
+}
+
+void vpp_dbg_back_trace(void)
+{
+ struct pt_regs *ptr;
+ unsigned int fp;
+ unsigned long flags;
+
+ ptr = kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
+
+ local_irq_save(flags);
+
+ MSG("\n\nstart back trace...\n");
+ load_regs(ptr);
+ fp = ptr->ARM_fp;
+ c_backtrace(fp, 0x1f);
+ MSG("back trace end...\n\n");
+
+ local_irq_restore(flags);
+
+ kfree(ptr);
+}
+EXPORT_SYMBOL(vpp_dbg_back_trace);
+#endif
+
+void vpp_reg_dump(unsigned int addr, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i += 16) {
+ DPRINT("0x%8x : 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ addr + i, inl(addr + i),
+ inl(addr + i + 4),
+ inl(addr + i + 8),
+ inl(addr + i + 12));
+ }
+}
+
+unsigned int *vpp_backup_reg(unsigned int addr, unsigned int size)
+{
+ unsigned int *ptr;
+ int i;
+
+ size += 4;
+ ptr = kmalloc(size, GFP_KERNEL);
+ if (ptr == 0) {
+ DPRINT("[VPP] *E* malloc backup fail\n");
+ return 0;
+ }
+
+ for (i = 0; i < size; i += 4)
+ ptr[i / 4] = inl(addr + i);
+ return ptr;
+}
+
+int vpp_restore_reg(unsigned int addr, unsigned int size,
+ unsigned int *reg_ptr)
+{
+ int i;
+
+ if (reg_ptr == NULL)
+ return 0;
+
+ size += 4;
+ for (i = 0; i < size; i += 4)
+ outl(reg_ptr[i / 4], addr + i);
+ kfree(reg_ptr);
+ reg_ptr = 0;
+ return 0;
+}
+
diff --git a/common/wmt_display/vpp-osif.h b/common/wmt_display/vpp-osif.h
new file mode 100755
index 0000000..3117e31
--- /dev/null
+++ b/common/wmt_display/vpp-osif.h
@@ -0,0 +1,266 @@
+/*++
+ * linux/drivers/video/wmt/vpp-osif.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#ifndef VPP_OSIF_H
+#define VPP_OSIF_H
+
+/*-------------------- DEPENDENCY -------------------------------------*/
+#ifdef CFG_LOADER
+ #define CONFIG_UBOOT
+
+ #ifdef __KERNEL__
+ #undef __KERNEL__
+ #endif
+#elif defined(__KERNEL__)
+ #define CONFIG_KERNEL
+#else
+ #define CONFIG_VPOST
+#endif
+
+/* -------------------------------------------------- */
+#ifdef DEBUG
+ #define DBG_MSG(fmt, args...) DPRINT("{%s} " fmt, __func__, ## args)
+#else
+ #define DBG_MSG(fmt, args...)
+#endif
+
+#ifdef DEBUG_DETAIL
+#define DBG_DETAIL(fmt, args...) DPRINT("{%s} " fmt, __func__, ## args)
+#else
+#define DBG_DETAIL(fmt, args...)
+#endif
+#define MSG(fmt, args...) DPRINT("" fmt, ## args)
+#define DBG_ERR(fmt, args...) \
+ DPRINT(KERN_ERR "*E* {%s} " fmt, __func__, ## args)
+#define DMSG(fmt, args...) \
+ DPRINT("{%s,%d} " fmt, __func__, __LINE__, ## args)
+
+#ifdef DEBUG
+#define DBGMSG(fmt, args...) DPRINT("{%s} " fmt, __func__, ## args)
+#else
+#define DBGMSG(fmt, args...)
+#endif
+
+#if 0 /* disable all msg */
+#undef MSG
+#undef DBGMSG
+
+#define MSG(fmt, args...)
+#define DBGMSG(fmt,args...)
+#endif
+
+#define HW_REG volatile
+
+/* -------------------------------------------------- */
+#ifdef CONFIG_KERNEL
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/wmt-mb.h>
+#include <linux/netlink.h>
+#include <linux/switch.h>
+#include <net/sock.h>
+#include <mach/hardware.h>
+#include <mach/wmt_mmap.h>
+
+#define SA_INTERRUPT IRQF_DISABLED
+#endif
+
+/* -------------------------------------------------- */
+#ifdef CONFIG_UBOOT
+#define CONFIG_WMT_EDID
+#define CONFIG_WMT_EXT_DEV_PLUG_DISABLE
+
+#include <linux/types.h>
+#include "../../board/wmt/include/common_def.h"
+#include <common.h>
+#include <malloc.h>
+#include "hw_devices.h"
+#include "hw/wmt_mmap.h"
+#include "hw/wmt-pwm.h"
+#include "hw/wmt-ost.h"
+#include "hw/wmt_gpio.h"
+#include "wmt_display.h"
+#include "../../board/wmt/include/wmt_clk.h"
+#include "../../board/wmt/include/i2c.h"
+
+#define abs(a) ((a>=0)? a:(-1*a))
+#endif
+
+/* -------------------------------------------------- */
+#ifdef CONFIG_VPOST
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "global.h"
+#define __ASM_ARCH_HARDWARE_H
+#include "../include/wmt_mmap.h"
+#include "../pmc/wmt_clk.h"
+#include "../i2c/i2c.h"
+#include "linux/wmt-mb.h"
+#endif
+
+/* following is the C++ header */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-------------------- EXPORTED PRIVATE CONSTANTS ----------------------------*/
+#ifdef CONFIG_KERNEL
+#define THE_MB_USER "VPP-MB"
+#define DPRINT printk
+/* -------------------------------------------------- */
+#endif
+
+#ifdef CONFIG_UBOOT
+#define IRQ_GPIO 0
+
+//--> modified by howayhuo to fix the charge-animation hangup bug
+#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
+//#define mdelay(x) wmt_delayus(1000*x)
+//#define udelay(x) wmt_delayus(x)
+//<-- end modification
+
+#define mb_alloc(a) malloc(a)
+#define kmalloc(a,b) malloc(a)
+#define kfree(a) free(a)
+#define GFP_KERNEL 0
+#define module_init(a)
+
+#define DPRINT printf
+#define mb_phys_to_virt(a) (a)
+#define mb_virt_to_phys(a) (a)
+#define EXPORT_SYMBOL(a)
+
+#define IRQF_SHARED 0
+#define IRQF_DISABLED 0
+#define SA_INTERRUPT 0
+
+#define KERN_ALERT
+#define KERN_ERR
+#define KERN_DEBUG
+#define KERN_WARNING
+#define KERN_INFO
+
+#define printk printf
+#endif
+
+/*-------------------- EXPORTED PRIVATE TYPES---------------------------------*/
+/* typedef void hdmi_xxx_t; *//*Example*/
+
+/*-------------------- EXPORTED PRIVATE VARIABLES ----------------------------*/
+#ifdef VPP_OSIF_C
+#define EXTERN
+#else
+#define EXTERN extern
+#endif /* ifdef VPP_OSIF_C */
+
+/* EXTERN int hdmi_xxx; *//*Example*/
+
+#undef EXTERN
+
+/*--------------------- EXPORTED PRIVATE MACROS ------------------------------*/
+/* #define HDMI_XXX_YYY xxxx *//*Example*/
+
+/*--------------------- EXPORTED PRIVATE FUNCTIONS --------------------------*/
+/* extern void hdmi_xxx(void); *//*Example*/
+#ifdef CONFIG_KERNEL
+extern void wmt_i2c_xfer_continue_if(struct i2c_msg *msg,
+ unsigned int num);
+extern void wmt_i2c_xfer_if(struct i2c_msg *msg);
+extern int wmt_i2c_xfer_continue_if_4(struct i2c_msg *msg,
+ unsigned int num, int bus_id);
+#else
+inline unsigned int inl(unsigned int offset);
+inline void outl(unsigned int val, unsigned int offset);
+inline unsigned short inw(unsigned int offset);
+inline void outw(unsigned short val, unsigned int offset);
+inline unsigned char inb(unsigned int offset);
+inline void outb(unsigned char val, unsigned int offset);
+#endif
+
+#ifdef CONFIG_UBOOT
+extern int wmt_getsyspara(char *varname,char *varval, int *varlen);
+extern int auto_pll_divisor(enum dev_id dev, enum clk_cmd cmd,
+ int unit, int freq);
+extern struct fb_var_screeninfo vfb_var;
+#endif
+
+#ifdef CONFIG_VPOST
+void vpp_initialization(int FunctionNumber);
+void udelay(int us);
+void mdelay(int ms);
+extern int auto_pll_divisor(enum dev_id dev, enum clk_cmd cmd,
+ int unit, int freq);
+extern void vpp_post_delay(U32 tmr);
+extern int get_num(unsigned int min, unsigned int max,
+ char *message, unsigned int retry);
+#endif
+
+extern unsigned int wmt_read_oscr(void);
+int wmt_getsyspara(char *varname,char *varval, int *varlen);
+int vpp_request_irq(unsigned int irq_no, void *routine,
+ unsigned int flags, char *name, void *arg);
+void vpp_free_irq(unsigned int irq_no, void *arg);
+int vpp_parse_param(char *buf, unsigned int *param,
+ int cnt, unsigned int hex_mask);
+void vpp_lock_l(void);
+void vpp_unlock(void);
+
+#define vpp_lock() vpp_lock_l(); \
+ /* DPRINT("vpp_lock %s %d\n",__FUNCTION__,__LINE__); */
+
+int vpp_i2c_write(int id, unsigned int addr, unsigned int index,
+ char *pdata, int len);
+int vpp_i2c_read(int id, unsigned int addr, unsigned int index,
+ char *pdata, int len);
+int vpp_i2c_enhanced_ddc_read(int id, unsigned int addr,
+ unsigned int index, char *pdata, int len);
+int vpp_i2c_init(int i2c_id, unsigned short addr);
+int vpp_i2c_release(void);
+void vpp_set_clock_enable(enum dev_id dev, int enable, int force);
+void vpp_udelay(unsigned int us);
+unsigned int vppif_reg32_write(unsigned int offset,
+ unsigned int mask, unsigned int shift, unsigned int val);
+unsigned int vppif_reg32_read(unsigned int offset,
+ unsigned int mask, unsigned int shift);
+unsigned int vppif_reg32_mask(unsigned int offset,
+ unsigned int mask, unsigned int shift);
+void vpp_reg_dump(unsigned int addr, int size);
+unsigned int *vpp_backup_reg(unsigned int addr, unsigned int size);
+int vpp_restore_reg(unsigned int addr,
+ unsigned int size, unsigned int *reg_ptr);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* VPP_OSIF_H */
+
diff --git a/common/wmt_display/vpp.c b/common/wmt_display/vpp.c
new file mode 100755
index 0000000..544d9db
--- /dev/null
+++ b/common/wmt_display/vpp.c
@@ -0,0 +1,1413 @@
+/*++
+ * linux/drivers/video/wmt/vpp.c
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#define VPP_C
+#undef DEBUG
+/* #define DEBUG */
+/* #define DEBUG_DETAIL */
+
+#include "vpp.h"
+
+struct vpp_mod_base_t *vpp_mod_base_list[VPP_MOD_MAX];
+
+unsigned int vpp_get_chipid(void)
+{
+ /* byte 3,2: chip id, byte 1:ver id, byte 0:sub id */
+ /* ex: 0x34290101 (0x3429 A0), 0x34290102 (0x3429 A1) */
+ return inl(SYSTEM_CFG_CTRL_BASE_ADDR);
+}
+
+inline void vpp_cache_sync(void)
+{
+ /* TODO */
+}
+
+void vpp_set_clock_enable(enum dev_id dev, int enable, int force)
+{
+#ifdef CONFIG_VPP_DISABLE_PM
+ return;
+#else
+ int cnt;
+
+ do {
+ cnt = auto_pll_divisor(dev,
+ (enable) ? CLK_ENABLE : CLK_DISABLE, 0, 0);
+ if (enable) {
+ if (cnt)
+ break;
+ } else {
+ if (cnt == 0)
+ break;
+ }
+ } while (force);
+/* MSG("%s(%d,%d,%d)\n", __FUNCTION__, dev, enable, cnt); */
+#endif
+}
+
+/*----------------------- vpp module --------------------------------------*/
+void vpp_mod_unregister(vpp_mod_t mod)
+{
+ struct vpp_mod_base_t *mod_p;
+
+ if (mod >= VPP_MOD_MAX)
+ return;
+
+ mod_p = vpp_mod_base_list[mod];
+ if (!mod_p)
+ return;
+
+ kfree(mod_p->fb_p);
+ kfree(mod_p);
+ vpp_mod_base_list[mod] = 0;
+}
+
+struct vpp_mod_base_t *vpp_mod_register(vpp_mod_t mod,
+ int size, unsigned int flags)
+{
+ struct vpp_mod_base_t *mod_p;
+
+ if (mod >= VPP_MOD_MAX)
+ return 0;
+
+ if (vpp_mod_base_list[mod])
+ vpp_mod_unregister(mod);
+
+ mod_p = kmalloc(size, GFP_KERNEL);
+ if (!mod_p)
+ return 0;
+
+ vpp_mod_base_list[mod] = mod_p;
+ memset(mod_p, 0, size);
+ mod_p->mod = mod;
+
+ if (flags & VPP_MOD_FLAG_FRAMEBUF) {
+ mod_p->fb_p = kmalloc(sizeof(struct vpp_fb_base_t), GFP_KERNEL);
+ if (!mod_p->fb_p)
+ goto error;
+ memset(mod_p->fb_p, 0, sizeof(struct vpp_fb_base_t));
+ }
+ DBG_DETAIL(" %d,0x%x,0x%x\n", mod, (int)mod_p, (int)mod_p->fb_p);
+ return mod_p;
+error:
+ vpp_mod_unregister(mod);
+ DPRINT("vpp mod register NG %d\n", mod);
+ return 0;
+}
+
+struct vpp_mod_base_t *vpp_mod_get_base(vpp_mod_t mod)
+{
+ if (mod >= VPP_MOD_MAX)
+ return 0;
+ return vpp_mod_base_list[mod];
+}
+
+struct vpp_fb_base_t *vpp_mod_get_fb_base(vpp_mod_t mod)
+{
+ struct vpp_mod_base_t *mod_p;
+ mod_p = vpp_mod_get_base(mod);
+ if (mod_p)
+ return mod_p->fb_p;
+ return 0;
+}
+
+vdo_framebuf_t *vpp_mod_get_framebuf(vpp_mod_t mod)
+{
+ struct vpp_mod_base_t *mod_p;
+
+ mod_p = vpp_mod_get_base(mod);
+ if (mod_p && mod_p->fb_p)
+ return &mod_p->fb_p->fb;
+ return 0;
+}
+
+void vpp_mod_set_clock(vpp_mod_t mod, vpp_flag_t enable, int force)
+{
+ struct vpp_mod_base_t *base;
+ enum dev_id pll_dev;
+ int cur_sts;
+ int ret;
+
+#ifdef CONFIG_VPP_DISABLE_PM
+ return;
+#endif
+
+ base = vpp_mod_get_base(mod);
+ if (base == 0)
+ return;
+
+ pll_dev = (base->pm & 0xFF);
+ if (pll_dev == 0)
+ return;
+
+ enable = (enable) ? VPP_FLAG_ENABLE : VPP_FLAG_DISABLE;
+ if (force) {
+ ret = auto_pll_divisor(pll_dev,
+ (enable) ? CLK_ENABLE : CLK_DISABLE, 0, 0);
+ DBG_DETAIL("[VPP] clk force(%s,%d),ret %d\n",
+ vpp_mod_str[mod], enable, ret);
+ return;
+ }
+
+ cur_sts = (base->pm & VPP_MOD_CLK_ON) ? 1 : 0;
+ if (cur_sts != enable) {
+ ret = auto_pll_divisor(pll_dev,
+ (enable) ? CLK_ENABLE : CLK_DISABLE, 0, 0);
+ base->pm = (enable) ? (base->pm | VPP_MOD_CLK_ON)
+ : (base->pm & ~VPP_MOD_CLK_ON);
+ DBG_MSG("[VPP] clk enable(%s,%d,cur %d),ret %d\n",
+ vpp_mod_str[mod], enable, cur_sts, ret);
+ }
+}
+
+vpp_display_format_t vpp_get_fb_field(vdo_framebuf_t *fb)
+{
+ if (fb->flag & VDO_FLAG_INTERLACE)
+ return VPP_DISP_FMT_FIELD;
+ return VPP_DISP_FMT_FRAME;
+}
+
+unsigned int vpp_get_base_clock(vpp_mod_t mod)
+{
+ unsigned int clock = 0;
+
+ switch (mod) {
+ default:
+ clock = auto_pll_divisor(DEV_VPP, GET_FREQ, 0, 0);
+ break;
+ case VPP_MOD_GOVRH:
+ clock = (p_govrh->vo_clock == 0) ?
+ auto_pll_divisor(DEV_HDMILVDS, GET_FREQ, 0, 0) :
+ p_govrh->vo_clock;
+ break;
+ case VPP_MOD_GOVRH2:
+ clock = (p_govrh2->vo_clock == 0) ?
+ auto_pll_divisor(DEV_DVO, GET_FREQ, 0, 0) :
+ p_govrh2->vo_clock;
+ break;
+ }
+ DBG_DETAIL("%d %d\n", mod, clock);
+ return clock;
+}
+
+void vpp_show_timing(char *str, struct fb_videomode *vmode,
+ vpp_clock_t *clk)
+{
+ DPRINT("----- %s timing -----\n", str);
+ if (vmode) {
+ int pixclk;
+
+ pixclk = (vmode->pixclock) ? PICOS2KHZ(vmode->pixclock) : 0;
+ pixclk *= 1000;
+
+ DPRINT("res(%d,%d),fps %d\n",
+ vmode->xres, vmode->yres, vmode->refresh);
+ DPRINT("pixclk %d(%d),hsync %d,vsync %d\n", vmode->pixclock,
+ pixclk, vmode->hsync_len, vmode->vsync_len);
+ DPRINT("left %d,right %d,upper %d,lower %d\n",
+ vmode->left_margin, vmode->right_margin,
+ vmode->upper_margin, vmode->lower_margin);
+ DPRINT("vmode 0x%x,sync 0x%x\n", vmode->vmode, vmode->sync);
+ }
+
+ if (clk) {
+ DPRINT("H beg %d,end %d,total %d\n", clk->begin_pixel_of_active,
+ clk->end_pixel_of_active, clk->total_pixel_of_line);
+ DPRINT("V beg %d,end %d,total %d\n", clk->begin_line_of_active,
+ clk->end_line_of_active, clk->total_line_of_frame);
+ DPRINT("Hsync %d, Vsync %d\n", clk->hsync, clk->vsync);
+ DPRINT("VBIE %d,PVBI %d\n", clk->line_number_between_VBIS_VBIE,
+ clk->line_number_between_PVBI_VBIS);
+ }
+ DPRINT("-----------------------\n");
+}
+
+void vpp_show_framebuf(char *str, vdo_framebuf_t *fb)
+{
+ if (fb == 0)
+ return;
+ DPRINT("----- %s framebuf -----\n", str);
+ DPRINT("Y addr 0x%x, size %d\n", fb->y_addr, fb->y_size);
+ DPRINT("C addr 0x%x, size %d\n", fb->c_addr, fb->c_size);
+ DPRINT("W %d, H %d, FB W %d, H %d\n", fb->img_w, fb->img_h,
+ fb->fb_w, fb->fb_h);
+ DPRINT("bpp %d, color fmt %s\n", fb->bpp, vpp_colfmt_str[fb->col_fmt]);
+ DPRINT("H crop %d, V crop %d, flag 0x%x\n",
+ fb->h_crop, fb->v_crop, fb->flag);
+ DPRINT("-----------------------\n");
+}
+
+void vpp_show_videomode(char *str, struct fb_videomode *v)
+{
+ if (v == 0)
+ return;
+ DPRINT("----- %s videomode -----\n", str);
+ DPRINT("%dx%d@%d,%d\n", v->xres, v->yres, v->refresh, v->pixclock);
+ DPRINT("h sync %d,bp %d,fp %d\n", v->hsync_len,
+ v->left_margin, v->right_margin);
+ DPRINT("v sync %d,bp %d,fp %d\n", v->vsync_len,
+ v->upper_margin, v->lower_margin);
+ DPRINT("sync 0x%x,vmode 0x%x,flag 0x%x\n", v->sync, v->vmode, v->flag);
+ DPRINT("hsync %s,vsync %s\n",
+ (v->sync & FB_SYNC_HOR_HIGH_ACT) ? "hi" : "lo",
+ (v->sync & FB_SYNC_VERT_HIGH_ACT) ? "hi" : "lo");
+ DPRINT("interlace %d,double %d\n",
+ (v->vmode & FB_VMODE_INTERLACED) ? 1 : 0,
+ (v->vmode & FB_VMODE_DOUBLE) ? 1 : 0);
+ DPRINT("-----------------------\n");
+}
+
+vpp_csc_t vpp_check_csc_mode(vpp_csc_t mode, vdo_color_fmt src_fmt,
+ vdo_color_fmt dst_fmt, unsigned int flags)
+{
+ if (mode >= VPP_CSC_MAX)
+ return VPP_CSC_BYPASS;
+
+ mode = (mode >= VPP_CSC_RGB2YUV_MIN) ?
+ (mode - VPP_CSC_RGB2YUV_MIN) : mode;
+ if (src_fmt >= VDO_COL_FMT_ARGB) {
+ mode = VPP_CSC_RGB2YUV_MIN + mode;
+ src_fmt = VDO_COL_FMT_ARGB;
+ } else {
+ src_fmt = VDO_COL_FMT_YUV444;
+ }
+ dst_fmt = (dst_fmt >= VDO_COL_FMT_ARGB) ?
+ VDO_COL_FMT_ARGB : VDO_COL_FMT_YUV444;
+ if (flags == 0)
+ mode = (src_fmt != dst_fmt) ? mode : VPP_CSC_BYPASS;
+ return mode;
+}
+
+int vpp_get_gcd(int A, int B)
+{
+ while (A != B) {
+ if (A > B)
+ A = A - B;
+ else
+ B = B - A;
+ }
+ return A;
+}
+
+int vpp_set_recursive_scale(vdo_framebuf_t *src_fb,
+ vdo_framebuf_t *dst_fb)
+{
+#ifdef WMT_FTBLK_SCL
+ int ret;
+
+ ret = p_scl->scale(src_fb, dst_fb);
+ return ret;
+#else
+ DBG_ERR("No scale\n");
+ return 0;
+#endif
+}
+
+unsigned int vpp_convert_colfmt(int yuv2rgb, unsigned int data)
+{
+ unsigned int r, g, b;
+ unsigned int y, u, v;
+ unsigned int alpha;
+
+ alpha = data & 0xff000000;
+ if (yuv2rgb) {
+ y = (data & 0xff0000) >> 16;
+ u = (data & 0xff00) >> 8;
+ v = (data & 0xff) >> 0;
+
+ r = ((1000 * y) + 1402 * (v - 128)) / 1000;
+ if (r > 0xFF)
+ r = 0xFF;
+ g = ((100000 * y) - (71414 * (v - 128))
+ - (34414 * (u - 128))) / 100000;
+ if (g > 0xFF)
+ g = 0xFF;
+ b = ((1000 * y) + (1772 * (u - 128))) / 1000;
+ if (b > 0xFF)
+ b = 0xFF;
+
+ data = ((r << 16) + (g << 8) + b);
+ } else {
+ r = (data & 0xff0000) >> 16;
+ g = (data & 0xff00) >> 8;
+ b = (data & 0xff) >> 0;
+
+ y = ((2990 * r) + (5870 * g) + (1440 * b)) / 10000;
+ if (y > 0xFF)
+ y = 0xFF;
+ u = (1280000 - (1687 * r) - (3313 * g) + (5000 * b)) / 10000;
+ if (u > 0xFF)
+ u = 0xFF;
+ v = (1280000 + (5000 * r) - (4187 * g) - (813 * b)) / 10000;
+ if (v > 0xFF)
+ v = 0xFF;
+
+ data = ((y << 16) + (v << 8) + u);
+ }
+ data = data + alpha;
+ return data;
+}
+
+void vpp_get_sys_parameter(void)
+{
+#ifndef CONFIG_VPOST
+ char buf[40];
+ int varlen = 40;
+#else
+ struct env_para_def param;
+#endif
+
+ /* vpp attribute by default */
+ g_vpp.dbg_msg_level = 0;
+ g_vpp.hdmi_audio_interface = VPP_HDMI_AUDIO_SPDIF;
+ g_vpp.hdmi_cp_enable = 1;
+
+#ifdef CONFIG_KERNEL
+ if (govrh_get_MIF_enable(p_govrh))
+ g_vpp.govrh_preinit = 1;
+ if (govrh_get_MIF_enable(p_govrh2))
+ g_vpp.govrh_preinit = 1;
+ MSG("[VPP] govrh preinit %d\n", g_vpp.govrh_preinit);
+#else
+ g_vpp.govrh_preinit = 0;
+ p_scl->scale_sync = 1;
+#endif
+
+#ifndef CONFIG_VPOST
+ if (wmt_getsyspara("wmt.display.hdmi_audio_inf", buf, &varlen) == 0) {
+ if (memcmp(buf, "i2s", 3) == 0)
+ g_vpp.hdmi_audio_interface = VPP_HDMI_AUDIO_I2S;
+ else if (memcmp(buf, "spdif", 5) == 0)
+ g_vpp.hdmi_audio_interface = VPP_HDMI_AUDIO_SPDIF;
+ }
+
+ g_vpp.mb_colfmt = VPP_UBOOT_COLFMT;
+ /* [uboot parameter] fb param : no:xresx:yres:xoffset:yoffset */
+ if (wmt_getsyspara("wmt.gralloc.param", buf, &varlen) == 0) {
+ unsigned int parm[1];
+
+ vpp_parse_param(buf, (unsigned int *)parm, 1, 0x1);
+ if (parm[0] == 32)
+ g_vpp.mb_colfmt = VDO_COL_FMT_ARGB;
+ MSG("mb colfmt : %s,%s\n", buf,
+ vpp_colfmt_str[g_vpp.mb_colfmt]);
+ }
+ p_govrh->fb_p->fb.col_fmt = g_vpp.mb_colfmt;
+ p_govrh2->fb_p->fb.col_fmt = g_vpp.mb_colfmt;
+
+ if (wmt_getsyspara("wmt.display.hdmi", buf, &varlen) == 0) {
+ unsigned int parm[1];
+
+ MSG("hdmi sp mode : %s\n", buf);
+ vpp_parse_param(buf, (unsigned int *)parm, 1, 0);
+ g_vpp.hdmi_sp_mode = (parm[0]) ? 1 : 0;
+ }
+
+ if (wmt_getsyspara("wmt.hdmi.disable", buf, &varlen) == 0)
+ g_vpp.hdmi_disable = 1;
+
+ /* [uboot parameter] reg operation : addr op val */
+ if (wmt_getsyspara("wmt.display.regop", buf, &varlen) == 0) {
+ unsigned int addr;
+ unsigned int val;
+ char op;
+ char *p, *endp;
+
+ p = buf;
+ while (1) {
+ addr = simple_strtoul(p, &endp, 16);
+ if (*endp == '\0')
+ break;
+
+ op = *endp;
+ if (endp[1] == '~') {
+ val = simple_strtoul(endp + 2, &endp, 16);
+ val = ~val;
+ } else
+ val = simple_strtoul(endp + 1, &endp, 16);
+
+ DBG_DETAIL(" reg op: 0x%X %c 0x%X\n", addr, op, val);
+ switch (op) {
+ case '|':
+ outl(inl(addr) | val, addr);
+ break;
+ case '=':
+ outl(val, addr);
+ break;
+ case '&':
+ outl(inl(addr) & val, addr);
+ break;
+ default:
+ DBG_ERR("Error, Unknown operator %c\n", op);
+ }
+
+ if (*endp == '\0')
+ break;
+ p = endp + 1;
+ }
+ }
+#else
+ if (env_read_para("wmt.display.hdmi", &param) == 0) {
+ g_vpp.hdmi_sp_mode = strtoul(param.value, 0, 16);
+ free(param.value);
+ }
+#endif
+} /* End of vpp_get_sys_parameter */
+
+void vpp_init(void)
+{
+ struct vpp_mod_base_t *mod_p;
+ unsigned int mod_mask;
+ int i;
+
+ auto_pll_divisor(DEV_NA12, CLK_ENABLE, 0, 0);
+ auto_pll_divisor(DEV_VPP, CLK_ENABLE, 0, 0);
+ auto_pll_divisor(DEV_HDCE, CLK_ENABLE, 0, 0);
+ auto_pll_divisor(DEV_HDMII2C, CLK_ENABLE, 0, 0);
+ auto_pll_divisor(DEV_HDMI, CLK_ENABLE, 0, 0);
+ auto_pll_divisor(DEV_GOVRHD, CLK_ENABLE, 0, 0);
+ auto_pll_divisor(DEV_DVO, CLK_ENABLE, 0, 0);
+ auto_pll_divisor(DEV_LVDS, CLK_ENABLE, 0, 0);
+ auto_pll_divisor(DEV_HDMILVDS, CLK_ENABLE, 0, 0);
+ auto_pll_divisor(DEV_SCL444U, CLK_ENABLE, 0, 0);
+
+ vpp_get_sys_parameter();
+
+ /* init video out module first */
+ if (g_vpp.govrh_preinit == 0) {
+ mod_mask = BIT(VPP_MOD_GOVRH2) | BIT(VPP_MOD_GOVRH)
+ | BIT(VPP_MOD_DISP) | BIT(VPP_MOD_LCDC);
+ for (i = 0; i < VPP_MOD_MAX; i++) {
+ if (!(mod_mask & (0x01 << i)))
+ continue;
+ mod_p = vpp_mod_get_base(i);
+ if (mod_p && mod_p->init)
+ mod_p->init(mod_p);
+ }
+ }
+
+#ifdef CONFIG_UBOOT
+ mod_mask = BIT(VPP_MOD_SCL) | BIT(VPP_MOD_SCLW);
+#else
+ /* init other module */
+ mod_mask = BIT(VPP_MOD_GOVW) | BIT(VPP_MOD_GOVM) | BIT(VPP_MOD_SCL)
+ | BIT(VPP_MOD_SCLW) | BIT(VPP_MOD_VPU) | BIT(VPP_MOD_VPUW)
+ | BIT(VPP_MOD_PIP) | BIT(VPP_MOD_VPPM);
+#endif
+ for (i = 0; i < VPP_MOD_MAX; i++) {
+ if (!(mod_mask & (0x01 << i)))
+ continue;
+ mod_p = vpp_mod_get_base(i);
+ if (mod_p && mod_p->init)
+ mod_p->init(mod_p);
+ }
+
+#ifdef WMT_FTBLK_LVDS
+ if (!g_vpp.govrh_preinit)
+ lvds_init();
+#endif
+#ifdef WMT_FTBLK_VOUT_HDMI
+ hdmi_init();
+#endif
+
+#ifndef CONFIG_VPOST
+ /* init vout device & get default resolution */
+ vout_init();
+#endif
+ vpp_set_clock_enable(DEV_SCL444U, 0, 1);
+ vpp_set_clock_enable(DEV_HDMII2C, 0, 0);
+ vpp_set_clock_enable(DEV_HDMI, 0, 0);
+ vpp_set_clock_enable(DEV_HDCE, 0, 0);
+ vpp_set_clock_enable(DEV_LVDS, 0, 0);
+}
+
+void vpp_get_colfmt_bpp(vdo_color_fmt colfmt, int *y_bpp, int *c_bpp)
+{
+ switch (colfmt) {
+ case VDO_COL_FMT_YUV420:
+ *y_bpp = 8;
+ *c_bpp = 4;
+ break;
+ case VDO_COL_FMT_YUV422H:
+ case VDO_COL_FMT_YUV422V:
+ *y_bpp = 8;
+ *c_bpp = 8;
+ break;
+ case VDO_COL_FMT_RGB_565:
+ case VDO_COL_FMT_RGB_1555:
+ case VDO_COL_FMT_RGB_5551:
+ *y_bpp = 16;
+ *c_bpp = 0;
+ break;
+ case VDO_COL_FMT_YUV444:
+ *y_bpp = 8;
+ *c_bpp = 16;
+ break;
+ case VDO_COL_FMT_RGB_888:
+ case VDO_COL_FMT_RGB_666:
+ *y_bpp = 24;
+ *c_bpp = 0;
+ break;
+ case VDO_COL_FMT_ARGB:
+ *y_bpp = 32;
+ *c_bpp = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+int vpp_calc_refresh(int pixclk, int xres, int yres)
+{
+ int refresh = 60;
+ int temp;
+
+ temp = xres * yres;
+ if (temp) {
+ refresh = pixclk / temp;
+ if (pixclk % temp)
+ refresh += 1;
+ }
+ return refresh;
+}
+
+int vpp_calc_align(int value, int align)
+{
+ if (value % align) {
+ value &= ~(align - 1);
+ value += align;
+ }
+ return value;
+}
+
+int vpp_calc_fb_width(vdo_color_fmt colfmt, int width)
+{
+ int y_bpp, c_bpp;
+
+ vpp_get_colfmt_bpp(colfmt, &y_bpp, &c_bpp);
+ return vpp_calc_align(width, VPP_FB_WIDTH_ALIGN / (y_bpp / 8));
+}
+
+void vpp_set_NA12_hiprio(int type)
+{
+#if 0
+ static int reg1, reg2;
+
+ switch (type) {
+ case 0: /* restore NA12 priority */
+ outl(reg1, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8);
+ outl(reg2, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC);
+ break;
+ case 1: /* set NA12 to high priority */
+ reg1 = inl(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8);
+ reg2 = inl(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC);
+ outl(0x600000, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8);
+ outl(0x0ff00000, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC);
+ break;
+ case 2:
+ reg1 = inl(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8);
+ reg2 = inl(MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC);
+ outl(0x20003f, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0x8);
+ outl(0x00ffff00, MEMORY_CTRL_V4_CFG_BASE_ADDR + 0xC);
+ break;
+ default:
+ break;
+ }
+#endif
+}
+
+#ifdef __KERNEL__
+int vpp_set_audio(int format, int sample_rate, int channel)
+{
+ struct vout_audio_t info;
+
+ MSG("set audio(fmt %d,rate %d,ch %d)\n",
+ format, sample_rate, channel);
+ info.fmt = format;
+ info.sample_rate = sample_rate;
+ info.channel = channel;
+ return vout_set_audio(&info);
+}
+#endif
+
+/*----------------------- vpp mb for stream ---------------------------------*/
+#ifdef CONFIG_VPP_STREAM_CAPTURE
+#ifdef CONFIG_VPP_STREAM_BLOCK
+DECLARE_WAIT_QUEUE_HEAD(vpp_mb_event);
+#endif
+
+unsigned int vpp_mb_get_mask(unsigned int phy)
+{
+ int i;
+ unsigned int mask;
+
+ for (i = 0; i < g_vpp.stream_mb_cnt; i++) {
+ if (g_vpp.stream_mb[i] == phy)
+ break;
+ }
+ if (i >= g_vpp.stream_mb_cnt)
+ return 0;
+ mask = 0x1 << i;
+ return mask;
+}
+
+int vpp_mb_get(unsigned int phy)
+{
+ unsigned int mask;
+ int i, cnt;
+
+#ifdef CONFIG_VPP_STREAM_BLOCK
+ vpp_unlock();
+ if (g_vpp.stream_mb_sync_flag)
+ vpp_dbg_show(VPP_DBGLVL_STREAM, 0, "mb_get wait");
+
+ i = wait_event_interruptible_timeout(vpp_mb_event,
+ (g_vpp.stream_mb_sync_flag != 1), HZ / 20);
+ vpp_lock();
+#else /* non-block */
+ if (g_vpp.stream_mb_sync_flag) { /* not new mb updated */
+ vpp_dbg_show(VPP_DBGLVL_STREAM, 0,
+ "*W* mb_get addr not update");
+ return -1;
+ }
+#endif
+ g_vpp.stream_mb_sync_flag = 1;
+ for (i = 0, cnt = 0; i < g_vpp.stream_mb_cnt; i++) {
+ if (g_vpp.stream_mb_lock & (0x1 << i))
+ cnt++;
+ }
+
+#if 0
+ if (cnt >= (g_vpp.stream_mb_cnt - 2)) {
+ vpp_dbg_show(VPP_DBGLVL_STREAM, 0, "*W* mb_get addr not free");
+ return -1;
+ }
+#endif
+
+ mask = vpp_mb_get_mask(phy);
+ if (mask == 0) {
+ vpp_dbg_show(VPP_DBGLVL_STREAM, 0, "*W* mb_get invalid addr");
+ return -1;
+ }
+ if (g_vpp.stream_mb_lock & mask) {
+ vpp_dbg_show(VPP_DBGLVL_STREAM, 0, "*W* mb_get lock addr");
+ return -1;
+ }
+ g_vpp.stream_mb_lock |= mask;
+ if (vpp_check_dbg_level(VPP_DBGLVL_STREAM)) {
+ char buf[50];
+
+ sprintf(buf, "stream mb get 0x%x,mask 0x%x(0x%x)",
+ phy, mask, g_vpp.stream_mb_lock);
+ vpp_dbg_show(VPP_DBGLVL_STREAM, 1, buf);
+ }
+ return 0;
+}
+
+int vpp_mb_put(unsigned int phy)
+{
+ unsigned int mask;
+
+ if (phy == 0) {
+ g_vpp.stream_mb_lock = 0;
+ g_vpp.stream_mb_index = 0;
+ return 0;
+ }
+
+ mask = vpp_mb_get_mask(phy);
+ if (mask == 0) {
+ DPRINT("[VPP] *W* mb_put addr 0x%x\n", phy);
+ return 1;
+ }
+ if (!(g_vpp.stream_mb_lock & mask))
+ DPRINT("[VPP] *W* mb_put nonlock addr 0x%x\n", phy);
+ g_vpp.stream_mb_lock &= ~mask;
+ if (vpp_check_dbg_level(VPP_DBGLVL_STREAM)) {
+ char buf[50];
+
+ sprintf(buf, "stream mb put 0x%x,mask 0x%x(0x%x)",
+ phy, mask, g_vpp.stream_mb_lock);
+ vpp_dbg_show(VPP_DBGLVL_STREAM, 2, buf);
+ }
+ return 0;
+}
+
+int vpp_mb_irqproc_sync(int arg)
+{
+ if (!g_vpp.stream_enable)
+ return 0;
+
+ g_vpp.stream_sync_cnt++;
+ if ((g_vpp.stream_sync_cnt % 2) == 0) {
+ g_vpp.stream_mb_sync_flag = 0;
+#ifdef CONFIG_VPP_STREAM_BLOCK
+ wake_up_interruptible(&vpp_mb_event);
+#endif
+ }
+ return 0;
+}
+
+/*----------------------- irq proc --------------------------------------*/
+struct vpp_irqproc_t *vpp_irqproc_array[32];
+struct list_head vpp_irqproc_free_list;
+struct vpp_proc_t vpp_proc_array[VPP_PROC_NUM];
+static void vpp_irqproc_do_tasklet(unsigned long data);
+
+void vpp_irqproc_init(void)
+{
+ int i;
+
+ INIT_LIST_HEAD(&vpp_irqproc_free_list);
+
+ for (i = 0; i < VPP_PROC_NUM; i++)
+ list_add_tail(&vpp_proc_array[i].list, &vpp_irqproc_free_list);
+}
+
+struct vpp_irqproc_t *vpp_irqproc_get_entry(enum vpp_int_t vpp_int)
+{
+ int no;
+
+ if (vpp_int == 0)
+ return 0;
+
+ for (no = 0; no < 32; no++) {
+ if (vpp_int & (0x1 << no))
+ break;
+ }
+
+ if (vpp_irqproc_array[no] == 0) { /* will create in first use */
+ struct vpp_irqproc_t *irqproc;
+
+ irqproc = kmalloc(sizeof(struct vpp_irqproc_t), GFP_KERNEL);
+ vpp_irqproc_array[no] = irqproc;
+ INIT_LIST_HEAD(&irqproc->list);
+ tasklet_init(&irqproc->tasklet,
+ vpp_irqproc_do_tasklet, vpp_int);
+ irqproc->ref = 0;
+ }
+ return vpp_irqproc_array[no];
+} /* End of vpp_irqproc_get_entry */
+
+void vpp_irqproc_set_ref(struct vpp_irqproc_t *irqproc,
+ enum vpp_int_t type, int enable)
+{
+ if (enable) {
+ irqproc->ref++;
+ if (vppm_get_int_enable(type) == 0)
+ vppm_set_int_enable(1, type);
+ } else {
+ irqproc->ref--;
+ if (irqproc->ref == 0)
+ vppm_set_int_enable(0, type);
+ }
+}
+
+static void vpp_irqproc_do_tasklet
+(
+ unsigned long data /*!<; // tasklet input data */
+)
+{
+ struct vpp_irqproc_t *irqproc;
+
+ vpp_lock();
+ irqproc = vpp_irqproc_get_entry(data);
+ if (irqproc) {
+ struct list_head *cur;
+ struct list_head *next;
+ struct vpp_proc_t *entry;
+
+ next = (&irqproc->list)->next;
+ while (next != &irqproc->list) {
+ cur = next;
+ next = cur->next;
+ entry = list_entry(cur, struct vpp_proc_t, list);
+ if (entry->func) {
+ if (entry->func(entry->arg))
+ continue;
+ }
+
+ if (entry->work_cnt == 0)
+ continue;
+
+ entry->work_cnt--;
+ if (entry->work_cnt == 0) {
+ if (entry->wait_ms == 0)
+ vpp_irqproc_set_ref(irqproc, data, 0);
+ else
+ up(&entry->sem);
+ list_del_init(cur);
+ list_add_tail(&entry->list,
+ &vpp_irqproc_free_list);
+ }
+ }
+ }
+ vpp_unlock();
+} /* End of vpp_irqproc_do_tasklet */
+
+int vpp_irqproc_work(
+ enum vpp_int_t type, /* interrupt type */
+ int (*func)(void *argc), /* proc function pointer */
+ void *arg, /* proc argument */
+ int wait_ms, /* wait complete timeout (ms) */
+ int work_cnt /* 0 - forever */
+)
+{
+ int ret;
+ struct vpp_proc_t *entry;
+ struct list_head *ptr;
+ struct vpp_irqproc_t *irqproc;
+
+#if 0
+ DPRINT("[VPP] vpp_irqproc_work(type 0x%x,wait %d,cnt %d)\n",
+ type, wait_ms, work_cnt);
+#endif
+ if ((vpp_irqproc_free_list.next == 0) ||
+ list_empty(&vpp_irqproc_free_list)) {
+ if (func)
+ func(arg);
+ return 0;
+ }
+
+ ret = 0;
+ vpp_lock();
+
+ ptr = vpp_irqproc_free_list.next;
+ entry = list_entry(ptr, struct vpp_proc_t, list);
+ list_del_init(ptr);
+ entry->func = func;
+ entry->arg = arg;
+ entry->type = type;
+ entry->wait_ms = wait_ms;
+ entry->work_cnt = work_cnt;
+ sema_init(&entry->sem, 1);
+ down(&entry->sem);
+
+ irqproc = vpp_irqproc_get_entry(type);
+ if (irqproc) {
+ list_add_tail(&entry->list, &irqproc->list);
+ } else {
+ irqproc = vpp_irqproc_array[31];
+ list_add_tail(&entry->list, &irqproc->list);
+ }
+ vpp_irqproc_set_ref(irqproc, type, 1);
+ vpp_unlock();
+
+ if (wait_ms) {
+ unsigned int tmr_cnt;
+
+ tmr_cnt = (wait_ms * HZ) / 1000;
+ ret = down_timeout(&entry->sem, tmr_cnt);
+ if (ret) {
+ DPRINT("*W* vpp_irqproc_work timeout(type 0x%x,%d)\n",
+ type, wait_ms);
+ vpp_lock();
+ list_del_init(ptr);
+ list_add_tail(ptr, &vpp_irqproc_free_list);
+ vpp_unlock();
+ if (func)
+ func(arg);
+ }
+ }
+
+ if ((work_cnt == 0) || (wait_ms == 0)) {
+ /* don't clear ref, forever will do in delete,
+ no wait will do in proc complete */
+ } else {
+ vpp_lock();
+ vpp_irqproc_set_ref(irqproc, type, 0);
+ vpp_unlock();
+ }
+ return ret;
+} /* End of vpp_irqproc_work */
+
+void vpp_irqproc_del_work(
+ enum vpp_int_t type, /* interrupt type */
+ int (*func)(void *argc) /* proc function pointer */
+)
+{
+ struct vpp_irqproc_t *irqproc;
+
+ vpp_lock();
+ irqproc = vpp_irqproc_get_entry(type);
+ if (irqproc) {
+ struct list_head *cur;
+ struct list_head *next;
+ struct vpp_proc_t *entry;
+
+ next = (&irqproc->list)->next;
+ while (next != &irqproc->list) {
+ cur = next;
+ next = cur->next;
+ entry = list_entry(cur, struct vpp_proc_t, list);
+ if (entry->func == func) {
+ vpp_irqproc_set_ref(irqproc, type, 0);
+ list_del_init(cur);
+ list_add_tail(&entry->list,
+ &vpp_irqproc_free_list);
+ }
+ }
+ }
+ vpp_unlock();
+}
+
+/*----------------------- Linux Netlink --------------------------------------*/
+#ifdef CONFIG_VPP_NOTIFY
+#define VPP_NETLINK_PROC_MAX 2
+
+struct vpp_netlink_proc_t {
+ __u32 pid;
+ rwlock_t lock;
+};
+
+struct switch_dev vpp_sdev = {
+ .name = "hdmi",
+};
+
+static struct switch_dev vpp_sdev_hdcp = {
+ .name = "hdcp",
+};
+
+static struct switch_dev vpp_sdev_audio = {
+ .name = "hdmi_audio",
+};
+
+struct vpp_netlink_proc_t vpp_netlink_proc[VPP_NETLINK_PROC_MAX];
+static struct sock *vpp_nlfd;
+static DEFINE_SEMAPHORE(vpp_netlink_receive_sem);
+
+struct vpp_netlink_proc_t *vpp_netlink_get_proc(int no)
+{
+ if (no == 0)
+ return 0;
+ if (no > VPP_NETLINK_PROC_MAX)
+ return 0;
+ return &vpp_netlink_proc[no - 1];
+}
+
+static void vpp_netlink_receive(struct sk_buff *skb)
+{
+ struct nlmsghdr *nlh = NULL;
+ struct vpp_netlink_proc_t *proc;
+
+ if (down_trylock(&vpp_netlink_receive_sem))
+ return;
+
+ if (skb->len >= sizeof(struct nlmsghdr)) {
+ nlh = nlmsg_hdr(skb);
+ if ((nlh->nlmsg_len >= sizeof(struct nlmsghdr))
+ && (skb->len >= nlh->nlmsg_len)) {
+ proc = vpp_netlink_get_proc(nlh->nlmsg_type);
+ if (proc) {
+ write_lock_bh(&proc->lock);
+ proc->pid = nlh->nlmsg_pid;
+ write_unlock_bh(&proc->lock);
+ DPRINT("[VPP] rx user pid 0x%x\n", proc->pid);
+ }
+ }
+ }
+ up(&vpp_netlink_receive_sem);
+ wmt_enable_mmfreq(WMT_MMFREQ_HDMI_PLUG, hdmi_get_plugin());
+}
+
+void vpp_netlink_init(void)
+{
+ vpp_netlink_proc[0].pid = 0;
+ vpp_netlink_proc[1].pid = 0;
+ rwlock_init(&(vpp_netlink_proc[0].lock));
+ rwlock_init(&(vpp_netlink_proc[1].lock));
+ vpp_nlfd = netlink_kernel_create(&init_net, NETLINK_CEC_TEST, 0,
+ vpp_netlink_receive, NULL, THIS_MODULE);
+ if (!vpp_nlfd)
+ DPRINT(KERN_ERR "can not create a netlink socket\n");
+}
+
+static ssize_t attr_show_parsed_edid(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t len = 0;
+ int i, j;
+ unsigned char audio_format, sample_freq, bitrate;
+ int sample_freq_num, bitrate_num;
+
+#ifdef DEBUG
+ DPRINT("------- EDID Parsed ------\n");
+ if(strlen(edid_parsed.tv_name.vendor_name) != 0)
+ DPRINT("Vendor Name: %s\n", edid_parsed.tv_name.vendor_name);
+
+ if(strlen(edid_parsed.tv_name.monitor_name) != 0)
+ DPRINT("Monitor Name: %s\n", edid_parsed.tv_name.monitor_name);
+
+ for (i = 0; i < AUD_SAD_NUM; i++) {
+ if (edid_parsed.sad[i].flag == 0) {
+ if (i == 0)
+ DPRINT("No SAD Data\n");
+ break;
+ }
+ DPRINT("SAD %d: 0x%02X 0x%02X 0x%02X\n", i,
+ edid_parsed.sad[i].sad_byte[0],
+ edid_parsed.sad[i].sad_byte[1],
+ edid_parsed.sad[i].sad_byte[2]);
+ }
+ DPRINT("--------------------------\n");
+#endif
+ /* print Vendor Name */
+ if (strlen(edid_parsed.tv_name.vendor_name) != 0) {
+ len += sprintf(buf + len, "%-16s", "Vendor Name");
+ len += sprintf(buf + len, ": %s\n", edid_parsed.tv_name.vendor_name);
+ }
+
+ /* print Monitor Name */
+ if (strlen(edid_parsed.tv_name.monitor_name) != 0) {
+ len += sprintf(buf + len, "%-16s", "Monitor Name");
+ len += sprintf(buf + len, ": %s\n", edid_parsed.tv_name.monitor_name);
+ }
+
+ for (i = 0; i < AUD_SAD_NUM; i++) {
+ if (edid_parsed.sad[i].flag == 0)
+ break;
+ /*
+ SAD Byte 1 (format and number of channels):
+ bit 7: Reserved (0)
+ bit 6..3: Audio format code
+ 1 = Linear Pulse Code Modulation (LPCM)
+ 2 = AC-3
+ 3 = MPEG1 (Layers 1 and 2)
+ 4 = MP3
+ 5 = MPEG2
+ 6 = AAC
+ 7 = DTS
+ 8 = ATRAC
+ 0, 15: Reserved
+ 9 = One-bit audio aka SACD
+ 10 = DD+
+ 11 = DTS-HD
+ 12 = MLP/Dolby TrueHD
+ 13 = DST Audio
+ 14 = Microsoft WMA Pro
+ bit 2..0: number of channels minus 1
+ (i.e. 000 = 1 channel; 001 = 2 channels; 111 =
+ 8 channels)
+ */
+ audio_format = (edid_parsed.sad[i].sad_byte[0] & 0x78) >> 3;
+ if (audio_format == 0 || audio_format == 15)
+ continue;
+
+ /* print header */
+ len += sprintf(buf + len, "%-16s", "Audio Format");
+ len += sprintf(buf + len, ": ");
+
+ switch (audio_format) {
+ case 1:
+ len += sprintf(buf + len, "pcm");
+ break;
+ case 2:
+ len += sprintf(buf + len, "ac3");
+ break;
+ case 3:
+ len += sprintf(buf + len, "mpeg1");
+ break;
+ case 4:
+ len += sprintf(buf + len, "mp3");
+ break;
+ case 5:
+ len += sprintf(buf + len, "mpeg2");
+ break;
+ case 6:
+ len += sprintf(buf + len, "aac");
+ break;
+ case 7:
+ len += sprintf(buf + len, "dts");
+ break;
+ case 8:
+ len += sprintf(buf + len, "atrac");
+ break;
+ case 9:
+ len += sprintf(buf + len, "one_bit_audio");
+ break;
+ case 10:
+ len += sprintf(buf + len, "eac3");
+ break;
+ case 11:
+ len += sprintf(buf + len, "dts-hd");
+ break;
+ case 12:
+ len += sprintf(buf + len, "mlp");
+ break;
+ case 13:
+ len += sprintf(buf + len, "dst");
+ break;
+ case 14:
+ len += sprintf(buf + len, "wmapro");
+ break;
+ default:
+ break;
+ }
+
+ /* separator */
+ len += sprintf(buf + len, ",");
+
+ /* number of channels */
+ len += sprintf(buf + len, "%d",
+ (edid_parsed.sad[i].sad_byte[0] & 0x7) + 1);
+
+ /* separator */
+ len += sprintf(buf + len, ",");
+
+ /*
+ SAD Byte 2 (sampling frequencies supported):
+ bit 7: Reserved (0)
+ bit 6: 192kHz
+ bit 5: 176kHz
+ bit 4: 96kHz
+ bit 3: 88kHz
+ bit 2: 48kHz
+ bit 1: 44kHz
+ bit 0: 32kHz
+ */
+ sample_freq = edid_parsed.sad[i].sad_byte[1];
+ sample_freq_num = 0;
+ for (j = 0; j < 7; j++) {
+ if (sample_freq & (1 << j)) {
+ if (sample_freq_num != 0)
+ len += sprintf(buf + len,
+ "|"); /* separator */
+ switch (j) {
+ case 0:
+ len += sprintf(buf + len, "32KHz");
+ break;
+ case 1:
+ len += sprintf(buf + len, "44KHz");
+ break;
+ case 2:
+ len += sprintf(buf + len, "48KHz");
+ break;
+ case 3:
+ len += sprintf(buf + len, "88KHz");
+ break;
+ case 4:
+ len += sprintf(buf + len, "96KHz");
+ break;
+ case 5:
+ len += sprintf(buf + len, "176KHz");
+ break;
+ case 6:
+ len += sprintf(buf + len, "192KHz");
+ break;
+ default:
+ break;
+ }
+ sample_freq_num++;
+ }
+ }
+
+ if (sample_freq_num == 0)
+ len += sprintf(buf + len, "0");
+
+ /* separator */
+ len += sprintf(buf + len, ",");
+
+ /*
+ SAD Byte 3 (bitrate):
+ For LPCM, bits 7:3 are reserved and the remaining bits
+ define bit depth
+ bit 2: 24 bit
+ bit 1: 20 bit
+ bit 0: 16 bit
+ For all other sound formats, bits 7..0 designate the maximum
+ supported bitrate divided by 8 kbit/s.
+ */
+ bitrate = edid_parsed.sad[i].sad_byte[2];
+ bitrate_num = 0;
+ if (audio_format == 1) { /* for LPCM */
+ for (j = 0; j < 3; j++) {
+ if (bitrate & (1 << j)) {
+ if (bitrate_num != 0)
+ len += sprintf(buf + len,
+ "|"); /* separator */
+ switch (j) {
+ case 0:
+ len += sprintf(buf + len,
+ "16bit");
+ break;
+ case 1:
+ len += sprintf(buf + len,
+ "20bit");
+ break;
+ case 2:
+ len += sprintf(buf + len,
+ "24bit");
+ break;
+ default:
+ break;
+ }
+ bitrate_num++;
+ }
+ }
+ } else if (audio_format >= 2 &&
+ audio_format <= 8) /* From AC3 to ATRAC */
+ len += sprintf(buf + len, "%dkbps", bitrate * 8);
+ else /* From One-bit-audio to WMA Pro*/
+ len += sprintf(buf + len, "%d", bitrate);
+
+ len += sprintf(buf + len, "\n");
+ }
+
+ if (len == 0)
+ len += sprintf(buf + len, "\n");
+
+ return len;
+}
+
+static DEVICE_ATTR(edid_parsed, 0444, attr_show_parsed_edid, NULL);
+
+void vpp_switch_state_init(void)
+{
+ /* /sys/class/switch/hdmi/state */
+ switch_dev_register(&vpp_sdev);
+ switch_set_state(&vpp_sdev, hdmi_get_plugin() ? 1 : 0);
+ switch_dev_register(&vpp_sdev_hdcp);
+ switch_set_state(&vpp_sdev_hdcp, 0);
+ switch_dev_register(&vpp_sdev_audio);
+ device_create_file(vpp_sdev.dev, &dev_attr_edid_parsed);
+}
+
+void vpp_netlink_notify(int no, int cmd, int arg)
+{
+ int ret;
+ int size;
+ unsigned char *old_tail;
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ struct vpp_netlink_proc_t *proc;
+
+ proc = vpp_netlink_get_proc(no);
+ if (!proc)
+ return;
+
+ MSG("[VPP] netlink notify %d,cmd %d,0x%x\n", no, cmd, arg);
+
+ switch (cmd) {
+ case DEVICE_RX_DATA:
+ size = NLMSG_SPACE(sizeof(struct wmt_cec_msg));
+ break;
+ case DEVICE_PLUG_IN:
+ case DEVICE_PLUG_OUT:
+ case DEVICE_STREAM:
+ size = NLMSG_SPACE(sizeof(struct wmt_cec_msg));
+ break;
+ default:
+ return;
+ }
+
+ skb = alloc_skb(size, GFP_ATOMIC);
+ if (skb == NULL)
+ return;
+ old_tail = skb->tail;
+ nlh = NLMSG_PUT(skb, 0, 0, 0, size-sizeof(*nlh));
+ nlh->nlmsg_len = skb->tail - old_tail;
+
+ switch (cmd) {
+ case DEVICE_RX_DATA:
+ nlh->nlmsg_type = DEVICE_RX_DATA;
+ memcpy(NLMSG_DATA(nlh), (struct wmt_cec_msg *)arg,
+ sizeof(struct wmt_cec_msg));
+ break;
+ case DEVICE_PLUG_IN:
+ case DEVICE_PLUG_OUT:
+ {
+ static int cnt;
+ struct wmt_cec_msg *msg;
+
+ msg = (struct wmt_cec_msg *)NLMSG_DATA(nlh);
+ msg->msgdata[0] = cnt;
+ cnt++;
+ }
+ if (arg) {
+ nlh->nlmsg_type = DEVICE_PLUG_IN;
+ nlh->nlmsg_flags = edid_get_hdmi_phy_addr();
+ } else {
+ nlh->nlmsg_type = DEVICE_PLUG_OUT;
+ }
+ size = NLMSG_SPACE(sizeof(0));
+ break;
+ case DEVICE_STREAM:
+ nlh->nlmsg_type = cmd;
+ nlh->nlmsg_flags = arg;
+ break;
+ default:
+ return;
+ }
+
+ NETLINK_CB(skb).pid = 0;
+ NETLINK_CB(skb).dst_group = 0;
+
+ if (proc->pid != 0) {
+ ret = netlink_unicast(vpp_nlfd, skb, proc->pid, MSG_DONTWAIT);
+ return;
+ }
+nlmsg_failure: /* NLMSG_PUT go to */
+ if (skb != NULL)
+ kfree_skb(skb);
+ return;
+}
+
+void vpp_netlink_notify_plug(int vo_num, int plugin)
+{
+ /* set unplug flag for check_var */
+ if (plugin == 0) {
+ int mask = 0;
+
+ if (vo_num == VPP_VOUT_ALL)
+ mask = ~0;
+ else {
+ struct vout_info_t *vo_info;
+ vo_info = vout_get_info_entry(vo_num);
+ if (vo_info)
+ mask = 0x1 << (vo_info->num);
+ }
+ g_vpp.fb_recheck |= mask;
+ }
+
+ if ((vpp_netlink_proc[0].pid == 0) && (vpp_netlink_proc[1].pid == 0))
+ return;
+
+ /* if hdmi unplug, clear edid_parsed */
+ if (hdmi_get_plugin() == 0)
+ memset(&edid_parsed, 0, sizeof(struct edid_parsed_t));
+
+ vpp_netlink_notify(USER_PID, DEVICE_PLUG_IN, plugin);
+ vpp_netlink_notify(WP_PID, DEVICE_PLUG_IN, plugin);
+
+ /* hdmi plugin/unplug */
+ plugin = hdmi_get_plugin();
+ switch_set_state(&vpp_sdev, plugin ? 1 : 0);
+ wmt_enable_mmfreq(WMT_MMFREQ_HDMI_PLUG, plugin);
+}
+
+void vpp_netlink_notify_cp(int enable)
+{
+ switch_set_state(&vpp_sdev_hdcp, enable);
+}
+EXPORT_SYMBOL(vpp_netlink_notify_cp);
+
+#endif /* CONFIG_VPP_NOTIFY */
+#endif /* __KERNEL__ */
diff --git a/common/wmt_display/vpp.h b/common/wmt_display/vpp.h
new file mode 100755
index 0000000..d960e2a
--- /dev/null
+++ b/common/wmt_display/vpp.h
@@ -0,0 +1,679 @@
+/*++
+ * linux/drivers/video/wmt/vpp.h
+ * WonderMedia video post processor (VPP) driver
+ *
+ * Copyright c 2014 WonderMedia Technologies, 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#include "vpp-osif.h"
+#include "./hw/wmt-vpp-hw.h"
+#include "com-vpp.h"
+#ifdef CONFIG_KERNEL
+#include "com-cec.h"
+#endif
+#include "vout.h"
+
+#ifndef VPP_H
+#define VPP_H
+
+#define CONFIG_VPP_SHENZHEN /* for ShenZhen code */
+
+/* VPP feature config */
+/* #define CONFIG_VPP_DEMO */ /* HDMI EDID, CP disable */
+#ifdef CONFIG_KERNEL
+#define CONFIG_VPP_STREAM_CAPTURE /* stream capture current video display */
+#define CONFIG_VPP_STREAM_BLOCK
+/* #define CONFIG_VPP_DISABLE_PM */ /* disable power management */
+#define CONFIG_VPP_VIRTUAL_DISPLAY /* virtual fb dev */
+#define CONFIG_VPP_NOTIFY
+#endif
+/* #define CONFIG_VPP_DYNAMIC_ALLOC */ /* frame buffer dynamic allocate */
+
+/* VPP constant define */
+#define VPP_MB_ALLOC_NUM 3
+#define VPP_STREAM_MB_ALLOC_NUM (VPP_MB_ALLOC_NUM * 2)
+
+enum vpp_int_t {
+ VPP_INT_NULL = 0,
+ VPP_INT_ALL = 0xffffffff,
+
+ VPP_INT_GOVRH_PVBI = BIT0,
+ VPP_INT_GOVRH_VBIS = BIT1, /* write done */
+ VPP_INT_GOVRH_VBIE = BIT2,
+
+ VPP_INT_GOVW_PVBI = BIT3,
+ VPP_INT_GOVW_VBIS = BIT4,
+ VPP_INT_GOVW_VBIE = BIT5,
+
+ VPP_INT_DISP_PVBI = BIT6,
+ VPP_INT_DISP_VBIS = BIT7,
+ VPP_INT_DISP_VBIE = BIT8,
+
+ VPP_INT_LCD_EOF = BIT9,
+
+ VPP_INT_SCL_PVBI = BIT12,
+ VPP_INT_SCL_VBIS = BIT13,
+ VPP_INT_SCL_VBIE = BIT14,
+
+ VPP_INT_VPU_PVBI = BIT15,
+ VPP_INT_VPU_VBIS = BIT16,
+ VPP_INT_VPU_VBIE = BIT17,
+
+ VPP_INT_GOVRH2_PVBI = BIT18,
+ VPP_INT_GOVRH2_VBIS = BIT19, /* write done */
+ VPP_INT_GOVRH2_VBIE = BIT20,
+
+ VPP_INT_MAX = BIT31,
+
+};
+
+enum vpp_int_err_t {
+ /* SCL */
+ VPP_INT_ERR_SCL_TG = BIT0,
+ VPP_INT_ERR_SCLR1_MIF = BIT1,
+ VPP_INT_ERR_SCLR2_MIF = BIT2,
+ VPP_INT_ERR_SCLW_MIFRGB = BIT3,
+ VPP_INT_ERR_SCLW_MIFY = BIT4,
+ VPP_INT_ERR_SCLW_MIFC = BIT5,
+
+ /* GOVRH2 */
+ VPP_INT_ERR_GOVRH2_MIF = BIT19,
+
+ /* GOVRH */
+ VPP_INT_ERR_GOVRH_MIF = BIT20,
+
+};
+
+/* VPP FB capability flag */
+#define VPP_FB_FLAG_COLFMT 0xFFFF
+#define VPP_FB_FLAG_SCALE BIT(16)
+#define VPP_FB_FLAG_CSC BIT(17)
+#define VPP_FB_FLAG_MEDIA BIT(18)
+#define VPP_FB_FLAG_FIELD BIT(19)
+
+struct vpp_fb_base_t {
+ vdo_framebuf_t fb;
+ vpp_csc_t csc_mode;
+ int framerate;
+ vpp_media_format_t media_fmt;
+ int wait_ready;
+ unsigned int capability;
+
+ void (*set_framebuf)(vdo_framebuf_t *fb);
+ void (*get_framebuf)(vdo_framebuf_t *fb);
+ void (*set_addr)(unsigned int yaddr, unsigned int caddr);
+ void (*get_addr)(unsigned int *yaddr, unsigned int *caddr);
+ void (*set_csc)(vpp_csc_t mode);
+ vdo_color_fmt(*get_color_fmt)(void);
+ void (*set_color_fmt)(vdo_color_fmt colfmt);
+ void (*fn_view)(int read, vdo_view_t *view);
+};
+
+#define VPP_MOD_BASE \
+ vpp_mod_t mod; /* module id*/\
+ void *mmio; /* regs base address */\
+ unsigned int int_catch; /* interrupt catch */\
+ struct vpp_fb_base_t *fb_p; /* framebuf base pointer */\
+ unsigned int pm; /* power dev id,bit31-0:power off */\
+ unsigned int *reg_bk; /* register backup pointer */\
+ void (*init)(void *base); /* module initial */\
+ void (*dump_reg)(void); /* dump hardware register */\
+ void (*set_enable)(vpp_flag_t enable); /* module enable/disable */\
+ void (*set_colorbar)(vpp_flag_t enable, int mode, int inv); \
+ /* hw colorbar enable/disable & mode */\
+ void (*set_tg)(vpp_clock_t *tmr, unsigned int pixel_clock); /*set tg*/\
+ void (*get_tg)(vpp_clock_t *tmr); /* get timing */\
+ unsigned int (*get_sts)(void); /* get interrupt or error status */\
+ void (*clr_sts)(unsigned int sts); /* clear interrupt or err status */\
+ void (*suspend)(int sts); /* module suspend */\
+ void (*resume)(int sts) /* module resume */
+/* End of vpp_mod_base_t */
+
+struct vpp_mod_base_t {
+ VPP_MOD_BASE;
+};
+
+#define VPP_MOD_FLAG_FRAMEBUF BIT(0)
+#define VPP_MOD_CLK_ON BIT(31)
+
+enum vpp_scale_mode_t {
+ VPP_SCALE_MODE_REC_TABLE, /* old design but 1/32 limit */
+ VPP_SCALE_MODE_RECURSIVE, /*no rec table,not smooth than bilinear mode*/
+ VPP_SCALE_MODE_BILINEAR,/*more smooth but less than 1/2 will drop line*/
+ VPP_SCALE_MODE_ADAPTIVE,/* scl dn 1-1/2 bilinear mode, other rec mode */
+ VPP_SCALE_MODE_MAX
+};
+
+enum vpp_hdmi_audio_inf_t {
+ VPP_HDMI_AUDIO_I2S,
+ VPP_HDMI_AUDIO_SPDIF,
+ VPP_HDMI_AUDIO_MAX
+};
+
+enum vpp_filter_mode_t {
+ VPP_FILTER_SCALE,
+ VPP_FILTER_DEBLOCK,
+ VPP_FILTER_FIELD_DEFLICKER,
+ VPP_FILTER_FRAME_DEFLICKER,
+ VPP_FILTER_MODE_MAX
+};
+
+#define VPP_DBG_PERIOD_NUM 10
+struct vpp_dbg_period_t {
+ int index;
+ int period_us[VPP_DBG_PERIOD_NUM];
+ struct timeval pre_tv;
+};
+
+struct vpp_dbg_timer_t {
+ struct timeval pre_tv;
+ unsigned int threshold;
+ unsigned int reset;
+ unsigned int cnt;
+ unsigned int sum;
+ unsigned int min;
+ unsigned int max;
+};
+
+#ifdef __KERNEL__
+#define VPP_PROC_NUM 10
+struct vpp_proc_t {
+ int (*func)(void *arg); /* function pointer */
+ void *arg; /* function argument */
+ struct list_head list;
+ enum vpp_int_t type; /* interrupt type */
+ struct semaphore sem; /* wait sem */
+ int wait_ms; /* wait complete timout (ms) */
+ int work_cnt; /* work counter if 0 then forever */
+};
+
+struct vpp_irqproc_t {
+ struct list_head list;
+ struct tasklet_struct tasklet;
+ int ref;
+};
+#endif
+
+#ifndef CFG_LOADER
+#include "vppm.h"
+#endif
+#include "lcd.h"
+
+/* #ifdef WMT_FTBLK_SCL */
+#include "scl.h"
+/* #endif */
+/*
+#ifdef WMT_FTBLK_GE
+#include "ge.h"
+#endif
+*/
+#ifdef WMT_FTBLK_GOVRH
+#include "govrh.h"
+#endif
+#ifdef WMT_FTBLK_LVDS
+#include "lvds.h"
+#endif
+/* #ifdef WMT_FTBLK_HDMI */
+#include "hdmi.h"
+#ifndef CFG_LOADER
+#include "cec.h"
+#endif
+/* #endif */
+#ifdef CONFIG_WMT_EDID
+#include "edid.h"
+#endif
+
+enum vpp_dbg_level_t {
+ VPP_DBGLVL_DISABLE = 0x0,
+ VPP_DBGLVL_SCALE = 1,
+ VPP_DBGLVL_DISPFB = 2,
+ VPP_DBGLVL_INT = 3,
+ VPP_DBGLVL_FPS = 4,
+ VPP_DBGLVL_IOCTL = 5,
+ VPP_DBGLVL_DIAG = 6,
+ VPP_DBGLVL_STREAM = 7,
+ VPP_DBGLVL_ALL = 0xFF,
+};
+
+struct vpp_info_t {
+ /* internal parameter */
+ int govrh_preinit;
+ int virtual_display;
+ int fb0_bitblit;
+ int fb_manual; /* not check var & internel timing */
+ int fb_recheck; /* recheck for plug but no change res */
+ int govrh_init_yres;
+ int stream_fb;
+
+ /* hdmi */
+ enum vpp_hdmi_audio_inf_t hdmi_audio_interface; /* 0-I2S, 1-SPDIF */
+ int hdmi_cp_enable; /* 0-off, 1-on */
+ int hdmi_audio_channel;
+ int hdmi_audio_freq;
+ unsigned int hdmi_ctrl;
+ unsigned int hdmi_audio_pb1;
+ unsigned int hdmi_audio_pb4;
+ unsigned int hdmi_i2c_freq;
+ unsigned int hdmi_i2c_udelay;
+ int hdmi_init;
+ unsigned int hdmi_bksv[2];
+ char *hdmi_cp_p;
+ int hdmi_3d_type;
+ unsigned int hdmi_pixel_clock;
+ int hdmi_certify_flag;
+ int hdmi_sp_mode;
+ int hdmi_disable;
+ int hdmi_ch_change;
+
+ /* alloc frame buffer */
+ int mb_colfmt;
+
+ /* debug */
+ int dbg_msg_level; /* debug message level */
+ int dbg_wait;
+ int dbg_flag;
+
+ /* dvi */
+ int dvi_int_disable;
+ int dvi_int_no; /* DVO external board interrupt use GPIOxx */
+ int dvi_i2c_no; /* DVO external board i2c bus id */
+
+#if 0
+ /* HDMI DDC debug */
+ int dbg_hdmi_ddc_ctrl_err;
+ int dbg_hdmi_ddc_read_err;
+ int dbg_hdmi_ddc_crc_err;
+#endif
+
+#ifdef CONFIG_VPP_STREAM_CAPTURE
+ /* stream capture current video display */
+ int stream_enable;
+ unsigned int stream_mb_lock;
+ int stream_mb_sync_flag;
+ int stream_mb_index;
+ unsigned int stream_mb[VPP_STREAM_MB_ALLOC_NUM];
+ int stream_mb_cnt;
+ unsigned int stream_sync_cnt;
+#endif
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef VPP_C
+#define EXTERN
+
+const unsigned int vpp_csc_parm[VPP_CSC_MAX][7] = {
+ /* C1,C2 C3,C4 C5,C6 C7,C8 C9,I
+ J,K b0:YC2RGB,b8:clamp */
+ {0x000004a8, 0x04a80662, 0x1cbf1e70, 0x081204a8, 0x00010000,
+ 0x00010001, 0x00000101}, /* YUV2RGB_SDTV_0_255 */
+ {0x00000400, 0x0400057c, 0x1d351ea8, 0x06ee0400, 0x00010000,
+ 0x00010001, 0x00000001}, /* YUV2RGB_SDTV_16_235 */
+ {0x000004a8, 0x04a8072c, 0x1ddd1f26, 0x087604a8, 0x00010000,
+ 0x00010001, 0x00000101}, /* YUV2RGB_HDTV_0_255 */
+ {0x00000400, 0x04000629, 0x1e2a1f45, 0x07440400, 0x00010000,
+ 0x00010001, 0x00000001}, /* YUV2RGB_HDTV_16_235 */
+ {0x00000400, 0x0400059c, 0x1d251ea0, 0x07170400, 0x00010000,
+ 0x00010001, 0x00000001}, /* YUV2RGB_JFIF_0_255 */
+ {0x00000400, 0x0400057c, 0x1d351ea8, 0x06ee0400, 0x00010000,
+ 0x00010001, 0x00000001}, /* YUV2RGB_SMPTE170M */
+ {0x00000400, 0x0400064d, 0x1e001f19, 0x074f0400, 0x00010000,
+ 0x00010001, 0x00000001}, /* YUV2RGB_SMPTE240M */
+ {0x02040107, 0x1f680064, 0x01c21ed6, 0x1e8701c2, 0x00211fb7,
+ 0x01010101, 0x00000000}, /* RGB2YUV_SDTV_0_255 */
+ {0x02590132, 0x1f500075, 0x020b1ea5, 0x1e4a020b, 0x00011fab,
+ 0x01010101, 0x00000000}, /* RGB2YUV_SDTV_16_235 */
+ {0x027500bb, 0x1f99003f, 0x01c21ea6, 0x1e6701c2, 0x00211fd7,
+ 0x01010101, 0x00000000}, /* RGB2YUV_HDTV_0_255 */
+ {0x02dc00da, 0x1f88004a, 0x020b1e6d, 0x1e25020b, 0x00011fd0,
+ 0x01010101, 0x00000000}, /* RGB2YUV_HDTV_16_235 */
+ {0x02590132, 0x1f530075, 0x02001ead, 0x1e530200, 0x00011fad,
+ 0x01010101, 0x00000000}, /* RGB2YUV_JFIF_0_255 */
+ {0x02590132, 0x1f500075, 0x020b1ea5, 0x1e4a020b, 0x00011fab,
+ 0x01010101, 0x00000000}, /* RGB2YUV_SMPTE170M */
+ {0x02ce00d9, 0x1f890059, 0x02001e77, 0x1e380200, 0x00011fc8,
+ 0x01010101, 0x00000000}, /* RGB2YUV_SMPTE240M */
+ {0x02780142, 0x1e80007a, 0x04711d0e, 0x1c470471, 0x00001f46,
+ 0x01010101, 0x00000000} /* RGB2YUV_JFIF_VT1625 */
+};
+
+const struct fb_videomode vpp_videomode[] = {
+ /* 640x480@60 DMT/CEA861 */
+ { NULL, 60, 640, 480, KHZ2PICOS(25175), 48, 16, 33, 10, 96, 2,
+ 0, FB_VMODE_NONINTERLACED, 0},
+#if 0
+ /* 640x480@60 CVT */
+ { NULL, 60, 640, 480, KHZ2PICOS(23750), 80, 16, 13, 3, 64, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+#endif
+ /* 640x480@75 DMT */
+ { NULL, 75, 640, 480, KHZ2PICOS(31500), 120, 16, 16, 1, 64, 3,
+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+#if 0
+ /* 640x480@75 CVT */
+ { NULL, 75, 640, 480, KHZ2PICOS(30750), 88, 24, 17, 3, 64, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+#endif
+ /* 720x480@60 CEA861 */
+ { NULL, 60, 720, 480, KHZ2PICOS(27027), 60, 16, 30, 9, 62, 6,
+ 0, FB_VMODE_NONINTERLACED, 0},
+ /* 720x480i@60 CEA861 */
+ { NULL, 60, 720, 480, KHZ2PICOS(27000), 114, 38, 30, 8, 124, 6,
+ 0, FB_VMODE_INTERLACED + FB_VMODE_DOUBLE, 0},
+ /* 720x576@50 CEA861 */
+ { NULL, 50, 720, 576, KHZ2PICOS(27000), 68, 12, 39, 5, 64, 5,
+ 0, FB_VMODE_NONINTERLACED, 0},
+ /* 720x576i@50 CEA861 */
+ { NULL, 50, 720, 576, KHZ2PICOS(27000), 138, 24, 38, 4, 126, 6,
+ 0, FB_VMODE_INTERLACED + FB_VMODE_DOUBLE, 0},
+ /* 800x480@60 CVT */
+ { NULL, 60, 800, 480, KHZ2PICOS(29500), 96, 24, 10, 3, 72, 7,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+ /* 800x480@75 CVT */
+ { NULL, 75, 800, 480, KHZ2PICOS(38500), 112, 32, 14, 3, 80, 7,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+ /* 800x600@60 DMT */
+ { NULL, 60, 800, 600, KHZ2PICOS(40000), 88, 40, 23, 1, 128, 4,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+#if 0
+ /* 800x600@60 CVT */
+ { NULL, 60, 800, 600, KHZ2PICOS(38250), 112, 32, 17, 3, 80, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+#endif
+ /* 800x600@75 DMT */
+ { NULL, 75, 800, 600, KHZ2PICOS(49500), 160, 16, 21, 1, 80, 3,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+#if 0
+ /* 800x600@75 CVT */
+ { NULL, 75, 800, 600, KHZ2PICOS(49000), 120, 40, 22, 3, 80, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+#endif
+ /* 848x480@60 DMT */
+ { NULL, 60, 848, 480, KHZ2PICOS(33750), 112, 16, 23, 6, 112, 8,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1024x600@60 DMT */
+ { NULL, 60, 1024, 600, KHZ2PICOS(49000), 144, 40, 11, 3, 104, 10,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1024x768@60 DMT */
+ { NULL, 60, 1024, 768, KHZ2PICOS(65000), 160, 24, 29, 3, 136, 6,
+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1024x768@60 CVT */
+ { NULL, 60, 1024, 768, KHZ2PICOS(63500), 152, 48, 23, 3, 104, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+ /* 1024x768@75 DMT */
+ { NULL, 75, 1024, 768, KHZ2PICOS(78750), 176, 16, 28, 1, 96, 3,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+#if 0
+ /* 1024x768@75 CVT */
+ { NULL, 75, 1024, 768, KHZ2PICOS(82000), 168, 64, 30, 3, 104, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+#endif
+ /* 1152x864@60 CVT */
+ { NULL, 60, 1152, 864, KHZ2PICOS(81750), 184, 64, 26, 3, 120, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+ /* 1152x864@75 DMT */
+ { NULL, 75, 1152, 864, KHZ2PICOS(108000), 256, 64, 32, 1, 128, 3,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1152x864@75 CVT */
+ { NULL, 75, 1152, 864, KHZ2PICOS(104000), 192, 72, 34, 3, 120, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+ /* 1280x720@50 CEA861,HDMI_1280x720p50_16x9 */
+ { NULL, 50, 1280, 720, KHZ2PICOS(74250), 220, 440, 20, 5, 40, 5,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, 0},
+ /* 1280x720@60 CEA861,HDMI_1280x720p60_16x9 */
+ { NULL, 60, 1280, 720, KHZ2PICOS(74250), 220, 110, 20, 5, 40, 5,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, 0},
+#if 0
+ /* 1280x720@60 CVT */
+ { NULL, 60, 1280, 720, KHZ2PICOS(74500), 192, 64, 20, 3, 128, 5,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+#endif
+ /* 1280x720@75 CVT */
+ { NULL, 75, 1280, 720, KHZ2PICOS(95750), 208, 80, 27, 3, 128, 5,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+ /* 1280x768@60 DMT/CVT */
+ { NULL, 60, 1280, 768, KHZ2PICOS(79500), 192, 64, 20, 3, 128, 7,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1280x768@75 DMT/CVT */
+ { NULL, 75, 1280, 768, KHZ2PICOS(102250), 208, 80, 27, 3, 128, 7,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1280x800@60 DMT/CVT */
+ { NULL, 60, 1280, 800, KHZ2PICOS(83500), 200, 72, 22, 3, 128, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1280x800@75 DMT/CVT */
+ { NULL, 75, 1280, 800, KHZ2PICOS(106500), 208, 80, 29, 3, 128, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1280x960@60 DMT */
+ { NULL, 60, 1280, 960, KHZ2PICOS(108000), 312, 96, 36, 1, 112, 3,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+#if 0
+ /* 1280x960@60 CVT */
+ { NULL, 60, 1280, 960, KHZ2PICOS(101250), 208, 80, 29, 3, 128, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+#endif
+ /* 1280x960@75 CVT */
+ { NULL, 75, 1280, 960, KHZ2PICOS(130000), 224, 88, 38, 3, 136, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+ /* 1280x1024@60 DMT */
+ { NULL, 60, 1280, 1024, KHZ2PICOS(108000), 248, 48, 38, 1, 112, 3,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+#if 0
+ /* 1280x1024@60 CVT */
+ { NULL, 60, 1280, 1024, KHZ2PICOS(109000), 216, 80, 29, 3, 136, 7,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+#endif
+ /* 1280x1024@75 DMT */
+ { NULL, 75, 1280, 1024, KHZ2PICOS(135000), 248, 16, 38, 1, 144, 3,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+#if 0
+ /* 1280x1024@75 CVT */
+ { NULL, 75, 1280, 1024, KHZ2PICOS(138750), 224, 88, 38, 3, 136, 7,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0},
+#endif
+ /* 1360x768@60 */
+ { NULL, 60, 1360, 768, KHZ2PICOS(85500), 256, 64, 18, 3, 112, 6,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, 0},
+ /* 1366x768@60 */
+ { NULL, 60, 1366, 768, KHZ2PICOS(85500), 213, 70, 24, 3, 143, 3,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, 0},
+ /* 1400x1050@60 DMT/CVT */
+ { NULL, 60, 1400, 1050, KHZ2PICOS(121750), 232, 88, 32, 3, 144, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+#if 0
+ /* 1400x1050@60+R DMT/CVT */
+ { NULL, 60, 1400, 1050, KHZ2PICOS(101000), 80, 48, 23, 3, 32, 4,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+#endif
+ /* 1440x480p@60 CEA861 */
+ { NULL, 60, 1400, 480, KHZ2PICOS(54054), 120, 32, 30, 9, 124, 6,
+ 0, FB_VMODE_NONINTERLACED, 0},
+ /* 1440x900@60 DMT/CVT */
+ { NULL, 60, 1440, 900, KHZ2PICOS(106500), 232, 80, 25, 3, 152, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1440x900@75 DMT/CVT */
+ { NULL, 75, 1440, 900, KHZ2PICOS(136750), 248, 96, 33, 3, 152, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1600x1200@60 DMT/CVT */
+ { NULL, 60, 1600, 1200, KHZ2PICOS(162000), 304, 64, 46, 1, 192, 3,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1680x1050@60 DMT/CVT */
+ { NULL, 60, 1680, 1050, KHZ2PICOS(146250), 280, 104, 30, 3, 176, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1920x1080@25,HDMI_1920x1080p25_16x9 */
+ { NULL, 25, 1920, 1080, KHZ2PICOS(74250), 148, 528, 36, 4, 44, 5,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, 0},
+ /* 1920x1080@30,HDMI_1920x1080p30_16x9 */
+ { NULL, 30, 1920, 1080, KHZ2PICOS(74250), 148, 88, 36, 4, 44, 5,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, 0},
+ /* 1920x1080@50,HDMI_1920x1080p50_16x9 */
+ { NULL, 50, 1920, 1080, KHZ2PICOS(148500), 148, 528, 36, 4, 44, 5,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, 0},
+ /* 1920x1080i@50 */
+ { NULL, 50, 1920, 1080, KHZ2PICOS(74250), 148, 528, 30, 4, 44, 10,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_INTERLACED, 0},
+ /* 1920x1080@60 */
+ { NULL, 60, 1920, 1080, KHZ2PICOS(148500), 148, 88, 36, 4, 44, 5,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, 0},
+ /* 1920x1080i@60 */
+ { NULL, 60, 1920, 1080, KHZ2PICOS(74250), 148, 88, 30, 4, 44, 10,
+ FB_SYNC_VERT_HIGH_ACT + FB_SYNC_HOR_HIGH_ACT,
+ FB_VMODE_INTERLACED, 0},
+ /* 1920x1200@60+R DMT/CVT */
+ { NULL, 60, 1920, 1200, KHZ2PICOS(154000), 80, 48, 26, 3, 32, 6,
+ FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ /* 1920x1200@60 DMT/CVT */
+ { NULL, 60, 1920, 1200, KHZ2PICOS(193250), 336, 136, 36, 3, 200, 6,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
+ { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 },
+};
+
+char *vpp_colfmt_str[] = {"YUV420", "YUV422H", "YUV422V", "YUV444", "YUV411",
+ "GRAY", "ARGB", "AUTO", "RGB888", "RGB666", "RGB565",
+ "RGB1555", "RGB5551"};
+const char *vpp_mod_str[] = {"GOVRH2", "GOVRH", "DISP", "GOVW", "GOVM", "SCL",
+ "SCLW", "VPU", "VPUW", "PIP", "VPPM", "LCDC", "CUR", "MAX"};
+
+#else
+#define EXTERN extern
+
+extern const unsigned int vpp_csc_parm[VPP_CSC_MAX][7];
+extern char *vpp_colfmt_str[];
+extern const struct fb_videomode vpp_videomode[];
+extern char *vpp_mod_str[];
+#ifdef CONFIG_VPP_NOTIFY
+extern struct switch_dev vpp_sdev;
+#endif
+#endif
+
+EXTERN struct vpp_info_t g_vpp;
+#ifdef VPP_C
+EXPORT_SYMBOL(g_vpp);
+#endif
+
+static inline int vpp_get_hdmi_spdif(void)
+{
+ return (g_vpp.hdmi_audio_interface == VPP_HDMI_AUDIO_SPDIF) ? 1 : 0;
+}
+
+/* Internal functions */
+EXTERN int get_key(void);
+EXTERN unsigned int vpp_get_chipid(void);
+
+/* Export functions */
+EXTERN void vpp_mod_unregister(vpp_mod_t mod);
+EXTERN struct vpp_mod_base_t *vpp_mod_register(vpp_mod_t mod, int size,
+ unsigned int flags);
+EXTERN struct vpp_mod_base_t *vpp_mod_get_base(vpp_mod_t mod);
+EXTERN struct vpp_fb_base_t *vpp_mod_get_fb_base(vpp_mod_t mod);
+EXTERN vdo_framebuf_t *vpp_mod_get_framebuf(vpp_mod_t mod);
+EXTERN void vpp_mod_init(void);
+EXTERN void vpp_mod_set_clock(vpp_mod_t mod,
+ vpp_flag_t enable, int force);
+
+EXTERN unsigned int vpp_get_base_clock(vpp_mod_t mod);
+EXTERN void vpp_set_video_scale(vdo_view_t *vw);
+EXTERN int vpp_set_recursive_scale(vdo_framebuf_t *src_fb,
+ vdo_framebuf_t *dst_fb);
+EXTERN vpp_display_format_t vpp_get_fb_field(vdo_framebuf_t *fb);
+EXTERN void vpp_wait_vsync(int no, int cnt);
+EXTERN int vpp_get_gcd(int A, int B);
+EXTERN vpp_csc_t vpp_check_csc_mode(vpp_csc_t mode,
+ vdo_color_fmt src_fmt, vdo_color_fmt dst_fmt, unsigned int flags);
+EXTERN inline void vpp_cache_sync(void);
+EXTERN int vpp_calc_refresh(int pixclk, int xres, int yres);
+EXTERN int vpp_calc_align(int value, int align);
+EXTERN int vpp_calc_fb_width(vdo_color_fmt colfmt, int width);
+EXTERN void vpp_get_colfmt_bpp(vdo_color_fmt colfmt,
+ int *y_bpp, int *c_bpp);
+EXTERN int vpp_irqproc_work(enum vpp_int_t type, int (*func)(void *argc),
+ void *arg, int wait_ms, int work_cnt);
+EXTERN int vpp_check_dbg_level(enum vpp_dbg_level_t level);
+
+#ifdef __KERNEL__
+EXTERN void vpp_dbg_show(int level, int tmr, char *str);
+EXTERN void vpp_dbg_wake_up(void);
+EXTERN int vpp_dbg_get_period_usec(struct vpp_dbg_period_t *p,
+ int cmd);
+EXTERN void vpp_dbg_timer(struct vpp_dbg_timer_t *p, char *str, int cmd);
+EXTERN void vpp_dbg_back_trace(void);
+EXTERN void vpp_dbg_show_val1(int level, int tmr, char *str, int val);
+EXTERN void vpp_dbg_wait(char *str);
+EXTERN void vpp_irqproc_init(void);
+EXTERN void vpp_irqproc_del_work(enum vpp_int_t type,
+ int (*func)(void *argc));
+EXTERN struct vpp_irqproc_t *vpp_irqproc_get_entry(
+ enum vpp_int_t vpp_int);
+
+/* dev-vpp.c */
+EXTERN int vpp_get_info(int fbn, struct fb_var_screeninfo *var);
+EXTERN int vpp_set_par(struct fb_info *info);
+EXTERN void vpp_backup_reg2(unsigned int addr,
+ unsigned int size, unsigned int *ptr);
+EXTERN void vpp_restore_reg2(unsigned int addr,
+ unsigned int size, unsigned int *reg_ptr);
+EXTERN int vpp_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info);
+EXTERN void vpp_netlink_init(void);
+EXTERN void vpp_netlink_notify(int no, int cmd, int arg);
+EXTERN void vpp_netlink_notify_plug(int vout_num, int plugin);
+EXTERN void vpp_netlink_notify_cp(int enable);
+EXTERN void vpp_switch_state_init(void);
+EXTERN int vpp_set_blank(struct fb_info *info, int blank);
+#endif
+
+EXTERN unsigned int vpp_convert_colfmt(int yuv2rgb, unsigned int data);
+EXTERN void vpp_init(void);
+
+/* EXTERN void vpp_set_power_mgr(int arg); */
+EXTERN void vpp_show_timing(char *str,
+ struct fb_videomode *vmode, vpp_clock_t *clk);
+EXTERN void vpp_show_framebuf(char *str, vdo_framebuf_t *fb);
+EXTERN void vpp_show_videomode(char *str, struct fb_videomode *v);
+EXTERN void vpp_set_NA12_hiprio(int type);
+
+EXTERN int vpp_mb_get(unsigned int phy);
+EXTERN int vpp_mb_put(unsigned int phy);
+EXTERN int vpp_mb_irqproc_sync(int arg);
+
+#undef EXTERN
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* VPP_H */
diff --git a/common/wmt_display/wmt-ost.c b/common/wmt_display/wmt-ost.c
new file mode 100755
index 0000000..92b8417
--- /dev/null
+++ b/common/wmt_display/wmt-ost.c
@@ -0,0 +1,107 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+should have received a copy of the GNU General Public License along with this
+program. If not, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+#include <common.h>
+#include "vpp.h"
+
+static WMT_OST_REG *pWMTOST;
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int wmt_write_ostc(void)
+{
+ unsigned int sw_counter = 30000;
+
+ while( pWMTOST->ostas & 0x10 ) {
+ if ( --sw_counter == 0 ) { // Need to be considered
+ printf("Count Write Active Busy\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int wmt_init_ost(void)
+{
+ //printf("wmt_init_ostimer\n");
+
+ if (pWMTOST == NULL)
+ pWMTOST = (WMT_OST_REG *)0xd8130100;
+
+ if (pWMTOST->ostctrl&0x01)
+ return 0;
+
+ pWMTOST->ostctrl = 0;
+ pWMTOST->ostwe = 0;
+
+ if (wmt_write_ostc())
+ return -1;
+
+ pWMTOST->ostct = 0;
+
+ pWMTOST->ostctrl = 1;
+
+ return 0;
+}
+
+int wmt_read_ostc(int *val)
+{
+ unsigned int sw_counter = 300000;
+
+ if (pWMTOST == NULL) {
+ if (wmt_init_ost())
+ return -1;
+ }
+
+ if ( (pWMTOST->ostctrl & 0x02 ) == 0 )
+ pWMTOST->ostctrl |= 0x02;
+
+ // Check OS Timer Count Value is Valid
+ while ( (pWMTOST->ostas & 0x20) == 0x20 ) {
+ if ( --sw_counter == 0 ) { // Need to be considered
+ printf("Read Count Request Fail\n");
+ break;
+ }
+ }
+ //*val = (int)pWMTOST->ostct; //Charles
+ *val = (int)pWMTOST->ostct/3;
+ return 0;
+}
+
+int wmt_delayus(int us)
+{
+ int count = 100;
+ int before,after;
+
+ //us = us*3;
+
+ if (wmt_read_ostc(&before))
+ return -1;
+ while(1) {
+ while(--count);
+ if (wmt_read_ostc(&after))
+ return -1;
+ if ((after - before) >= us) {
+ //printf("request = %d , result = %d\n",us,(after - before));
+ break;
+ }
+ count = 100;
+ }
+ return 0;
+}
+
diff --git a/common/wmt_display/wmt_cmd_display.c b/common/wmt_display/wmt_cmd_display.c
new file mode 100755
index 0000000..966972c
--- /dev/null
+++ b/common/wmt_display/wmt_cmd_display.c
@@ -0,0 +1,357 @@
+/*++
+Copyright (c) 2014 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+should have received a copy of the GNU General Public License along with this
+program. If not, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <version.h>
+#include <stdarg.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <linux/stddef.h>
+#include <asm/byteorder.h>
+
+#include "vpp.h"
+#include "wmt_display.h"
+#include "minivgui.h"
+#include "hw/wmt-pwm.h"
+#include "../../board/wmt/include/wmt_iomux.h"
+
+extern int text_x, text_y;
+extern void lcd_blt_enable(int no, int enable);
+extern void *arm_memset(void *s, int c, size_t count);
+extern void lcd_spi_setup(void);
+
+int display_init(int on, int force)
+{
+ struct vout_t *vo;
+ int i;
+
+ if ((g_display_vaild & DISPLAY_ENABLE) == DISPLAY_ENABLE) {
+ if (force) { // force re-initial
+ if (g_display_param.vout == VPP_VOUT_LCD)
+ lcd_blt_enable(g_pwm_setting.pwm_no, 0);
+ // govrh_set_dvo_enable(VPP_FLAG_DISABLE);
+ // govrh_set_tg_enable(VPP_FLAG_DISABLE);
+ for (i = 0; i < VPP_VOUT_NUM; i++) {
+ vo = vout_get_entry(i);
+ if (!vo)
+ continue;
+ vout_set_blank(i, VOUT_BLANK_POWERDOWN);
+ }
+
+ if (g_display_param.vout == VPP_VOUT_DVI)
+ //Wait for 500ms to let the TV's CVBS signal disconnect. It can avoid to the screen scratch
+ mdelay(500);
+
+ g_display_vaild = 0;
+ }
+ } else
+ force = 1;
+
+ if (force) {
+ if (wmt_graphic_init()) {
+ printf("wmt_graphic_init failed\n");
+ return -1;
+ } else
+ printf("wmt_graphic_init ok\n");
+
+ text_x = 30;
+ text_y = 30 - CHAR_HEIGHT;
+
+ lcd_spi_setup();
+ }
+
+ if ((g_display_param.vout == VPP_VOUT_LCD) && (on != 0)) {
+ printf("before lcd_blt_enable !!!!!!!!!\n");
+ lcd_blt_enable(g_pwm_setting.pwm_no, 1);
+ printf("lcd_blt_enable !!!!!!!!!\n");
+ }
+
+ return 0;
+}
+
+static void framebuffer_clean(void)
+{
+ int no;
+ mv_surface *s;
+
+ for(no = 0; no < VPP_VOUT_INFO_NUM; no++) {
+ s = mv_getSurface(no);
+ if(s->startAddr)
+ arm_memset(s->startAddr, 0, s->height * s->lineBytes);
+ }
+}
+
+int display_clear(void)
+{
+ if (g_display_vaild & DISPLAY_ENABLE) {
+ framebuffer_clean();
+ return 0;
+ } else
+ return display_init(1, 0);
+}
+
+int display_show(int clearFB)
+{
+ struct vout_info_t *info;
+ mv_surface *s;
+ int i;
+
+ if (g_img_phy == 0xFFFF) {
+ printf("%s is not found , command (display show) is invaild\n", ENV_IMGADDR);
+ return -1;
+ }
+ if (display_init(0, 0))
+ return -1;
+
+ printf("Loading BMP .....\n");
+
+ g_logo_scale = (g_vpp.virtual_display) ? LOGO_MODE_MAX : LOGO_NOT_SCALE;
+
+ //Becuase the logo scale has bug in portrait screen, don't scale logo when screen is portrait
+ //Fix it in the future
+ if(g_display_direction == 0 || g_display_direction == 2)
+ g_logo_scale = LOGO_NOT_SCALE;
+
+ for (i = 0; i < VPP_VOUT_INFO_NUM; i++) {
+ info = vout_info[i];
+ if (!info)
+ break;
+ if(g_logo_scale == LOGO_NOT_SCALE) {
+ if (mv_loadBmp(i, (unsigned char *)g_img_phy, clearFB)) {
+ printf("failed\r\n");
+ return -1;
+ }
+ continue;
+ }
+ /* sclae logo */
+ s = mv_getSurface(i);
+ if (s->startAddr) {
+ vdo_framebuf_t src_fb, *dst_fb;
+ unsigned int logo_addr = (unsigned int)s->startAddr;
+ int line_bytes = s->lineBytes;
+
+ s->startAddr = (char *)(logo_addr - 1920 * 1080 * 4);
+ s->lineBytes = 1920 * 4;
+ s->width = 1920;
+ s->height = 1080;
+ if (mv_loadBmp(i, (unsigned char *)g_img_phy, clearFB)) {
+ printf("failed\r\n");
+ return -1;
+ }
+ memset(&src_fb, 0, sizeof(vdo_framebuf_t));
+ src_fb.col_fmt = (s->bits_per_pixel == 16) ?
+ VDO_COL_FMT_RGB_565 : VDO_COL_FMT_ARGB;
+ src_fb.img_w = s->img_width;
+ src_fb.img_h = s->img_height;
+ src_fb.fb_w = s->lineBytes / (s->bits_per_pixel / 8);
+ src_fb.fb_h = s->img_height;
+ src_fb.y_addr = (unsigned int)s->img_startAddr;
+ dst_fb = &info->fb;
+ vpp_set_recursive_scale(&src_fb, dst_fb);
+
+ /* recover startAddr and lineBytes */
+ s->startAddr = (char *)logo_addr;
+ s->lineBytes = line_bytes;
+ }
+ }
+ printf("Load Ok\n");
+ if (g_display_param.vout == VPP_VOUT_LCD) {
+ lcd_blt_enable(g_pwm_setting.pwm_no, 1);
+ //lcd_uboot_set_backlight();
+ }
+ return 0;
+}
+
+int display_animation(unsigned int img_phy_addr)
+{
+ g_logo_x = -1;
+ g_logo_y = -1;
+ if (display_init(0, 0))
+ return -1;
+ if (mv_loadBmp(0, (unsigned char *)img_phy_addr, 1)) {
+ printf("failed\r\n");
+ return -1;
+ }
+ if (mv_loadBmp(1, (unsigned char *)img_phy_addr, 1)) {
+ printf("failed\r\n");
+ return -1;
+ }
+ if (g_display_param.vout == VPP_VOUT_LCD)
+ lcd_blt_enable(g_pwm_setting.pwm_no, 1);
+ return 0;
+}
+
+static int display_set_pwm(char *val, int on)
+{
+
+ if (val == NULL) {
+ printf("error : can not get pwm parameter\n");
+ return -1;
+ }
+
+ lcd_blt_enable(g_pwm_setting.pwm_no, 0);
+
+ parse_pwm_params(NULL, val);
+
+ if ((g_display_vaild & PWMDEFMASK) == PWMDEFTP) {
+ lcd_blt_set_pwm(g_pwm_setting.pwm_no, g_pwm_setting.duty, g_pwm_setting.period);
+ } else {
+ // fan : may need to check PWM power ..
+ pwm_set_period(g_pwm_setting.pwm_no, g_pwm_setting.period - 1);
+ pwm_set_duty(g_pwm_setting.pwm_no, g_pwm_setting.duty - 1);
+ pwm_set_control(g_pwm_setting.pwm_no, (g_pwm_setting.duty - 1) ? 0x35 : 0x8);
+ pwm_set_gpio(g_pwm_setting.pwm_no, g_pwm_setting.duty - 1);
+ pwm_set_scalar(g_pwm_setting.pwm_no, g_pwm_setting.scalar - 1);
+ }
+
+ lcd_blt_enable(g_pwm_setting.pwm_no, on);
+
+ return 0;
+}
+
+static int wmt_display_main (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int tmp;
+
+ switch (argc) {
+ case 0:
+ case 1:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 0;
+ default:
+ if (strncmp(argv[1], "init", 2) == 0) {
+ if (argc == 3) {
+ if (strcmp(argv[2], "force") == 0) {
+ display_init(1, 1);
+ return 0;
+ }
+ }
+ display_init(1, 0);
+ return 0;
+ }
+
+ if (strncmp(argv[1], "clear", 2) == 0) {
+ display_clear();
+ return 0;
+ }
+
+ if (strncmp(argv[1], "show", 2) == 0) {
+ if (4 == argc) {
+ g_logo_x = simple_strtoul(argv[2], NULL, 10);
+ g_logo_y = simple_strtoul(argv[3], NULL, 10);
+ printf("(%d, %d) ", g_logo_x, g_logo_y);
+ } else {
+ g_logo_x = -1;
+ g_logo_y = -1;
+ }
+ display_show(1);
+ return 0;
+ }
+
+ if (strncmp(argv[1], "setpwm", 2) == 0) {
+ if (argc == 3) {
+ if (argv[2] != NULL) {
+ display_set_pwm(argv[2], 1);
+ return 0;
+ }
+ } else if (argc == 4) {
+ tmp = simple_strtoul(argv[2], NULL, 10);
+ if (argv[3] != NULL) {
+ display_set_pwm(argv[3], tmp);
+ return 0;
+ }
+ }
+ }
+
+ if (!strncmp(argv[1], "backlight", 2)) {
+ if (!strncmp(argv[2], "on", 2))
+ lcd_backlight_power_on(1);
+ else
+ lcd_backlight_power_on(0);
+ return 0;
+ }
+
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 0;
+
+ }
+}
+
+U_BOOT_CMD(
+ display, 5, 1, wmt_display_main,
+ "show - \n",
+ NULL
+);
+
+static int do_avdetect(cmd_tbl_t *cmd, int flag, int argc, char *argv[])
+{
+ int ret;
+ struct gpio_param_t avdetect_gpio;
+
+ ret = parse_gpio_param("wmt.io.avdetect", &avdetect_gpio);
+ if(ret) {
+ DPRINT("please set wmt.io.avdetect\n");
+ return -1;
+ }
+
+ if(avdetect_gpio.gpiono > 19) {
+ DPRINT("invalid avdetect gpio no: %d\n", avdetect_gpio.gpiono);
+ return -1;
+ }
+
+ gpio_direction_input(avdetect_gpio.gpiono);
+ gpio_setpull(avdetect_gpio.gpiono, GPIO_PULL_UP);
+ mdelay(10);
+
+ if (avdetect_gpio.act) {
+ if(gpio_get_value(avdetect_gpio.gpiono))
+ DPRINT("av plug in\n");
+ else
+ DPRINT("av plug out\n");
+ } else {
+ if(gpio_get_value(avdetect_gpio.gpiono))
+ DPRINT("av plug out\n");
+ else
+ DPRINT("av plug in\n");
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ avdetect, 1, 0, do_avdetect,
+ "avdetect - print AV in/out status\n",
+ ""
+);
+
+static int do_dumphdmi(cmd_tbl_t *cmd, int flag, int argc, char *argv[])
+{
+ p_govrh->dump_reg();
+ p_govrh2->dump_reg();
+ hdmi_reg_dump();
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ dumphdmi, 1, 0, do_dumphdmi,
+ "dumphdmi - dump govrh,govrh2 and hdmi register\n",
+ ""
+);
+
diff --git a/common/wmt_display/wmt_display.h b/common/wmt_display/wmt_display.h
new file mode 100755
index 0000000..85a7310
--- /dev/null
+++ b/common/wmt_display/wmt_display.h
@@ -0,0 +1,170 @@
+/*++
+Copyright (c) 2010 WonderMedia Technologies, 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 License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+should have received a copy of the GNU General Public License along with this
+program. If not, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#ifndef __WM_LOGO_H__
+#define __WM_LOGO_H__
+
+#include "vpp.h"
+
+typedef struct
+{
+ int width;
+ int height;
+ int lineBytes;
+ unsigned int bits_per_pixel;
+ char * startAddr;
+
+ int img_width;
+ int img_height;
+ char *img_startAddr;
+}mv_surface;
+
+typedef struct
+{
+ int left;
+ int top;
+ int right;
+ int bottom;
+}mv_Rect;
+
+
+#define ENV_DISPLAY_PARM "wmt.display.param"
+#define ENV_DISPLAY_PARM2 "wmt.display.param2"
+#define ENV_DISPLAY_TMR "wmt.display.tmr"
+#define ENV_DISPLAY_PWM "wmt.display.pwm"
+#define ENV_MEMTOTAL "memtotal"
+#define ENV_IMGADDR "wmt.display.logoaddr"
+#define ENV_LCD_POWERON "wmt.lcd.poweron"
+#define ENV_DIRECTPATH "wmt.display.direct_path"
+#define ENV_DIRECTFB "wmt.display.fb"
+#define ENV_PMEM "wmt.pmem.param"
+#define ENV_LCD_POWER "wmt.gpo.lcd"
+#define ENV_POWER_LED "wmt.gpo.pwrled"
+#define ENV_LOGO_LED_CONTROL "wmt.gpo.logoled"
+#define ENV_CHARGE_ANIMATION "wmt.display.chargeanim"
+
+struct wmt_display_param_t {
+ unsigned int vout;
+ unsigned int op1;
+ unsigned int op2;
+ unsigned int resx;
+ unsigned int resy;
+ unsigned int fps_pixclk;
+};
+
+struct wmt_pwm_setting_t {
+ unsigned int pwm_no;
+ unsigned int scalar;
+ unsigned int period;
+ unsigned int duty;
+ unsigned int config;
+};
+
+struct gpio_operation_t {
+ unsigned int id;
+ unsigned int gpiono;
+ unsigned int act;
+ unsigned int bitmap;
+ unsigned int ctl;
+ unsigned int oc;
+ unsigned int od;
+};
+
+struct gpio_param_t {
+ unsigned int flag;
+ unsigned int gpiono;
+ unsigned int act;
+};
+
+struct wmt_backlight_param_t {
+ int pwm_no;
+ int invert;
+ int gpio; /* switch */
+ int active;
+};
+
+typedef enum {
+ LOGO_NOT_SCALE,
+ LOGO_ORI_SCALE_FULL, // Put the logo to a buffer which size is logo original size, and then scale the buffer to full screen
+ LOGO_720P_SCALE_FULL, // Put the logo to the center of a buffer which size is 720p, and then scale the buffer to full screen
+ LOGO_MODE_MAX
+} logo_scale_t;
+
+#ifdef WMT_DISPLAY
+#define EXTERN
+#else
+#define EXTERN extern
+#endif
+
+EXTERN struct wmt_display_param_t g_display_param;
+EXTERN struct wmt_display_param_t g_display_param2;
+EXTERN struct wmt_pwm_setting_t g_pwm_setting;
+EXTERN struct gpio_operation_t g_lcd_pw_pin;
+EXTERN unsigned int g_fb_phy;
+EXTERN unsigned int g_img_phy;
+EXTERN int g_logo_x;
+EXTERN int g_logo_y;
+EXTERN logo_scale_t g_logo_scale;
+
+#ifdef CONFIG_VPP_SHENZHEN
+EXTERN struct wmt_backlight_param_t g_backlight_param;
+#endif
+
+/*
+ 0 : not initial
+ not 0 :
+ bit 0 :
+ 1 : initial ok
+ 0 : not initial
+ bit1 :
+ 1 : get tmr from env
+ 0 : get tmr auto
+ bit[2:3] :
+ 00 : run pwm default (freq, level)
+ 01 : run pwm from env (freq, level)
+ 10 : run pwm from env (scalar, period, duty)
+ 11 : mask for pwm env config
+*/
+EXTERN int g_display_vaild;
+
+#define DISPLAY_ENABLE 1
+#define TMRFROMENV 1<<1
+#define PWMDEFTP 1<<2
+#define PWMDEFSZ 1<<3
+#define PWMDEFMASK 0x0c
+
+// cmd_textout
+#define CHAR_WIDTH 12
+#define CHAR_HEIGHT 22 // 16
+
+int display_init(int on, int force);
+int parse_display_tmr(char *name);
+int parse_pwm_params(char *name, char *val);
+int parse_gpio_operation(char *name);
+int parse_gpio_param(const char *name, struct gpio_param_t *p_gpio_pin);
+int wmt_graphic_init(void);
+int uboot_vpp_alloc_framebuffer(unsigned int resx,unsigned int resy);
+void lcd_blt_set_pwm(int no, int level, int freq);
+
+#ifdef CONFIG_VPP_SHENZHEN
+int parse_backlight_params(void);
+#endif
+
+#undef EXTERN
+
+
+#endif /* __WM_LOGO_H__ */