• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/dream/qdsp5/
1/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
2 *
3 * Verificion code for aDSP VENC packets from userspace.
4 *
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 */
18#include <linux/io.h>
19
20#define ADSP_DEBUG_MSGS 0
21#if ADSP_DEBUG_MSGS
22#define DLOG(fmt,args...) \
23	do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
24	     ##args); } \
25	while (0)
26#else
27#define DLOG(x...) do {} while (0)
28#endif
29
30#include <mach/qdsp5/qdsp5venccmdi.h>
31#include "adsp.h"
32
33
34static unsigned short x_dimension, y_dimension;
35
36static inline void *high_low_short_to_ptr(unsigned short high,
37					  unsigned short low)
38{
39	return (void *)((((unsigned long)high) << 16) | ((unsigned long)low));
40}
41
42static inline void ptr_to_high_low_short(void *ptr, unsigned short *high,
43					 unsigned short *low)
44{
45	*high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff);
46	*low = (unsigned short)((unsigned long)ptr & 0xffff);
47}
48
49static int pmem_fixup_high_low(unsigned short *high,
50				unsigned short *low,
51				unsigned short size_high,
52				unsigned short size_low,
53				struct msm_adsp_module *module,
54				unsigned long *addr, unsigned long *size)
55{
56	void *phys_addr;
57	unsigned long phys_size;
58	unsigned long kvaddr;
59
60	phys_addr = high_low_short_to_ptr(*high, *low);
61	phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low);
62	DLOG("virt %x %x\n", phys_addr, phys_size);
63	if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) {
64		DLOG("ah%x al%x sh%x sl%x addr %x size %x\n",
65			*high, *low, size_high, size_low, phys_addr, phys_size);
66		return -1;
67	}
68	ptr_to_high_low_short(phys_addr, high, low);
69	DLOG("phys %x %x\n", phys_addr, phys_size);
70	if (addr)
71		*addr = kvaddr;
72	if (size)
73		*size = phys_size;
74	return 0;
75}
76
77static int verify_venc_cmd(struct msm_adsp_module *module,
78			       void *cmd_data, size_t cmd_size)
79{
80	unsigned short cmd_id = ((unsigned short *)cmd_data)[0];
81	unsigned long frame_buf_size, luma_buf_size, chroma_buf_size;
82	unsigned short frame_buf_size_high, frame_buf_size_low;
83	unsigned short luma_buf_size_high, luma_buf_size_low;
84	unsigned short chroma_buf_size_high, chroma_buf_size_low;
85	videnc_cmd_cfg *config_cmd;
86	videnc_cmd_frame_start *frame_cmd;
87	videnc_cmd_dis *dis_cmd;
88
89	DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data);
90	switch (cmd_id) {
91	case VIDENC_CMD_ACTIVE:
92		if (cmd_size < sizeof(videnc_cmd_active))
93			return -1;
94		break;
95	case VIDENC_CMD_IDLE:
96		if (cmd_size < sizeof(videnc_cmd_idle))
97			return -1;
98		x_dimension = y_dimension = 0;
99		break;
100	case VIDENC_CMD_STATUS_QUERY:
101		if (cmd_size < sizeof(videnc_cmd_status_query))
102			return -1;
103		break;
104	case VIDENC_CMD_RC_CFG:
105		if (cmd_size < sizeof(videnc_cmd_rc_cfg))
106			return -1;
107		break;
108	case VIDENC_CMD_INTRA_REFRESH:
109		if (cmd_size < sizeof(videnc_cmd_intra_refresh))
110			return -1;
111		break;
112	case VIDENC_CMD_DIGITAL_ZOOM:
113		if (cmd_size < sizeof(videnc_cmd_digital_zoom))
114			return -1;
115		break;
116	case VIDENC_CMD_DIS_CFG:
117		if (cmd_size < sizeof(videnc_cmd_dis_cfg))
118			return -1;
119		break;
120	case VIDENC_CMD_CFG:
121		if (cmd_size < sizeof(videnc_cmd_cfg))
122			return -1;
123		config_cmd = (videnc_cmd_cfg *)cmd_data;
124		x_dimension = ((config_cmd->venc_frame_dim) & 0xFF00)>>8;
125		x_dimension = x_dimension*16;
126		y_dimension = (config_cmd->venc_frame_dim) & 0xFF;
127		y_dimension = y_dimension * 16;
128		break;
129	case VIDENC_CMD_FRAME_START:
130		if (cmd_size < sizeof(videnc_cmd_frame_start))
131			return -1;
132		frame_cmd = (videnc_cmd_frame_start *)cmd_data;
133		luma_buf_size = x_dimension * y_dimension;
134		chroma_buf_size = luma_buf_size>>1;
135		frame_buf_size = luma_buf_size + chroma_buf_size;
136		ptr_to_high_low_short((void *)luma_buf_size,
137			      &luma_buf_size_high,
138			      &luma_buf_size_low);
139		ptr_to_high_low_short((void *)chroma_buf_size,
140			      &chroma_buf_size_high,
141			      &chroma_buf_size_low);
142		ptr_to_high_low_short((void *)frame_buf_size,
143			      &frame_buf_size_high,
144			      &frame_buf_size_low);
145		/* Address of raw Y data. */
146		if (pmem_fixup_high_low(&frame_cmd->input_luma_addr_high,
147					&frame_cmd->input_luma_addr_low,
148					luma_buf_size_high,
149					luma_buf_size_low,
150					module,
151					NULL, NULL))
152			return -1;
153		/* Address of raw CbCr data */
154		if (pmem_fixup_high_low(&frame_cmd->input_chroma_addr_high,
155					&frame_cmd->input_chroma_addr_low,
156					chroma_buf_size_high,
157					chroma_buf_size_low,
158					module,
159					NULL, NULL))
160			return -1;
161		/* Reference VOP */
162		if (pmem_fixup_high_low(&frame_cmd->ref_vop_buf_ptr_high,
163					&frame_cmd->ref_vop_buf_ptr_low,
164					frame_buf_size_high,
165					frame_buf_size_low,
166					module,
167					NULL, NULL))
168			return -1;
169		/* Encoded Packet Address */
170		if (pmem_fixup_high_low(&frame_cmd->enc_pkt_buf_ptr_high,
171					&frame_cmd->enc_pkt_buf_ptr_low,
172					frame_cmd->enc_pkt_buf_size_high,
173					frame_cmd->enc_pkt_buf_size_low,
174					module,
175					NULL, NULL))
176			return -1;
177		/* Unfiltered VOP Buffer Address */
178		if (pmem_fixup_high_low(
179				&frame_cmd->unfilt_recon_vop_buf_ptr_high,
180				&frame_cmd->unfilt_recon_vop_buf_ptr_low,
181				frame_buf_size_high,
182				frame_buf_size_low,
183				module,
184				NULL, NULL))
185			return -1;
186		/* Filtered VOP Buffer Address */
187		if (pmem_fixup_high_low(&frame_cmd->filt_recon_vop_buf_ptr_high,
188					&frame_cmd->filt_recon_vop_buf_ptr_low,
189					frame_buf_size_high,
190					frame_buf_size_low,
191					module,
192					NULL, NULL))
193			return -1;
194		break;
195	case VIDENC_CMD_DIS:
196		if (cmd_size < sizeof(videnc_cmd_dis))
197			return -1;
198		dis_cmd = (videnc_cmd_dis *)cmd_data;
199		luma_buf_size = x_dimension * y_dimension;
200		ptr_to_high_low_short((void *)luma_buf_size,
201			      &luma_buf_size_high,
202			      &luma_buf_size_low);
203		/* Prev VFE Luma Output Address */
204		if (pmem_fixup_high_low(&dis_cmd->vfe_out_prev_luma_addr_high,
205					&dis_cmd->vfe_out_prev_luma_addr_low,
206					luma_buf_size_high,
207					luma_buf_size_low,
208					module,
209					NULL, NULL))
210			return -1;
211		break;
212	default:
213		printk(KERN_INFO "adsp_video:unknown encoder video command %u\n",
214			cmd_id);
215		return 0;
216	}
217
218	return 0;
219}
220
221
222int adsp_videoenc_verify_cmd(struct msm_adsp_module *module,
223			 unsigned int queue_id, void *cmd_data,
224			 size_t cmd_size)
225{
226	switch (queue_id) {
227	case QDSP_mpuVEncCmdQueue:
228		DLOG("\n");
229		return verify_venc_cmd(module, cmd_data, cmd_size);
230	default:
231		printk(KERN_INFO "unknown video queue %u\n", queue_id);
232		return 0;
233	}
234}
235