summaryrefslogtreecommitdiff
path: root/drivers/video/wmt/vpp-osif.c
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-13 15:08:24 +0530
committerSrikant Patnaik2015-01-13 15:08:24 +0530
commit97327692361306d1e6259021bc425e32832fdb50 (patch)
treefe9088f3248ec61e24f404f21b9793cb644b7f01 /drivers/video/wmt/vpp-osif.c
parent2d05a8f663478a44e088d122e0d62109bbc801d0 (diff)
parenta3a8b90b61e21be3dde9101c4e86c881e0f06210 (diff)
downloadFOSSEE-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.c891
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