blob: d7b62d1c408824fe678f463680f097f74640c9dc [file] [log] [blame]
Kevin Chan1d5fd4a2013-01-11 14:08:14 -08001/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/module.h>
14
15#include "msm_isp32.h"
16#include "msm_isp_util.h"
17#include "msm_isp_axi_util.h"
18#include "msm_isp.h"
19#include "msm.h"
20
21#define VFE32_BURST_LEN 4
22#define VFE32_EQUAL_SLICE_UB 117
23#define VFE32_WM_BASE(idx) (0x4C + 0x18 * idx)
24#define VFE32_RDI_BASE(idx) (0x734 + 0x4 * idx)
25#define VFE32_RDI_MN_BASE(m) (0x734 + 0x4 * m/3)
26#define VFE32_RDI_MN_SEL_SHIFT(m) (4*(m%3) + 4)
27#define VFE32_RDI_MN_FB_SHIFT(m) ((m%3) + 16)
28#define VFE32_XBAR_BASE(idx) (0x40 + 0x4 * (idx / 4))
29#define VFE32_XBAR_SHIFT(idx) ((idx % 4) * 8)
30#define VFE32_PING_PONG_BASE(wm, ping_pong) \
31 (VFE32_WM_BASE(wm) + 0x4 * (1 + (~(ping_pong >> wm) & 0x1)))
32
33/*Temporary use fixed bus vectors in VFE */
34static struct msm_bus_vectors msm_vfe32_init_vectors[] = {
35 {
36 .src = MSM_BUS_MASTER_VFE,
37 .dst = MSM_BUS_SLAVE_EBI_CH0,
38 .ab = 0,
39 .ib = 0,
40 },
41};
42
43static struct msm_bus_vectors msm_vfe32_preview_vectors[] = {
44 {
45 .src = MSM_BUS_MASTER_VFE,
46 .dst = MSM_BUS_SLAVE_EBI_CH0,
47 .ab = 1027648000,
48 .ib = 1105920000,
49 },
50};
51
52static struct msm_bus_paths msm_vfe32_bus_client_config[] = {
53 {
54 ARRAY_SIZE(msm_vfe32_init_vectors),
55 msm_vfe32_init_vectors,
56 },
57 {
58 ARRAY_SIZE(msm_vfe32_preview_vectors),
59 msm_vfe32_preview_vectors,
60 },
61};
62
63static struct msm_bus_scale_pdata msm_vfe32_bus_client_pdata = {
64 msm_vfe32_bus_client_config,
65 ARRAY_SIZE(msm_vfe32_bus_client_config),
66 .name = "msm_camera_vfe",
67};
68
69static struct msm_cam_clk_info msm_vfe32_clk_info[] = {
70 {"vfe_clk", 228570000},
71 {"vfe_pclk", -1},
72 {"csi_vfe_clk", -1},
73};
74
75static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev)
76{
77 int rc = -1;
78
79 vfe_dev->bus_perf_client =
80 msm_bus_scale_register_client(&msm_vfe32_bus_client_pdata);
81 if (!vfe_dev->bus_perf_client) {
82 pr_err("%s: Registration Failed!\n", __func__);
83 vfe_dev->bus_perf_client = 0;
84 goto bus_scale_register_failed;
85 }
86 msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 1);
87
88 if (vfe_dev->fs_vfe) {
89 rc = regulator_enable(vfe_dev->fs_vfe);
90 if (rc) {
91 pr_err("%s: Regulator enable failed\n", __func__);
92 goto fs_failed;
93 }
94 }
95
96 rc = msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
97 vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 1);
98 if (rc < 0)
99 goto clk_enable_failed;
100
101 vfe_dev->vfe_base = ioremap(vfe_dev->vfe_mem->start,
102 resource_size(vfe_dev->vfe_mem));
103 if (!vfe_dev->vfe_base) {
104 rc = -ENOMEM;
105 pr_err("%s: vfe ioremap failed\n", __func__);
106 goto vfe_remap_failed;
107 }
108
109 rc = request_irq(vfe_dev->vfe_irq->start, msm_isp_process_irq,
110 IRQF_TRIGGER_RISING, "vfe", vfe_dev);
111 if (rc < 0) {
112 pr_err("%s: irq request failed\n", __func__);
113 goto irq_req_failed;
114 }
115
116 return rc;
117irq_req_failed:
118 iounmap(vfe_dev->vfe_base);
119vfe_remap_failed:
120 msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
121 vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 0);
122clk_enable_failed:
123 regulator_disable(vfe_dev->fs_vfe);
124fs_failed:
125 msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 0);
126 msm_bus_scale_unregister_client(vfe_dev->bus_perf_client);
127bus_scale_register_failed:
128 return rc;
129}
130
131static void msm_vfe32_release_hardware(struct vfe_device *vfe_dev)
132{
133 free_irq(vfe_dev->vfe_irq->start, vfe_dev);
134 tasklet_kill(&vfe_dev->vfe_tasklet);
135 iounmap(vfe_dev->vfe_base);
136 msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
137 vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 0);
138 regulator_disable(vfe_dev->fs_vfe);
139 msm_bus_scale_client_update_request(vfe_dev->bus_perf_client, 0);
140 msm_bus_scale_unregister_client(vfe_dev->bus_perf_client);
141}
142
143static void msm_vfe32_init_hardware_reg(struct vfe_device *vfe_dev)
144{
145 /* CGC_OVERRIDE */
146 msm_camera_io_w(0x07FFFFFF, vfe_dev->vfe_base + 0xC);
147 /* BUS_CFG */
148 msm_camera_io_w(0x00000001, vfe_dev->vfe_base + 0x3C);
149 msm_camera_io_w(0x00000025, vfe_dev->vfe_base + 0x1C);
150 msm_camera_io_w_mb(0x1DFFFFFF, vfe_dev->vfe_base + 0x20);
151 msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x24);
152 msm_camera_io_w_mb(0x1FFFFFFF, vfe_dev->vfe_base + 0x28);
153}
154
155static void msm_vfe32_process_reset_irq(struct vfe_device *vfe_dev,
156 uint32_t irq_status0, uint32_t irq_status1)
157{
158 if (irq_status1 & (1 << 23))
159 complete(&vfe_dev->reset_complete);
160}
161
162static void msm_vfe32_process_halt_irq(struct vfe_device *vfe_dev,
163 uint32_t irq_status0, uint32_t irq_status1)
164{
165 if (irq_status1 & (1 << 24))
166 complete(&vfe_dev->halt_complete);
167}
168
169static void msm_vfe32_process_camif_irq(struct vfe_device *vfe_dev,
170 uint32_t irq_status0, uint32_t irq_status1)
171{
172 if (!(irq_status0 & 0x1F))
173 return;
174
175 if (irq_status0 & (1 << 0)) {
176 ISP_DBG("%s: PIX0 frame id: %lu\n", __func__,
177 vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
178 msm_isp_update_framedrop_count(vfe_dev);
179 vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id++;
180 }
181}
182
183static void msm_vfe32_process_violation_irq(struct vfe_device *vfe_dev)
184{
185 uint32_t violation_status;
186 violation_status = msm_camera_io_r(vfe_dev->vfe_base + 0x48);
187 if (!violation_status)
188 return;
189
190 if (violation_status & (1 << 0))
191 pr_err("%s: black violation\n", __func__);
192 if (violation_status & (1 << 1))
193 pr_err("%s: rolloff violation\n", __func__);
194 if (violation_status & (1 << 2))
195 pr_err("%s: demux violation\n", __func__);
196 if (violation_status & (1 << 3))
197 pr_err("%s: demosaic violation\n", __func__);
198 if (violation_status & (1 << 4))
199 pr_err("%s: crop violation\n", __func__);
200 if (violation_status & (1 << 5))
201 pr_err("%s: scale violation\n", __func__);
202 if (violation_status & (1 << 6))
203 pr_err("%s: wb violation\n", __func__);
204 if (violation_status & (1 << 7))
205 pr_err("%s: clf violation\n", __func__);
206 if (violation_status & (1 << 8))
207 pr_err("%s: matrix violation\n", __func__);
208 if (violation_status & (1 << 9))
209 pr_err("%s: rgb lut violation\n", __func__);
210 if (violation_status & (1 << 10))
211 pr_err("%s: la violation\n", __func__);
212 if (violation_status & (1 << 11))
213 pr_err("%s: chroma enhance violation\n", __func__);
214 if (violation_status & (1 << 12))
215 pr_err("%s: chroma supress mce violation\n", __func__);
216 if (violation_status & (1 << 13))
217 pr_err("%s: skin enhance violation\n", __func__);
218 if (violation_status & (1 << 14))
219 pr_err("%s: asf violation\n", __func__);
220 if (violation_status & (1 << 15))
221 pr_err("%s: scale y violation\n", __func__);
222 if (violation_status & (1 << 16))
223 pr_err("%s: scale cbcr violation\n", __func__);
224 if (violation_status & (1 << 17))
225 pr_err("%s: chroma subsample violation\n", __func__);
226 if (violation_status & (1 << 18))
227 pr_err("%s: framedrop enc y violation\n", __func__);
228 if (violation_status & (1 << 19))
229 pr_err("%s: framedrop enc cbcr violation\n", __func__);
230 if (violation_status & (1 << 20))
231 pr_err("%s: framedrop view y violation\n", __func__);
232 if (violation_status & (1 << 21))
233 pr_err("%s: framedrop view cbcr violation\n", __func__);
234 if (violation_status & (1 << 22))
235 pr_err("%s: realign buf y violation\n", __func__);
236 if (violation_status & (1 << 23))
237 pr_err("%s: realign buf cb violation\n", __func__);
238 if (violation_status & (1 << 24))
239 pr_err("%s: realign buf cr violation\n", __func__);
240}
241
242static void msm_vfe32_process_error_irq(struct vfe_device *vfe_dev,
243 uint32_t irq_status0, uint32_t irq_status1)
244{
245 uint32_t camif_status;
246 if (!(irq_status1 & 0x7FFFFF))
247 return;
248
249 if (irq_status1 & (1 << 0)) {
250 camif_status = msm_camera_io_r(vfe_dev->vfe_base + 0x204);
251 pr_err("%s: camif error status: 0x%x\n",
252 __func__, camif_status);
253 }
254 if (irq_status1 & (1 << 1))
255 pr_err("%s: stats bhist overwrite\n", __func__);
256 if (irq_status1 & (1 << 2))
257 pr_err("%s: stats cs overwrite\n", __func__);
258 if (irq_status1 & (1 << 3))
259 pr_err("%s: stats ihist overwrite\n", __func__);
260 if (irq_status1 & (1 << 4))
261 pr_err("%s: realign buf y overflow\n", __func__);
262 if (irq_status1 & (1 << 5))
263 pr_err("%s: realign buf cb overflow\n", __func__);
264 if (irq_status1 & (1 << 6))
265 pr_err("%s: realign buf cr overflow\n", __func__);
266 if (irq_status1 & (1 << 7)) {
267 pr_err("%s: violation\n", __func__);
268 msm_vfe32_process_violation_irq(vfe_dev);
269 }
270 if (irq_status1 & (1 << 8))
271 pr_err("%s: image master 0 bus overflow\n", __func__);
272 if (irq_status1 & (1 << 9))
273 pr_err("%s: image master 1 bus overflow\n", __func__);
274 if (irq_status1 & (1 << 10))
275 pr_err("%s: image master 2 bus overflow\n", __func__);
276 if (irq_status1 & (1 << 11))
277 pr_err("%s: image master 3 bus overflow\n", __func__);
278 if (irq_status1 & (1 << 12))
279 pr_err("%s: image master 4 bus overflow\n", __func__);
280 if (irq_status1 & (1 << 13))
281 pr_err("%s: image master 5 bus overflow\n", __func__);
282 if (irq_status1 & (1 << 14))
283 pr_err("%s: image master 6 bus overflow\n", __func__);
284 if (irq_status1 & (1 << 15))
285 pr_err("%s: status ae/bg bus overflow\n", __func__);
286 if (irq_status1 & (1 << 16))
287 pr_err("%s: status af/bf bus overflow\n", __func__);
288 if (irq_status1 & (1 << 17))
289 pr_err("%s: status awb bus overflow\n", __func__);
290 if (irq_status1 & (1 << 18))
291 pr_err("%s: status rs bus overflow\n", __func__);
292 if (irq_status1 & (1 << 19))
293 pr_err("%s: status cs bus overflow\n", __func__);
294 if (irq_status1 & (1 << 20))
295 pr_err("%s: status ihist bus overflow\n", __func__);
296 if (irq_status1 & (1 << 21))
297 pr_err("%s: status skin bhist bus overflow\n", __func__);
298 if (irq_status1 & (1 << 22))
299 pr_err("%s: axi error\n", __func__);
300}
301
302static void msm_vfe32_read_irq_status(struct vfe_device *vfe_dev,
303 uint32_t *irq_status0, uint32_t *irq_status1)
304{
305 *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
306 *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x30);
307 msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x24);
308 msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x28);
309 msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x18);
310}
311
312static void msm_vfe32_process_reg_update(struct vfe_device *vfe_dev,
313 uint32_t irq_status0, uint32_t irq_status1)
314{
315 if (!(irq_status0 & 0x20) && !(irq_status1 & 0x1C000000))
316 return;
317
318 if (vfe_dev->axi_data.stream_update)
319 msm_isp_axi_stream_update(vfe_dev);
320
321 msm_isp_update_framedrop_reg(vfe_dev);
322
323 return;
324}
325
326static void msm_vfe32_reg_update(
327 struct vfe_device *vfe_dev, uint32_t update_mask)
328{
329 msm_camera_io_w_mb(update_mask, vfe_dev->vfe_base + 0x260);
330}
331
332static long msm_vfe32_reset_hardware(struct vfe_device *vfe_dev)
333{
334 init_completion(&vfe_dev->reset_complete);
335 msm_camera_io_w_mb(0x3FF, vfe_dev->vfe_base + 0x4);
336 return wait_for_completion_interruptible_timeout(
337 &vfe_dev->reset_complete, msecs_to_jiffies(50));
338}
339
340static void msm_vfe32_axi_reload_wm(
341 struct vfe_device *vfe_dev, uint32_t reload_mask)
342{
343 msm_camera_io_w_mb(reload_mask, vfe_dev->vfe_base + 0x38);
344}
345
346static void msm_vfe32_axi_enable_wm(struct vfe_device *vfe_dev,
347 uint8_t wm_idx, uint8_t enable)
348{
349 if (enable)
350 msm_camera_io_w_mb(0x1,
351 vfe_dev->vfe_base + VFE32_WM_BASE(wm_idx));
352 else
353 msm_camera_io_w_mb(0x0,
354 vfe_dev->vfe_base + VFE32_WM_BASE(wm_idx));
355}
356
357static void msm_vfe32_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
358 struct msm_vfe_axi_stream *stream_info)
359{
360 struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
361 uint32_t comp_mask, comp_mask_index =
362 stream_info->comp_mask_index;
363 uint32_t irq_mask;
364
365 comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x34);
366 comp_mask &= ~(0x7F << (comp_mask_index * 8));
367 comp_mask |= (axi_data->composite_info[comp_mask_index].
368 stream_composite_mask << (comp_mask_index * 8));
369 msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x34);
370
371 irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
372 irq_mask |= 1 << (comp_mask_index + 21);
373 msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
374}
375
376static void msm_vfe32_axi_clear_comp_mask(struct vfe_device *vfe_dev,
377 struct msm_vfe_axi_stream *stream_info)
378{
379 uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
380 uint32_t irq_mask;
381
382 comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x34);
383 comp_mask &= ~(0x7F << (comp_mask_index * 8));
384 msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x34);
385
386 irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
387 irq_mask &= ~(1 << (comp_mask_index + 21));
388 msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
389}
390
391static void msm_vfe32_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
392 struct msm_vfe_axi_stream *stream_info)
393{
394 uint32_t irq_mask;
395 irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
396 irq_mask |= 1 << (stream_info->wm[0] + 6);
397 msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
398}
399
400static void msm_vfe32_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
401 struct msm_vfe_axi_stream *stream_info)
402{
403 uint32_t irq_mask;
404 irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
405 irq_mask &= ~(1 << (stream_info->wm[0] + 6));
406 msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
407}
408
409static void msm_vfe32_cfg_framedrop(struct vfe_device *vfe_dev,
410 struct msm_vfe_axi_stream *stream_info)
411{
412 uint32_t framedrop_pattern = 0;
413
414 if (stream_info->init_frame_drop == 0)
415 framedrop_pattern = stream_info->framedrop_pattern;
416
417 if (stream_info->stream_type == BURST_STREAM &&
418 stream_info->burst_frame_count == 0)
419 framedrop_pattern = 0;
420
421 if (stream_info->stream_src == PIX_ENCODER) {
422 msm_camera_io_w(0x1F, vfe_dev->vfe_base + 0x504);
423 msm_camera_io_w(0x1F, vfe_dev->vfe_base + 0x508);
424 msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x50C);
425 msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x510);
426 } else if (stream_info->stream_src == PIX_VIEWFINDER) {
427 msm_camera_io_w(0x1F, vfe_dev->vfe_base + 0x514);
428 msm_camera_io_w(0x1F, vfe_dev->vfe_base + 0x518);
429 msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x51C);
430 msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x520);
431 }
432 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x260);
433}
434
435static void msm_vfe32_clear_framedrop(struct vfe_device *vfe_dev,
436 struct msm_vfe_axi_stream *stream_info)
437{
438 if (stream_info->stream_src == PIX_ENCODER) {
439 msm_camera_io_w(0, vfe_dev->vfe_base + 0x50C);
440 msm_camera_io_w(0, vfe_dev->vfe_base + 0x510);
441 } else if (stream_info->stream_src == PIX_VIEWFINDER) {
442 msm_camera_io_w(0, vfe_dev->vfe_base + 0x51C);
443 msm_camera_io_w(0, vfe_dev->vfe_base + 0x520);
444 }
445}
446
447static void msm_vfe32_cfg_camif(struct vfe_device *vfe_dev,
448 struct msm_vfe_pix_cfg *pix_cfg)
449{
450 uint16_t first_pixel, last_pixel, first_line, last_line;
451 struct msm_vfe_camif_cfg *camif_cfg = &pix_cfg->camif_cfg;
452 uint32_t val;
453
454 first_pixel = camif_cfg->left_crop;
455 last_pixel = camif_cfg->pixels_per_line -
456 camif_cfg->left_crop -
457 camif_cfg->right_crop;
458 first_line = camif_cfg->left_crop;
459 last_line = camif_cfg->lines_per_frame -
460 camif_cfg->top_crop -
461 camif_cfg->bottom_crop;
462
463 msm_camera_io_w(pix_cfg->input_mux << 16 | pix_cfg->pixel_pattern,
464 vfe_dev->vfe_base + 0x14);
465
466 msm_camera_io_w(camif_cfg->lines_per_frame << 16 |
467 camif_cfg->pixels_per_line,
468 vfe_dev->vfe_base + 0x1EC);
469
470 msm_camera_io_w(ISP_SUB(first_pixel) << 16 | ISP_SUB(last_pixel),
471 vfe_dev->vfe_base + 0x1F0);
472
473 msm_camera_io_w(ISP_SUB(first_line) << 16 | ISP_SUB(last_line),
474 vfe_dev->vfe_base + 0x1F4);
475
476 val = msm_camera_io_r(vfe_dev->vfe_base + 0x6FC);
477 val &= 0xFFFFFFFC;
478 val |= camif_cfg->camif_input;
479 msm_camera_io_w(val, vfe_dev->vfe_base + 0x6FC);
480}
481
482static void msm_vfe32_update_camif_state(
483 struct vfe_device *vfe_dev,
484 enum msm_isp_camif_update_state update_state)
485{
486 uint32_t val;
487 bool bus_en, vfe_en;
488 if (update_state == NO_UPDATE)
489 return;
490
491 val = msm_camera_io_r(vfe_dev->vfe_base + 0x1E4);
492 if (update_state == ENABLE_CAMIF) {
493 bus_en =
494 ((vfe_dev->axi_data.src_info[
495 VFE_PIX_0].raw_stream_count > 0) ? 1 : 0);
496 vfe_en =
497 ((vfe_dev->axi_data.src_info[
498 VFE_PIX_0].pix_stream_count > 0) ? 1 : 0);
499 val &= 0xFFFFFF3F;
500 val = val | bus_en << 7 | vfe_en << 6;
501 msm_camera_io_w(val, vfe_dev->vfe_base + 0x1E4);
502 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1E0);
503 vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1;
504 } else if (update_state == DISABLE_CAMIF) {
505 msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x1E0);
506 vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
507 }
508}
509
510static void msm_vfe32_axi_cfg_wm_reg(
511 struct vfe_device *vfe_dev,
512 struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd,
513 uint8_t plane_idx)
514{
515 uint32_t val;
516 struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
517 struct msm_vfe_axi_stream *stream_info =
518 &axi_data->stream_info[
519 (stream_cfg_cmd->axi_stream_handle & 0xFF)];
520 uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[plane_idx]);
521
522 /*WR_IMAGE_SIZE*/
523 val =
524 ((msm_isp_cal_word_per_line(stream_cfg_cmd->output_format,
525 stream_cfg_cmd->plane_cfg[
526 plane_idx].output_width)+1)/2 - 1) << 16 |
527 (stream_cfg_cmd->plane_cfg[plane_idx].output_height - 1);
528 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x10);
529
530 /*WR_BUFFER_CFG*/
531 val =
532 msm_isp_cal_word_per_line(stream_cfg_cmd->output_format,
533 stream_cfg_cmd->plane_cfg[plane_idx].output_width) << 16 |
534 (stream_cfg_cmd->plane_cfg[
535 plane_idx].output_scan_lines - 1) << 4 |
536 VFE32_BURST_LEN >> 2;
537 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
538 return;
539}
540
541static void msm_vfe32_axi_clear_wm_reg(
542 struct vfe_device *vfe_dev,
543 struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
544{
545 uint32_t val = 0;
546 uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[plane_idx]);
547 /*WR_IMAGE_SIZE*/
548 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x10);
549 /*WR_BUFFER_CFG*/
550 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
551 return;
552}
553
554static void msm_vfe32_axi_cfg_rdi_reg(
555 struct vfe_device *vfe_dev,
556 struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd,
557 uint8_t plane_idx)
558{
559 struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
560 struct msm_vfe_axi_stream *stream_info =
561 &axi_data->stream_info[(stream_cfg_cmd->axi_stream_handle & 0xFF)];
562 struct msm_vfe_axi_plane_cfg *plane_cfg =
563 &stream_cfg_cmd->plane_cfg[plane_idx];
564 uint8_t rdi = stream_info->rdi[plane_idx];
565 uint8_t rdi_master = stream_info->rdi_master[plane_idx];
566 uint32_t rdi_reg_cfg;
567
568 rdi_reg_cfg = msm_camera_io_r(vfe_dev->vfe_base + VFE32_RDI_BASE(rdi));
569 rdi_reg_cfg = (rdi_reg_cfg & 0xFFFFFFF) | rdi_master << 28;
570 msm_camera_io_w(rdi_reg_cfg, vfe_dev->vfe_base + VFE32_RDI_BASE(rdi));
571
572 rdi_reg_cfg = msm_camera_io_r(
573 vfe_dev->vfe_base + VFE32_RDI_MN_BASE(rdi_master));
574 rdi_reg_cfg &= ~((0xF << VFE32_RDI_MN_SEL_SHIFT(rdi_master)) |
575 (0x1 << VFE32_RDI_MN_FB_SHIFT(rdi_master)));
576 rdi_reg_cfg |= (plane_cfg->rdi_cid <<
577 VFE32_RDI_MN_SEL_SHIFT(rdi_master) |
578 (stream_cfg_cmd->frame_base <<
579 VFE32_RDI_MN_FB_SHIFT(rdi_master)));
580 msm_camera_io_w(rdi_reg_cfg,
581 vfe_dev->vfe_base +
582 VFE32_RDI_MN_BASE(rdi_master));
583}
584
585static void msm_vfe32_axi_cfg_wm_xbar_reg(
586 struct vfe_device *vfe_dev,
587 struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd,
588 uint8_t plane_idx)
589{
590 struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
591 struct msm_vfe_axi_stream *stream_info =
592 &axi_data->stream_info[(stream_cfg_cmd->axi_stream_handle & 0xFF)];
593 struct msm_vfe_axi_plane_cfg *plane_cfg =
594 &stream_cfg_cmd->plane_cfg[plane_idx];
595 uint8_t wm = stream_info->wm[plane_idx];
596 uint32_t xbar_cfg = 0;
597 uint32_t xbar_reg_cfg = 0;
598
599 switch (stream_cfg_cmd->stream_src) {
600 case PIX_ENCODER:
601 case PIX_VIEWFINDER: {
602 if (plane_cfg->output_plane_format
603 != CRCB_PLANE) {
604 /*SINGLE_STREAM_SEL*/
605 xbar_cfg |= plane_cfg->output_plane_format << 5;
606 } else {
607 switch (stream_cfg_cmd->output_format) {
608 case V4L2_PIX_FMT_NV12:
609 case V4L2_PIX_FMT_NV16:
610 xbar_cfg |= 0x3 << 3; /*PAIR_STREAM_SWAP_CTRL*/
611 break;
612 }
613 xbar_cfg |= 0x1 << 1; /*PAIR_STREAM_EN*/
614 }
615 if (stream_cfg_cmd->stream_src == PIX_VIEWFINDER)
616 xbar_cfg |= 0x1; /*VIEW_STREAM_EN*/
617 break;
618 }
619 case CAMIF_RAW:
620 xbar_cfg = 0x60;
621 break;
622 case IDEAL_RAW:
623 xbar_cfg = 0x80;
624 break;
625 case RDI:
626 if (stream_info->rdi[plane_idx] == 0)
627 xbar_cfg = 0xA0;
628 else if (stream_info->rdi[plane_idx] == 1)
629 xbar_cfg = 0xC0;
630 else if (stream_info->rdi[plane_idx] == 2)
631 xbar_cfg = 0xE0;
632 break;
633 default:
634 pr_err("%s: Invalid stream src\n", __func__);
635 }
636 xbar_reg_cfg = msm_camera_io_r(vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
637 xbar_reg_cfg &= ~(0xFF << VFE32_XBAR_SHIFT(wm));
638 xbar_reg_cfg |= (xbar_cfg << VFE32_XBAR_SHIFT(wm));
639 msm_camera_io_w(xbar_reg_cfg, vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
640 return;
641}
642
643static void msm_vfe32_axi_clear_wm_xbar_reg(
644 struct vfe_device *vfe_dev,
645 struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
646{
647 uint8_t wm = stream_info->wm[plane_idx];
648 uint32_t xbar_reg_cfg = 0;
649
650 xbar_reg_cfg = msm_camera_io_r(vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
651 xbar_reg_cfg &= ~(0xFF << VFE32_XBAR_SHIFT(wm));
652 msm_camera_io_w(xbar_reg_cfg, vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
653}
654
655static void msm_vfe32_cfg_axi_ub(struct vfe_device *vfe_dev)
656{
657 int i;
658 uint32_t ub_offset = 0;
659 struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
660 for (i = 0; i < axi_data->hw_info->num_wm; i++) {
661 msm_camera_io_w(ub_offset << 16 | (VFE32_EQUAL_SLICE_UB - 1),
662 vfe_dev->vfe_base + VFE32_WM_BASE(i) + 0xC);
663 ub_offset += VFE32_EQUAL_SLICE_UB;
664 }
665}
666
667static void msm_vfe32_update_ping_pong_addr(struct vfe_device *vfe_dev,
668 uint8_t wm_idx, uint32_t pingpong_status, unsigned long paddr)
669{
670 msm_camera_io_w(paddr, vfe_dev->vfe_base +
671 VFE32_PING_PONG_BASE(wm_idx, pingpong_status));
672}
673
674static long msm_vfe32_axi_halt(struct vfe_device *vfe_dev)
675{
676 uint32_t halt_mask;
677 halt_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x20);
678 halt_mask |= (1 << 24);
679 msm_camera_io_w_mb(halt_mask, vfe_dev->vfe_base + 0x20);
680 init_completion(&vfe_dev->halt_complete);
681 /*TD: Need to fix crashes with this*/
682 /*msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1D8);*/
683 return wait_for_completion_interruptible_timeout(
684 &vfe_dev->halt_complete, msecs_to_jiffies(500));
685}
686
687static uint32_t msm_vfe32_get_wm_mask(
688 uint32_t irq_status0, uint32_t irq_status1)
689{
690 return (irq_status0 >> 6) & 0x7F;
691}
692
693static uint32_t msm_vfe32_get_comp_mask(
694 uint32_t irq_status0, uint32_t irq_status1)
695{
696 return (irq_status0 >> 21) & 0x7;
697}
698
699static uint32_t msm_vfe32_get_pingpong_status(struct vfe_device *vfe_dev)
700{
701 return msm_camera_io_r(vfe_dev->vfe_base + 0x180);
702}
703
704static int msm_vfe32_get_platform_data(struct vfe_device *vfe_dev)
705{
706 int rc = 0;
707 vfe_dev->vfe_mem = platform_get_resource_byname(vfe_dev->pdev,
708 IORESOURCE_MEM, "vfe");
709 if (!vfe_dev->vfe_mem) {
710 pr_err("%s: no mem resource?\n", __func__);
711 rc = -ENODEV;
712 goto vfe_no_resource;
713 }
714
715 vfe_dev->vfe_irq = platform_get_resource_byname(vfe_dev->pdev,
716 IORESOURCE_IRQ, "vfe");
717 if (!vfe_dev->vfe_irq) {
718 pr_err("%s: no irq resource?\n", __func__);
719 rc = -ENODEV;
720 goto vfe_no_resource;
721 }
722
723 vfe_dev->fs_vfe = regulator_get(&vfe_dev->pdev->dev, "vdd");
724 if (IS_ERR(vfe_dev->fs_vfe)) {
725 pr_err("%s: Regulator get failed %ld\n", __func__,
726 PTR_ERR(vfe_dev->fs_vfe));
727 vfe_dev->fs_vfe = NULL;
728 rc = -ENODEV;
729 goto vfe_no_resource;
730 }
731
732 vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe_imgwr");
733 if (!vfe_dev->iommu_ctx[0]) {
734 pr_err("%s: no iommux ctx resource?\n", __func__);
735 rc = -ENODEV;
736 goto vfe_no_resource;
737 }
738
739 vfe_dev->iommu_ctx[1] = msm_iommu_get_ctx("vfe_misc");
740 if (!vfe_dev->iommu_ctx[1]) {
741 pr_err("%s: no iommux ctx resource?\n", __func__);
742 rc = -ENODEV;
743 goto vfe_no_resource;
744 }
745 vfe_dev->num_ctx = 2;
746
747vfe_no_resource:
748 return rc;
749}
750
751struct msm_vfe_axi_hardware_info msm_vfe32_axi_hw_info = {
752 .num_wm = 7,
753 .num_comp_mask = 3,
754 .num_rdi = 3,
755 .num_rdi_master = 3,
756};
757
758static struct v4l2_subdev_core_ops msm_vfe32_subdev_core_ops = {
759 .ioctl = msm_isp_ioctl,
760 .subscribe_event = msm_isp_subscribe_event,
761 .unsubscribe_event = msm_isp_unsubscribe_event,
762};
763
764static struct v4l2_subdev_ops msm_vfe32_subdev_ops = {
765 .core = &msm_vfe32_subdev_core_ops,
766};
767
768static struct v4l2_subdev_internal_ops msm_vfe32_internal_ops = {
769 .open = msm_isp_open_node,
770 .close = msm_isp_close_node,
771};
772
773struct msm_vfe_hardware_info vfe32_hw_info = {
774 .vfe_ops = {
775 .irq_ops = {
776 .read_irq_status = msm_vfe32_read_irq_status,
777 .process_camif_irq = msm_vfe32_process_camif_irq,
778 .process_reset_irq = msm_vfe32_process_reset_irq,
779 .process_halt_irq = msm_vfe32_process_halt_irq,
780 .process_reset_irq = msm_vfe32_process_reset_irq,
781 .process_error_irq = msm_vfe32_process_error_irq,
782 .process_reg_update = msm_vfe32_process_reg_update,
783 .process_axi_irq = msm_isp_process_axi_irq,
784 },
785 .axi_ops = {
786 .reload_wm = msm_vfe32_axi_reload_wm,
787 .enable_wm = msm_vfe32_axi_enable_wm,
788 .cfg_comp_mask = msm_vfe32_axi_cfg_comp_mask,
789 .clear_comp_mask = msm_vfe32_axi_clear_comp_mask,
790 .cfg_wm_irq_mask = msm_vfe32_axi_cfg_wm_irq_mask,
791 .clear_wm_irq_mask = msm_vfe32_axi_clear_wm_irq_mask,
792 .cfg_framedrop = msm_vfe32_cfg_framedrop,
793 .clear_framedrop = msm_vfe32_clear_framedrop,
794 .cfg_wm_reg = msm_vfe32_axi_cfg_wm_reg,
795 .clear_wm_reg = msm_vfe32_axi_clear_wm_reg,
796 .cfg_wm_xbar_reg = msm_vfe32_axi_cfg_wm_xbar_reg,
797 .clear_wm_xbar_reg = msm_vfe32_axi_clear_wm_xbar_reg,
798 .cfg_rdi_reg = msm_vfe32_axi_cfg_rdi_reg,
799 .cfg_ub = msm_vfe32_cfg_axi_ub,
800 .update_ping_pong_addr =
801 msm_vfe32_update_ping_pong_addr,
802 .get_comp_mask = msm_vfe32_get_comp_mask,
803 .get_wm_mask = msm_vfe32_get_wm_mask,
804 .get_pingpong_status = msm_vfe32_get_pingpong_status,
805 .halt = msm_vfe32_axi_halt,
806 },
807 .core_ops = {
808 .reg_update = msm_vfe32_reg_update,
809 .cfg_camif = msm_vfe32_cfg_camif,
810 .update_camif_state = msm_vfe32_update_camif_state,
811 .reset_hw = msm_vfe32_reset_hardware,
812 .init_hw = msm_vfe32_init_hardware,
813 .init_hw_reg = msm_vfe32_init_hardware_reg,
814 .release_hw = msm_vfe32_release_hardware,
815 .get_platform_data = msm_vfe32_get_platform_data,
816 },
817 },
818 .axi_hw_info = &msm_vfe32_axi_hw_info,
819 .subdev_ops = &msm_vfe32_subdev_ops,
820 .subdev_internal_ops = &msm_vfe32_internal_ops,
821};
822EXPORT_SYMBOL(vfe32_hw_info);