diff options
Diffstat (limited to 'drivers/video/wmt/vppm.c')
-rw-r--r-- | drivers/video/wmt/vppm.c | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/drivers/video/wmt/vppm.c b/drivers/video/wmt/vppm.c new file mode 100644 index 00000000..f3bc7d9f --- /dev/null +++ b/drivers/video/wmt/vppm.c @@ -0,0 +1,283 @@ +/*++ + * linux/drivers/video/wmt/vppm.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 VPPM_C +/* #define DEBUG */ +/* #define DEBUG_DETAIL */ + +#include "vppm.h" + +void vppm_set_int_enable(vpp_flag_t enable, vpp_int_t int_bit) +{ +#ifdef WMT_FTBLK_SCL + if (int_bit & VPP_INT_SCL_VBIE) + vppif_reg32_write(VPP_SCL_INTEN_VBIE, enable); + if (int_bit & VPP_INT_SCL_VBIS) + vppif_reg32_write(VPP_SCL_INTEN_VBIS, enable); + if (int_bit & VPP_INT_SCL_PVBI) + vppif_reg32_write(VPP_SCL_INTEN_PVBI, enable); +#endif +#ifdef WMT_FTBLK_GOVRH + if (int_bit & VPP_INT_GOVRH_VBIE) + vppif_reg32_write(VPP_GOVRH_INTEN_VBIE, enable); + if (int_bit & VPP_INT_GOVRH_VBIS) + vppif_reg32_write(VPP_GOVRH_INTEN_VBIS, enable); + if (int_bit & VPP_INT_GOVRH_PVBI) + vppif_reg32_write(VPP_GOVRH_INTEN_PVBI, enable); +#endif +#ifdef WMT_FTBLK_GOVRH + if (int_bit & VPP_INT_GOVRH2_VBIE) + vppif_reg32_write(VPP_GOVRH2_INTEN_VBIE, enable); + if (int_bit & VPP_INT_GOVRH2_VBIS) + vppif_reg32_write(VPP_GOVRH2_INTEN_VBIS, enable); + if (int_bit & VPP_INT_GOVRH2_PVBI) + vppif_reg32_write(VPP_GOVRH2_INTEN_PVBI, enable); +#endif +} + +int vppm_get_int_enable(vpp_int_t int_bit) +{ + int ret = 0; + +#ifdef WMT_FTBLK_SCL + if (int_bit & VPP_INT_SCL_VBIE) + ret = vppif_reg32_read(VPP_SCL_INTEN_VBIE); + if (int_bit & VPP_INT_SCL_VBIS) + ret = vppif_reg32_read(VPP_SCL_INTEN_VBIS); + if (int_bit & VPP_INT_SCL_PVBI) + ret = vppif_reg32_read(VPP_SCL_INTEN_PVBI); +#endif +#ifdef WMT_FTBLK_GOVRH + if (int_bit & VPP_INT_GOVRH_VBIE) + ret = vppif_reg32_read(VPP_GOVRH_INTEN_VBIE); + if (int_bit & VPP_INT_GOVRH_VBIS) + ret = vppif_reg32_read(VPP_GOVRH_INTEN_VBIS); + if (int_bit & VPP_INT_GOVRH_PVBI) + ret = vppif_reg32_read(VPP_GOVRH_INTEN_PVBI); +#endif +#ifdef WMT_FTBLK_GOVRH + if (int_bit & VPP_INT_GOVRH2_VBIE) + ret = vppif_reg32_read(VPP_GOVRH2_INTEN_VBIE); + if (int_bit & VPP_INT_GOVRH2_VBIS) + ret = vppif_reg32_read(VPP_GOVRH2_INTEN_VBIS); + if (int_bit & VPP_INT_GOVRH2_PVBI) + ret = vppif_reg32_read(VPP_GOVRH2_INTEN_PVBI); +#endif + return ret; +} + +vpp_int_t vppm_get_int_status(void) +{ + unsigned int int_enable_reg; + unsigned int int_sts_reg; + vpp_int_t int_sts = 0; + + int_enable_reg = vppif_reg32_in(REG_VPP_INTEN); + int_sts_reg = vppif_reg32_in(REG_VPP_INTSTS); + +#ifdef WMT_FTBLK_SCL + if ((int_enable_reg & BIT18) && (int_sts_reg & BIT18)) + int_sts |= VPP_INT_SCL_VBIE; + if ((int_enable_reg & BIT17) && (int_sts_reg & BIT17)) + int_sts |= VPP_INT_SCL_VBIS; + if ((int_enable_reg & BIT16) && (int_sts_reg & BIT16)) + int_sts |= VPP_INT_SCL_PVBI; +#endif +#ifdef WMT_FTBLK_GOVRH + if ((int_enable_reg & BIT10) && (int_sts_reg & BIT10)) + int_sts |= VPP_INT_GOVRH_VBIE; + if ((int_enable_reg & BIT9) && (int_sts_reg & BIT9)) + int_sts |= VPP_INT_GOVRH_VBIS; + if ((int_enable_reg & BIT8) && (int_sts_reg & BIT8)) + int_sts |= VPP_INT_GOVRH_PVBI; +#endif +#ifdef WMT_FTBLK_GOVRH + if ((int_enable_reg & BIT14) && (int_sts_reg & BIT14)) + int_sts |= VPP_INT_GOVRH2_VBIE; + if ((int_enable_reg & BIT13) && (int_sts_reg & BIT13)) + int_sts |= VPP_INT_GOVRH2_VBIS; + if ((int_enable_reg & BIT12) && (int_sts_reg & BIT12)) + int_sts |= VPP_INT_GOVRH2_PVBI; +#endif + return int_sts; +} + +void vppm_clean_int_status(vpp_int_t int_sts) +{ +#ifdef WMT_FTBLK_SCL + if (int_sts & VPP_INT_SCL_VBIE) + vppif_reg8_out(REG_VPP_INTSTS + 0x2, 0x4); + if (int_sts & VPP_INT_SCL_VBIS) + vppif_reg8_out(REG_VPP_INTSTS + 0x2, 0x2); + if (int_sts & VPP_INT_SCL_PVBI) + vppif_reg8_out(REG_VPP_INTSTS + 0x2, 0x1); +#endif +#ifdef WMT_FTBLK_GOVRH + if (int_sts & VPP_INT_GOVRH_VBIE) + vppif_reg8_out(REG_VPP_INTSTS + 0x1, 0x4); + if (int_sts & VPP_INT_GOVRH_VBIS) + vppif_reg8_out(REG_VPP_INTSTS + 0x1, 0x2); + if (int_sts & VPP_INT_GOVRH_PVBI) + vppif_reg8_out(REG_VPP_INTSTS + 0x1, 0x1); +#endif +#ifdef WMT_FTBLK_GOVRH + if (int_sts & VPP_INT_GOVRH2_VBIE) + vppif_reg32_out(REG_VPP_INTSTS, 0x00004000); + if (int_sts & VPP_INT_GOVRH2_VBIS) + vppif_reg32_out(REG_VPP_INTSTS, 0x00002000); + if (int_sts & VPP_INT_GOVRH2_PVBI) + vppif_reg32_out(REG_VPP_INTSTS, 0x00001000); +#endif +} + +void vppm_set_module_reset(vpp_mod_t mod) +{ + unsigned int value1 = 0x00, value2 = 0x00; + unsigned int value3 = 0x00; + +#ifdef WMT_FTBLK_SCL + if (mod == VPP_MOD_SCL) + value1 |= BIT0; +#endif +#ifdef WMT_FTBLK_GOVRH + if (mod == VPP_MOD_GOVRH) + value2 |= (BIT0 | BIT8 | BIT9); +#endif + vppif_reg32_out(REG_VPP_SWRST1_SEL, ~value1); + vppif_reg32_out(REG_VPP_SWRST1_SEL, 0x1010101); + vppif_reg32_out(REG_VPP_SWRST2_SEL, ~value2); + vppif_reg32_out(REG_VPP_SWRST2_SEL, 0x1011311); + vppif_reg32_out(REG_VPP_SWRST3_SEL, ~value3); + vppif_reg32_out(REG_VPP_SWRST3_SEL, 0x10101); +} + +void vppm_reg_dump(void) +{ + unsigned int reg1, reg2; + + DPRINT("========== VPPM register dump ==========\n"); + vpp_reg_dump(REG_VPP_BEGIN, REG_VPP_END - REG_VPP_BEGIN); + + DPRINT("---------- VPP Interrupt ----------\n"); + reg1 = vppif_reg32_in(REG_VPP_INTSTS); + reg2 = vppif_reg32_in(REG_VPP_INTEN); + DPRINT("GOVRH PVBI(En %d,%d),VBIS(En %d,%d),VBIE(En %d,%d)\n", + vppif_reg32_read(VPP_GOVRH_INTEN_PVBI), + vppif_reg32_read(VPP_GOVRH_INTSTS_PVBI), + vppif_reg32_read(VPP_GOVRH_INTEN_VBIS), + vppif_reg32_read(VPP_GOVRH_INTSTS_VBIS), + vppif_reg32_read(VPP_GOVRH_INTEN_VBIE), + vppif_reg32_read(VPP_GOVRH_INTSTS_VBIE)); + + DPRINT("GOVRH2 PVBI(En %d,%d),VBIS(En %d,%d),VBIE(En %d,%d)\n", + vppif_reg32_read(VPP_GOVRH2_INTEN_PVBI), + vppif_reg32_read(VPP_GOVRH2_INTSTS_PVBI), + vppif_reg32_read(VPP_GOVRH2_INTEN_VBIS), + vppif_reg32_read(VPP_GOVRH2_INTSTS_VBIS), + vppif_reg32_read(VPP_GOVRH2_INTEN_VBIE), + vppif_reg32_read(VPP_GOVRH2_INTSTS_VBIE)); + + DPRINT("SCL PVBI(En %d,%d),VBIS(En %d,%d),VBIE(En %d,%d)\n", + vppif_reg32_read(VPP_SCL_INTEN_PVBI), + vppif_reg32_read(VPP_SCL_INTSTS_PVBI), + vppif_reg32_read(VPP_SCL_INTEN_VBIS), + vppif_reg32_read(VPP_SCL_INTSTS_VBIS), + vppif_reg32_read(VPP_SCL_INTEN_VBIE), + vppif_reg32_read(VPP_SCL_INTSTS_VBIE)); +} + +#ifdef CONFIG_PM +void vppm_suspend(int sts) +{ + switch (sts) { + case 0: /* disable module */ + break; + case 1: /* disable tg */ + break; + case 2: /* backup register */ + p_vppm->reg_bk = vpp_backup_reg(REG_VPP_BEGIN, + (REG_VPP_END - REG_VPP_BEGIN)); + break; + default: + break; + } +} + +void vppm_resume(int sts) +{ + switch (sts) { + case 0: /* restore register */ + vpp_restore_reg(REG_VPP_BEGIN, (REG_VPP_END - REG_VPP_BEGIN), + p_vppm->reg_bk); + p_vppm->reg_bk = 0; + break; + case 1: /* enable module */ + break; + case 2: /* enable tg */ + break; + default: + break; + } +} +#else +#define vppm_suspend NULL +#define vppm_resume NULL +#endif + +void vppm_init(void *base) +{ + vppm_mod_t *mod_p; + + mod_p = (vppm_mod_t *) base; + + vppm_set_module_reset(0); + vppm_set_int_enable(VPP_FLAG_ENABLE, mod_p->int_catch); + vppm_clean_int_status(~0); +} + +int vppm_mod_init(void) +{ + vppm_mod_t *mod_p; + + mod_p = (vppm_mod_t *) vpp_mod_register(VPP_MOD_VPPM, + sizeof(vppm_mod_t), 0); + if (!mod_p) { + DPRINT("*E* VPP module register fail\n"); + return -1; + } + + /* module member variable */ + mod_p->int_catch = VPP_INT_NULL; + + /* module member function */ + mod_p->init = vppm_init; + mod_p->dump_reg = vppm_reg_dump; + mod_p->get_sts = vppm_get_int_status; + mod_p->clr_sts = vppm_clean_int_status; + mod_p->suspend = vppm_suspend; + mod_p->resume = vppm_resume; + + p_vppm = mod_p; + return 0; +} +module_init(vppm_mod_init); |