diff options
Diffstat (limited to 'drivers/video/wmt/lvds.c')
-rw-r--r-- | drivers/video/wmt/lvds.c | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/drivers/video/wmt/lvds.c b/drivers/video/wmt/lvds.c new file mode 100644 index 00000000..3f8f8c83 --- /dev/null +++ b/drivers/video/wmt/lvds.c @@ -0,0 +1,204 @@ +/*++ + * linux/drivers/video/wmt/lvds.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 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*/ + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void lvds_xxx(void); *//*Example*/ + +/*----------------------- Function Body --------------------------------------*/ +void lvds_set_power_down(int pwrdn) +{ + DBG_DETAIL("(%d)\n", pwrdn); + + vppif_reg32_write(LVDS_PD, pwrdn); + mdelay(1); + vppif_reg32_write(LVDS_PD_L2HA, pwrdn); +} + +void lvds_set_enable(vpp_flag_t enable) +{ + DBG_DETAIL("(%d)\n", enable); + vppif_reg32_write(LVDS_TRE_EN, (enable) ? 0 : 1); + vppif_reg32_write(LVDS_MODE, (enable) ? 1 : 0); + vppif_reg32_write(LVDS_RESA_EN, (enable) ? 0 : 1); +#ifdef CONFIG_UBOOT + if ((enable) && (lcd_get_lvds_id() == LCD_LVDS_1024x600)) { + /* GPIO10 VDD_EN->CLK delay 16->38ms */ + REG32_VAL(GPIO_BASE_ADDR + 0x80) |= 0x400; + REG32_VAL(GPIO_BASE_ADDR + 0xC0) |= 0x400; + mdelay(16); + } +#endif +} + +int lvds_get_enable(void) +{ + return vppif_reg32_read(LVDS_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 + vppif_reg32_write(LVDS_TEST, mode_change); + vppif_reg32_write(LVDS_IGS_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); + + vppif_reg32_write(LVDS_HSYNC_POLAR_LO, h_lo); + vppif_reg32_write(LVDS_VSYNC_POLAR_LO, v_lo); +} + +void lvds_get_sync_polar(int *hsync_hi, int *vsync_hi) +{ + *hsync_hi = (vppif_reg32_read(LVDS_HSYNC_POLAR_LO)) ? 0 : 1; + *vsync_hi = (vppif_reg32_read(LVDS_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", vppif_reg32_read(LVDS_TEST), + vppif_reg32_read(LVDS_DUAL_CHANNEL), + vppif_reg32_read(LVDS_INV_CLK)); + DPRINT("ldi shift left %d,IGS bpp type %d\n", + vppif_reg32_read(LVDS_LDI_SHIFT_LEFT), + vppif_reg32_read(LVDS_IGS_BPP_TYPE)); + DPRINT("rsen %d,pll ready %d\n", vppif_reg32_read(LVDS_RSEN), + vppif_reg32_read(LVDS_PLL_READY)); + DPRINT("pwr dn %d\n", vppif_reg32_read(LVDS_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 = vppif_reg32_read(LVDS_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) +{ + vppif_reg32_write(LVDS_REG_LEVEL, 1); + vppif_reg32_write(LVDS_REG_UPDATE, 1); + vppif_reg32_write(LVDS_PLL_R_F, 0x1); + vppif_reg32_write(LVDS_PLL_CPSET, 0x1); + vppif_reg32_write(LVDS_TRE_EN, 0x0); + vppif_reg32_write(LVDS_VBG_SEL, 2); + vppif_reg32_write(LVDS_DRV_PDMODE, 0); + vppif_reg32_write(LVDS_LDI_SHIFT_LEFT, 1); + vppif_reg32_out(REG_LVDS_TEST2, 0x31432); +} + +#endif /* WMT_FTBLK_LVDS */ + |