blob: dc9b6643300add0e4d0595fda3604ebe91fb1979 [file] [log] [blame]
Pratap Nirujogi6e759912018-01-17 17:51:17 +05301/* Copyright (c) 2012-2015, 2018, 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#include <linux/sched.h>
15#include "msm_jpeg_hw.h"
16#include "msm_jpeg_core.h"
17#include "msm_jpeg_platform.h"
18#include "msm_jpeg_common.h"
19
20int msm_jpeg_core_reset(struct msm_jpeg_device *pgmn_dev, uint8_t op_mode,
21 void *base, int size) {
22 unsigned long flags;
23 int rc = 0;
24 int tm = 500; /*500ms*/
25
26 JPEG_DBG("%s:%d] reset", __func__, __LINE__);
27 memset(&pgmn_dev->fe_pingpong_buf, 0,
28 sizeof(pgmn_dev->fe_pingpong_buf));
29 pgmn_dev->fe_pingpong_buf.is_fe = 1;
30 memset(&pgmn_dev->we_pingpong_buf, 0,
31 sizeof(pgmn_dev->we_pingpong_buf));
32 spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
33 pgmn_dev->reset_done_ack = 0;
34 if (pgmn_dev->core_type == MSM_JPEG_CORE_CODEC)
35 msm_jpeg_hw_reset(base, size);
36 else
37 msm_jpeg_hw_reset_dma(base, size);
38
39 spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
40 rc = wait_event_timeout(
41 pgmn_dev->reset_wait,
42 pgmn_dev->reset_done_ack,
43 msecs_to_jiffies(tm));
44
45 if (!pgmn_dev->reset_done_ack) {
46 JPEG_DBG("%s: reset ACK failed %d", __func__, rc);
47 return -EBUSY;
48 }
49
50 JPEG_DBG("%s: reset_done_ack rc %d", __func__, rc);
51 spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
52 pgmn_dev->reset_done_ack = 0;
53 pgmn_dev->state = MSM_JPEG_RESET;
54 spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
55
56 return 0;
57}
58
59void msm_jpeg_core_release(struct msm_jpeg_device *pgmn_dev)
60{
61 int i = 0;
62
63 for (i = 0; i < 2; i++) {
64 if (pgmn_dev->we_pingpong_buf.buf_status[i] &&
65 pgmn_dev->release_buf)
66 msm_jpeg_platform_p2v(pgmn_dev->iommu_hdl,
67 pgmn_dev->we_pingpong_buf.buf[i].ion_fd);
68 pgmn_dev->we_pingpong_buf.buf_status[i] = 0;
69 }
70}
71
72void msm_jpeg_core_init(struct msm_jpeg_device *pgmn_dev)
73{
74 init_waitqueue_head(&pgmn_dev->reset_wait);
75 spin_lock_init(&pgmn_dev->reset_lock);
76}
77
78int msm_jpeg_core_fe_start(struct msm_jpeg_device *pgmn_dev)
79{
80 msm_jpeg_hw_fe_start(pgmn_dev->base);
81 return 0;
82}
83
84/* fetch engine */
85int msm_jpeg_core_fe_buf_update(struct msm_jpeg_device *pgmn_dev,
86 struct msm_jpeg_core_buf *buf)
87{
88 int rc = 0;
89
90 if (buf->cbcr_len == 0)
91 buf->cbcr_buffer_addr = 0x0;
92
93 JPEG_DBG("%s:%d] 0x%08x %d 0x%08x %d\n", __func__, __LINE__,
94 (int) buf->y_buffer_addr, buf->y_len,
95 (int) buf->cbcr_buffer_addr, buf->cbcr_len);
96
97 if (pgmn_dev->core_type == MSM_JPEG_CORE_CODEC) {
98 rc = msm_jpeg_hw_pingpong_update(&pgmn_dev->fe_pingpong_buf,
99 buf, pgmn_dev->base);
100 if (rc < 0)
101 return rc;
102 msm_jpeg_hw_fe_mmu_prefetch(buf, pgmn_dev->base,
103 pgmn_dev->decode_flag);
104 } else {
105 rc = msm_jpegdma_hw_pingpong_update(
106 &pgmn_dev->fe_pingpong_buf, buf, pgmn_dev->base);
107 if (rc < 0)
108 return rc;
109 msm_jpegdma_hw_fe_mmu_prefetch(buf, pgmn_dev->base);
110 }
111
112 return rc;
113}
114
115static void *msm_jpeg_core_fe_pingpong_irq(int jpeg_irq_status,
116 struct msm_jpeg_device *pgmn_dev)
117{
118 return msm_jpeg_hw_pingpong_irq(&pgmn_dev->fe_pingpong_buf);
119}
120
121/* write engine */
122int msm_jpeg_core_we_buf_update(struct msm_jpeg_device *pgmn_dev,
123 struct msm_jpeg_core_buf *buf) {
124
125 JPEG_DBG("%s:%d] 0x%08x 0x%08x %d\n", __func__, __LINE__,
126 (int) buf->y_buffer_addr, (int) buf->cbcr_buffer_addr,
127 buf->y_len);
128
129 pgmn_dev->we_pingpong_buf.buf[0] = *buf;
130 pgmn_dev->we_pingpong_buf.buf_status[0] = 1;
131
132 if (pgmn_dev->core_type == MSM_JPEG_CORE_CODEC) {
133 msm_jpeg_hw_we_buffer_update(
134 &pgmn_dev->we_pingpong_buf.buf[0], 0, pgmn_dev->base);
135 msm_jpeg_hw_we_mmu_prefetch(buf, pgmn_dev->base,
136 pgmn_dev->decode_flag);
137 } else {
138 msm_jpegdma_hw_we_buffer_update(
139 &pgmn_dev->we_pingpong_buf.buf[0], 0, pgmn_dev->base);
140 msm_jpegdma_hw_we_mmu_prefetch(buf, pgmn_dev->base);
141 }
142
143 return 0;
144}
145
146int msm_jpeg_core_we_buf_reset(struct msm_jpeg_device *pgmn_dev,
147 struct msm_jpeg_hw_buf *buf)
148{
149 int i = 0;
150
151 for (i = 0; i < 2; i++) {
152 if (pgmn_dev->we_pingpong_buf.buf[i].y_buffer_addr
153 == buf->y_buffer_addr)
154 pgmn_dev->we_pingpong_buf.buf_status[i] = 0;
155 }
156 return 0;
157}
158
159static void *msm_jpeg_core_we_pingpong_irq(int jpeg_irq_status,
160 struct msm_jpeg_device *pgmn_dev)
161{
162 JPEG_DBG("%s:%d]\n", __func__, __LINE__);
163
164 return msm_jpeg_hw_pingpong_irq(&pgmn_dev->we_pingpong_buf);
165}
166
167static void *msm_jpeg_core_framedone_irq(int jpeg_irq_status,
168 struct msm_jpeg_device *pgmn_dev)
169{
170 struct msm_jpeg_hw_buf *buf_p;
171
172 JPEG_DBG("%s:%d]\n", __func__, __LINE__);
173
174 buf_p = msm_jpeg_hw_pingpong_active_buffer(
175 &pgmn_dev->we_pingpong_buf);
176 if (buf_p && !pgmn_dev->decode_flag) {
177 buf_p->framedone_len =
178 msm_jpeg_hw_encode_output_size(pgmn_dev->base);
179 JPEG_DBG("%s:%d] framedone_len %d\n", __func__, __LINE__,
180 buf_p->framedone_len);
181 }
182
183 return buf_p;
184}
185
186static void *msm_jpeg_core_reset_ack_irq(int jpeg_irq_status,
187 struct msm_jpeg_device *pgmn_dev)
188{
189 /* @todo return the status back to msm_jpeg_core_reset */
190 JPEG_DBG("%s:%d]\n", __func__, __LINE__);
191 return NULL;
192}
193
194static void *msm_jpeg_core_err_irq(int jpeg_irq_status,
195 struct msm_jpeg_device *pgmn_dev)
196{
197 JPEG_PR_ERR("%s: Error %x\n", __func__, jpeg_irq_status);
198 return NULL;
199}
200
201static int (*msm_jpeg_irq_handler)(int, void *, void *);
202
203static void msm_jpeg_core_return_buffers(struct msm_jpeg_device *pgmn_dev,
204 int jpeg_irq_status)
205{
206 void *data = NULL;
207
208 data = msm_jpeg_core_fe_pingpong_irq(jpeg_irq_status,
209 pgmn_dev);
210 if (msm_jpeg_irq_handler)
211 msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_FE,
212 pgmn_dev, data);
213 data = msm_jpeg_core_we_pingpong_irq(jpeg_irq_status,
214 pgmn_dev);
215 if (msm_jpeg_irq_handler)
216 msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_WE,
217 pgmn_dev, data);
218}
219
220irqreturn_t msm_jpeg_core_irq(int irq_num, void *context)
221{
222 void *data = NULL;
223 unsigned long flags;
224 int jpeg_irq_status;
225 struct msm_jpeg_device *pgmn_dev = (struct msm_jpeg_device *)context;
226
227 JPEG_DBG("%s:%d] irq_num = %d\n", __func__, __LINE__, irq_num);
228
229 jpeg_irq_status = msm_jpeg_hw_irq_get_status(pgmn_dev->base);
230
231 JPEG_DBG("%s:%d] jpeg_irq_status = %0x\n", __func__, __LINE__,
232 jpeg_irq_status);
233
234 /*For reset and framedone IRQs, clear all bits*/
235 if (pgmn_dev->state == MSM_JPEG_IDLE) {
236 JPEG_DBG_HIGH("%s %d ] Error IRQ received state %d",
237 __func__, __LINE__, pgmn_dev->state);
238 JPEG_DBG_HIGH("%s %d ] Ignoring the Error", __func__,
239 __LINE__);
240 msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
241 JPEG_IRQ_CLEAR_ALL, pgmn_dev->base);
242 return IRQ_HANDLED;
243 } else if (jpeg_irq_status & 0x10000000) {
244 msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
245 JPEG_IRQ_CLEAR_ALL, pgmn_dev->base);
246 } else if (jpeg_irq_status & 0x1) {
247 msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
248 JPEG_IRQ_CLEAR_ALL, pgmn_dev->base);
249 if (pgmn_dev->decode_flag)
250 msm_jpeg_decode_status(pgmn_dev->base);
251 } else {
252 msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
253 jpeg_irq_status, pgmn_dev->base);
254 }
255
256 if (msm_jpeg_hw_irq_is_frame_done(jpeg_irq_status)) {
257 /* send fe ping pong irq */
258 JPEG_DBG_HIGH("%s:%d] Session done\n", __func__, __LINE__);
259 data = msm_jpeg_core_fe_pingpong_irq(jpeg_irq_status,
260 pgmn_dev);
261 if (msm_jpeg_irq_handler)
262 msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_FE,
263 context, data);
264 data = msm_jpeg_core_framedone_irq(jpeg_irq_status,
265 pgmn_dev);
266 if (msm_jpeg_irq_handler)
267 msm_jpeg_irq_handler(
268 MSM_JPEG_HW_MASK_COMP_FRAMEDONE,
269 context, data);
270 pgmn_dev->state = MSM_JPEG_INIT;
271 }
272 if (msm_jpeg_hw_irq_is_reset_ack(jpeg_irq_status)) {
273 data = msm_jpeg_core_reset_ack_irq(jpeg_irq_status,
274 pgmn_dev);
275 spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
276 pgmn_dev->reset_done_ack = 1;
277 spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
278 wake_up(&pgmn_dev->reset_wait);
279 if (msm_jpeg_irq_handler)
280 msm_jpeg_irq_handler(
281 MSM_JPEG_HW_MASK_COMP_RESET_ACK,
282 context, data);
283 }
284
285 /* Unexpected/unintended HW interrupt */
286 if (msm_jpeg_hw_irq_is_err(jpeg_irq_status)) {
287 if (pgmn_dev->state != MSM_JPEG_EXECUTING) {
288 /*Clear all the bits and ignore the IRQ*/
289 JPEG_DBG_HIGH("%s %d ] Error IRQ received state %d",
290 __func__, __LINE__, pgmn_dev->state);
291 JPEG_DBG_HIGH("%s %d ] Ignoring the Error", __func__,
292 __LINE__);
293 msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
294 JPEG_IRQ_CLEAR_ALL, pgmn_dev->base);
295 } else {
296 if (pgmn_dev->decode_flag)
297 msm_jpeg_decode_status(pgmn_dev->base);
298 msm_jpeg_core_return_buffers(pgmn_dev, jpeg_irq_status);
299 data = msm_jpeg_core_err_irq(jpeg_irq_status, pgmn_dev);
300 if (msm_jpeg_irq_handler) {
301 msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_ERR,
302 context, data);
303 }
304 }
305 }
306
307 return IRQ_HANDLED;
308}
309
310irqreturn_t msm_jpegdma_core_irq(int irq_num, void *context)
311{
312 void *data = NULL;
313 unsigned long flags;
314 int jpeg_irq_status;
315 struct msm_jpeg_device *pgmn_dev = context;
316
317 JPEG_DBG("%s:%d] irq_num = %d\n", __func__, __LINE__, irq_num);
318
319 jpeg_irq_status = msm_jpegdma_hw_irq_get_status(pgmn_dev->base);
320
321 JPEG_DBG("%s:%d] jpeg_irq_status = %0x\n", __func__, __LINE__,
322 jpeg_irq_status);
323
324 /*For reset and framedone IRQs, clear all bits*/
325 if (pgmn_dev->state == MSM_JPEG_IDLE) {
326 JPEG_DBG_HIGH("%s %d ] Error IRQ received state %d",
327 __func__, __LINE__, pgmn_dev->state);
328 JPEG_DBG_HIGH("%s %d ] Ignoring the Error", __func__,
329 __LINE__);
330 msm_jpegdma_hw_irq_clear(JPEGDMA_IRQ_CLEAR_BMSK,
331 JPEGDMA_IRQ_CLEAR_ALL, pgmn_dev->base);
332 return IRQ_HANDLED;
333 } else if (jpeg_irq_status & 0x00000400) {
334 msm_jpegdma_hw_irq_clear(JPEGDMA_IRQ_CLEAR_BMSK,
335 JPEGDMA_IRQ_CLEAR_ALL, pgmn_dev->base);
336 } else if (jpeg_irq_status & 0x1) {
337 msm_jpegdma_hw_irq_clear(JPEGDMA_IRQ_CLEAR_BMSK,
338 JPEGDMA_IRQ_CLEAR_ALL, pgmn_dev->base);
339 } else {
340 msm_jpegdma_hw_irq_clear(JPEGDMA_IRQ_CLEAR_BMSK,
341 jpeg_irq_status, pgmn_dev->base);
342 }
343
344 if (msm_jpegdma_hw_irq_is_frame_done(jpeg_irq_status)) {
345 /* send fe ping pong irq */
346 JPEG_DBG_HIGH("%s:%d] Session done\n", __func__, __LINE__);
347 data = msm_jpeg_core_fe_pingpong_irq(jpeg_irq_status,
348 pgmn_dev);
349 if (msm_jpeg_irq_handler)
350 msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_FE,
351 context, data);
352 data = msm_jpeg_core_framedone_irq(jpeg_irq_status,
353 pgmn_dev);
354 if (msm_jpeg_irq_handler)
355 msm_jpeg_irq_handler(
356 MSM_JPEG_HW_MASK_COMP_FRAMEDONE,
357 context, data);
358 pgmn_dev->state = MSM_JPEG_INIT;
359 }
360 if (msm_jpegdma_hw_irq_is_reset_ack(jpeg_irq_status)) {
361 data = msm_jpeg_core_reset_ack_irq(jpeg_irq_status,
362 pgmn_dev);
363 spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
364 pgmn_dev->reset_done_ack = 1;
365 spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
366 wake_up(&pgmn_dev->reset_wait);
367 if (msm_jpeg_irq_handler)
368 msm_jpeg_irq_handler(
369 MSM_JPEG_HW_MASK_COMP_RESET_ACK,
370 context, data);
371 }
372
373 return IRQ_HANDLED;
374}
375
376void msm_jpeg_core_irq_install(int (*irq_handler) (int, void *, void *))
377{
378 msm_jpeg_irq_handler = irq_handler;
379}
380
381void msm_jpeg_core_irq_remove(void)
382{
383 msm_jpeg_irq_handler = NULL;
384}