2 * Copyright (C) 2012 Spreadtrum Communications Inc.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <linux/uaccess.h>
15 #include <linux/sprd_mm.h>
16 #include <linux/delay.h>
17 #include <video/sprd_isp.h>
18 #include <asm/cacheflush.h>
19 #include "isp_block.h"
23 #define ISP_LSC_TIME_OUT_MAX 500
24 #define ISP_LSC_BUF0 0
25 #define ISP_LSC_BUF1 1
27 static int32_t isp_k_2d_lsc_param_load(struct isp_memory *src_buf,
28 struct isp_k_private *isp_private)
31 uint32_t time_out_cnt = 0;
32 uint32_t addr = 0, reg_value = 0;
33 void *buf_ptr = (void *)isp_private->lsc_buf_addr;
34 uint32_t buf_len = isp_private->lsc_buf_len;
36 if ((0x00 != src_buf->addr) && (0x00 != src_buf->len)
37 && (00 != isp_private->lsc_buf_addr) && (0x00 != isp_private->lsc_buf_len)
38 && (src_buf->len <= isp_private->lsc_buf_len)) {
40 ret = copy_from_user((void *)isp_private->lsc_buf_addr, (void *)src_buf->addr, src_buf->len);
42 printk("isp_k_2d_lsc_param_load: copy error, ret=0x%x\n", (uint32_t)ret);
46 dmac_flush_range(buf_ptr, buf_ptr + buf_len);
47 outer_flush_range(__pa(buf_ptr), __pa(buf_ptr) + buf_len);
49 addr = (uint32_t)__pa(isp_private->lsc_buf_addr);
51 #if defined(CONFIG_MACH_CORE3)
55 local_irq_save(flags);
57 reg_value = REG_RD(ISP_LSC_STATUS);
58 while((0x00 == (reg_value & ISP_LNC_STATUS_OK))
59 && (time_out_cnt < (ISP_LSC_TIME_OUT_MAX * 1000))) {
61 reg_value = REG_RD(ISP_LSC_STATUS);
64 if (time_out_cnt >= (ISP_LSC_TIME_OUT_MAX * 1000)) {
66 printk("isp_k_2d_lsc_param_load: lsc status time out error.\n");
69 if (ISP_LSC_BUF0 = isp_private->lsc_load_buf_id) {
70 isp_private->lsc_load_buf_id = ISP_LSC_BUF1;
72 isp_private->lsc_load_buf_id = ISP_LSC_BUF0;
74 REG_MWR(ISP_LSC_LOAD_BUF, BIT_0, isp_private->lsc_load_buf_id);
75 REG_WR(ISP_LSC_PARAM_ADDR, addr);
76 REG_OWR(ISP_LSC_LOAD_EB, BIT_0);
77 isp_private->lsc_update_buf_id = isp_private->lsc_load_buf_id;
79 local_irq_restore(flags);
82 if (ISP_LSC_BUF0 == isp_private->lsc_load_buf_id) {
83 isp_private->lsc_load_buf_id = ISP_LSC_BUF1;
85 isp_private->lsc_load_buf_id = ISP_LSC_BUF0;
87 REG_MWR(ISP_LSC_LOAD_BUF, BIT_0, isp_private->lsc_load_buf_id);
88 REG_WR(ISP_LSC_PARAM_ADDR, addr);
89 REG_OWR(ISP_LSC_LOAD_EB, BIT_0);
90 isp_private->lsc_update_buf_id = isp_private->lsc_load_buf_id;
92 reg_value = REG_RD(ISP_INT_RAW);
94 while ((0x00 == (reg_value & ISP_INT_LSC_LOAD))
95 && (time_out_cnt < ISP_LSC_TIME_OUT_MAX)) {
97 reg_value = REG_RD(ISP_INT_RAW);
100 if (time_out_cnt >= ISP_LSC_TIME_OUT_MAX) {
102 printk("isp_k_2d_lsc_param_load: lsc load time out error.\n");
104 REG_OWR(ISP_INT_CLEAR, ISP_INT_LSC_LOAD);
106 printk("isp_k_2d_lsc_param_load: buffer error.\n");
112 static int32_t isp_k_2d_lsc_block(struct isp_io_param *param,
113 struct isp_k_private *isp_private)
116 struct isp_memory src_buf;
117 struct isp_dev_lsc_info lsc_info;
119 memset(&lsc_info, 0x00, sizeof(lsc_info));
121 ret = copy_from_user((void *)&lsc_info, param->property_param, sizeof(lsc_info));
123 printk("isp_k_2d_lsc_block: copy error, ret=0x%x\n", (uint32_t)ret);
127 if (lsc_info.bypass) {
128 REG_OWR(ISP_LSC_PARAM, BIT_0);
130 REG_MWR(ISP_LSC_PARAM, BIT_0, 0);
133 REG_MWR(ISP_LSC_GRID_PITCH, 0x1FF, lsc_info.grid_pitch);
135 REG_MWR(ISP_LSC_GRID_PITCH, (BIT_17 | BIT_16), (lsc_info.grid_mode << 16));
137 REG_MWR(ISP_LSC_MISC, (BIT_1 | BIT_0), lsc_info.endian);
139 src_buf.addr = lsc_info.buf_addr;
140 src_buf.len = lsc_info.buf_len;
141 ret = isp_k_2d_lsc_param_load(&src_buf, isp_private);
146 static int32_t isp_k_lsc_bypass(struct isp_io_param *param)
151 ret = copy_from_user((void *)&bypass, param->property_param, sizeof(bypass));
153 printk("isp_k_lsc_bypass: copy error, ret=0x%x\n", (uint32_t)ret);
158 REG_OWR(ISP_LSC_PARAM, BIT_0);
160 REG_MWR(ISP_LSC_PARAM, BIT_0, 0);
166 static int32_t isp_k_2d_lsc_param_update(struct isp_io_param *param,
167 struct isp_k_private *isp_private)
171 REG_MWR(ISP_LSC_PARAM, BIT_1, (isp_private->lsc_update_buf_id << 1));
176 static int32_t isp_k_2d_lsc_pos(struct isp_io_param *param)
180 struct isp_img_offset offset = {0, 0};
182 ret = copy_from_user((void *)&offset, param->property_param, sizeof(offset));
184 printk("isp_k_lens_pos: copy error, ret=0x%x\n", (uint32_t)ret);
188 val = ((offset.y & 0x7F) << 8) | (offset.x & 0x7F);
190 REG_WR(ISP_LSC_SLICE_POS, val);
195 static int32_t isp_k_2d_lsc_grid_size(struct isp_io_param *param)
199 struct isp_img_size size = {0, 0};
201 ret = copy_from_user((void *)&size, param->property_param, sizeof(size));
203 printk("isp_k_2d_lsc_grid_size: copy error, ret=0x%x\n", (uint32_t)ret);
207 val = ((size.height & 0xFFFF) << 16) | (size.width & 0xFFFF);
208 REG_WR(ISP_LSC_GRID_SIZE, val);
213 static int32_t isp_k_2d_lsc_slice_size(struct isp_io_param *param)
217 struct isp_img_size size = {0, 0};
219 ret = copy_from_user((void *)&size, param->property_param, sizeof(size));
221 printk("isp_k_2d_lsc_slice_size: copy error, ret=0x%x\n", (uint32_t)ret);
225 val = ((size.height & 0xFFFF) << 16) | (size.width & 0xFFFF);
227 REG_WR(ISP_LSC_SLICE_SIZE, val);
232 int32_t isp_k_cfg_2d_lsc(struct isp_io_param *param,
233 struct isp_k_private *isp_private)
238 printk("isp_k_cfg_2d_lsc: param is null error.\n");
242 if (NULL == param->property_param) {
243 printk("isp_k_cfg_2d_lsc: property_param is null error.\n");
247 switch(param->property) {
248 case ISP_PRO_2D_LSC_BLOCK:
249 ret = isp_k_2d_lsc_block(param, isp_private);
251 case ISP_PRO_2D_LSC_BYPASS:
252 ret = isp_k_lsc_bypass(param);
254 case ISP_PRO_2D_LSC_PARAM_UPDATE:
255 ret = isp_k_2d_lsc_param_update(param, isp_private);
257 case ISP_PRO_2D_LSC_POS:
258 ret = isp_k_2d_lsc_pos(param);
260 case ISP_PRO_2D_LSC_GRID_SIZE:
261 ret = isp_k_2d_lsc_grid_size(param);
263 case ISP_PRO_2D_LSC_SLICE_SIZE:
264 ret = isp_k_2d_lsc_slice_size(param);
267 printk("isp_k_cfg_2d_lsc: fail cmd id:%d, not supported.\n", param->property);