diff options
Diffstat (limited to 'drivers/video/wmt/devices/lcd.c')
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/devices/lcd.c | 528 |
1 files changed, 255 insertions, 273 deletions
diff --git a/drivers/video/wmt/devices/lcd.c b/drivers/video/wmt/devices/lcd.c index a6099294..195d3483 100755..100644 --- a/drivers/video/wmt/devices/lcd.c +++ b/drivers/video/wmt/devices/lcd.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/lcd.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * 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 @@ -26,15 +26,9 @@ /* #define DEBUG */ /* #define DEBUG_DETAIL */ /*----------------------- DEPENDENCE -----------------------------------------*/ +#include <linux/gpio.h> #include "../lcd.h" #include "../vout.h" -#ifdef CONFIG_KERNEL -#include <linux/gpio.h> -#endif - -#ifdef CONFIG_VPP_SHENZHEN -#include <mach/wmt_iomux.h> -#endif /*----------------------- PRIVATE MACRO --------------------------------------*/ /* #define LCD_XXXX xxxx *//*Example*/ @@ -45,7 +39,7 @@ /*----------------------- PRIVATE TYPE --------------------------------------*/ /* typedef xxxx lcd_xxx_t; *//*Example*/ struct lcd_device_t { - struct lcd_parm_t* (*get_parm)(int arg); + lcd_parm_t* (*get_parm)(int arg); }; /*----------EXPORTED PRIVATE VARIABLES are defined in lcd.h -------------*/ @@ -54,127 +48,102 @@ struct lcd_device_t { 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; +lcd_panel_t lcd_panel_id = LCD_PANEL_MAX; int lcd_panel_bpp = 24; -struct vout_dev_t lcd_vout_dev_ops; +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; +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 */ + lcd_type = type; /* 0-LCD, 1-LVDS */ } int lcd_get_type(void) { - return lcd_type; + 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}}; + int gpio; + int active; +} lcd_power; +/*----------------------- Function Body --------------------------------------*/ static int parse_uboot_param(void) { - char buf[64]; - unsigned int parm[32]; - int l = sizeof(buf); - int ret, 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)) { - pr_err("please set wmt.lcd.power\n"); - return -EINVAL; - } - - 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]; - - ret = gpio_request(lcd_power[i].gpio, "lcd power"); - if (ret) { - pr_err("request gpio %d failed for lcd power\n", - lcd_power[i].gpio); - return ret; - } - - DPRINT("lcd power%d: gpio%d, active %d\n", - i, lcd_power[i].gpio, lcd_power[i].active); - } - - return 0; + char buf[64]; + size_t l = sizeof(buf); + int ret; + + if (wmt_getsyspara("wmt.lcd.power", buf, &l)) { + pr_err("please set wmt.lcd.power\n"); + return -EINVAL; + } + + ret = sscanf(buf, "%d:%d", &lcd_power.gpio, &lcd_power.active); + if (ret < 2) { + pr_err("Batt: bat env param: %s\n", buf); + return -EINVAL; + } + + printk("lcd power: gpio-%d, active %d\n", lcd_power.gpio, lcd_power.active); + + ret = gpio_request(lcd_power.gpio, "lcd power"); + if (ret) { + pr_err("request gpio %d failed\n", lcd_power.gpio); + return ret; + } + + 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); + if (lcd_power.gpio < 0) + return; - DBG_MSG("lcd_power_on: i = %d, on = %d, gpio = %d, active = %d\n", - i, on, lcd_power[i].gpio, lcd_power[i].active); - } + gpio_direction_output(lcd_power.gpio, on ? lcd_power.active : !lcd_power.active); } -#endif +/*----------------------- Backlight --------------------------------------*/ void lcd_set_lvds_id(int id) { - lcd_lvds_id = id; + lcd_lvds_id = id; } int lcd_get_lvds_id(void) { - return lcd_lvds_id; + return lcd_lvds_id; } void lcd_set_parm(int id, int bpp) { - lcd_panel_id = id; - lcd_panel_bpp = bpp; + lcd_panel_id = id; + lcd_panel_bpp = bpp; } -struct lcd_parm_t *lcd_get_parm(enum lcd_panel_t id, unsigned int arg) +lcd_parm_t *lcd_get_parm(lcd_panel_t id, unsigned int arg) { - struct lcd_device_t *p; + struct lcd_device_t *p; - p = &lcd_device_array[id]; - if (p && p->get_parm) - return p->get_parm(arg); - return 0; + 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) +vout_dev_t *lcd_get_dev(void) { - if (lcd_panel_id >= LCD_PANEL_MAX) - return 0; - return &lcd_vout_dev_ops; + if (lcd_panel_id >= LCD_PANEL_MAX) + return 0; + return &lcd_vout_dev_ops; } #ifdef CONFIG_KERNEL @@ -183,257 +152,270 @@ static DEFINE_SEMAPHORE(lcd_sem); void lcd_set_mutex(int lock) { #ifdef CONFIG_KERNEL - if (lock) - down(&lcd_sem); - else - up(&lcd_sem); + if (lock) + down(&lcd_sem); + else + up(&lcd_sem); #endif } + +/* #define CONFIG_PANEL_SET_CLOCK */ 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); +#ifdef CONFIG_PANEL_SET_CLOCK + int hdmi_off; #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); + + DBG_MSG("%d\n", enable); + if (!p_lcd) + return; + + lcd_set_mutex(1); +#ifdef CONFIG_PANEL_SET_CLOCK + /* enable NA12 in Panel on */ + hdmi_off = (govrh_get_MIF_enable(p_govrh)) ? 0 : 1; + if (hdmi_off && enable) + vpp_set_clock_enable(DEV_NA12, enable, 1); #endif - } - } - lcd_set_mutex(0); + + if (enable) { + if (p_lcd->initial) + p_lcd->initial(); + else { + lcd_enable_signal(1); /* singal enable */ + //REG32_VAL(GPIO_BASE_ADDR + 0x80) |= 0x801; + //REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x801; + } + } else { + if (p_lcd->uninitial) + p_lcd->uninitial(); + else { + lcd_enable_signal(0); /* singal disable */ + //REG32_VAL(GPIO_BASE_ADDR + 0xC0) &= ~0x801; + } + } + +#ifdef CONFIG_PANEL_SET_CLOCK + /* disable VPP & NA12 clock in Panel off */ + if (hdmi_off) { + vpp_set_clock_enable(DEV_VPP, enable, 1); + vpp_set_clock_enable(DEV_GOVRHD, enable, 1); + vpp_set_clock_enable(DEV_HDMILVDS, enable, 1); + if (enable == 0) + vpp_set_clock_enable(DEV_NA12, enable, 1); + } +#endif + lcd_set_mutex(0); } void lcd_enable_signal(int enable) { - int hdmi_off; + int hdmi_off; - DBG_MSG("%d\n", enable); - if (lcd_get_type()) { /* LVDS */ - /* TODO */ - } else { /* LCD */ - govrh_set_dvo_enable(p_govrh2, enable); - } + 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); + 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 */ + 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; + 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; + 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 --------------------------------*/ +/*----------------------- 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 ? false : true); - lcd_set_enable(enable ? false : true); - save_state = enable; - } -#endif + static int save_state = -1; + + if (save_state != enable) { + /* lcd enable control by user */ + lcd_power_on(enable ? false : true); + lcd_set_enable(enable ? false : true); + save_state = enable; + } } -static void wmt_config_govrh_polar(struct vout_t *vo) +static void wmt_config_govrh_polar(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); + /* wmt.display.polar [clock polar]:[hsync polart]:[vsync polar]*/ + char buf[64]; + size_t l = sizeof(buf); + int clk_pol, hsync_pol, vsync_pol; + + if (wmt_getsyspara("wmt.display.polar", buf, &l)) { + return; + } + + sscanf(buf, "%d:%d:%d", &clk_pol, &hsync_pol, &vsync_pol); + + printk("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; + vout_t *vo; + 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; + return (p_lcd) ? 1 : 0; } int lcd_get_edid(char *buf) { - return 1; + return 1; } -int lcd_config(struct vout_info_t *info) +int lcd_config(vout_info_t *info) { - info->resx = p_lcd->vmode.xres; - info->resy = p_lcd->vmode.yres; - info->fps = p_lcd->vmode.refresh; - return 0; + 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) +int lcd_init(vout_t *vo) { - DBG_MSG("%d\n", lcd_panel_id); + DBG_MSG("%d\n", lcd_panel_id); - /* vo_set_lcd_id(LCD_CHILIN_LW0700AT9003); */ - if (lcd_panel_id >= LCD_PANEL_MAX) - return -1; + /* 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 (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; + 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; + /* 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, +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(); + if (parse_uboot_param()) { + lcd_power.gpio = -1; + } - vout_device_register(&lcd_vout_dev_ops); - return 0; + vout_device_register(&lcd_vout_dev_ops); + return 0; } /* End of lcd_module_init */ module_init(lcd_module_init); /*--------------------End of Function Body -----------------------------------*/ |