aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c')
-rw-r--r--drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c
new file mode 100644
index 000000000000..ee3744950523
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c
@@ -0,0 +1,235 @@
+/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
+ *
+ * Verificion code for aDSP VENC packets from userspace.
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+#include <linux/io.h>
+
+#define ADSP_DEBUG_MSGS 0
+#if ADSP_DEBUG_MSGS
+#define DLOG(fmt,args...) \
+ do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
+ ##args); } \
+ while (0)
+#else
+#define DLOG(x...) do {} while (0)
+#endif
+
+#include <mach/qdsp5/qdsp5venccmdi.h>
+#include "adsp.h"
+
+
+static unsigned short x_dimension, y_dimension;
+
+static inline void *high_low_short_to_ptr(unsigned short high,
+ unsigned short low)
+{
+ return (void *)((((unsigned long)high) << 16) | ((unsigned long)low));
+}
+
+static inline void ptr_to_high_low_short(void *ptr, unsigned short *high,
+ unsigned short *low)
+{
+ *high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff);
+ *low = (unsigned short)((unsigned long)ptr & 0xffff);
+}
+
+static int pmem_fixup_high_low(unsigned short *high,
+ unsigned short *low,
+ unsigned short size_high,
+ unsigned short size_low,
+ struct msm_adsp_module *module,
+ unsigned long *addr, unsigned long *size)
+{
+ void *phys_addr;
+ unsigned long phys_size;
+ unsigned long kvaddr;
+
+ phys_addr = high_low_short_to_ptr(*high, *low);
+ phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low);
+ DLOG("virt %x %x\n", phys_addr, phys_size);
+ if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) {
+ DLOG("ah%x al%x sh%x sl%x addr %x size %x\n",
+ *high, *low, size_high, size_low, phys_addr, phys_size);
+ return -1;
+ }
+ ptr_to_high_low_short(phys_addr, high, low);
+ DLOG("phys %x %x\n", phys_addr, phys_size);
+ if (addr)
+ *addr = kvaddr;
+ if (size)
+ *size = phys_size;
+ return 0;
+}
+
+static int verify_venc_cmd(struct msm_adsp_module *module,
+ void *cmd_data, size_t cmd_size)
+{
+ unsigned short cmd_id = ((unsigned short *)cmd_data)[0];
+ unsigned long frame_buf_size, luma_buf_size, chroma_buf_size;
+ unsigned short frame_buf_size_high, frame_buf_size_low;
+ unsigned short luma_buf_size_high, luma_buf_size_low;
+ unsigned short chroma_buf_size_high, chroma_buf_size_low;
+ videnc_cmd_cfg *config_cmd;
+ videnc_cmd_frame_start *frame_cmd;
+ videnc_cmd_dis *dis_cmd;
+
+ DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data);
+ switch (cmd_id) {
+ case VIDENC_CMD_ACTIVE:
+ if (cmd_size < sizeof(videnc_cmd_active))
+ return -1;
+ break;
+ case VIDENC_CMD_IDLE:
+ if (cmd_size < sizeof(videnc_cmd_idle))
+ return -1;
+ x_dimension = y_dimension = 0;
+ break;
+ case VIDENC_CMD_STATUS_QUERY:
+ if (cmd_size < sizeof(videnc_cmd_status_query))
+ return -1;
+ break;
+ case VIDENC_CMD_RC_CFG:
+ if (cmd_size < sizeof(videnc_cmd_rc_cfg))
+ return -1;
+ break;
+ case VIDENC_CMD_INTRA_REFRESH:
+ if (cmd_size < sizeof(videnc_cmd_intra_refresh))
+ return -1;
+ break;
+ case VIDENC_CMD_DIGITAL_ZOOM:
+ if (cmd_size < sizeof(videnc_cmd_digital_zoom))
+ return -1;
+ break;
+ case VIDENC_CMD_DIS_CFG:
+ if (cmd_size < sizeof(videnc_cmd_dis_cfg))
+ return -1;
+ break;
+ case VIDENC_CMD_CFG:
+ if (cmd_size < sizeof(videnc_cmd_cfg))
+ return -1;
+ config_cmd = (videnc_cmd_cfg *)cmd_data;
+ x_dimension = ((config_cmd->venc_frame_dim) & 0xFF00)>>8;
+ x_dimension = x_dimension*16;
+ y_dimension = (config_cmd->venc_frame_dim) & 0xFF;
+ y_dimension = y_dimension * 16;
+ break;
+ case VIDENC_CMD_FRAME_START:
+ if (cmd_size < sizeof(videnc_cmd_frame_start))
+ return -1;
+ frame_cmd = (videnc_cmd_frame_start *)cmd_data;
+ luma_buf_size = x_dimension * y_dimension;
+ chroma_buf_size = luma_buf_size>>1;
+ frame_buf_size = luma_buf_size + chroma_buf_size;
+ ptr_to_high_low_short((void *)luma_buf_size,
+ &luma_buf_size_high,
+ &luma_buf_size_low);
+ ptr_to_high_low_short((void *)chroma_buf_size,
+ &chroma_buf_size_high,
+ &chroma_buf_size_low);
+ ptr_to_high_low_short((void *)frame_buf_size,
+ &frame_buf_size_high,
+ &frame_buf_size_low);
+ /* Address of raw Y data. */
+ if (pmem_fixup_high_low(&frame_cmd->input_luma_addr_high,
+ &frame_cmd->input_luma_addr_low,
+ luma_buf_size_high,
+ luma_buf_size_low,
+ module,
+ NULL, NULL))
+ return -1;
+ /* Address of raw CbCr data */
+ if (pmem_fixup_high_low(&frame_cmd->input_chroma_addr_high,
+ &frame_cmd->input_chroma_addr_low,
+ chroma_buf_size_high,
+ chroma_buf_size_low,
+ module,
+ NULL, NULL))
+ return -1;
+ /* Reference VOP */
+ if (pmem_fixup_high_low(&frame_cmd->ref_vop_buf_ptr_high,
+ &frame_cmd->ref_vop_buf_ptr_low,
+ frame_buf_size_high,
+ frame_buf_size_low,
+ module,
+ NULL, NULL))
+ return -1;
+ /* Encoded Packet Address */
+ if (pmem_fixup_high_low(&frame_cmd->enc_pkt_buf_ptr_high,
+ &frame_cmd->enc_pkt_buf_ptr_low,
+ frame_cmd->enc_pkt_buf_size_high,
+ frame_cmd->enc_pkt_buf_size_low,
+ module,
+ NULL, NULL))
+ return -1;
+ /* Unfiltered VOP Buffer Address */
+ if (pmem_fixup_high_low(
+ &frame_cmd->unfilt_recon_vop_buf_ptr_high,
+ &frame_cmd->unfilt_recon_vop_buf_ptr_low,
+ frame_buf_size_high,
+ frame_buf_size_low,
+ module,
+ NULL, NULL))
+ return -1;
+ /* Filtered VOP Buffer Address */
+ if (pmem_fixup_high_low(&frame_cmd->filt_recon_vop_buf_ptr_high,
+ &frame_cmd->filt_recon_vop_buf_ptr_low,
+ frame_buf_size_high,
+ frame_buf_size_low,
+ module,
+ NULL, NULL))
+ return -1;
+ break;
+ case VIDENC_CMD_DIS:
+ if (cmd_size < sizeof(videnc_cmd_dis))
+ return -1;
+ dis_cmd = (videnc_cmd_dis *)cmd_data;
+ luma_buf_size = x_dimension * y_dimension;
+ ptr_to_high_low_short((void *)luma_buf_size,
+ &luma_buf_size_high,
+ &luma_buf_size_low);
+ /* Prev VFE Luma Output Address */
+ if (pmem_fixup_high_low(&dis_cmd->vfe_out_prev_luma_addr_high,
+ &dis_cmd->vfe_out_prev_luma_addr_low,
+ luma_buf_size_high,
+ luma_buf_size_low,
+ module,
+ NULL, NULL))
+ return -1;
+ break;
+ default:
+ printk(KERN_INFO "adsp_video:unknown encoder video command %u\n",
+ cmd_id);
+ return 0;
+ }
+
+ return 0;
+}
+
+
+int adsp_videoenc_verify_cmd(struct msm_adsp_module *module,
+ unsigned int queue_id, void *cmd_data,
+ size_t cmd_size)
+{
+ switch (queue_id) {
+ case QDSP_mpuVEncCmdQueue:
+ DLOG("\n");
+ return verify_venc_cmd(module, cmd_data, cmd_size);
+ default:
+ printk(KERN_INFO "unknown video queue %u\n", queue_id);
+ return 0;
+ }
+}
+