/*++ * 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 . * * 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);