diff options
author | Srikant Patnaik | 2015-01-13 15:08:24 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-13 15:08:24 +0530 |
commit | 97327692361306d1e6259021bc425e32832fdb50 (patch) | |
tree | fe9088f3248ec61e24f404f21b9793cb644b7f01 /drivers/video/wmt/vpp-osif.c | |
parent | 2d05a8f663478a44e088d122e0d62109bbc801d0 (diff) | |
parent | a3a8b90b61e21be3dde9101c4e86c881e0f06210 (diff) | |
download | FOSSEE-netbook-kernel-source-97327692361306d1e6259021bc425e32832fdb50.tar.gz FOSSEE-netbook-kernel-source-97327692361306d1e6259021bc425e32832fdb50.tar.bz2 FOSSEE-netbook-kernel-source-97327692361306d1e6259021bc425e32832fdb50.zip |
dirty fix to merging
Diffstat (limited to 'drivers/video/wmt/vpp-osif.c')
-rw-r--r-- | drivers/video/wmt/vpp-osif.c | 891 |
1 files changed, 891 insertions, 0 deletions
diff --git a/drivers/video/wmt/vpp-osif.c b/drivers/video/wmt/vpp-osif.c new file mode 100644 index 00000000..a8505a59 --- /dev/null +++ b/drivers/video/wmt/vpp-osif.c @@ -0,0 +1,891 @@ +/*++ + * linux/drivers/video/wmt/osif.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 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 +int vpp_dvi_i2c_id; + +/*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ +/* void lvds_xxx(void); *//*Example*/ + +/*----------------------- Function Body --------------------------------------*/ +#ifdef __KERNEL__ +#include <asm/io.h> +#include <linux/proc_fs.h> +#else +__inline__ U32 inl(U32 offset) +{ + return REG32_VAL(offset); +} + +__inline__ void outl(U32 val, U32 offset) +{ + REG32_VAL(offset) = val; +} + +static __inline__ U16 inw(U32 offset) +{ + return REG16_VAL(offset); +} + +static __inline__ void outw(U16 val, U32 offset) +{ + REG16_VAL(offset) = val; +} + +static __inline__ U8 inb(U32 offset) +{ + return REG8_VAL(offset); +} + +static __inline__ void outb(U8 val, U32 offset) +{ + REG8_VAL(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 + +extern unsigned int wmt_read_oscr(void); +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 */ +U8 vppif_reg8_in(U32 offset) +{ + return inb(offset); +} + +U8 vppif_reg8_out(U32 offset, U8 val) +{ + outb(val, offset); + return val; +} + +U16 vppif_reg16_in(U32 offset) +{ + return inw(offset); +} + +U16 vppif_reg16_out(U32 offset, U16 val) +{ + outw(val, offset); + return val; +} + +U32 vppif_reg32_in(U32 offset) +{ + return inl(offset); +} + +U32 vppif_reg32_out(U32 offset, U32 val) +{ + outl(val, offset); + return val; +} + +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; +} + +U32 vppif_reg32_read(U32 offset, U32 mask, U32 shift) +{ + return (inl(offset) & mask) >> shift; +} + +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) +{ + int i = 0; + char *p; + + p = getenv(varname); + 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); */ + return 0; +} +#endif + +#ifndef CONFIG_VPOST +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++) { + param[i] = simple_strtoul(p, &endp, + (hex_mask & (0x1 << i)) ? 16 : 0); + if (*endp == '\0') + break; + p = endp + 1; + + if (*p == '\0') + break; + } + return i + 1; +} +#endif + +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, 1); +#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); + + vpp_dvi_i2c_id = i2c_id; + 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 + vpp_dvi_i2c_id = i2c_id & 0xF; + 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; + + if (id & VPP_DVI_I2C_BIT) + id = vpp_dvi_i2c_id; + 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; + + if (id & VPP_DVI_I2C_BIT) + id = vpp_dvi_i2c_id; + 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; + + if (id & VPP_DVI_I2C_BIT) + id = vpp_dvi_i2c_id; + 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(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(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(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,fps %d.%02d\n", + str, p->cnt, p->sum, us_1t, + p->min, p->max, 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 |