• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/dream/qdsp5/
1/* arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
2 *
3 * Verification code for aDSP VFE 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
19#include <mach/qdsp5/qdsp5vfecmdi.h>
20#include "adsp.h"
21
22static uint32_t size1_y, size2_y, size1_cbcr, size2_cbcr;
23static uint32_t af_size = 4228;
24static uint32_t awb_size = 8196;
25
26static inline int verify_cmd_op_ack(struct msm_adsp_module *module,
27				    void *cmd_data, size_t cmd_size)
28{
29	vfe_cmd_op1_ack *cmd = (vfe_cmd_op1_ack *)cmd_data;
30	void **addr_y = (void **)&cmd->op1_buf_y_addr;
31	void **addr_cbcr = (void **)(&cmd->op1_buf_cbcr_addr);
32
33	if (cmd_size != sizeof(vfe_cmd_op1_ack))
34		return -1;
35	if ((*addr_y && adsp_pmem_fixup(module, addr_y, size1_y)) ||
36	    (*addr_cbcr && adsp_pmem_fixup(module, addr_cbcr, size1_cbcr)))
37		return -1;
38	return 0;
39}
40
41static inline int verify_cmd_stats_autofocus_cfg(struct msm_adsp_module *module,
42						 void *cmd_data, size_t cmd_size)
43{
44	int i;
45	vfe_cmd_stats_autofocus_cfg *cmd =
46		(vfe_cmd_stats_autofocus_cfg *)cmd_data;
47
48	if (cmd_size != sizeof(vfe_cmd_stats_autofocus_cfg))
49		return -1;
50
51	for (i = 0; i < 3; i++) {
52		void **addr = (void **)(&cmd->af_stats_op_buf[i]);
53		if (*addr && adsp_pmem_fixup(module, addr, af_size))
54			return -1;
55	}
56	return 0;
57}
58
59static inline int verify_cmd_stats_wb_exp_cfg(struct msm_adsp_module *module,
60					      void *cmd_data, size_t cmd_size)
61{
62	vfe_cmd_stats_wb_exp_cfg *cmd =
63		(vfe_cmd_stats_wb_exp_cfg *)cmd_data;
64	int i;
65
66	if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_cfg))
67		return -1;
68
69	for (i = 0; i < 3; i++) {
70		void **addr = (void **)(&cmd->wb_exp_stats_op_buf[i]);
71		if (*addr && adsp_pmem_fixup(module, addr, awb_size))
72			return -1;
73	}
74	return 0;
75}
76
77static inline int verify_cmd_stats_af_ack(struct msm_adsp_module *module,
78					  void *cmd_data, size_t cmd_size)
79{
80	vfe_cmd_stats_af_ack *cmd = (vfe_cmd_stats_af_ack *)cmd_data;
81	void **addr = (void **)&cmd->af_stats_op_buf;
82
83	if (cmd_size != sizeof(vfe_cmd_stats_af_ack))
84		return -1;
85
86	if (*addr && adsp_pmem_fixup(module, addr, af_size))
87		return -1;
88	return 0;
89}
90
91static inline int verify_cmd_stats_wb_exp_ack(struct msm_adsp_module *module,
92					      void *cmd_data, size_t cmd_size)
93{
94	vfe_cmd_stats_wb_exp_ack *cmd =
95		(vfe_cmd_stats_wb_exp_ack *)cmd_data;
96	void **addr = (void **)&cmd->wb_exp_stats_op_buf;
97
98	if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_ack))
99		return -1;
100
101	if (*addr && adsp_pmem_fixup(module, addr, awb_size))
102		return -1;
103	return 0;
104}
105
106static int verify_vfe_command(struct msm_adsp_module *module,
107			      void *cmd_data, size_t cmd_size)
108{
109	uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
110	switch (cmd_id) {
111	case VFE_CMD_OP1_ACK:
112		return verify_cmd_op_ack(module, cmd_data, cmd_size);
113	case VFE_CMD_OP2_ACK:
114		return verify_cmd_op_ack(module, cmd_data, cmd_size);
115	case VFE_CMD_STATS_AUTOFOCUS_CFG:
116		return verify_cmd_stats_autofocus_cfg(module, cmd_data,
117						      cmd_size);
118	case VFE_CMD_STATS_WB_EXP_CFG:
119		return verify_cmd_stats_wb_exp_cfg(module, cmd_data, cmd_size);
120	case VFE_CMD_STATS_AF_ACK:
121		return verify_cmd_stats_af_ack(module, cmd_data, cmd_size);
122	case VFE_CMD_STATS_WB_EXP_ACK:
123		return verify_cmd_stats_wb_exp_ack(module, cmd_data, cmd_size);
124	default:
125		if (cmd_id > 29) {
126			printk(KERN_ERR "adsp: module %s: invalid VFE command id %d\n", module->name, cmd_id);
127			return -1;
128		}
129	}
130	return 0;
131}
132
133static int verify_vfe_command_scale(struct msm_adsp_module *module,
134				    void *cmd_data, size_t cmd_size)
135{
136	uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
137	if (cmd_id > 1) {
138		printk(KERN_ERR "adsp: module %s: invalid VFE SCALE command id %d\n", module->name, cmd_id);
139		return -1;
140	}
141	return 0;
142}
143
144
145static uint32_t get_size(uint32_t hw)
146{
147	uint32_t height, width;
148	uint32_t height_mask = 0x3ffc;
149	uint32_t width_mask = 0x3ffc000;
150
151	height = (hw & height_mask) >> 2;
152	width = (hw & width_mask) >> 14 ;
153	return height * width;
154}
155
156static int verify_vfe_command_table(struct msm_adsp_module *module,
157				    void *cmd_data, size_t cmd_size)
158{
159	uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
160	int i;
161
162	switch (cmd_id) {
163	case VFE_CMD_AXI_IP_CFG:
164	{
165		vfe_cmd_axi_ip_cfg *cmd = (vfe_cmd_axi_ip_cfg *)cmd_data;
166		uint32_t size;
167		if (cmd_size != sizeof(vfe_cmd_axi_ip_cfg)) {
168			printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_IP_CFG) command size %d\n",
169				module->name, cmd_size);
170			return -1;
171		}
172		size = get_size(cmd->ip_cfg_part2);
173
174		for (i = 0; i < 8; i++) {
175			void **addr = (void **)
176				&cmd->ip_buf_addr[i];
177			if (*addr && adsp_pmem_fixup(module, addr, size))
178				return -1;
179		}
180	}
181	case VFE_CMD_AXI_OP_CFG:
182	{
183		vfe_cmd_axi_op_cfg *cmd = (vfe_cmd_axi_op_cfg *)cmd_data;
184		void **addr1_y, **addr2_y, **addr1_cbcr, **addr2_cbcr;
185
186		if (cmd_size != sizeof(vfe_cmd_axi_op_cfg)) {
187			printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_OP_CFG) command size %d\n",
188				module->name, cmd_size);
189			return -1;
190		}
191		size1_y = get_size(cmd->op1_y_cfg_part2);
192		size1_cbcr = get_size(cmd->op1_cbcr_cfg_part2);
193		size2_y = get_size(cmd->op2_y_cfg_part2);
194		size2_cbcr = get_size(cmd->op2_cbcr_cfg_part2);
195		for (i = 0; i < 8; i++) {
196			addr1_y = (void **)(&cmd->op1_buf1_addr[2*i]);
197			addr1_cbcr = (void **)(&cmd->op1_buf1_addr[2*i+1]);
198			addr2_y = (void **)(&cmd->op2_buf1_addr[2*i]);
199			addr2_cbcr = (void **)(&cmd->op2_buf1_addr[2*i+1]);
200/*
201			printk("module %s: [%d] %p %p %p %p\n",
202				module->name, i,
203				*addr1_y, *addr1_cbcr, *addr2_y, *addr2_cbcr);
204*/
205			if ((*addr1_y && adsp_pmem_fixup(module, addr1_y, size1_y)) ||
206			    (*addr1_cbcr && adsp_pmem_fixup(module, addr1_cbcr, size1_cbcr)) ||
207			    (*addr2_y && adsp_pmem_fixup(module, addr2_y, size2_y)) ||
208			    (*addr2_cbcr && adsp_pmem_fixup(module, addr2_cbcr, size2_cbcr)))
209				return -1;
210		}
211	}
212	default:
213		if (cmd_id > 4) {
214			printk(KERN_ERR "adsp: module %s: invalid VFE TABLE command id %d\n",
215				module->name, cmd_id);
216			return -1;
217		}
218	}
219	return 0;
220}
221
222int adsp_vfe_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_vfeCommandQueue:
228		return verify_vfe_command(module, cmd_data, cmd_size);
229	case QDSP_vfeCommandScaleQueue:
230		return verify_vfe_command_scale(module, cmd_data, cmd_size);
231	case QDSP_vfeCommandTableQueue:
232		return verify_vfe_command_table(module, cmd_data, cmd_size);
233	default:
234		printk(KERN_ERR "adsp: module %s: unknown queue id %d\n",
235			module->name, queue_id);
236		return -1;
237	}
238}
239