diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-22 19:54:53 (GMT) |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-22 20:01:40 (GMT) |
commit | ae19ffbadc1b2100285a5b5b3d0a4e0a11390904 (patch) | |
tree | 3c2086ab67398a019089a47ca3f362a4bc6db74f /drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c | |
parent | 34e84f39a27d059a3e6ec6e8b94aafa702e6f220 (diff) | |
parent | 9173a8ef24a6b1b8031507b35b8ffe5f85a87692 (diff) | |
download | linux-fsl-qoriq-ae19ffbadc1b2100285a5b5b3d0a4e0a11390904.tar.xz |
Merge branch 'master' into for-linus
Diffstat (limited to 'drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c')
-rw-r--r-- | drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c | 235 |
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 0000000..ee37449 --- /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; + } +} + |