]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel...
[net-next-2.6.git] / drivers / staging / dream / qdsp5 / adsp_videoenc_verify_cmd.c
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
34 static unsigned short x_dimension, y_dimension;
35
36 static 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
42 static 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
49 static 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
77 static 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
222 int 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