diff options
author | Arun Kumar K <arun.kk@samsung.com> | 2012-10-03 21:19:08 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-10-05 21:53:37 -0400 |
commit | 43a1ea1f90382a6a8fcf5ed94835b8518ebdefc8 (patch) | |
tree | 69489808e3fdb9694540cb135f3d7aeaa0ad43f9 /drivers | |
parent | 77a788fc2d4089c64eb355a004f1f16b22eb3ab1 (diff) |
[media] s5p-mfc: Update MFCv5 driver for callback based architecture
Modifies the driver to use a callback based architecture
for hardware dependent calls. This architecture is suitable
for supporting co-existence with newer versions of MFC hardware.
Signed-off-by: Arun Kumar K <arun.kk@samsung.com>
Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
Acked-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
18 files changed, 852 insertions, 326 deletions
diff --git a/drivers/media/platform/s5p-mfc/Makefile b/drivers/media/platform/s5p-mfc/Makefile index 39496b806b11..cfb9ee9f543a 100644 --- a/drivers/media/platform/s5p-mfc/Makefile +++ b/drivers/media/platform/s5p-mfc/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o | 1 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o |
2 | s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o s5p_mfc_opr_v5.o | 2 | s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o s5p_mfc_opr.o |
3 | s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o | 3 | s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o |
4 | s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_cmd_v5.o | 4 | s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_cmd.o |
5 | s5p-mfc-y += s5p_mfc_pm.o | 5 | s5p-mfc-y += s5p_mfc_pm.o |
6 | s5p-mfc-y += s5p_mfc_opr_v5.o s5p_mfc_cmd_v5.o | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 74bb28482844..d711b0f7420b 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c | |||
@@ -22,13 +22,14 @@ | |||
22 | #include <media/v4l2-event.h> | 22 | #include <media/v4l2-event.h> |
23 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
24 | #include <media/videobuf2-core.h> | 24 | #include <media/videobuf2-core.h> |
25 | #include "regs-mfc.h" | 25 | #include "s5p_mfc_common.h" |
26 | #include "s5p_mfc_ctrl.h" | 26 | #include "s5p_mfc_ctrl.h" |
27 | #include "s5p_mfc_debug.h" | 27 | #include "s5p_mfc_debug.h" |
28 | #include "s5p_mfc_dec.h" | 28 | #include "s5p_mfc_dec.h" |
29 | #include "s5p_mfc_enc.h" | 29 | #include "s5p_mfc_enc.h" |
30 | #include "s5p_mfc_intr.h" | 30 | #include "s5p_mfc_intr.h" |
31 | #include "s5p_mfc_opr_v5.h" | 31 | #include "s5p_mfc_opr.h" |
32 | #include "s5p_mfc_cmd.h" | ||
32 | #include "s5p_mfc_pm.h" | 33 | #include "s5p_mfc_pm.h" |
33 | 34 | ||
34 | #define S5P_MFC_NAME "s5p-mfc" | 35 | #define S5P_MFC_NAME "s5p-mfc" |
@@ -148,10 +149,12 @@ static void s5p_mfc_watchdog_worker(struct work_struct *work) | |||
148 | if (!ctx) | 149 | if (!ctx) |
149 | continue; | 150 | continue; |
150 | ctx->state = MFCINST_ERROR; | 151 | ctx->state = MFCINST_ERROR; |
151 | s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst); | 152 | s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue, |
152 | s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src); | 153 | &ctx->vq_dst); |
154 | s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue, | ||
155 | &ctx->vq_src); | ||
153 | clear_work_bit(ctx); | 156 | clear_work_bit(ctx); |
154 | wake_up_ctx(ctx, S5P_FIMV_R2H_CMD_ERR_RET, 0); | 157 | wake_up_ctx(ctx, S5P_MFC_R2H_CMD_ERR_RET, 0); |
155 | } | 158 | } |
156 | clear_bit(0, &dev->hw_lock); | 159 | clear_bit(0, &dev->hw_lock); |
157 | spin_unlock_irqrestore(&dev->irqlock, flags); | 160 | spin_unlock_irqrestore(&dev->irqlock, flags); |
@@ -198,6 +201,7 @@ static void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev) | |||
198 | static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx) | 201 | static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx) |
199 | { | 202 | { |
200 | struct s5p_mfc_buf *dst_buf; | 203 | struct s5p_mfc_buf *dst_buf; |
204 | struct s5p_mfc_dev *dev = ctx->dev; | ||
201 | 205 | ||
202 | ctx->state = MFCINST_FINISHED; | 206 | ctx->state = MFCINST_FINISHED; |
203 | ctx->sequence++; | 207 | ctx->sequence++; |
@@ -212,8 +216,8 @@ static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx) | |||
212 | ctx->dst_queue_cnt--; | 216 | ctx->dst_queue_cnt--; |
213 | dst_buf->b->v4l2_buf.sequence = (ctx->sequence++); | 217 | dst_buf->b->v4l2_buf.sequence = (ctx->sequence++); |
214 | 218 | ||
215 | if (s5p_mfc_read_info_v5(ctx, PIC_TIME_TOP) == | 219 | if (s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_top, ctx) == |
216 | s5p_mfc_read_info_v5(ctx, PIC_TIME_BOT)) | 220 | s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_bot, ctx)) |
217 | dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE; | 221 | dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE; |
218 | else | 222 | else |
219 | dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED; | 223 | dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED; |
@@ -227,8 +231,11 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx) | |||
227 | { | 231 | { |
228 | struct s5p_mfc_dev *dev = ctx->dev; | 232 | struct s5p_mfc_dev *dev = ctx->dev; |
229 | struct s5p_mfc_buf *dst_buf, *src_buf; | 233 | struct s5p_mfc_buf *dst_buf, *src_buf; |
230 | size_t dec_y_addr = s5p_mfc_get_dec_y_adr(); | 234 | size_t dec_y_addr; |
231 | unsigned int frame_type = s5p_mfc_get_frame_type(); | 235 | unsigned int frame_type; |
236 | |||
237 | dec_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dec_y_adr, dev); | ||
238 | frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev); | ||
232 | 239 | ||
233 | /* Copy timestamp / timecode from decoded src to dst and set | 240 | /* Copy timestamp / timecode from decoded src to dst and set |
234 | appropraite flags */ | 241 | appropraite flags */ |
@@ -264,10 +271,13 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err) | |||
264 | { | 271 | { |
265 | struct s5p_mfc_dev *dev = ctx->dev; | 272 | struct s5p_mfc_dev *dev = ctx->dev; |
266 | struct s5p_mfc_buf *dst_buf; | 273 | struct s5p_mfc_buf *dst_buf; |
267 | size_t dspl_y_addr = s5p_mfc_get_dspl_y_adr(); | 274 | size_t dspl_y_addr; |
268 | unsigned int frame_type = s5p_mfc_get_frame_type(); | 275 | unsigned int frame_type; |
269 | unsigned int index; | 276 | unsigned int index; |
270 | 277 | ||
278 | dspl_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_y_adr, dev); | ||
279 | frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev); | ||
280 | |||
271 | /* If frame is same as previous then skip and do not dequeue */ | 281 | /* If frame is same as previous then skip and do not dequeue */ |
272 | if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) { | 282 | if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) { |
273 | if (!ctx->after_packed_pb) | 283 | if (!ctx->after_packed_pb) |
@@ -284,8 +294,10 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err) | |||
284 | list_del(&dst_buf->list); | 294 | list_del(&dst_buf->list); |
285 | ctx->dst_queue_cnt--; | 295 | ctx->dst_queue_cnt--; |
286 | dst_buf->b->v4l2_buf.sequence = ctx->sequence; | 296 | dst_buf->b->v4l2_buf.sequence = ctx->sequence; |
287 | if (s5p_mfc_read_info_v5(ctx, PIC_TIME_TOP) == | 297 | if (s5p_mfc_hw_call(dev->mfc_ops, |
288 | s5p_mfc_read_info_v5(ctx, PIC_TIME_BOT)) | 298 | get_pic_type_top, ctx) == |
299 | s5p_mfc_hw_call(dev->mfc_ops, | ||
300 | get_pic_type_bot, ctx)) | ||
289 | dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE; | 301 | dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE; |
290 | else | 302 | else |
291 | dst_buf->b->v4l2_buf.field = | 303 | dst_buf->b->v4l2_buf.field = |
@@ -316,21 +328,21 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, | |||
316 | 328 | ||
317 | unsigned int index; | 329 | unsigned int index; |
318 | 330 | ||
319 | dst_frame_status = s5p_mfc_get_dspl_status() | 331 | dst_frame_status = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev) |
320 | & S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK; | 332 | & S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK; |
321 | res_change = s5p_mfc_get_dspl_status() | 333 | res_change = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev) |
322 | & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK; | 334 | & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK; |
323 | mfc_debug(2, "Frame Status: %x\n", dst_frame_status); | 335 | mfc_debug(2, "Frame Status: %x\n", dst_frame_status); |
324 | if (ctx->state == MFCINST_RES_CHANGE_INIT) | 336 | if (ctx->state == MFCINST_RES_CHANGE_INIT) |
325 | ctx->state = MFCINST_RES_CHANGE_FLUSH; | 337 | ctx->state = MFCINST_RES_CHANGE_FLUSH; |
326 | if (res_change) { | 338 | if (res_change) { |
327 | ctx->state = MFCINST_RES_CHANGE_INIT; | 339 | ctx->state = MFCINST_RES_CHANGE_INIT; |
328 | s5p_mfc_clear_int_flags(dev); | 340 | s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); |
329 | wake_up_ctx(ctx, reason, err); | 341 | wake_up_ctx(ctx, reason, err); |
330 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 342 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) |
331 | BUG(); | 343 | BUG(); |
332 | s5p_mfc_clock_off(); | 344 | s5p_mfc_clock_off(); |
333 | s5p_mfc_try_run(dev); | 345 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
334 | return; | 346 | return; |
335 | } | 347 | } |
336 | if (ctx->dpb_flush_flag) | 348 | if (ctx->dpb_flush_flag) |
@@ -364,9 +376,12 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, | |||
364 | && !list_empty(&ctx->src_queue)) { | 376 | && !list_empty(&ctx->src_queue)) { |
365 | src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, | 377 | src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, |
366 | list); | 378 | list); |
367 | ctx->consumed_stream += s5p_mfc_get_consumed_stream(); | 379 | ctx->consumed_stream += s5p_mfc_hw_call(dev->mfc_ops, |
368 | if (ctx->codec_mode != S5P_FIMV_CODEC_H264_DEC && | 380 | get_consumed_stream, dev); |
369 | s5p_mfc_get_frame_type() == S5P_FIMV_DECODE_FRAME_P_FRAME | 381 | if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC && |
382 | s5p_mfc_hw_call(dev->mfc_ops, | ||
383 | get_dec_frame_type, dev) == | ||
384 | S5P_FIMV_DECODE_FRAME_P_FRAME | ||
370 | && ctx->consumed_stream + STUFF_BYTE < | 385 | && ctx->consumed_stream + STUFF_BYTE < |
371 | src_buf->b->v4l2_planes[0].bytesused) { | 386 | src_buf->b->v4l2_planes[0].bytesused) { |
372 | /* Run MFC again on the same buffer */ | 387 | /* Run MFC again on the same buffer */ |
@@ -378,7 +393,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, | |||
378 | ctx->consumed_stream = 0; | 393 | ctx->consumed_stream = 0; |
379 | list_del(&src_buf->list); | 394 | list_del(&src_buf->list); |
380 | ctx->src_queue_cnt--; | 395 | ctx->src_queue_cnt--; |
381 | if (s5p_mfc_err_dec(err) > 0) | 396 | if (s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) > 0) |
382 | vb2_buffer_done(src_buf->b, VB2_BUF_STATE_ERROR); | 397 | vb2_buffer_done(src_buf->b, VB2_BUF_STATE_ERROR); |
383 | else | 398 | else |
384 | vb2_buffer_done(src_buf->b, VB2_BUF_STATE_DONE); | 399 | vb2_buffer_done(src_buf->b, VB2_BUF_STATE_DONE); |
@@ -389,12 +404,12 @@ leave_handle_frame: | |||
389 | if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING) | 404 | if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING) |
390 | || ctx->dst_queue_cnt < ctx->dpb_count) | 405 | || ctx->dst_queue_cnt < ctx->dpb_count) |
391 | clear_work_bit(ctx); | 406 | clear_work_bit(ctx); |
392 | s5p_mfc_clear_int_flags(dev); | 407 | s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); |
393 | wake_up_ctx(ctx, reason, err); | 408 | wake_up_ctx(ctx, reason, err); |
394 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 409 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) |
395 | BUG(); | 410 | BUG(); |
396 | s5p_mfc_clock_off(); | 411 | s5p_mfc_clock_off(); |
397 | s5p_mfc_try_run(dev); | 412 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
398 | } | 413 | } |
399 | 414 | ||
400 | /* Error handling for interrupt */ | 415 | /* Error handling for interrupt */ |
@@ -411,7 +426,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx, | |||
411 | 426 | ||
412 | dev = ctx->dev; | 427 | dev = ctx->dev; |
413 | mfc_err("Interrupt Error: %08x\n", err); | 428 | mfc_err("Interrupt Error: %08x\n", err); |
414 | s5p_mfc_clear_int_flags(dev); | 429 | s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); |
415 | wake_up_dev(dev, reason, err); | 430 | wake_up_dev(dev, reason, err); |
416 | 431 | ||
417 | /* Error recovery is dependent on the state of context */ | 432 | /* Error recovery is dependent on the state of context */ |
@@ -440,9 +455,11 @@ static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx, | |||
440 | ctx->state = MFCINST_ERROR; | 455 | ctx->state = MFCINST_ERROR; |
441 | /* Mark all dst buffers as having an error */ | 456 | /* Mark all dst buffers as having an error */ |
442 | spin_lock_irqsave(&dev->irqlock, flags); | 457 | spin_lock_irqsave(&dev->irqlock, flags); |
443 | s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst); | 458 | s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue, |
459 | &ctx->vq_dst); | ||
444 | /* Mark all src buffers as having an error */ | 460 | /* Mark all src buffers as having an error */ |
445 | s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src); | 461 | s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue, |
462 | &ctx->vq_src); | ||
446 | spin_unlock_irqrestore(&dev->irqlock, flags); | 463 | spin_unlock_irqrestore(&dev->irqlock, flags); |
447 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 464 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) |
448 | BUG(); | 465 | BUG(); |
@@ -469,8 +486,10 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, | |||
469 | if (ctx->c_ops->post_seq_start(ctx)) | 486 | if (ctx->c_ops->post_seq_start(ctx)) |
470 | mfc_err("post_seq_start() failed\n"); | 487 | mfc_err("post_seq_start() failed\n"); |
471 | } else { | 488 | } else { |
472 | ctx->img_width = s5p_mfc_get_img_width(); | 489 | ctx->img_width = s5p_mfc_hw_call(dev->mfc_ops, get_img_width, |
473 | ctx->img_height = s5p_mfc_get_img_height(); | 490 | dev); |
491 | ctx->img_height = s5p_mfc_hw_call(dev->mfc_ops, get_img_height, | ||
492 | dev); | ||
474 | 493 | ||
475 | ctx->buf_width = ALIGN(ctx->img_width, | 494 | ctx->buf_width = ALIGN(ctx->img_width, |
476 | S5P_FIMV_NV12MT_HALIGN); | 495 | S5P_FIMV_NV12MT_HALIGN); |
@@ -506,18 +525,19 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, | |||
506 | guard_height, S5P_FIMV_DEC_BUF_ALIGN); | 525 | guard_height, S5P_FIMV_DEC_BUF_ALIGN); |
507 | ctx->mv_size = 0; | 526 | ctx->mv_size = 0; |
508 | } | 527 | } |
509 | ctx->dpb_count = s5p_mfc_get_dpb_count(); | 528 | ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count, |
529 | dev); | ||
510 | if (ctx->img_width == 0 || ctx->img_height == 0) | 530 | if (ctx->img_width == 0 || ctx->img_height == 0) |
511 | ctx->state = MFCINST_ERROR; | 531 | ctx->state = MFCINST_ERROR; |
512 | else | 532 | else |
513 | ctx->state = MFCINST_HEAD_PARSED; | 533 | ctx->state = MFCINST_HEAD_PARSED; |
514 | } | 534 | } |
515 | s5p_mfc_clear_int_flags(dev); | 535 | s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); |
516 | clear_work_bit(ctx); | 536 | clear_work_bit(ctx); |
517 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 537 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) |
518 | BUG(); | 538 | BUG(); |
519 | s5p_mfc_clock_off(); | 539 | s5p_mfc_clock_off(); |
520 | s5p_mfc_try_run(dev); | 540 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
521 | wake_up_ctx(ctx, reason, err); | 541 | wake_up_ctx(ctx, reason, err); |
522 | } | 542 | } |
523 | 543 | ||
@@ -532,7 +552,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx, | |||
532 | if (ctx == NULL) | 552 | if (ctx == NULL) |
533 | return; | 553 | return; |
534 | dev = ctx->dev; | 554 | dev = ctx->dev; |
535 | s5p_mfc_clear_int_flags(dev); | 555 | s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); |
536 | ctx->int_type = reason; | 556 | ctx->int_type = reason; |
537 | ctx->int_err = err; | 557 | ctx->int_err = err; |
538 | ctx->int_cond = 1; | 558 | ctx->int_cond = 1; |
@@ -559,7 +579,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx, | |||
559 | s5p_mfc_clock_off(); | 579 | s5p_mfc_clock_off(); |
560 | 580 | ||
561 | wake_up(&ctx->queue); | 581 | wake_up(&ctx->queue); |
562 | s5p_mfc_try_run(dev); | 582 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
563 | } else { | 583 | } else { |
564 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 584 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) |
565 | BUG(); | 585 | BUG(); |
@@ -601,7 +621,7 @@ static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx, | |||
601 | 621 | ||
602 | s5p_mfc_clock_off(); | 622 | s5p_mfc_clock_off(); |
603 | wake_up(&ctx->queue); | 623 | wake_up(&ctx->queue); |
604 | s5p_mfc_try_run(dev); | 624 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
605 | } | 625 | } |
606 | 626 | ||
607 | /* Interrupt processing */ | 627 | /* Interrupt processing */ |
@@ -617,81 +637,83 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv) | |||
617 | atomic_set(&dev->watchdog_cnt, 0); | 637 | atomic_set(&dev->watchdog_cnt, 0); |
618 | ctx = dev->ctx[dev->curr_ctx]; | 638 | ctx = dev->ctx[dev->curr_ctx]; |
619 | /* Get the reason of interrupt and the error code */ | 639 | /* Get the reason of interrupt and the error code */ |
620 | reason = s5p_mfc_get_int_reason(); | 640 | reason = s5p_mfc_hw_call(dev->mfc_ops, get_int_reason, dev); |
621 | err = s5p_mfc_get_int_err(); | 641 | err = s5p_mfc_hw_call(dev->mfc_ops, get_int_err, dev); |
622 | mfc_debug(1, "Int reason: %d (err: %08x)\n", reason, err); | 642 | mfc_debug(1, "Int reason: %d (err: %08x)\n", reason, err); |
623 | switch (reason) { | 643 | switch (reason) { |
624 | case S5P_FIMV_R2H_CMD_ERR_RET: | 644 | case S5P_MFC_R2H_CMD_ERR_RET: |
625 | /* An error has occured */ | 645 | /* An error has occured */ |
626 | if (ctx->state == MFCINST_RUNNING && | 646 | if (ctx->state == MFCINST_RUNNING && |
627 | s5p_mfc_err_dec(err) >= S5P_FIMV_ERR_WARNINGS_START) | 647 | s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) >= |
648 | dev->warn_start) | ||
628 | s5p_mfc_handle_frame(ctx, reason, err); | 649 | s5p_mfc_handle_frame(ctx, reason, err); |
629 | else | 650 | else |
630 | s5p_mfc_handle_error(ctx, reason, err); | 651 | s5p_mfc_handle_error(ctx, reason, err); |
631 | clear_bit(0, &dev->enter_suspend); | 652 | clear_bit(0, &dev->enter_suspend); |
632 | break; | 653 | break; |
633 | 654 | ||
634 | case S5P_FIMV_R2H_CMD_SLICE_DONE_RET: | 655 | case S5P_MFC_R2H_CMD_SLICE_DONE_RET: |
635 | case S5P_FIMV_R2H_CMD_FRAME_DONE_RET: | 656 | case S5P_MFC_R2H_CMD_FIELD_DONE_RET: |
657 | case S5P_MFC_R2H_CMD_FRAME_DONE_RET: | ||
636 | if (ctx->c_ops->post_frame_start) { | 658 | if (ctx->c_ops->post_frame_start) { |
637 | if (ctx->c_ops->post_frame_start(ctx)) | 659 | if (ctx->c_ops->post_frame_start(ctx)) |
638 | mfc_err("post_frame_start() failed\n"); | 660 | mfc_err("post_frame_start() failed\n"); |
639 | s5p_mfc_clear_int_flags(dev); | 661 | s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); |
640 | wake_up_ctx(ctx, reason, err); | 662 | wake_up_ctx(ctx, reason, err); |
641 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 663 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) |
642 | BUG(); | 664 | BUG(); |
643 | s5p_mfc_clock_off(); | 665 | s5p_mfc_clock_off(); |
644 | s5p_mfc_try_run(dev); | 666 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
645 | } else { | 667 | } else { |
646 | s5p_mfc_handle_frame(ctx, reason, err); | 668 | s5p_mfc_handle_frame(ctx, reason, err); |
647 | } | 669 | } |
648 | break; | 670 | break; |
649 | 671 | ||
650 | case S5P_FIMV_R2H_CMD_SEQ_DONE_RET: | 672 | case S5P_MFC_R2H_CMD_SEQ_DONE_RET: |
651 | s5p_mfc_handle_seq_done(ctx, reason, err); | 673 | s5p_mfc_handle_seq_done(ctx, reason, err); |
652 | break; | 674 | break; |
653 | 675 | ||
654 | case S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET: | 676 | case S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET: |
655 | ctx->inst_no = s5p_mfc_get_inst_no(); | 677 | ctx->inst_no = s5p_mfc_hw_call(dev->mfc_ops, get_inst_no, dev); |
656 | ctx->state = MFCINST_GOT_INST; | 678 | ctx->state = MFCINST_GOT_INST; |
657 | clear_work_bit(ctx); | 679 | clear_work_bit(ctx); |
658 | wake_up(&ctx->queue); | 680 | wake_up(&ctx->queue); |
659 | goto irq_cleanup_hw; | 681 | goto irq_cleanup_hw; |
660 | 682 | ||
661 | case S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET: | 683 | case S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET: |
662 | clear_work_bit(ctx); | 684 | clear_work_bit(ctx); |
663 | ctx->state = MFCINST_FREE; | 685 | ctx->state = MFCINST_FREE; |
664 | wake_up(&ctx->queue); | 686 | wake_up(&ctx->queue); |
665 | goto irq_cleanup_hw; | 687 | goto irq_cleanup_hw; |
666 | 688 | ||
667 | case S5P_FIMV_R2H_CMD_SYS_INIT_RET: | 689 | case S5P_MFC_R2H_CMD_SYS_INIT_RET: |
668 | case S5P_FIMV_R2H_CMD_FW_STATUS_RET: | 690 | case S5P_MFC_R2H_CMD_FW_STATUS_RET: |
669 | case S5P_FIMV_R2H_CMD_SLEEP_RET: | 691 | case S5P_MFC_R2H_CMD_SLEEP_RET: |
670 | case S5P_FIMV_R2H_CMD_WAKEUP_RET: | 692 | case S5P_MFC_R2H_CMD_WAKEUP_RET: |
671 | if (ctx) | 693 | if (ctx) |
672 | clear_work_bit(ctx); | 694 | clear_work_bit(ctx); |
673 | s5p_mfc_clear_int_flags(dev); | 695 | s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); |
674 | wake_up_dev(dev, reason, err); | 696 | wake_up_dev(dev, reason, err); |
675 | clear_bit(0, &dev->hw_lock); | 697 | clear_bit(0, &dev->hw_lock); |
676 | clear_bit(0, &dev->enter_suspend); | 698 | clear_bit(0, &dev->enter_suspend); |
677 | break; | 699 | break; |
678 | 700 | ||
679 | case S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET: | 701 | case S5P_MFC_R2H_CMD_INIT_BUFFERS_RET: |
680 | s5p_mfc_handle_init_buffers(ctx, reason, err); | 702 | s5p_mfc_handle_init_buffers(ctx, reason, err); |
681 | break; | 703 | break; |
682 | 704 | ||
683 | case S5P_FIMV_R2H_CMD_ENC_COMPLETE_RET: | 705 | case S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET: |
684 | s5p_mfc_handle_stream_complete(ctx, reason, err); | 706 | s5p_mfc_handle_stream_complete(ctx, reason, err); |
685 | break; | 707 | break; |
686 | 708 | ||
687 | default: | 709 | default: |
688 | mfc_debug(2, "Unknown int reason\n"); | 710 | mfc_debug(2, "Unknown int reason\n"); |
689 | s5p_mfc_clear_int_flags(dev); | 711 | s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); |
690 | } | 712 | } |
691 | mfc_debug_leave(); | 713 | mfc_debug_leave(); |
692 | return IRQ_HANDLED; | 714 | return IRQ_HANDLED; |
693 | irq_cleanup_hw: | 715 | irq_cleanup_hw: |
694 | s5p_mfc_clear_int_flags(dev); | 716 | s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); |
695 | ctx->int_type = reason; | 717 | ctx->int_type = reason; |
696 | ctx->int_err = err; | 718 | ctx->int_err = err; |
697 | ctx->int_cond = 1; | 719 | ctx->int_cond = 1; |
@@ -700,7 +722,7 @@ irq_cleanup_hw: | |||
700 | 722 | ||
701 | s5p_mfc_clock_off(); | 723 | s5p_mfc_clock_off(); |
702 | 724 | ||
703 | s5p_mfc_try_run(dev); | 725 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
704 | mfc_debug(2, "Exit via irq_cleanup_hw\n"); | 726 | mfc_debug(2, "Exit via irq_cleanup_hw\n"); |
705 | return IRQ_HANDLED; | 727 | return IRQ_HANDLED; |
706 | } | 728 | } |
@@ -748,6 +770,7 @@ static int s5p_mfc_open(struct file *file) | |||
748 | if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) { | 770 | if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) { |
749 | ctx->type = MFCINST_DECODER; | 771 | ctx->type = MFCINST_DECODER; |
750 | ctx->c_ops = get_dec_codec_ops(); | 772 | ctx->c_ops = get_dec_codec_ops(); |
773 | s5p_mfc_dec_init(ctx); | ||
751 | /* Setup ctrl handler */ | 774 | /* Setup ctrl handler */ |
752 | ret = s5p_mfc_dec_ctrls_setup(ctx); | 775 | ret = s5p_mfc_dec_ctrls_setup(ctx); |
753 | if (ret) { | 776 | if (ret) { |
@@ -760,6 +783,7 @@ static int s5p_mfc_open(struct file *file) | |||
760 | /* only for encoder */ | 783 | /* only for encoder */ |
761 | INIT_LIST_HEAD(&ctx->ref_queue); | 784 | INIT_LIST_HEAD(&ctx->ref_queue); |
762 | ctx->ref_queue_cnt = 0; | 785 | ctx->ref_queue_cnt = 0; |
786 | s5p_mfc_enc_init(ctx); | ||
763 | /* Setup ctrl handler */ | 787 | /* Setup ctrl handler */ |
764 | ret = s5p_mfc_enc_ctrls_setup(ctx); | 788 | ret = s5p_mfc_enc_ctrls_setup(ctx); |
765 | if (ret) { | 789 | if (ret) { |
@@ -885,19 +909,20 @@ static int s5p_mfc_release(struct file *file) | |||
885 | ctx->state = MFCINST_RETURN_INST; | 909 | ctx->state = MFCINST_RETURN_INST; |
886 | set_work_bit_irqsave(ctx); | 910 | set_work_bit_irqsave(ctx); |
887 | s5p_mfc_clean_ctx_int_flags(ctx); | 911 | s5p_mfc_clean_ctx_int_flags(ctx); |
888 | s5p_mfc_try_run(dev); | 912 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
889 | /* Wait until instance is returned or timeout occured */ | 913 | /* Wait until instance is returned or timeout occured */ |
890 | if (s5p_mfc_wait_for_done_ctx | 914 | if (s5p_mfc_wait_for_done_ctx |
891 | (ctx, S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET, 0)) { | 915 | (ctx, S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)) { |
892 | s5p_mfc_clock_off(); | 916 | s5p_mfc_clock_off(); |
893 | mfc_err("Err returning instance\n"); | 917 | mfc_err("Err returning instance\n"); |
894 | } | 918 | } |
895 | mfc_debug(2, "After free instance\n"); | 919 | mfc_debug(2, "After free instance\n"); |
896 | /* Free resources */ | 920 | /* Free resources */ |
897 | s5p_mfc_release_codec_buffers(ctx); | 921 | s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx); |
898 | s5p_mfc_release_instance_buffer(ctx); | 922 | s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx); |
899 | if (ctx->type == MFCINST_DECODER) | 923 | if (ctx->type == MFCINST_DECODER) |
900 | s5p_mfc_release_dec_desc_buffer(ctx); | 924 | s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer, |
925 | ctx); | ||
901 | 926 | ||
902 | ctx->inst_no = MFC_NO_INSTANCE_SET; | 927 | ctx->inst_no = MFC_NO_INSTANCE_SET; |
903 | } | 928 | } |
@@ -909,6 +934,7 @@ static int s5p_mfc_release(struct file *file) | |||
909 | mfc_debug(2, "Last instance - release firmware\n"); | 934 | mfc_debug(2, "Last instance - release firmware\n"); |
910 | /* reset <-> F/W release */ | 935 | /* reset <-> F/W release */ |
911 | s5p_mfc_reset(dev); | 936 | s5p_mfc_reset(dev); |
937 | s5p_mfc_deinit_hw(dev); | ||
912 | s5p_mfc_release_firmware(dev); | 938 | s5p_mfc_release_firmware(dev); |
913 | del_timer_sync(&dev->watchdog_timer); | 939 | del_timer_sync(&dev->watchdog_timer); |
914 | if (s5p_mfc_power_off() < 0) | 940 | if (s5p_mfc_power_off() < 0) |
@@ -1159,6 +1185,10 @@ static int s5p_mfc_probe(struct platform_device *pdev) | |||
1159 | dev->watchdog_timer.data = (unsigned long)dev; | 1185 | dev->watchdog_timer.data = (unsigned long)dev; |
1160 | dev->watchdog_timer.function = s5p_mfc_watchdog; | 1186 | dev->watchdog_timer.function = s5p_mfc_watchdog; |
1161 | 1187 | ||
1188 | /* Initialize HW ops and commands based on MFC version */ | ||
1189 | s5p_mfc_init_hw_ops(dev); | ||
1190 | s5p_mfc_init_hw_cmds(dev); | ||
1191 | |||
1162 | pr_debug("%s--\n", __func__); | 1192 | pr_debug("%s--\n", __func__); |
1163 | return 0; | 1193 | return 0; |
1164 | 1194 | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c new file mode 100644 index 000000000000..8ea304be7e68 --- /dev/null +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c | ||
3 | * | ||
4 | * Copyright (C) 2012 Samsung Electronics Co., Ltd. | ||
5 | * http://www.samsung.com/ | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include "s5p_mfc_cmd.h" | ||
14 | #include "s5p_mfc_common.h" | ||
15 | #include "s5p_mfc_debug.h" | ||
16 | #include "s5p_mfc_cmd_v5.h" | ||
17 | |||
18 | static struct s5p_mfc_hw_cmds *s5p_mfc_cmds; | ||
19 | |||
20 | void s5p_mfc_init_hw_cmds(struct s5p_mfc_dev *dev) | ||
21 | { | ||
22 | s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v5(); | ||
23 | dev->mfc_cmds = s5p_mfc_cmds; | ||
24 | } | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h new file mode 100644 index 000000000000..282e6c780702 --- /dev/null +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h | ||
3 | * | ||
4 | * Copyright (C) 2012 Samsung Electronics Co., Ltd. | ||
5 | * http://www.samsung.com/ | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef S5P_MFC_CMD_H_ | ||
14 | #define S5P_MFC_CMD_H_ | ||
15 | |||
16 | #include "s5p_mfc_common.h" | ||
17 | |||
18 | #define MAX_H2R_ARG 4 | ||
19 | |||
20 | struct s5p_mfc_cmd_args { | ||
21 | unsigned int arg[MAX_H2R_ARG]; | ||
22 | }; | ||
23 | |||
24 | struct s5p_mfc_hw_cmds { | ||
25 | int (*cmd_host2risc)(struct s5p_mfc_dev *dev, int cmd, | ||
26 | struct s5p_mfc_cmd_args *args); | ||
27 | int (*sys_init_cmd)(struct s5p_mfc_dev *dev); | ||
28 | int (*sleep_cmd)(struct s5p_mfc_dev *dev); | ||
29 | int (*wakeup_cmd)(struct s5p_mfc_dev *dev); | ||
30 | int (*open_inst_cmd)(struct s5p_mfc_ctx *ctx); | ||
31 | int (*close_inst_cmd)(struct s5p_mfc_ctx *ctx); | ||
32 | }; | ||
33 | |||
34 | void s5p_mfc_init_hw_cmds(struct s5p_mfc_dev *dev); | ||
35 | #endif /* S5P_MFC_CMD_H_ */ | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c index cdd02b9295c1..e4eb9569ba15 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c | 2 | * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * http://www.samsung.com/ | 5 | * http://www.samsung.com/ |
@@ -11,13 +11,13 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "regs-mfc.h" | 13 | #include "regs-mfc.h" |
14 | #include "s5p_mfc_cmd_v5.h" | 14 | #include "s5p_mfc_cmd.h" |
15 | #include "s5p_mfc_common.h" | 15 | #include "s5p_mfc_common.h" |
16 | #include "s5p_mfc_debug.h" | 16 | #include "s5p_mfc_debug.h" |
17 | 17 | ||
18 | /* This function is used to send a command to the MFC */ | 18 | /* This function is used to send a command to the MFC */ |
19 | static int s5p_mfc_cmd_host2risc(struct s5p_mfc_dev *dev, int cmd, | 19 | int s5p_mfc_cmd_host2risc_v5(struct s5p_mfc_dev *dev, int cmd, |
20 | struct s5p_mfc_cmd_args *args) | 20 | struct s5p_mfc_cmd_args *args) |
21 | { | 21 | { |
22 | int cur_cmd; | 22 | int cur_cmd; |
23 | unsigned long timeout; | 23 | unsigned long timeout; |
@@ -41,35 +41,37 @@ static int s5p_mfc_cmd_host2risc(struct s5p_mfc_dev *dev, int cmd, | |||
41 | } | 41 | } |
42 | 42 | ||
43 | /* Initialize the MFC */ | 43 | /* Initialize the MFC */ |
44 | int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev) | 44 | int s5p_mfc_sys_init_cmd_v5(struct s5p_mfc_dev *dev) |
45 | { | 45 | { |
46 | struct s5p_mfc_cmd_args h2r_args; | 46 | struct s5p_mfc_cmd_args h2r_args; |
47 | 47 | ||
48 | memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); | 48 | memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); |
49 | h2r_args.arg[0] = dev->fw_size; | 49 | h2r_args.arg[0] = dev->fw_size; |
50 | return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SYS_INIT, &h2r_args); | 50 | return s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_SYS_INIT, |
51 | &h2r_args); | ||
51 | } | 52 | } |
52 | 53 | ||
53 | /* Suspend the MFC hardware */ | 54 | /* Suspend the MFC hardware */ |
54 | int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev) | 55 | int s5p_mfc_sleep_cmd_v5(struct s5p_mfc_dev *dev) |
55 | { | 56 | { |
56 | struct s5p_mfc_cmd_args h2r_args; | 57 | struct s5p_mfc_cmd_args h2r_args; |
57 | 58 | ||
58 | memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); | 59 | memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); |
59 | return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SLEEP, &h2r_args); | 60 | return s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_SLEEP, &h2r_args); |
60 | } | 61 | } |
61 | 62 | ||
62 | /* Wake up the MFC hardware */ | 63 | /* Wake up the MFC hardware */ |
63 | int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev) | 64 | int s5p_mfc_wakeup_cmd_v5(struct s5p_mfc_dev *dev) |
64 | { | 65 | { |
65 | struct s5p_mfc_cmd_args h2r_args; | 66 | struct s5p_mfc_cmd_args h2r_args; |
66 | 67 | ||
67 | memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); | 68 | memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); |
68 | return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_WAKEUP, &h2r_args); | 69 | return s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_WAKEUP, |
70 | &h2r_args); | ||
69 | } | 71 | } |
70 | 72 | ||
71 | 73 | ||
72 | int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx) | 74 | int s5p_mfc_open_inst_cmd_v5(struct s5p_mfc_ctx *ctx) |
73 | { | 75 | { |
74 | struct s5p_mfc_dev *dev = ctx->dev; | 76 | struct s5p_mfc_dev *dev = ctx->dev; |
75 | struct s5p_mfc_cmd_args h2r_args; | 77 | struct s5p_mfc_cmd_args h2r_args; |
@@ -79,11 +81,41 @@ int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx) | |||
79 | mfc_debug(2, "Getting instance number (codec: %d)\n", ctx->codec_mode); | 81 | mfc_debug(2, "Getting instance number (codec: %d)\n", ctx->codec_mode); |
80 | dev->curr_ctx = ctx->num; | 82 | dev->curr_ctx = ctx->num; |
81 | memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); | 83 | memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); |
82 | h2r_args.arg[0] = ctx->codec_mode; | 84 | switch (ctx->codec_mode) { |
85 | case S5P_MFC_CODEC_H264_DEC: | ||
86 | h2r_args.arg[0] = S5P_FIMV_CODEC_H264_DEC; | ||
87 | break; | ||
88 | case S5P_MFC_CODEC_VC1_DEC: | ||
89 | h2r_args.arg[0] = S5P_FIMV_CODEC_VC1_DEC; | ||
90 | break; | ||
91 | case S5P_MFC_CODEC_MPEG4_DEC: | ||
92 | h2r_args.arg[0] = S5P_FIMV_CODEC_MPEG4_DEC; | ||
93 | break; | ||
94 | case S5P_MFC_CODEC_MPEG2_DEC: | ||
95 | h2r_args.arg[0] = S5P_FIMV_CODEC_MPEG2_DEC; | ||
96 | break; | ||
97 | case S5P_MFC_CODEC_H263_DEC: | ||
98 | h2r_args.arg[0] = S5P_FIMV_CODEC_H263_DEC; | ||
99 | break; | ||
100 | case S5P_MFC_CODEC_VC1RCV_DEC: | ||
101 | h2r_args.arg[0] = S5P_FIMV_CODEC_VC1RCV_DEC; | ||
102 | break; | ||
103 | case S5P_MFC_CODEC_H264_ENC: | ||
104 | h2r_args.arg[0] = S5P_FIMV_CODEC_H264_ENC; | ||
105 | break; | ||
106 | case S5P_MFC_CODEC_MPEG4_ENC: | ||
107 | h2r_args.arg[0] = S5P_FIMV_CODEC_MPEG4_ENC; | ||
108 | break; | ||
109 | case S5P_MFC_CODEC_H263_ENC: | ||
110 | h2r_args.arg[0] = S5P_FIMV_CODEC_H263_ENC; | ||
111 | break; | ||
112 | default: | ||
113 | h2r_args.arg[0] = S5P_FIMV_CODEC_NONE; | ||
114 | }; | ||
83 | h2r_args.arg[1] = 0; /* no crc & no pixelcache */ | 115 | h2r_args.arg[1] = 0; /* no crc & no pixelcache */ |
84 | h2r_args.arg[2] = ctx->ctx_ofs; | 116 | h2r_args.arg[2] = ctx->ctx_ofs; |
85 | h2r_args.arg[3] = ctx->ctx_size; | 117 | h2r_args.arg[3] = ctx->ctx_size; |
86 | ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE, | 118 | ret = s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE, |
87 | &h2r_args); | 119 | &h2r_args); |
88 | if (ret) { | 120 | if (ret) { |
89 | mfc_err("Failed to create a new instance\n"); | 121 | mfc_err("Failed to create a new instance\n"); |
@@ -92,7 +124,7 @@ int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx) | |||
92 | return ret; | 124 | return ret; |
93 | } | 125 | } |
94 | 126 | ||
95 | int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx) | 127 | int s5p_mfc_close_inst_cmd_v5(struct s5p_mfc_ctx *ctx) |
96 | { | 128 | { |
97 | struct s5p_mfc_dev *dev = ctx->dev; | 129 | struct s5p_mfc_dev *dev = ctx->dev; |
98 | struct s5p_mfc_cmd_args h2r_args; | 130 | struct s5p_mfc_cmd_args h2r_args; |
@@ -108,7 +140,7 @@ int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx) | |||
108 | dev->curr_ctx = ctx->num; | 140 | dev->curr_ctx = ctx->num; |
109 | memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); | 141 | memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); |
110 | h2r_args.arg[0] = ctx->inst_no; | 142 | h2r_args.arg[0] = ctx->inst_no; |
111 | ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_CLOSE_INSTANCE, | 143 | ret = s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_CLOSE_INSTANCE, |
112 | &h2r_args); | 144 | &h2r_args); |
113 | if (ret) { | 145 | if (ret) { |
114 | mfc_err("Failed to return an instance\n"); | 146 | mfc_err("Failed to return an instance\n"); |
@@ -118,3 +150,17 @@ int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx) | |||
118 | return 0; | 150 | return 0; |
119 | } | 151 | } |
120 | 152 | ||
153 | /* Initialize cmd function pointers for MFC v5 */ | ||
154 | static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v5 = { | ||
155 | .cmd_host2risc = s5p_mfc_cmd_host2risc_v5, | ||
156 | .sys_init_cmd = s5p_mfc_sys_init_cmd_v5, | ||
157 | .sleep_cmd = s5p_mfc_sleep_cmd_v5, | ||
158 | .wakeup_cmd = s5p_mfc_wakeup_cmd_v5, | ||
159 | .open_inst_cmd = s5p_mfc_open_inst_cmd_v5, | ||
160 | .close_inst_cmd = s5p_mfc_close_inst_cmd_v5, | ||
161 | }; | ||
162 | |||
163 | struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void) | ||
164 | { | ||
165 | return &s5p_mfc_cmds_v5; | ||
166 | } | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h index 8b090d3723e7..6928a5514c1b 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h | 2 | * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * http://www.samsung.com/ | 5 | * http://www.samsung.com/ |
@@ -10,21 +10,11 @@ | |||
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifndef S5P_MFC_CMD_H_ | 13 | #ifndef S5P_MFC_CMD_V5_H_ |
14 | #define S5P_MFC_CMD_H_ | 14 | #define S5P_MFC_CMD_V5_H_ |
15 | 15 | ||
16 | #include "s5p_mfc_common.h" | 16 | #include "s5p_mfc_common.h" |
17 | 17 | ||
18 | #define MAX_H2R_ARG 4 | 18 | struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void); |
19 | |||
20 | struct s5p_mfc_cmd_args { | ||
21 | unsigned int arg[MAX_H2R_ARG]; | ||
22 | }; | ||
23 | |||
24 | int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev); | ||
25 | int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev); | ||
26 | int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev); | ||
27 | int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx); | ||
28 | int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx); | ||
29 | 19 | ||
30 | #endif /* S5P_MFC_CMD_H_ */ | 20 | #endif /* S5P_MFC_CMD_H_ */ |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 519b0d66d8d1..82931d471d5e 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h | |||
@@ -74,7 +74,40 @@ static inline dma_addr_t s5p_mfc_mem_cookie(void *a, void *b) | |||
74 | #define MFC_ENC_CAP_PLANE_COUNT 1 | 74 | #define MFC_ENC_CAP_PLANE_COUNT 1 |
75 | #define MFC_ENC_OUT_PLANE_COUNT 2 | 75 | #define MFC_ENC_OUT_PLANE_COUNT 2 |
76 | #define STUFF_BYTE 4 | 76 | #define STUFF_BYTE 4 |
77 | #define MFC_MAX_CTRLS 64 | 77 | #define MFC_MAX_CTRLS 70 |
78 | |||
79 | #define S5P_MFC_CODEC_NONE -1 | ||
80 | #define S5P_MFC_CODEC_H264_DEC 0 | ||
81 | #define S5P_MFC_CODEC_H264_MVC_DEC 1 | ||
82 | #define S5P_MFC_CODEC_VC1_DEC 2 | ||
83 | #define S5P_MFC_CODEC_MPEG4_DEC 3 | ||
84 | #define S5P_MFC_CODEC_MPEG2_DEC 4 | ||
85 | #define S5P_MFC_CODEC_H263_DEC 5 | ||
86 | #define S5P_MFC_CODEC_VC1RCV_DEC 6 | ||
87 | #define S5P_MFC_CODEC_VP8_DEC 7 | ||
88 | |||
89 | #define S5P_MFC_CODEC_H264_ENC 20 | ||
90 | #define S5P_MFC_CODEC_H264_MVC_ENC 21 | ||
91 | #define S5P_MFC_CODEC_MPEG4_ENC 22 | ||
92 | #define S5P_MFC_CODEC_H263_ENC 23 | ||
93 | |||
94 | #define S5P_MFC_R2H_CMD_EMPTY 0 | ||
95 | #define S5P_MFC_R2H_CMD_SYS_INIT_RET 1 | ||
96 | #define S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET 2 | ||
97 | #define S5P_MFC_R2H_CMD_SEQ_DONE_RET 3 | ||
98 | #define S5P_MFC_R2H_CMD_INIT_BUFFERS_RET 4 | ||
99 | #define S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET 6 | ||
100 | #define S5P_MFC_R2H_CMD_SLEEP_RET 7 | ||
101 | #define S5P_MFC_R2H_CMD_WAKEUP_RET 8 | ||
102 | #define S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET 9 | ||
103 | #define S5P_MFC_R2H_CMD_DPB_FLUSH_RET 10 | ||
104 | #define S5P_MFC_R2H_CMD_NAL_ABORT_RET 11 | ||
105 | #define S5P_MFC_R2H_CMD_FW_STATUS_RET 12 | ||
106 | #define S5P_MFC_R2H_CMD_FRAME_DONE_RET 13 | ||
107 | #define S5P_MFC_R2H_CMD_FIELD_DONE_RET 14 | ||
108 | #define S5P_MFC_R2H_CMD_SLICE_DONE_RET 15 | ||
109 | #define S5P_MFC_R2H_CMD_ENC_BUFFER_FUL_RET 16 | ||
110 | #define S5P_MFC_R2H_CMD_ERR_RET 32 | ||
78 | 111 | ||
79 | #define mfc_read(dev, offset) readl(dev->regs_base + (offset)) | 112 | #define mfc_read(dev, offset) readl(dev->regs_base + (offset)) |
80 | #define mfc_write(dev, data, offset) writel((data), dev->regs_base + \ | 113 | #define mfc_write(dev, data, offset) writel((data), dev->regs_base + \ |
@@ -212,6 +245,9 @@ struct s5p_mfc_pm { | |||
212 | * @watchdog_work: worker for the watchdog | 245 | * @watchdog_work: worker for the watchdog |
213 | * @alloc_ctx: videobuf2 allocator contexts for two memory banks | 246 | * @alloc_ctx: videobuf2 allocator contexts for two memory banks |
214 | * @enter_suspend: flag set when entering suspend | 247 | * @enter_suspend: flag set when entering suspend |
248 | * @warn_start: hardware error code from which warnings start | ||
249 | * @mfc_ops: ops structure holding HW operation function pointers | ||
250 | * @mfc_cmds: cmd structure holding HW commands function pointers | ||
215 | * | 251 | * |
216 | */ | 252 | */ |
217 | struct s5p_mfc_dev { | 253 | struct s5p_mfc_dev { |
@@ -248,6 +284,10 @@ struct s5p_mfc_dev { | |||
248 | struct work_struct watchdog_work; | 284 | struct work_struct watchdog_work; |
249 | void *alloc_ctx[2]; | 285 | void *alloc_ctx[2]; |
250 | unsigned long enter_suspend; | 286 | unsigned long enter_suspend; |
287 | |||
288 | int warn_start; | ||
289 | struct s5p_mfc_hw_ops *mfc_ops; | ||
290 | struct s5p_mfc_hw_cmds *mfc_cmds; | ||
251 | }; | 291 | }; |
252 | 292 | ||
253 | /** | 293 | /** |
@@ -565,6 +605,9 @@ struct mfc_control { | |||
565 | __u8 is_volatile; | 605 | __u8 is_volatile; |
566 | }; | 606 | }; |
567 | 607 | ||
608 | /* Macro for making hardware specific calls */ | ||
609 | #define s5p_mfc_hw_call(f, op, args...) \ | ||
610 | ((f && f->op) ? f->op(args) : -ENODEV) | ||
568 | 611 | ||
569 | #define fh_to_ctx(__fh) container_of(__fh, struct s5p_mfc_ctx, fh) | 612 | #define fh_to_ctx(__fh) container_of(__fh, struct s5p_mfc_ctx, fh) |
570 | #define ctrl_to_ctx(__ctrl) \ | 613 | #define ctrl_to_ctx(__ctrl) \ |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index f31bff981a54..7666e9445fba 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | |||
@@ -15,11 +15,11 @@ | |||
15 | #include <linux/firmware.h> | 15 | #include <linux/firmware.h> |
16 | #include <linux/jiffies.h> | 16 | #include <linux/jiffies.h> |
17 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
18 | #include "regs-mfc.h" | 18 | #include "s5p_mfc_cmd.h" |
19 | #include "s5p_mfc_cmd_v5.h" | ||
20 | #include "s5p_mfc_common.h" | 19 | #include "s5p_mfc_common.h" |
21 | #include "s5p_mfc_debug.h" | 20 | #include "s5p_mfc_debug.h" |
22 | #include "s5p_mfc_intr.h" | 21 | #include "s5p_mfc_intr.h" |
22 | #include "s5p_mfc_opr.h" | ||
23 | #include "s5p_mfc_pm.h" | 23 | #include "s5p_mfc_pm.h" |
24 | 24 | ||
25 | static void *s5p_mfc_bitproc_buf; | 25 | static void *s5p_mfc_bitproc_buf; |
@@ -230,7 +230,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) | |||
230 | s5p_mfc_clean_dev_int_flags(dev); | 230 | s5p_mfc_clean_dev_int_flags(dev); |
231 | mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); | 231 | mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); |
232 | mfc_debug(2, "Will now wait for completion of firmware transfer\n"); | 232 | mfc_debug(2, "Will now wait for completion of firmware transfer\n"); |
233 | if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_FW_STATUS_RET)) { | 233 | if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) { |
234 | mfc_err("Failed to load firmware\n"); | 234 | mfc_err("Failed to load firmware\n"); |
235 | s5p_mfc_reset(dev); | 235 | s5p_mfc_reset(dev); |
236 | s5p_mfc_clock_off(); | 236 | s5p_mfc_clock_off(); |
@@ -238,7 +238,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) | |||
238 | } | 238 | } |
239 | s5p_mfc_clean_dev_int_flags(dev); | 239 | s5p_mfc_clean_dev_int_flags(dev); |
240 | /* 4. Initialize firmware */ | 240 | /* 4. Initialize firmware */ |
241 | ret = s5p_mfc_sys_init_cmd(dev); | 241 | ret = s5p_mfc_hw_call(dev->mfc_cmds, sys_init_cmd, dev); |
242 | if (ret) { | 242 | if (ret) { |
243 | mfc_err("Failed to send command to MFC - timeout\n"); | 243 | mfc_err("Failed to send command to MFC - timeout\n"); |
244 | s5p_mfc_reset(dev); | 244 | s5p_mfc_reset(dev); |
@@ -246,7 +246,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) | |||
246 | return ret; | 246 | return ret; |
247 | } | 247 | } |
248 | mfc_debug(2, "Ok, now will write a command to init the system\n"); | 248 | mfc_debug(2, "Ok, now will write a command to init the system\n"); |
249 | if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SYS_INIT_RET)) { | 249 | if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SYS_INIT_RET)) { |
250 | mfc_err("Failed to load firmware\n"); | 250 | mfc_err("Failed to load firmware\n"); |
251 | s5p_mfc_reset(dev); | 251 | s5p_mfc_reset(dev); |
252 | s5p_mfc_clock_off(); | 252 | s5p_mfc_clock_off(); |
@@ -254,7 +254,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) | |||
254 | } | 254 | } |
255 | dev->int_cond = 0; | 255 | dev->int_cond = 0; |
256 | if (dev->int_err != 0 || dev->int_type != | 256 | if (dev->int_err != 0 || dev->int_type != |
257 | S5P_FIMV_R2H_CMD_SYS_INIT_RET) { | 257 | S5P_MFC_R2H_CMD_SYS_INIT_RET) { |
258 | /* Failure. */ | 258 | /* Failure. */ |
259 | mfc_err("Failed to init firmware - error: %d int: %d\n", | 259 | mfc_err("Failed to init firmware - error: %d int: %d\n", |
260 | dev->int_err, dev->int_type); | 260 | dev->int_err, dev->int_type); |
@@ -271,6 +271,17 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) | |||
271 | } | 271 | } |
272 | 272 | ||
273 | 273 | ||
274 | /* Deinitialize hardware */ | ||
275 | void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev) | ||
276 | { | ||
277 | s5p_mfc_clock_on(); | ||
278 | |||
279 | s5p_mfc_reset(dev); | ||
280 | s5p_mfc_hw_call(dev->mfc_ops, release_dev_context_buffer, dev); | ||
281 | |||
282 | s5p_mfc_clock_off(); | ||
283 | } | ||
284 | |||
274 | int s5p_mfc_sleep(struct s5p_mfc_dev *dev) | 285 | int s5p_mfc_sleep(struct s5p_mfc_dev *dev) |
275 | { | 286 | { |
276 | int ret; | 287 | int ret; |
@@ -278,19 +289,19 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev) | |||
278 | mfc_debug_enter(); | 289 | mfc_debug_enter(); |
279 | s5p_mfc_clock_on(); | 290 | s5p_mfc_clock_on(); |
280 | s5p_mfc_clean_dev_int_flags(dev); | 291 | s5p_mfc_clean_dev_int_flags(dev); |
281 | ret = s5p_mfc_sleep_cmd(dev); | 292 | ret = s5p_mfc_hw_call(dev->mfc_cmds, sleep_cmd, dev); |
282 | if (ret) { | 293 | if (ret) { |
283 | mfc_err("Failed to send command to MFC - timeout\n"); | 294 | mfc_err("Failed to send command to MFC - timeout\n"); |
284 | return ret; | 295 | return ret; |
285 | } | 296 | } |
286 | if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SLEEP_RET)) { | 297 | if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SLEEP_RET)) { |
287 | mfc_err("Failed to sleep\n"); | 298 | mfc_err("Failed to sleep\n"); |
288 | return -EIO; | 299 | return -EIO; |
289 | } | 300 | } |
290 | s5p_mfc_clock_off(); | 301 | s5p_mfc_clock_off(); |
291 | dev->int_cond = 0; | 302 | dev->int_cond = 0; |
292 | if (dev->int_err != 0 || dev->int_type != | 303 | if (dev->int_err != 0 || dev->int_type != |
293 | S5P_FIMV_R2H_CMD_SLEEP_RET) { | 304 | S5P_MFC_R2H_CMD_SLEEP_RET) { |
294 | /* Failure. */ | 305 | /* Failure. */ |
295 | mfc_err("Failed to sleep - error: %d int: %d\n", dev->int_err, | 306 | mfc_err("Failed to sleep - error: %d int: %d\n", dev->int_err, |
296 | dev->int_type); | 307 | dev->int_type); |
@@ -320,7 +331,7 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) | |||
320 | s5p_mfc_clear_cmds(dev); | 331 | s5p_mfc_clear_cmds(dev); |
321 | s5p_mfc_clean_dev_int_flags(dev); | 332 | s5p_mfc_clean_dev_int_flags(dev); |
322 | /* 3. Initialize firmware */ | 333 | /* 3. Initialize firmware */ |
323 | ret = s5p_mfc_wakeup_cmd(dev); | 334 | ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev); |
324 | if (ret) { | 335 | if (ret) { |
325 | mfc_err("Failed to send command to MFC - timeout\n"); | 336 | mfc_err("Failed to send command to MFC - timeout\n"); |
326 | return ret; | 337 | return ret; |
@@ -328,14 +339,14 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) | |||
328 | /* 4. Release reset signal to the RISC */ | 339 | /* 4. Release reset signal to the RISC */ |
329 | mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); | 340 | mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); |
330 | mfc_debug(2, "Ok, now will write a command to wakeup the system\n"); | 341 | mfc_debug(2, "Ok, now will write a command to wakeup the system\n"); |
331 | if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_WAKEUP_RET)) { | 342 | if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) { |
332 | mfc_err("Failed to load firmware\n"); | 343 | mfc_err("Failed to load firmware\n"); |
333 | return -EIO; | 344 | return -EIO; |
334 | } | 345 | } |
335 | s5p_mfc_clock_off(); | 346 | s5p_mfc_clock_off(); |
336 | dev->int_cond = 0; | 347 | dev->int_cond = 0; |
337 | if (dev->int_err != 0 || dev->int_type != | 348 | if (dev->int_err != 0 || dev->int_type != |
338 | S5P_FIMV_R2H_CMD_WAKEUP_RET) { | 349 | S5P_MFC_R2H_CMD_WAKEUP_RET) { |
339 | /* Failure. */ | 350 | /* Failure. */ |
340 | mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err, | 351 | mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err, |
341 | dev->int_type); | 352 | dev->int_type); |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h index e1e0c544b6a2..90aa9b9886d5 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h | |||
@@ -20,6 +20,7 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev); | |||
20 | int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev); | 20 | int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev); |
21 | 21 | ||
22 | int s5p_mfc_init_hw(struct s5p_mfc_dev *dev); | 22 | int s5p_mfc_init_hw(struct s5p_mfc_dev *dev); |
23 | void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev); | ||
23 | 24 | ||
24 | int s5p_mfc_sleep(struct s5p_mfc_dev *dev); | 25 | int s5p_mfc_sleep(struct s5p_mfc_dev *dev); |
25 | int s5p_mfc_wakeup(struct s5p_mfc_dev *dev); | 26 | int s5p_mfc_wakeup(struct s5p_mfc_dev *dev); |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index 653f14bca380..107609c4e51a 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | |||
@@ -23,82 +23,84 @@ | |||
23 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
24 | #include <media/v4l2-ctrls.h> | 24 | #include <media/v4l2-ctrls.h> |
25 | #include <media/videobuf2-core.h> | 25 | #include <media/videobuf2-core.h> |
26 | #include "regs-mfc.h" | ||
27 | #include "s5p_mfc_common.h" | 26 | #include "s5p_mfc_common.h" |
28 | #include "s5p_mfc_debug.h" | 27 | #include "s5p_mfc_debug.h" |
29 | #include "s5p_mfc_dec.h" | 28 | #include "s5p_mfc_dec.h" |
30 | #include "s5p_mfc_intr.h" | 29 | #include "s5p_mfc_intr.h" |
31 | #include "s5p_mfc_opr_v5.h" | 30 | #include "s5p_mfc_opr.h" |
32 | #include "s5p_mfc_pm.h" | 31 | #include "s5p_mfc_pm.h" |
33 | 32 | ||
33 | #define DEF_SRC_FMT_DEC V4L2_PIX_FMT_H264 | ||
34 | #define DEF_DST_FMT_DEC V4L2_PIX_FMT_NV12MT | ||
35 | |||
34 | static struct s5p_mfc_fmt formats[] = { | 36 | static struct s5p_mfc_fmt formats[] = { |
35 | { | 37 | { |
36 | .name = "4:2:0 2 Planes 64x32 Tiles", | 38 | .name = "4:2:0 2 Planes 64x32 Tiles", |
37 | .fourcc = V4L2_PIX_FMT_NV12MT, | 39 | .fourcc = V4L2_PIX_FMT_NV12MT, |
38 | .codec_mode = S5P_FIMV_CODEC_NONE, | 40 | .codec_mode = S5P_MFC_CODEC_NONE, |
39 | .type = MFC_FMT_RAW, | 41 | .type = MFC_FMT_RAW, |
40 | .num_planes = 2, | 42 | .num_planes = 2, |
41 | }, | 43 | }, |
42 | { | 44 | { |
43 | .name = "4:2:0 2 Planes", | 45 | .name = "4:2:0 2 Planes", |
44 | .fourcc = V4L2_PIX_FMT_NV12M, | 46 | .fourcc = V4L2_PIX_FMT_NV12M, |
45 | .codec_mode = S5P_FIMV_CODEC_NONE, | 47 | .codec_mode = S5P_MFC_CODEC_NONE, |
46 | .type = MFC_FMT_RAW, | 48 | .type = MFC_FMT_RAW, |
47 | .num_planes = 2, | 49 | .num_planes = 2, |
48 | }, | 50 | }, |
49 | { | 51 | { |
50 | .name = "H264 Encoded Stream", | 52 | .name = "H264 Encoded Stream", |
51 | .fourcc = V4L2_PIX_FMT_H264, | 53 | .fourcc = V4L2_PIX_FMT_H264, |
52 | .codec_mode = S5P_FIMV_CODEC_H264_DEC, | 54 | .codec_mode = S5P_MFC_CODEC_H264_DEC, |
53 | .type = MFC_FMT_DEC, | 55 | .type = MFC_FMT_DEC, |
54 | .num_planes = 1, | 56 | .num_planes = 1, |
55 | }, | 57 | }, |
56 | { | 58 | { |
57 | .name = "H263 Encoded Stream", | 59 | .name = "H263 Encoded Stream", |
58 | .fourcc = V4L2_PIX_FMT_H263, | 60 | .fourcc = V4L2_PIX_FMT_H263, |
59 | .codec_mode = S5P_FIMV_CODEC_H263_DEC, | 61 | .codec_mode = S5P_MFC_CODEC_H263_DEC, |
60 | .type = MFC_FMT_DEC, | 62 | .type = MFC_FMT_DEC, |
61 | .num_planes = 1, | 63 | .num_planes = 1, |
62 | }, | 64 | }, |
63 | { | 65 | { |
64 | .name = "MPEG1 Encoded Stream", | 66 | .name = "MPEG1 Encoded Stream", |
65 | .fourcc = V4L2_PIX_FMT_MPEG1, | 67 | .fourcc = V4L2_PIX_FMT_MPEG1, |
66 | .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC, | 68 | .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, |
67 | .type = MFC_FMT_DEC, | 69 | .type = MFC_FMT_DEC, |
68 | .num_planes = 1, | 70 | .num_planes = 1, |
69 | }, | 71 | }, |
70 | { | 72 | { |
71 | .name = "MPEG2 Encoded Stream", | 73 | .name = "MPEG2 Encoded Stream", |
72 | .fourcc = V4L2_PIX_FMT_MPEG2, | 74 | .fourcc = V4L2_PIX_FMT_MPEG2, |
73 | .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC, | 75 | .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, |
74 | .type = MFC_FMT_DEC, | 76 | .type = MFC_FMT_DEC, |
75 | .num_planes = 1, | 77 | .num_planes = 1, |
76 | }, | 78 | }, |
77 | { | 79 | { |
78 | .name = "MPEG4 Encoded Stream", | 80 | .name = "MPEG4 Encoded Stream", |
79 | .fourcc = V4L2_PIX_FMT_MPEG4, | 81 | .fourcc = V4L2_PIX_FMT_MPEG4, |
80 | .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC, | 82 | .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, |
81 | .type = MFC_FMT_DEC, | 83 | .type = MFC_FMT_DEC, |
82 | .num_planes = 1, | 84 | .num_planes = 1, |
83 | }, | 85 | }, |
84 | { | 86 | { |
85 | .name = "XviD Encoded Stream", | 87 | .name = "XviD Encoded Stream", |
86 | .fourcc = V4L2_PIX_FMT_XVID, | 88 | .fourcc = V4L2_PIX_FMT_XVID, |
87 | .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC, | 89 | .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, |
88 | .type = MFC_FMT_DEC, | 90 | .type = MFC_FMT_DEC, |
89 | .num_planes = 1, | 91 | .num_planes = 1, |
90 | }, | 92 | }, |
91 | { | 93 | { |
92 | .name = "VC1 Encoded Stream", | 94 | .name = "VC1 Encoded Stream", |
93 | .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G, | 95 | .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G, |
94 | .codec_mode = S5P_FIMV_CODEC_VC1_DEC, | 96 | .codec_mode = S5P_MFC_CODEC_VC1_DEC, |
95 | .type = MFC_FMT_DEC, | 97 | .type = MFC_FMT_DEC, |
96 | .num_planes = 1, | 98 | .num_planes = 1, |
97 | }, | 99 | }, |
98 | { | 100 | { |
99 | .name = "VC1 RCV Encoded Stream", | 101 | .name = "VC1 RCV Encoded Stream", |
100 | .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L, | 102 | .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L, |
101 | .codec_mode = S5P_FIMV_CODEC_VC1RCV_DEC, | 103 | .codec_mode = S5P_MFC_CODEC_VC1RCV_DEC, |
102 | .type = MFC_FMT_DEC, | 104 | .type = MFC_FMT_DEC, |
103 | .num_planes = 1, | 105 | .num_planes = 1, |
104 | }, | 106 | }, |
@@ -296,7 +298,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
296 | /* If the MFC is parsing the header, | 298 | /* If the MFC is parsing the header, |
297 | * so wait until it is finished */ | 299 | * so wait until it is finished */ |
298 | s5p_mfc_clean_ctx_int_flags(ctx); | 300 | s5p_mfc_clean_ctx_int_flags(ctx); |
299 | s5p_mfc_wait_for_done_ctx(ctx, S5P_FIMV_R2H_CMD_SEQ_DONE_RET, | 301 | s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_SEQ_DONE_RET, |
300 | 0); | 302 | 0); |
301 | } | 303 | } |
302 | if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && | 304 | if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && |
@@ -379,7 +381,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
379 | goto out; | 381 | goto out; |
380 | } | 382 | } |
381 | fmt = find_format(f, MFC_FMT_DEC); | 383 | fmt = find_format(f, MFC_FMT_DEC); |
382 | if (!fmt || fmt->codec_mode == S5P_FIMV_CODEC_NONE) { | 384 | if (!fmt || fmt->codec_mode == S5P_MFC_CODEC_NONE) { |
383 | mfc_err("Unknown codec\n"); | 385 | mfc_err("Unknown codec\n"); |
384 | ret = -EINVAL; | 386 | ret = -EINVAL; |
385 | goto out; | 387 | goto out; |
@@ -475,7 +477,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
475 | return -ENOMEM; | 477 | return -ENOMEM; |
476 | } | 478 | } |
477 | ctx->total_dpb_count = reqbufs->count; | 479 | ctx->total_dpb_count = reqbufs->count; |
478 | ret = s5p_mfc_alloc_codec_buffers(ctx); | 480 | ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_codec_buffers, ctx); |
479 | if (ret) { | 481 | if (ret) { |
480 | mfc_err("Failed to allocate decoding buffers\n"); | 482 | mfc_err("Failed to allocate decoding buffers\n"); |
481 | reqbufs->count = 0; | 483 | reqbufs->count = 0; |
@@ -491,15 +493,16 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
491 | reqbufs->count = 0; | 493 | reqbufs->count = 0; |
492 | s5p_mfc_clock_on(); | 494 | s5p_mfc_clock_on(); |
493 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); | 495 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); |
494 | s5p_mfc_release_codec_buffers(ctx); | 496 | s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, |
497 | ctx); | ||
495 | s5p_mfc_clock_off(); | 498 | s5p_mfc_clock_off(); |
496 | return -ENOMEM; | 499 | return -ENOMEM; |
497 | } | 500 | } |
498 | if (s5p_mfc_ctx_ready(ctx)) | 501 | if (s5p_mfc_ctx_ready(ctx)) |
499 | set_work_bit_irqsave(ctx); | 502 | set_work_bit_irqsave(ctx); |
500 | s5p_mfc_try_run(dev); | 503 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
501 | s5p_mfc_wait_for_done_ctx(ctx, | 504 | s5p_mfc_wait_for_done_ctx(ctx, |
502 | S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET, 0); | 505 | S5P_MFC_R2H_CMD_INIT_BUFFERS_RET, 0); |
503 | } | 506 | } |
504 | return ret; | 507 | return ret; |
505 | } | 508 | } |
@@ -581,18 +584,22 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
581 | ctx->src_bufs_cnt = 0; | 584 | ctx->src_bufs_cnt = 0; |
582 | ctx->capture_state = QUEUE_FREE; | 585 | ctx->capture_state = QUEUE_FREE; |
583 | ctx->output_state = QUEUE_FREE; | 586 | ctx->output_state = QUEUE_FREE; |
584 | s5p_mfc_alloc_instance_buffer(ctx); | 587 | s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, |
585 | s5p_mfc_alloc_dec_temp_buffers(ctx); | 588 | ctx); |
589 | s5p_mfc_hw_call(dev->mfc_ops, alloc_dec_temp_buffers, | ||
590 | ctx); | ||
586 | set_work_bit_irqsave(ctx); | 591 | set_work_bit_irqsave(ctx); |
587 | s5p_mfc_clean_ctx_int_flags(ctx); | 592 | s5p_mfc_clean_ctx_int_flags(ctx); |
588 | s5p_mfc_try_run(dev); | 593 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
589 | 594 | ||
590 | if (s5p_mfc_wait_for_done_ctx(ctx, | 595 | if (s5p_mfc_wait_for_done_ctx(ctx, |
591 | S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET, 0)) { | 596 | S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) { |
592 | /* Error or timeout */ | 597 | /* Error or timeout */ |
593 | mfc_err("Error getting instance from hardware\n"); | 598 | mfc_err("Error getting instance from hardware\n"); |
594 | s5p_mfc_release_instance_buffer(ctx); | 599 | s5p_mfc_hw_call(dev->mfc_ops, |
595 | s5p_mfc_release_dec_desc_buffer(ctx); | 600 | release_instance_buffer, ctx); |
601 | s5p_mfc_hw_call(dev->mfc_ops, | ||
602 | release_dec_desc_buffer, ctx); | ||
596 | return -EIO; | 603 | return -EIO; |
597 | } | 604 | } |
598 | mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); | 605 | mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); |
@@ -661,7 +668,7 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl) | |||
661 | /* Should wait for the header to be parsed */ | 668 | /* Should wait for the header to be parsed */ |
662 | s5p_mfc_clean_ctx_int_flags(ctx); | 669 | s5p_mfc_clean_ctx_int_flags(ctx); |
663 | s5p_mfc_wait_for_done_ctx(ctx, | 670 | s5p_mfc_wait_for_done_ctx(ctx, |
664 | S5P_FIMV_R2H_CMD_SEQ_DONE_RET, 0); | 671 | S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); |
665 | if (ctx->state >= MFCINST_HEAD_PARSED && | 672 | if (ctx->state >= MFCINST_HEAD_PARSED && |
666 | ctx->state < MFCINST_ABORT) { | 673 | ctx->state < MFCINST_ABORT) { |
667 | ctrl->val = ctx->dpb_count; | 674 | ctrl->val = ctx->dpb_count; |
@@ -685,6 +692,7 @@ static int vidioc_g_crop(struct file *file, void *priv, | |||
685 | struct v4l2_crop *cr) | 692 | struct v4l2_crop *cr) |
686 | { | 693 | { |
687 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); | 694 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); |
695 | struct s5p_mfc_dev *dev = ctx->dev; | ||
688 | u32 left, right, top, bottom; | 696 | u32 left, right, top, bottom; |
689 | 697 | ||
690 | if (ctx->state != MFCINST_HEAD_PARSED && | 698 | if (ctx->state != MFCINST_HEAD_PARSED && |
@@ -694,10 +702,10 @@ static int vidioc_g_crop(struct file *file, void *priv, | |||
694 | return -EINVAL; | 702 | return -EINVAL; |
695 | } | 703 | } |
696 | if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264) { | 704 | if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264) { |
697 | left = s5p_mfc_read_info_v5(ctx, CROP_INFO_H); | 705 | left = s5p_mfc_hw_call(dev->mfc_ops, get_crop_info_h, ctx); |
698 | right = left >> S5P_FIMV_SHARED_CROP_RIGHT_SHIFT; | 706 | right = left >> S5P_FIMV_SHARED_CROP_RIGHT_SHIFT; |
699 | left = left & S5P_FIMV_SHARED_CROP_LEFT_MASK; | 707 | left = left & S5P_FIMV_SHARED_CROP_LEFT_MASK; |
700 | top = s5p_mfc_read_info_v5(ctx, CROP_INFO_V); | 708 | top = s5p_mfc_hw_call(dev->mfc_ops, get_crop_info_v, ctx); |
701 | bottom = top >> S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT; | 709 | bottom = top >> S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT; |
702 | top = top & S5P_FIMV_SHARED_CROP_TOP_MASK; | 710 | top = top & S5P_FIMV_SHARED_CROP_TOP_MASK; |
703 | cr->c.left = left; | 711 | cr->c.left = left; |
@@ -875,7 +883,7 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) | |||
875 | /* If context is ready then dev = work->data;schedule it to run */ | 883 | /* If context is ready then dev = work->data;schedule it to run */ |
876 | if (s5p_mfc_ctx_ready(ctx)) | 884 | if (s5p_mfc_ctx_ready(ctx)) |
877 | set_work_bit_irqsave(ctx); | 885 | set_work_bit_irqsave(ctx); |
878 | s5p_mfc_try_run(dev); | 886 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
879 | return 0; | 887 | return 0; |
880 | } | 888 | } |
881 | 889 | ||
@@ -891,19 +899,21 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q) | |||
891 | dev->curr_ctx == ctx->num && dev->hw_lock) { | 899 | dev->curr_ctx == ctx->num && dev->hw_lock) { |
892 | ctx->state = MFCINST_ABORT; | 900 | ctx->state = MFCINST_ABORT; |
893 | s5p_mfc_wait_for_done_ctx(ctx, | 901 | s5p_mfc_wait_for_done_ctx(ctx, |
894 | S5P_FIMV_R2H_CMD_FRAME_DONE_RET, 0); | 902 | S5P_MFC_R2H_CMD_FRAME_DONE_RET, 0); |
895 | aborted = 1; | 903 | aborted = 1; |
896 | } | 904 | } |
897 | spin_lock_irqsave(&dev->irqlock, flags); | 905 | spin_lock_irqsave(&dev->irqlock, flags); |
898 | if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 906 | if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
899 | s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst); | 907 | s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue, |
908 | &ctx->vq_dst); | ||
900 | INIT_LIST_HEAD(&ctx->dst_queue); | 909 | INIT_LIST_HEAD(&ctx->dst_queue); |
901 | ctx->dst_queue_cnt = 0; | 910 | ctx->dst_queue_cnt = 0; |
902 | ctx->dpb_flush_flag = 1; | 911 | ctx->dpb_flush_flag = 1; |
903 | ctx->dec_dst_flag = 0; | 912 | ctx->dec_dst_flag = 0; |
904 | } | 913 | } |
905 | if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 914 | if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
906 | s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src); | 915 | s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue, |
916 | &ctx->vq_src); | ||
907 | INIT_LIST_HEAD(&ctx->src_queue); | 917 | INIT_LIST_HEAD(&ctx->src_queue); |
908 | ctx->src_queue_cnt = 0; | 918 | ctx->src_queue_cnt = 0; |
909 | } | 919 | } |
@@ -943,7 +953,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb) | |||
943 | } | 953 | } |
944 | if (s5p_mfc_ctx_ready(ctx)) | 954 | if (s5p_mfc_ctx_ready(ctx)) |
945 | set_work_bit_irqsave(ctx); | 955 | set_work_bit_irqsave(ctx); |
946 | s5p_mfc_try_run(dev); | 956 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
947 | } | 957 | } |
948 | 958 | ||
949 | static struct vb2_ops s5p_mfc_dec_qops = { | 959 | static struct vb2_ops s5p_mfc_dec_qops = { |
@@ -1027,3 +1037,13 @@ void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx) | |||
1027 | ctx->ctrls[i] = NULL; | 1037 | ctx->ctrls[i] = NULL; |
1028 | } | 1038 | } |
1029 | 1039 | ||
1040 | void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx) | ||
1041 | { | ||
1042 | struct v4l2_format f; | ||
1043 | f.fmt.pix_mp.pixelformat = DEF_SRC_FMT_DEC; | ||
1044 | ctx->src_fmt = find_format(&f, MFC_FMT_DEC); | ||
1045 | f.fmt.pix_mp.pixelformat = DEF_DST_FMT_DEC; | ||
1046 | ctx->dst_fmt = find_format(&f, MFC_FMT_RAW); | ||
1047 | mfc_debug(2, "Default src_fmt is %x, dest_fmt is %x\n", | ||
1048 | (unsigned int)ctx->src_fmt, (unsigned int)ctx->dst_fmt); | ||
1049 | } | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.h b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.h index fdf1d99a9d15..d06a7cab5eb1 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.h | |||
@@ -19,5 +19,6 @@ const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void); | |||
19 | struct s5p_mfc_fmt *get_dec_def_fmt(bool src); | 19 | struct s5p_mfc_fmt *get_dec_def_fmt(bool src); |
20 | int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx); | 20 | int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx); |
21 | void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx); | 21 | void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx); |
22 | void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx); | ||
22 | 23 | ||
23 | #endif /* S5P_MFC_DEC_H_ */ | 24 | #endif /* S5P_MFC_DEC_H_ */ |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index f5f7e3c9a1a3..3b0e594004d4 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | |||
@@ -25,46 +25,48 @@ | |||
25 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
26 | #include <media/v4l2-ctrls.h> | 26 | #include <media/v4l2-ctrls.h> |
27 | #include <media/videobuf2-core.h> | 27 | #include <media/videobuf2-core.h> |
28 | #include "regs-mfc.h" | ||
29 | #include "s5p_mfc_common.h" | 28 | #include "s5p_mfc_common.h" |
30 | #include "s5p_mfc_debug.h" | 29 | #include "s5p_mfc_debug.h" |
31 | #include "s5p_mfc_enc.h" | 30 | #include "s5p_mfc_enc.h" |
32 | #include "s5p_mfc_intr.h" | 31 | #include "s5p_mfc_intr.h" |
33 | #include "s5p_mfc_opr_v5.h" | 32 | #include "s5p_mfc_opr.h" |
33 | |||
34 | #define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12MT | ||
35 | #define DEF_DST_FMT_ENC V4L2_PIX_FMT_H264 | ||
34 | 36 | ||
35 | static struct s5p_mfc_fmt formats[] = { | 37 | static struct s5p_mfc_fmt formats[] = { |
36 | { | 38 | { |
37 | .name = "4:2:0 2 Planes 64x32 Tiles", | 39 | .name = "4:2:0 2 Planes 64x32 Tiles", |
38 | .fourcc = V4L2_PIX_FMT_NV12MT, | 40 | .fourcc = V4L2_PIX_FMT_NV12MT, |
39 | .codec_mode = S5P_FIMV_CODEC_NONE, | 41 | .codec_mode = S5P_MFC_CODEC_NONE, |
40 | .type = MFC_FMT_RAW, | 42 | .type = MFC_FMT_RAW, |
41 | .num_planes = 2, | 43 | .num_planes = 2, |
42 | }, | 44 | }, |
43 | { | 45 | { |
44 | .name = "4:2:0 2 Planes", | 46 | .name = "4:2:0 2 Planes", |
45 | .fourcc = V4L2_PIX_FMT_NV12M, | 47 | .fourcc = V4L2_PIX_FMT_NV12M, |
46 | .codec_mode = S5P_FIMV_CODEC_NONE, | 48 | .codec_mode = S5P_MFC_CODEC_NONE, |
47 | .type = MFC_FMT_RAW, | 49 | .type = MFC_FMT_RAW, |
48 | .num_planes = 2, | 50 | .num_planes = 2, |
49 | }, | 51 | }, |
50 | { | 52 | { |
51 | .name = "H264 Encoded Stream", | 53 | .name = "H264 Encoded Stream", |
52 | .fourcc = V4L2_PIX_FMT_H264, | 54 | .fourcc = V4L2_PIX_FMT_H264, |
53 | .codec_mode = S5P_FIMV_CODEC_H264_ENC, | 55 | .codec_mode = S5P_MFC_CODEC_H264_ENC, |
54 | .type = MFC_FMT_ENC, | 56 | .type = MFC_FMT_ENC, |
55 | .num_planes = 1, | 57 | .num_planes = 1, |
56 | }, | 58 | }, |
57 | { | 59 | { |
58 | .name = "MPEG4 Encoded Stream", | 60 | .name = "MPEG4 Encoded Stream", |
59 | .fourcc = V4L2_PIX_FMT_MPEG4, | 61 | .fourcc = V4L2_PIX_FMT_MPEG4, |
60 | .codec_mode = S5P_FIMV_CODEC_MPEG4_ENC, | 62 | .codec_mode = S5P_MFC_CODEC_MPEG4_ENC, |
61 | .type = MFC_FMT_ENC, | 63 | .type = MFC_FMT_ENC, |
62 | .num_planes = 1, | 64 | .num_planes = 1, |
63 | }, | 65 | }, |
64 | { | 66 | { |
65 | .name = "H263 Encoded Stream", | 67 | .name = "H263 Encoded Stream", |
66 | .fourcc = V4L2_PIX_FMT_H263, | 68 | .fourcc = V4L2_PIX_FMT_H263, |
67 | .codec_mode = S5P_FIMV_CODEC_H263_ENC, | 69 | .codec_mode = S5P_MFC_CODEC_H263_ENC, |
68 | .type = MFC_FMT_ENC, | 70 | .type = MFC_FMT_ENC, |
69 | .num_planes = 1, | 71 | .num_planes = 1, |
70 | }, | 72 | }, |
@@ -619,7 +621,8 @@ static int enc_pre_seq_start(struct s5p_mfc_ctx *ctx) | |||
619 | dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); | 621 | dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); |
620 | dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0); | 622 | dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0); |
621 | dst_size = vb2_plane_size(dst_mb->b, 0); | 623 | dst_size = vb2_plane_size(dst_mb->b, 0); |
622 | s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size); | 624 | s5p_mfc_hw_call(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr, |
625 | dst_size); | ||
623 | spin_unlock_irqrestore(&dev->irqlock, flags); | 626 | spin_unlock_irqrestore(&dev->irqlock, flags); |
624 | return 0; | 627 | return 0; |
625 | } | 628 | } |
@@ -638,14 +641,14 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) | |||
638 | list_del(&dst_mb->list); | 641 | list_del(&dst_mb->list); |
639 | ctx->dst_queue_cnt--; | 642 | ctx->dst_queue_cnt--; |
640 | vb2_set_plane_payload(dst_mb->b, 0, | 643 | vb2_set_plane_payload(dst_mb->b, 0, |
641 | s5p_mfc_get_enc_strm_size()); | 644 | s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev)); |
642 | vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); | 645 | vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); |
643 | spin_unlock_irqrestore(&dev->irqlock, flags); | 646 | spin_unlock_irqrestore(&dev->irqlock, flags); |
644 | } | 647 | } |
645 | ctx->state = MFCINST_RUNNING; | 648 | ctx->state = MFCINST_RUNNING; |
646 | if (s5p_mfc_ctx_ready(ctx)) | 649 | if (s5p_mfc_ctx_ready(ctx)) |
647 | set_work_bit_irqsave(ctx); | 650 | set_work_bit_irqsave(ctx); |
648 | s5p_mfc_try_run(dev); | 651 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
649 | return 0; | 652 | return 0; |
650 | } | 653 | } |
651 | 654 | ||
@@ -662,14 +665,16 @@ static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx) | |||
662 | src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); | 665 | src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); |
663 | src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0); | 666 | src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0); |
664 | src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1); | 667 | src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1); |
665 | s5p_mfc_set_enc_frame_buffer(ctx, src_y_addr, src_c_addr); | 668 | s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx, src_y_addr, |
669 | src_c_addr); | ||
666 | spin_unlock_irqrestore(&dev->irqlock, flags); | 670 | spin_unlock_irqrestore(&dev->irqlock, flags); |
667 | 671 | ||
668 | spin_lock_irqsave(&dev->irqlock, flags); | 672 | spin_lock_irqsave(&dev->irqlock, flags); |
669 | dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); | 673 | dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); |
670 | dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0); | 674 | dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0); |
671 | dst_size = vb2_plane_size(dst_mb->b, 0); | 675 | dst_size = vb2_plane_size(dst_mb->b, 0); |
672 | s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size); | 676 | s5p_mfc_hw_call(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr, |
677 | dst_size); | ||
673 | spin_unlock_irqrestore(&dev->irqlock, flags); | 678 | spin_unlock_irqrestore(&dev->irqlock, flags); |
674 | 679 | ||
675 | return 0; | 680 | return 0; |
@@ -685,15 +690,16 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) | |||
685 | unsigned int strm_size; | 690 | unsigned int strm_size; |
686 | unsigned long flags; | 691 | unsigned long flags; |
687 | 692 | ||
688 | slice_type = s5p_mfc_get_enc_slice_type(); | 693 | slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev); |
689 | strm_size = s5p_mfc_get_enc_strm_size(); | 694 | strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev); |
690 | mfc_debug(2, "Encoded slice type: %d", slice_type); | 695 | mfc_debug(2, "Encoded slice type: %d", slice_type); |
691 | mfc_debug(2, "Encoded stream size: %d", strm_size); | 696 | mfc_debug(2, "Encoded stream size: %d", strm_size); |
692 | mfc_debug(2, "Display order: %d", | 697 | mfc_debug(2, "Display order: %d", |
693 | mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT)); | 698 | mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT)); |
694 | spin_lock_irqsave(&dev->irqlock, flags); | 699 | spin_lock_irqsave(&dev->irqlock, flags); |
695 | if (slice_type >= 0) { | 700 | if (slice_type >= 0) { |
696 | s5p_mfc_get_enc_frame_buffer(ctx, &enc_y_addr, &enc_c_addr); | 701 | s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx, |
702 | &enc_y_addr, &enc_c_addr); | ||
697 | list_for_each_entry(mb_entry, &ctx->src_queue, list) { | 703 | list_for_each_entry(mb_entry, &ctx->src_queue, list) { |
698 | mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0); | 704 | mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0); |
699 | mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1); | 705 | mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1); |
@@ -939,15 +945,16 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
939 | pix_fmt_mp->plane_fmt[0].bytesperline = 0; | 945 | pix_fmt_mp->plane_fmt[0].bytesperline = 0; |
940 | ctx->dst_bufs_cnt = 0; | 946 | ctx->dst_bufs_cnt = 0; |
941 | ctx->capture_state = QUEUE_FREE; | 947 | ctx->capture_state = QUEUE_FREE; |
942 | s5p_mfc_alloc_instance_buffer(ctx); | 948 | s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx); |
943 | set_work_bit_irqsave(ctx); | 949 | set_work_bit_irqsave(ctx); |
944 | s5p_mfc_clean_ctx_int_flags(ctx); | 950 | s5p_mfc_clean_ctx_int_flags(ctx); |
945 | s5p_mfc_try_run(dev); | 951 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
946 | if (s5p_mfc_wait_for_done_ctx(ctx, \ | 952 | if (s5p_mfc_wait_for_done_ctx(ctx, \ |
947 | S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET, 1)) { | 953 | S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 1)) { |
948 | /* Error or timeout */ | 954 | /* Error or timeout */ |
949 | mfc_err("Error getting instance from hardware\n"); | 955 | mfc_err("Error getting instance from hardware\n"); |
950 | s5p_mfc_release_instance_buffer(ctx); | 956 | s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, |
957 | ctx); | ||
951 | ret = -EIO; | 958 | ret = -EIO; |
952 | goto out; | 959 | goto out; |
953 | } | 960 | } |
@@ -1042,7 +1049,8 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1042 | return ret; | 1049 | return ret; |
1043 | } | 1050 | } |
1044 | ctx->capture_state = QUEUE_BUFS_REQUESTED; | 1051 | ctx->capture_state = QUEUE_BUFS_REQUESTED; |
1045 | ret = s5p_mfc_alloc_codec_buffers(ctx); | 1052 | ret = s5p_mfc_hw_call(ctx->dev->mfc_ops, alloc_codec_buffers, |
1053 | ctx); | ||
1046 | if (ret) { | 1054 | if (ret) { |
1047 | mfc_err("Failed to allocate encoding buffers\n"); | 1055 | mfc_err("Failed to allocate encoding buffers\n"); |
1048 | reqbufs->count = 0; | 1056 | reqbufs->count = 0; |
@@ -1500,7 +1508,7 @@ int vidioc_encoder_cmd(struct file *file, void *priv, | |||
1500 | mfc_debug(2, "EOS: empty src queue, entering finishing state"); | 1508 | mfc_debug(2, "EOS: empty src queue, entering finishing state"); |
1501 | ctx->state = MFCINST_FINISHING; | 1509 | ctx->state = MFCINST_FINISHING; |
1502 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1510 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1503 | s5p_mfc_try_run(dev); | 1511 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
1504 | } else { | 1512 | } else { |
1505 | mfc_debug(2, "EOS: marking last buffer of stream"); | 1513 | mfc_debug(2, "EOS: marking last buffer of stream"); |
1506 | buf = list_entry(ctx->src_queue.prev, | 1514 | buf = list_entry(ctx->src_queue.prev, |
@@ -1715,7 +1723,7 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) | |||
1715 | /* If context is ready then dev = work->data;schedule it to run */ | 1723 | /* If context is ready then dev = work->data;schedule it to run */ |
1716 | if (s5p_mfc_ctx_ready(ctx)) | 1724 | if (s5p_mfc_ctx_ready(ctx)) |
1717 | set_work_bit_irqsave(ctx); | 1725 | set_work_bit_irqsave(ctx); |
1718 | s5p_mfc_try_run(dev); | 1726 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
1719 | return 0; | 1727 | return 0; |
1720 | } | 1728 | } |
1721 | 1729 | ||
@@ -1729,19 +1737,21 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q) | |||
1729 | ctx->state == MFCINST_RUNNING) && | 1737 | ctx->state == MFCINST_RUNNING) && |
1730 | dev->curr_ctx == ctx->num && dev->hw_lock) { | 1738 | dev->curr_ctx == ctx->num && dev->hw_lock) { |
1731 | ctx->state = MFCINST_ABORT; | 1739 | ctx->state = MFCINST_ABORT; |
1732 | s5p_mfc_wait_for_done_ctx(ctx, S5P_FIMV_R2H_CMD_FRAME_DONE_RET, | 1740 | s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_FRAME_DONE_RET, |
1733 | 0); | 1741 | 0); |
1734 | } | 1742 | } |
1735 | ctx->state = MFCINST_FINISHED; | 1743 | ctx->state = MFCINST_FINISHED; |
1736 | spin_lock_irqsave(&dev->irqlock, flags); | 1744 | spin_lock_irqsave(&dev->irqlock, flags); |
1737 | if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 1745 | if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
1738 | s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst); | 1746 | s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue, |
1747 | &ctx->vq_dst); | ||
1739 | INIT_LIST_HEAD(&ctx->dst_queue); | 1748 | INIT_LIST_HEAD(&ctx->dst_queue); |
1740 | ctx->dst_queue_cnt = 0; | 1749 | ctx->dst_queue_cnt = 0; |
1741 | } | 1750 | } |
1742 | if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 1751 | if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
1743 | cleanup_ref_queue(ctx); | 1752 | cleanup_ref_queue(ctx); |
1744 | s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src); | 1753 | s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue, |
1754 | &ctx->vq_src); | ||
1745 | INIT_LIST_HEAD(&ctx->src_queue); | 1755 | INIT_LIST_HEAD(&ctx->src_queue); |
1746 | ctx->src_queue_cnt = 0; | 1756 | ctx->src_queue_cnt = 0; |
1747 | } | 1757 | } |
@@ -1782,7 +1792,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb) | |||
1782 | } | 1792 | } |
1783 | if (s5p_mfc_ctx_ready(ctx)) | 1793 | if (s5p_mfc_ctx_ready(ctx)) |
1784 | set_work_bit_irqsave(ctx); | 1794 | set_work_bit_irqsave(ctx); |
1785 | s5p_mfc_try_run(dev); | 1795 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
1786 | } | 1796 | } |
1787 | 1797 | ||
1788 | static struct vb2_ops s5p_mfc_enc_qops = { | 1798 | static struct vb2_ops s5p_mfc_enc_qops = { |
@@ -1880,3 +1890,13 @@ void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx) | |||
1880 | for (i = 0; i < NUM_CTRLS; i++) | 1890 | for (i = 0; i < NUM_CTRLS; i++) |
1881 | ctx->ctrls[i] = NULL; | 1891 | ctx->ctrls[i] = NULL; |
1882 | } | 1892 | } |
1893 | |||
1894 | void s5p_mfc_enc_init(struct s5p_mfc_ctx *ctx) | ||
1895 | { | ||
1896 | struct v4l2_format f; | ||
1897 | f.fmt.pix_mp.pixelformat = DEF_SRC_FMT_ENC; | ||
1898 | ctx->src_fmt = find_format(&f, MFC_FMT_RAW); | ||
1899 | f.fmt.pix_mp.pixelformat = DEF_DST_FMT_ENC; | ||
1900 | ctx->dst_fmt = find_format(&f, MFC_FMT_ENC); | ||
1901 | } | ||
1902 | |||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.h b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.h index ca9fd66bd310..5118d46b3a9e 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.h | |||
@@ -19,5 +19,6 @@ const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void); | |||
19 | struct s5p_mfc_fmt *get_enc_def_fmt(bool src); | 19 | struct s5p_mfc_fmt *get_enc_def_fmt(bool src); |
20 | int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx); | 20 | int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx); |
21 | void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx); | 21 | void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx); |
22 | void s5p_mfc_enc_init(struct s5p_mfc_ctx *ctx); | ||
22 | 23 | ||
23 | #endif /* S5P_MFC_ENC_H_ */ | 24 | #endif /* S5P_MFC_ENC_H_ */ |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_intr.c b/drivers/media/platform/s5p-mfc/s5p_mfc_intr.c index 37860e299021..5b8f0e085e6d 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_intr.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_intr.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/wait.h> | 19 | #include <linux/wait.h> |
20 | #include "regs-mfc.h" | ||
21 | #include "s5p_mfc_common.h" | 20 | #include "s5p_mfc_common.h" |
22 | #include "s5p_mfc_debug.h" | 21 | #include "s5p_mfc_debug.h" |
23 | #include "s5p_mfc_intr.h" | 22 | #include "s5p_mfc_intr.h" |
@@ -28,7 +27,7 @@ int s5p_mfc_wait_for_done_dev(struct s5p_mfc_dev *dev, int command) | |||
28 | 27 | ||
29 | ret = wait_event_interruptible_timeout(dev->queue, | 28 | ret = wait_event_interruptible_timeout(dev->queue, |
30 | (dev->int_cond && (dev->int_type == command | 29 | (dev->int_cond && (dev->int_type == command |
31 | || dev->int_type == S5P_FIMV_R2H_CMD_ERR_RET)), | 30 | || dev->int_type == S5P_MFC_R2H_CMD_ERR_RET)), |
32 | msecs_to_jiffies(MFC_INT_TIMEOUT)); | 31 | msecs_to_jiffies(MFC_INT_TIMEOUT)); |
33 | if (ret == 0) { | 32 | if (ret == 0) { |
34 | mfc_err("Interrupt (dev->int_type:%d, command:%d) timed out\n", | 33 | mfc_err("Interrupt (dev->int_type:%d, command:%d) timed out\n", |
@@ -40,7 +39,7 @@ int s5p_mfc_wait_for_done_dev(struct s5p_mfc_dev *dev, int command) | |||
40 | } | 39 | } |
41 | mfc_debug(1, "Finished waiting (dev->int_type:%d, command: %d)\n", | 40 | mfc_debug(1, "Finished waiting (dev->int_type:%d, command: %d)\n", |
42 | dev->int_type, command); | 41 | dev->int_type, command); |
43 | if (dev->int_type == S5P_FIMV_R2H_CMD_ERR_RET) | 42 | if (dev->int_type == S5P_MFC_R2H_CMD_ERR_RET) |
44 | return 1; | 43 | return 1; |
45 | return 0; | 44 | return 0; |
46 | } | 45 | } |
@@ -60,12 +59,12 @@ int s5p_mfc_wait_for_done_ctx(struct s5p_mfc_ctx *ctx, | |||
60 | if (interrupt) { | 59 | if (interrupt) { |
61 | ret = wait_event_interruptible_timeout(ctx->queue, | 60 | ret = wait_event_interruptible_timeout(ctx->queue, |
62 | (ctx->int_cond && (ctx->int_type == command | 61 | (ctx->int_cond && (ctx->int_type == command |
63 | || ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET)), | 62 | || ctx->int_type == S5P_MFC_R2H_CMD_ERR_RET)), |
64 | msecs_to_jiffies(MFC_INT_TIMEOUT)); | 63 | msecs_to_jiffies(MFC_INT_TIMEOUT)); |
65 | } else { | 64 | } else { |
66 | ret = wait_event_timeout(ctx->queue, | 65 | ret = wait_event_timeout(ctx->queue, |
67 | (ctx->int_cond && (ctx->int_type == command | 66 | (ctx->int_cond && (ctx->int_type == command |
68 | || ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET)), | 67 | || ctx->int_type == S5P_MFC_R2H_CMD_ERR_RET)), |
69 | msecs_to_jiffies(MFC_INT_TIMEOUT)); | 68 | msecs_to_jiffies(MFC_INT_TIMEOUT)); |
70 | } | 69 | } |
71 | if (ret == 0) { | 70 | if (ret == 0) { |
@@ -78,7 +77,7 @@ int s5p_mfc_wait_for_done_ctx(struct s5p_mfc_ctx *ctx, | |||
78 | } | 77 | } |
79 | mfc_debug(1, "Finished waiting (ctx->int_type:%d, command: %d)\n", | 78 | mfc_debug(1, "Finished waiting (ctx->int_type:%d, command: %d)\n", |
80 | ctx->int_type, command); | 79 | ctx->int_type, command); |
81 | if (ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET) | 80 | if (ctx->int_type == S5P_MFC_R2H_CMD_ERR_RET) |
82 | return 1; | 81 | return 1; |
83 | return 0; | 82 | return 0; |
84 | } | 83 | } |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c new file mode 100644 index 000000000000..b6246b2ae759 --- /dev/null +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * drivers/media/platform/s5p-mfc/s5p_mfc_opr.c | ||
3 | * | ||
4 | * Samsung MFC (Multi Function Codec - FIMV) driver | ||
5 | * This file contains hw related functions. | ||
6 | * | ||
7 | * Kamil Debski, Copyright (c) 2012 Samsung Electronics Co., Ltd. | ||
8 | * http://www.samsung.com/ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include "s5p_mfc_opr.h" | ||
16 | #include "s5p_mfc_opr_v5.h" | ||
17 | |||
18 | static struct s5p_mfc_hw_ops *s5p_mfc_ops; | ||
19 | |||
20 | void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev) | ||
21 | { | ||
22 | s5p_mfc_ops = s5p_mfc_init_hw_ops_v5(); | ||
23 | dev->warn_start = S5P_FIMV_ERR_WARNINGS_START; | ||
24 | dev->mfc_ops = s5p_mfc_ops; | ||
25 | } | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h new file mode 100644 index 000000000000..420abecafec0 --- /dev/null +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * drivers/media/platform/s5p-mfc/s5p_mfc_opr.h | ||
3 | * | ||
4 | * Header file for Samsung MFC (Multi Function Codec - FIMV) driver | ||
5 | * Contains declarations of hw related functions. | ||
6 | * | ||
7 | * Kamil Debski, Copyright (C) 2012 Samsung Electronics Co., Ltd. | ||
8 | * http://www.samsung.com/ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef S5P_MFC_OPR_H_ | ||
16 | #define S5P_MFC_OPR_H_ | ||
17 | |||
18 | #include "s5p_mfc_common.h" | ||
19 | |||
20 | struct s5p_mfc_hw_ops { | ||
21 | int (*alloc_dec_temp_buffers)(struct s5p_mfc_ctx *ctx); | ||
22 | void (*release_dec_desc_buffer)(struct s5p_mfc_ctx *ctx); | ||
23 | int (*alloc_codec_buffers)(struct s5p_mfc_ctx *ctx); | ||
24 | void (*release_codec_buffers)(struct s5p_mfc_ctx *ctx); | ||
25 | int (*alloc_instance_buffer)(struct s5p_mfc_ctx *ctx); | ||
26 | void (*release_instance_buffer)(struct s5p_mfc_ctx *ctx); | ||
27 | int (*alloc_dev_context_buffer)(struct s5p_mfc_dev *dev); | ||
28 | void (*release_dev_context_buffer)(struct s5p_mfc_dev *dev); | ||
29 | void (*dec_calc_dpb_size)(struct s5p_mfc_ctx *ctx); | ||
30 | void (*enc_calc_src_size)(struct s5p_mfc_ctx *ctx); | ||
31 | int (*set_dec_stream_buffer)(struct s5p_mfc_ctx *ctx, | ||
32 | int buf_addr, unsigned int start_num_byte, | ||
33 | unsigned int buf_size); | ||
34 | int (*set_dec_frame_buffer)(struct s5p_mfc_ctx *ctx); | ||
35 | int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx, | ||
36 | unsigned long addr, unsigned int size); | ||
37 | void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx, | ||
38 | unsigned long y_addr, unsigned long c_addr); | ||
39 | void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx, | ||
40 | unsigned long *y_addr, unsigned long *c_addr); | ||
41 | int (*set_enc_ref_buffer)(struct s5p_mfc_ctx *ctx); | ||
42 | int (*init_decode)(struct s5p_mfc_ctx *ctx); | ||
43 | int (*init_encode)(struct s5p_mfc_ctx *ctx); | ||
44 | int (*encode_one_frame)(struct s5p_mfc_ctx *ctx); | ||
45 | void (*try_run)(struct s5p_mfc_dev *dev); | ||
46 | void (*cleanup_queue)(struct list_head *lh, | ||
47 | struct vb2_queue *vq); | ||
48 | void (*clear_int_flags)(struct s5p_mfc_dev *dev); | ||
49 | void (*write_info)(struct s5p_mfc_ctx *ctx, unsigned int data, | ||
50 | unsigned int ofs); | ||
51 | unsigned int (*read_info)(struct s5p_mfc_ctx *ctx, | ||
52 | unsigned int ofs); | ||
53 | int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev); | ||
54 | int (*get_dec_y_adr)(struct s5p_mfc_dev *dev); | ||
55 | int (*get_dspl_status)(struct s5p_mfc_dev *dev); | ||
56 | int (*get_dec_status)(struct s5p_mfc_dev *dev); | ||
57 | int (*get_dec_frame_type)(struct s5p_mfc_dev *dev); | ||
58 | int (*get_disp_frame_type)(struct s5p_mfc_ctx *ctx); | ||
59 | int (*get_consumed_stream)(struct s5p_mfc_dev *dev); | ||
60 | int (*get_int_reason)(struct s5p_mfc_dev *dev); | ||
61 | int (*get_int_err)(struct s5p_mfc_dev *dev); | ||
62 | int (*err_dec)(unsigned int err); | ||
63 | int (*err_dspl)(unsigned int err); | ||
64 | int (*get_img_width)(struct s5p_mfc_dev *dev); | ||
65 | int (*get_img_height)(struct s5p_mfc_dev *dev); | ||
66 | int (*get_dpb_count)(struct s5p_mfc_dev *dev); | ||
67 | int (*get_mv_count)(struct s5p_mfc_dev *dev); | ||
68 | int (*get_inst_no)(struct s5p_mfc_dev *dev); | ||
69 | int (*get_enc_strm_size)(struct s5p_mfc_dev *dev); | ||
70 | int (*get_enc_slice_type)(struct s5p_mfc_dev *dev); | ||
71 | int (*get_enc_dpb_count)(struct s5p_mfc_dev *dev); | ||
72 | int (*get_enc_pic_count)(struct s5p_mfc_dev *dev); | ||
73 | int (*get_sei_avail_status)(struct s5p_mfc_ctx *ctx); | ||
74 | int (*get_mvc_num_views)(struct s5p_mfc_dev *dev); | ||
75 | int (*get_mvc_view_id)(struct s5p_mfc_dev *dev); | ||
76 | unsigned int (*get_pic_type_top)(struct s5p_mfc_ctx *ctx); | ||
77 | unsigned int (*get_pic_type_bot)(struct s5p_mfc_ctx *ctx); | ||
78 | unsigned int (*get_crop_info_h)(struct s5p_mfc_ctx *ctx); | ||
79 | unsigned int (*get_crop_info_v)(struct s5p_mfc_ctx *ctx); | ||
80 | }; | ||
81 | |||
82 | void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev); | ||
83 | |||
84 | #endif /* S5P_MFC_OPR_H_ */ | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index baa05af6ca88..17928c82c7f4 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/media/platform/samsung/mfc5/s5p_mfc_opr.c | 2 | * drivers/media/platform/samsung/mfc5/s5p_mfc_opr_v5.c |
3 | * | 3 | * |
4 | * Samsung MFC (Multi Function Codec - FIMV) driver | 4 | * Samsung MFC (Multi Function Codec - FIMV) driver |
5 | * This file contains hw related functions. | 5 | * This file contains hw related functions. |
@@ -12,14 +12,14 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include "regs-mfc.h" | ||
16 | #include "s5p_mfc_cmd_v5.h" | ||
17 | #include "s5p_mfc_common.h" | 15 | #include "s5p_mfc_common.h" |
16 | #include "s5p_mfc_cmd.h" | ||
18 | #include "s5p_mfc_ctrl.h" | 17 | #include "s5p_mfc_ctrl.h" |
19 | #include "s5p_mfc_debug.h" | 18 | #include "s5p_mfc_debug.h" |
20 | #include "s5p_mfc_intr.h" | 19 | #include "s5p_mfc_intr.h" |
21 | #include "s5p_mfc_opr_v5.h" | ||
22 | #include "s5p_mfc_pm.h" | 20 | #include "s5p_mfc_pm.h" |
21 | #include "s5p_mfc_opr.h" | ||
22 | #include "s5p_mfc_opr_v5.h" | ||
23 | #include <asm/cacheflush.h> | 23 | #include <asm/cacheflush.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
@@ -34,7 +34,7 @@ | |||
34 | #define OFFSETB(x) (((x) - dev->bank2) >> MFC_OFFSET_SHIFT) | 34 | #define OFFSETB(x) (((x) - dev->bank2) >> MFC_OFFSET_SHIFT) |
35 | 35 | ||
36 | /* Allocate temporary buffers for decoding */ | 36 | /* Allocate temporary buffers for decoding */ |
37 | int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx) | 37 | int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx) |
38 | { | 38 | { |
39 | void *desc_virt; | 39 | void *desc_virt; |
40 | struct s5p_mfc_dev *dev = ctx->dev; | 40 | struct s5p_mfc_dev *dev = ctx->dev; |
@@ -63,7 +63,7 @@ int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx) | |||
63 | } | 63 | } |
64 | 64 | ||
65 | /* Release temporary buffers for decoding */ | 65 | /* Release temporary buffers for decoding */ |
66 | void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx) | 66 | void s5p_mfc_release_dec_desc_buffer_v5(struct s5p_mfc_ctx *ctx) |
67 | { | 67 | { |
68 | if (ctx->desc_phys) { | 68 | if (ctx->desc_phys) { |
69 | vb2_dma_contig_memops.put(ctx->desc_buf); | 69 | vb2_dma_contig_memops.put(ctx->desc_buf); |
@@ -73,7 +73,7 @@ void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx) | |||
73 | } | 73 | } |
74 | 74 | ||
75 | /* Allocate codec buffers */ | 75 | /* Allocate codec buffers */ |
76 | int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx) | 76 | int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx) |
77 | { | 77 | { |
78 | struct s5p_mfc_dev *dev = ctx->dev; | 78 | struct s5p_mfc_dev *dev = ctx->dev; |
79 | unsigned int enc_ref_y_size = 0; | 79 | unsigned int enc_ref_y_size = 0; |
@@ -89,7 +89,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx) | |||
89 | * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN); | 89 | * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN); |
90 | enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN); | 90 | enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN); |
91 | 91 | ||
92 | if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) { | 92 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) { |
93 | enc_ref_c_size = ALIGN(ctx->img_width, | 93 | enc_ref_c_size = ALIGN(ctx->img_width, |
94 | S5P_FIMV_NV12MT_HALIGN) | 94 | S5P_FIMV_NV12MT_HALIGN) |
95 | * ALIGN(ctx->img_height >> 1, | 95 | * ALIGN(ctx->img_height >> 1, |
@@ -111,14 +111,14 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx) | |||
111 | } | 111 | } |
112 | /* Codecs have different memory requirements */ | 112 | /* Codecs have different memory requirements */ |
113 | switch (ctx->codec_mode) { | 113 | switch (ctx->codec_mode) { |
114 | case S5P_FIMV_CODEC_H264_DEC: | 114 | case S5P_MFC_CODEC_H264_DEC: |
115 | ctx->bank1_size = | 115 | ctx->bank1_size = |
116 | ALIGN(S5P_FIMV_DEC_NB_IP_SIZE + | 116 | ALIGN(S5P_FIMV_DEC_NB_IP_SIZE + |
117 | S5P_FIMV_DEC_VERT_NB_MV_SIZE, | 117 | S5P_FIMV_DEC_VERT_NB_MV_SIZE, |
118 | S5P_FIMV_DEC_BUF_ALIGN); | 118 | S5P_FIMV_DEC_BUF_ALIGN); |
119 | ctx->bank2_size = ctx->total_dpb_count * ctx->mv_size; | 119 | ctx->bank2_size = ctx->total_dpb_count * ctx->mv_size; |
120 | break; | 120 | break; |
121 | case S5P_FIMV_CODEC_MPEG4_DEC: | 121 | case S5P_MFC_CODEC_MPEG4_DEC: |
122 | ctx->bank1_size = | 122 | ctx->bank1_size = |
123 | ALIGN(S5P_FIMV_DEC_NB_DCAC_SIZE + | 123 | ALIGN(S5P_FIMV_DEC_NB_DCAC_SIZE + |
124 | S5P_FIMV_DEC_UPNB_MV_SIZE + | 124 | S5P_FIMV_DEC_UPNB_MV_SIZE + |
@@ -128,8 +128,8 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx) | |||
128 | S5P_FIMV_DEC_BUF_ALIGN); | 128 | S5P_FIMV_DEC_BUF_ALIGN); |
129 | ctx->bank2_size = 0; | 129 | ctx->bank2_size = 0; |
130 | break; | 130 | break; |
131 | case S5P_FIMV_CODEC_VC1RCV_DEC: | 131 | case S5P_MFC_CODEC_VC1RCV_DEC: |
132 | case S5P_FIMV_CODEC_VC1_DEC: | 132 | case S5P_MFC_CODEC_VC1_DEC: |
133 | ctx->bank1_size = | 133 | ctx->bank1_size = |
134 | ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE + | 134 | ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE + |
135 | S5P_FIMV_DEC_UPNB_MV_SIZE + | 135 | S5P_FIMV_DEC_UPNB_MV_SIZE + |
@@ -139,11 +139,11 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx) | |||
139 | S5P_FIMV_DEC_BUF_ALIGN); | 139 | S5P_FIMV_DEC_BUF_ALIGN); |
140 | ctx->bank2_size = 0; | 140 | ctx->bank2_size = 0; |
141 | break; | 141 | break; |
142 | case S5P_FIMV_CODEC_MPEG2_DEC: | 142 | case S5P_MFC_CODEC_MPEG2_DEC: |
143 | ctx->bank1_size = 0; | 143 | ctx->bank1_size = 0; |
144 | ctx->bank2_size = 0; | 144 | ctx->bank2_size = 0; |
145 | break; | 145 | break; |
146 | case S5P_FIMV_CODEC_H263_DEC: | 146 | case S5P_MFC_CODEC_H263_DEC: |
147 | ctx->bank1_size = | 147 | ctx->bank1_size = |
148 | ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE + | 148 | ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE + |
149 | S5P_FIMV_DEC_UPNB_MV_SIZE + | 149 | S5P_FIMV_DEC_UPNB_MV_SIZE + |
@@ -152,7 +152,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx) | |||
152 | S5P_FIMV_DEC_BUF_ALIGN); | 152 | S5P_FIMV_DEC_BUF_ALIGN); |
153 | ctx->bank2_size = 0; | 153 | ctx->bank2_size = 0; |
154 | break; | 154 | break; |
155 | case S5P_FIMV_CODEC_H264_ENC: | 155 | case S5P_MFC_CODEC_H264_ENC: |
156 | ctx->bank1_size = (enc_ref_y_size * 2) + | 156 | ctx->bank1_size = (enc_ref_y_size * 2) + |
157 | S5P_FIMV_ENC_UPMV_SIZE + | 157 | S5P_FIMV_ENC_UPMV_SIZE + |
158 | S5P_FIMV_ENC_COLFLG_SIZE + | 158 | S5P_FIMV_ENC_COLFLG_SIZE + |
@@ -162,7 +162,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx) | |||
162 | (enc_ref_c_size * 4) + | 162 | (enc_ref_c_size * 4) + |
163 | S5P_FIMV_ENC_INTRAPRED_SIZE; | 163 | S5P_FIMV_ENC_INTRAPRED_SIZE; |
164 | break; | 164 | break; |
165 | case S5P_FIMV_CODEC_MPEG4_ENC: | 165 | case S5P_MFC_CODEC_MPEG4_ENC: |
166 | ctx->bank1_size = (enc_ref_y_size * 2) + | 166 | ctx->bank1_size = (enc_ref_y_size * 2) + |
167 | S5P_FIMV_ENC_UPMV_SIZE + | 167 | S5P_FIMV_ENC_UPMV_SIZE + |
168 | S5P_FIMV_ENC_COLFLG_SIZE + | 168 | S5P_FIMV_ENC_COLFLG_SIZE + |
@@ -170,7 +170,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx) | |||
170 | ctx->bank2_size = (enc_ref_y_size * 2) + | 170 | ctx->bank2_size = (enc_ref_y_size * 2) + |
171 | (enc_ref_c_size * 4); | 171 | (enc_ref_c_size * 4); |
172 | break; | 172 | break; |
173 | case S5P_FIMV_CODEC_H263_ENC: | 173 | case S5P_MFC_CODEC_H263_ENC: |
174 | ctx->bank1_size = (enc_ref_y_size * 2) + | 174 | ctx->bank1_size = (enc_ref_y_size * 2) + |
175 | S5P_FIMV_ENC_UPMV_SIZE + | 175 | S5P_FIMV_ENC_UPMV_SIZE + |
176 | S5P_FIMV_ENC_ACDCCOEF_SIZE; | 176 | S5P_FIMV_ENC_ACDCCOEF_SIZE; |
@@ -211,7 +211,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx) | |||
211 | } | 211 | } |
212 | 212 | ||
213 | /* Release buffers allocated for codec */ | 213 | /* Release buffers allocated for codec */ |
214 | void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx) | 214 | void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx *ctx) |
215 | { | 215 | { |
216 | if (ctx->bank1_buf) { | 216 | if (ctx->bank1_buf) { |
217 | vb2_dma_contig_memops.put(ctx->bank1_buf); | 217 | vb2_dma_contig_memops.put(ctx->bank1_buf); |
@@ -228,7 +228,7 @@ void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx) | |||
228 | } | 228 | } |
229 | 229 | ||
230 | /* Allocate memory for instance data buffer */ | 230 | /* Allocate memory for instance data buffer */ |
231 | int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx) | 231 | int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx) |
232 | { | 232 | { |
233 | void *context_virt; | 233 | void *context_virt; |
234 | struct s5p_mfc_dev *dev = ctx->dev; | 234 | struct s5p_mfc_dev *dev = ctx->dev; |
@@ -289,7 +289,7 @@ int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx) | |||
289 | } | 289 | } |
290 | 290 | ||
291 | /* Release instance buffer */ | 291 | /* Release instance buffer */ |
292 | void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx) | 292 | void s5p_mfc_release_instance_buffer_v5(struct s5p_mfc_ctx *ctx) |
293 | { | 293 | { |
294 | if (ctx->ctx_buf) { | 294 | if (ctx->ctx_buf) { |
295 | vb2_dma_contig_memops.put(ctx->ctx_buf); | 295 | vb2_dma_contig_memops.put(ctx->ctx_buf); |
@@ -303,22 +303,44 @@ void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx) | |||
303 | } | 303 | } |
304 | } | 304 | } |
305 | 305 | ||
306 | void s5p_mfc_write_info_v5(struct s5p_mfc_ctx *ctx, unsigned int data, | 306 | int s5p_mfc_alloc_dev_context_buffer_v5(struct s5p_mfc_dev *dev) |
307 | { | ||
308 | /* NOP */ | ||
309 | |||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | void s5p_mfc_release_dev_context_buffer_v5(struct s5p_mfc_dev *dev) | ||
314 | { | ||
315 | /* NOP */ | ||
316 | } | ||
317 | |||
318 | static void s5p_mfc_write_info_v5(struct s5p_mfc_ctx *ctx, unsigned int data, | ||
307 | unsigned int ofs) | 319 | unsigned int ofs) |
308 | { | 320 | { |
309 | writel(data, (ctx->shm + ofs)); | 321 | writel(data, (ctx->shm + ofs)); |
310 | wmb(); | 322 | wmb(); |
311 | } | 323 | } |
312 | 324 | ||
313 | unsigned int s5p_mfc_read_info_v5(struct s5p_mfc_ctx *ctx, | 325 | static unsigned int s5p_mfc_read_info_v5(struct s5p_mfc_ctx *ctx, |
314 | unsigned int ofs) | 326 | unsigned int ofs) |
315 | { | 327 | { |
316 | rmb(); | 328 | rmb(); |
317 | return readl(ctx->shm + ofs); | 329 | return readl(ctx->shm + ofs); |
318 | } | 330 | } |
319 | 331 | ||
332 | void s5p_mfc_dec_calc_dpb_size_v5(struct s5p_mfc_ctx *ctx) | ||
333 | { | ||
334 | /* NOP */ | ||
335 | } | ||
336 | |||
337 | void s5p_mfc_enc_calc_src_size_v5(struct s5p_mfc_ctx *ctx) | ||
338 | { | ||
339 | /* NOP */ | ||
340 | } | ||
341 | |||
320 | /* Set registers for decoding temporary buffers */ | 342 | /* Set registers for decoding temporary buffers */ |
321 | void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx) | 343 | static void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx) |
322 | { | 344 | { |
323 | struct s5p_mfc_dev *dev = ctx->dev; | 345 | struct s5p_mfc_dev *dev = ctx->dev; |
324 | 346 | ||
@@ -334,7 +356,7 @@ static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx) | |||
334 | } | 356 | } |
335 | 357 | ||
336 | /* Set registers for decoding stream buffer */ | 358 | /* Set registers for decoding stream buffer */ |
337 | int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr, | 359 | int s5p_mfc_set_dec_stream_buffer_v5(struct s5p_mfc_ctx *ctx, int buf_addr, |
338 | unsigned int start_num_byte, unsigned int buf_size) | 360 | unsigned int start_num_byte, unsigned int buf_size) |
339 | { | 361 | { |
340 | struct s5p_mfc_dev *dev = ctx->dev; | 362 | struct s5p_mfc_dev *dev = ctx->dev; |
@@ -347,7 +369,7 @@ int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr, | |||
347 | } | 369 | } |
348 | 370 | ||
349 | /* Set decoding frame buffer */ | 371 | /* Set decoding frame buffer */ |
350 | int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx) | 372 | int s5p_mfc_set_dec_frame_buffer_v5(struct s5p_mfc_ctx *ctx) |
351 | { | 373 | { |
352 | unsigned int frame_size, i; | 374 | unsigned int frame_size, i; |
353 | unsigned int frame_size_ch, frame_size_mv; | 375 | unsigned int frame_size_ch, frame_size_mv; |
@@ -366,7 +388,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx) | |||
366 | S5P_FIMV_SI_CH0_DPB_CONF_CTRL); | 388 | S5P_FIMV_SI_CH0_DPB_CONF_CTRL); |
367 | s5p_mfc_set_shared_buffer(ctx); | 389 | s5p_mfc_set_shared_buffer(ctx); |
368 | switch (ctx->codec_mode) { | 390 | switch (ctx->codec_mode) { |
369 | case S5P_FIMV_CODEC_H264_DEC: | 391 | case S5P_MFC_CODEC_H264_DEC: |
370 | mfc_write(dev, OFFSETA(buf_addr1), | 392 | mfc_write(dev, OFFSETA(buf_addr1), |
371 | S5P_FIMV_H264_VERT_NB_MV_ADR); | 393 | S5P_FIMV_H264_VERT_NB_MV_ADR); |
372 | buf_addr1 += S5P_FIMV_DEC_VERT_NB_MV_SIZE; | 394 | buf_addr1 += S5P_FIMV_DEC_VERT_NB_MV_SIZE; |
@@ -375,7 +397,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx) | |||
375 | buf_addr1 += S5P_FIMV_DEC_NB_IP_SIZE; | 397 | buf_addr1 += S5P_FIMV_DEC_NB_IP_SIZE; |
376 | buf_size1 -= S5P_FIMV_DEC_NB_IP_SIZE; | 398 | buf_size1 -= S5P_FIMV_DEC_NB_IP_SIZE; |
377 | break; | 399 | break; |
378 | case S5P_FIMV_CODEC_MPEG4_DEC: | 400 | case S5P_MFC_CODEC_MPEG4_DEC: |
379 | mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_NB_DCAC_ADR); | 401 | mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_NB_DCAC_ADR); |
380 | buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE; | 402 | buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE; |
381 | buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE; | 403 | buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE; |
@@ -392,7 +414,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx) | |||
392 | buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE; | 414 | buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE; |
393 | buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE; | 415 | buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE; |
394 | break; | 416 | break; |
395 | case S5P_FIMV_CODEC_H263_DEC: | 417 | case S5P_MFC_CODEC_H263_DEC: |
396 | mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_OT_LINE_ADR); | 418 | mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_OT_LINE_ADR); |
397 | buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE; | 419 | buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE; |
398 | buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE; | 420 | buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE; |
@@ -406,8 +428,8 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx) | |||
406 | buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE; | 428 | buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE; |
407 | buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE; | 429 | buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE; |
408 | break; | 430 | break; |
409 | case S5P_FIMV_CODEC_VC1_DEC: | 431 | case S5P_MFC_CODEC_VC1_DEC: |
410 | case S5P_FIMV_CODEC_VC1RCV_DEC: | 432 | case S5P_MFC_CODEC_VC1RCV_DEC: |
411 | mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_NB_DCAC_ADR); | 433 | mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_NB_DCAC_ADR); |
412 | buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE; | 434 | buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE; |
413 | buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE; | 435 | buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE; |
@@ -430,7 +452,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx) | |||
430 | buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE; | 452 | buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE; |
431 | buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE; | 453 | buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE; |
432 | break; | 454 | break; |
433 | case S5P_FIMV_CODEC_MPEG2_DEC: | 455 | case S5P_MFC_CODEC_MPEG2_DEC: |
434 | break; | 456 | break; |
435 | default: | 457 | default: |
436 | mfc_err("Unknown codec for decoding (%x)\n", | 458 | mfc_err("Unknown codec for decoding (%x)\n", |
@@ -453,7 +475,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx) | |||
453 | ctx->dst_bufs[i].cookie.raw.chroma); | 475 | ctx->dst_bufs[i].cookie.raw.chroma); |
454 | mfc_write(dev, OFFSETA(ctx->dst_bufs[i].cookie.raw.chroma), | 476 | mfc_write(dev, OFFSETA(ctx->dst_bufs[i].cookie.raw.chroma), |
455 | S5P_FIMV_DEC_CHROMA_ADR + i * 4); | 477 | S5P_FIMV_DEC_CHROMA_ADR + i * 4); |
456 | if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) { | 478 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC) { |
457 | mfc_debug(2, "\tBuf2: %x, size: %d\n", | 479 | mfc_debug(2, "\tBuf2: %x, size: %d\n", |
458 | buf_addr2, buf_size2); | 480 | buf_addr2, buf_size2); |
459 | mfc_write(dev, OFFSETB(buf_addr2), | 481 | mfc_write(dev, OFFSETB(buf_addr2), |
@@ -471,7 +493,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx) | |||
471 | } | 493 | } |
472 | s5p_mfc_write_info_v5(ctx, frame_size, ALLOC_LUMA_DPB_SIZE); | 494 | s5p_mfc_write_info_v5(ctx, frame_size, ALLOC_LUMA_DPB_SIZE); |
473 | s5p_mfc_write_info_v5(ctx, frame_size_ch, ALLOC_CHROMA_DPB_SIZE); | 495 | s5p_mfc_write_info_v5(ctx, frame_size_ch, ALLOC_CHROMA_DPB_SIZE); |
474 | if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) | 496 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC) |
475 | s5p_mfc_write_info_v5(ctx, frame_size_mv, ALLOC_MV_SIZE); | 497 | s5p_mfc_write_info_v5(ctx, frame_size_mv, ALLOC_MV_SIZE); |
476 | mfc_write(dev, ((S5P_FIMV_CH_INIT_BUFS & S5P_FIMV_CH_MASK) | 498 | mfc_write(dev, ((S5P_FIMV_CH_INIT_BUFS & S5P_FIMV_CH_MASK) |
477 | << S5P_FIMV_CH_SHIFT) | (ctx->inst_no), | 499 | << S5P_FIMV_CH_SHIFT) | (ctx->inst_no), |
@@ -480,7 +502,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx) | |||
480 | } | 502 | } |
481 | 503 | ||
482 | /* Set registers for encoding stream buffer */ | 504 | /* Set registers for encoding stream buffer */ |
483 | int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx, | 505 | int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx, |
484 | unsigned long addr, unsigned int size) | 506 | unsigned long addr, unsigned int size) |
485 | { | 507 | { |
486 | struct s5p_mfc_dev *dev = ctx->dev; | 508 | struct s5p_mfc_dev *dev = ctx->dev; |
@@ -490,7 +512,7 @@ int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx, | |||
490 | return 0; | 512 | return 0; |
491 | } | 513 | } |
492 | 514 | ||
493 | void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx, | 515 | void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx, |
494 | unsigned long y_addr, unsigned long c_addr) | 516 | unsigned long y_addr, unsigned long c_addr) |
495 | { | 517 | { |
496 | struct s5p_mfc_dev *dev = ctx->dev; | 518 | struct s5p_mfc_dev *dev = ctx->dev; |
@@ -499,7 +521,7 @@ void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx, | |||
499 | mfc_write(dev, OFFSETB(c_addr), S5P_FIMV_ENC_SI_CH0_CUR_C_ADR); | 521 | mfc_write(dev, OFFSETB(c_addr), S5P_FIMV_ENC_SI_CH0_CUR_C_ADR); |
500 | } | 522 | } |
501 | 523 | ||
502 | void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx, | 524 | void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx, |
503 | unsigned long *y_addr, unsigned long *c_addr) | 525 | unsigned long *y_addr, unsigned long *c_addr) |
504 | { | 526 | { |
505 | struct s5p_mfc_dev *dev = ctx->dev; | 527 | struct s5p_mfc_dev *dev = ctx->dev; |
@@ -511,7 +533,7 @@ void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx, | |||
511 | } | 533 | } |
512 | 534 | ||
513 | /* Set encoding ref & codec buffer */ | 535 | /* Set encoding ref & codec buffer */ |
514 | int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx) | 536 | int s5p_mfc_set_enc_ref_buffer_v5(struct s5p_mfc_ctx *ctx) |
515 | { | 537 | { |
516 | struct s5p_mfc_dev *dev = ctx->dev; | 538 | struct s5p_mfc_dev *dev = ctx->dev; |
517 | size_t buf_addr1, buf_addr2; | 539 | size_t buf_addr1, buf_addr2; |
@@ -527,7 +549,7 @@ int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx) | |||
527 | enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN) | 549 | enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN) |
528 | * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN); | 550 | * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN); |
529 | enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN); | 551 | enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN); |
530 | if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) { | 552 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) { |
531 | enc_ref_c_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN) | 553 | enc_ref_c_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN) |
532 | * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN); | 554 | * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN); |
533 | enc_ref_c_size = ALIGN(enc_ref_c_size, S5P_FIMV_NV12MT_SALIGN); | 555 | enc_ref_c_size = ALIGN(enc_ref_c_size, S5P_FIMV_NV12MT_SALIGN); |
@@ -541,7 +563,7 @@ int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx) | |||
541 | } | 563 | } |
542 | mfc_debug(2, "buf_size1: %d, buf_size2: %d\n", buf_size1, buf_size2); | 564 | mfc_debug(2, "buf_size1: %d, buf_size2: %d\n", buf_size1, buf_size2); |
543 | switch (ctx->codec_mode) { | 565 | switch (ctx->codec_mode) { |
544 | case S5P_FIMV_CODEC_H264_ENC: | 566 | case S5P_MFC_CODEC_H264_ENC: |
545 | for (i = 0; i < 2; i++) { | 567 | for (i = 0; i < 2; i++) { |
546 | mfc_write(dev, OFFSETA(buf_addr1), | 568 | mfc_write(dev, OFFSETA(buf_addr1), |
547 | S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i)); | 569 | S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i)); |
@@ -581,7 +603,7 @@ int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx) | |||
581 | mfc_debug(2, "buf_size1: %d, buf_size2: %d\n", | 603 | mfc_debug(2, "buf_size1: %d, buf_size2: %d\n", |
582 | buf_size1, buf_size2); | 604 | buf_size1, buf_size2); |
583 | break; | 605 | break; |
584 | case S5P_FIMV_CODEC_MPEG4_ENC: | 606 | case S5P_MFC_CODEC_MPEG4_ENC: |
585 | for (i = 0; i < 2; i++) { | 607 | for (i = 0; i < 2; i++) { |
586 | mfc_write(dev, OFFSETA(buf_addr1), | 608 | mfc_write(dev, OFFSETA(buf_addr1), |
587 | S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i)); | 609 | S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i)); |
@@ -612,7 +634,7 @@ int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx) | |||
612 | mfc_debug(2, "buf_size1: %d, buf_size2: %d\n", | 634 | mfc_debug(2, "buf_size1: %d, buf_size2: %d\n", |
613 | buf_size1, buf_size2); | 635 | buf_size1, buf_size2); |
614 | break; | 636 | break; |
615 | case S5P_FIMV_CODEC_H263_ENC: | 637 | case S5P_MFC_CODEC_H263_ENC: |
616 | for (i = 0; i < 2; i++) { | 638 | for (i = 0; i < 2; i++) { |
617 | mfc_write(dev, OFFSETA(buf_addr1), | 639 | mfc_write(dev, OFFSETA(buf_addr1), |
618 | S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i)); | 640 | S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i)); |
@@ -1016,13 +1038,13 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) | |||
1016 | } | 1038 | } |
1017 | 1039 | ||
1018 | /* Initialize decoding */ | 1040 | /* Initialize decoding */ |
1019 | int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx) | 1041 | int s5p_mfc_init_decode_v5(struct s5p_mfc_ctx *ctx) |
1020 | { | 1042 | { |
1021 | struct s5p_mfc_dev *dev = ctx->dev; | 1043 | struct s5p_mfc_dev *dev = ctx->dev; |
1022 | 1044 | ||
1023 | s5p_mfc_set_shared_buffer(ctx); | 1045 | s5p_mfc_set_shared_buffer(ctx); |
1024 | /* Setup loop filter, for decoding this is only valid for MPEG4 */ | 1046 | /* Setup loop filter, for decoding this is only valid for MPEG4 */ |
1025 | if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_DEC) | 1047 | if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_DEC) |
1026 | mfc_write(dev, ctx->loop_filter_mpeg4, S5P_FIMV_ENC_LF_CTRL); | 1048 | mfc_write(dev, ctx->loop_filter_mpeg4, S5P_FIMV_ENC_LF_CTRL); |
1027 | else | 1049 | else |
1028 | mfc_write(dev, 0, S5P_FIMV_ENC_LF_CTRL); | 1050 | mfc_write(dev, 0, S5P_FIMV_ENC_LF_CTRL); |
@@ -1052,7 +1074,7 @@ static void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush) | |||
1052 | } | 1074 | } |
1053 | 1075 | ||
1054 | /* Decode a single frame */ | 1076 | /* Decode a single frame */ |
1055 | int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx, | 1077 | int s5p_mfc_decode_one_frame_v5(struct s5p_mfc_ctx *ctx, |
1056 | enum s5p_mfc_decode_arg last_frame) | 1078 | enum s5p_mfc_decode_arg last_frame) |
1057 | { | 1079 | { |
1058 | struct s5p_mfc_dev *dev = ctx->dev; | 1080 | struct s5p_mfc_dev *dev = ctx->dev; |
@@ -1081,15 +1103,15 @@ int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx, | |||
1081 | return 0; | 1103 | return 0; |
1082 | } | 1104 | } |
1083 | 1105 | ||
1084 | int s5p_mfc_init_encode(struct s5p_mfc_ctx *ctx) | 1106 | int s5p_mfc_init_encode_v5(struct s5p_mfc_ctx *ctx) |
1085 | { | 1107 | { |
1086 | struct s5p_mfc_dev *dev = ctx->dev; | 1108 | struct s5p_mfc_dev *dev = ctx->dev; |
1087 | 1109 | ||
1088 | if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) | 1110 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) |
1089 | s5p_mfc_set_enc_params_h264(ctx); | 1111 | s5p_mfc_set_enc_params_h264(ctx); |
1090 | else if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_ENC) | 1112 | else if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_ENC) |
1091 | s5p_mfc_set_enc_params_mpeg4(ctx); | 1113 | s5p_mfc_set_enc_params_mpeg4(ctx); |
1092 | else if (ctx->codec_mode == S5P_FIMV_CODEC_H263_ENC) | 1114 | else if (ctx->codec_mode == S5P_MFC_CODEC_H263_ENC) |
1093 | s5p_mfc_set_enc_params_h263(ctx); | 1115 | s5p_mfc_set_enc_params_h263(ctx); |
1094 | else { | 1116 | else { |
1095 | mfc_err("Unknown codec for encoding (%x)\n", | 1117 | mfc_err("Unknown codec for encoding (%x)\n", |
@@ -1103,7 +1125,7 @@ int s5p_mfc_init_encode(struct s5p_mfc_ctx *ctx) | |||
1103 | } | 1125 | } |
1104 | 1126 | ||
1105 | /* Encode a single frame */ | 1127 | /* Encode a single frame */ |
1106 | int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx) | 1128 | int s5p_mfc_encode_one_frame_v5(struct s5p_mfc_ctx *ctx) |
1107 | { | 1129 | { |
1108 | struct s5p_mfc_dev *dev = ctx->dev; | 1130 | struct s5p_mfc_dev *dev = ctx->dev; |
1109 | int cmd; | 1131 | int cmd; |
@@ -1149,10 +1171,10 @@ static void s5p_mfc_run_res_change(struct s5p_mfc_ctx *ctx) | |||
1149 | { | 1171 | { |
1150 | struct s5p_mfc_dev *dev = ctx->dev; | 1172 | struct s5p_mfc_dev *dev = ctx->dev; |
1151 | 1173 | ||
1152 | s5p_mfc_set_dec_stream_buffer(ctx, 0, 0, 0); | 1174 | s5p_mfc_set_dec_stream_buffer_v5(ctx, 0, 0, 0); |
1153 | dev->curr_ctx = ctx->num; | 1175 | dev->curr_ctx = ctx->num; |
1154 | s5p_mfc_clean_ctx_int_flags(ctx); | 1176 | s5p_mfc_clean_ctx_int_flags(ctx); |
1155 | s5p_mfc_decode_one_frame(ctx, MFC_DEC_RES_CHANGE); | 1177 | s5p_mfc_decode_one_frame_v5(ctx, MFC_DEC_RES_CHANGE); |
1156 | } | 1178 | } |
1157 | 1179 | ||
1158 | static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame) | 1180 | static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame) |
@@ -1172,9 +1194,9 @@ static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame) | |||
1172 | /* Get the next source buffer */ | 1194 | /* Get the next source buffer */ |
1173 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); | 1195 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); |
1174 | temp_vb->flags |= MFC_BUF_FLAG_USED; | 1196 | temp_vb->flags |= MFC_BUF_FLAG_USED; |
1175 | s5p_mfc_set_dec_stream_buffer(ctx, | 1197 | s5p_mfc_set_dec_stream_buffer_v5(ctx, |
1176 | vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), ctx->consumed_stream, | 1198 | vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), |
1177 | temp_vb->b->v4l2_planes[0].bytesused); | 1199 | ctx->consumed_stream, temp_vb->b->v4l2_planes[0].bytesused); |
1178 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1200 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1179 | index = temp_vb->b->v4l2_buf.index; | 1201 | index = temp_vb->b->v4l2_buf.index; |
1180 | dev->curr_ctx = ctx->num; | 1202 | dev->curr_ctx = ctx->num; |
@@ -1184,7 +1206,7 @@ static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame) | |||
1184 | mfc_debug(2, "Setting ctx->state to FINISHING\n"); | 1206 | mfc_debug(2, "Setting ctx->state to FINISHING\n"); |
1185 | ctx->state = MFCINST_FINISHING; | 1207 | ctx->state = MFCINST_FINISHING; |
1186 | } | 1208 | } |
1187 | s5p_mfc_decode_one_frame(ctx, last_frame); | 1209 | s5p_mfc_decode_one_frame_v5(ctx, last_frame); |
1188 | return 0; | 1210 | return 0; |
1189 | } | 1211 | } |
1190 | 1212 | ||
@@ -1210,7 +1232,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) | |||
1210 | } | 1232 | } |
1211 | if (list_empty(&ctx->src_queue)) { | 1233 | if (list_empty(&ctx->src_queue)) { |
1212 | /* send null frame */ | 1234 | /* send null frame */ |
1213 | s5p_mfc_set_enc_frame_buffer(ctx, dev->bank2, dev->bank2); | 1235 | s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->bank2, dev->bank2); |
1214 | src_mb = NULL; | 1236 | src_mb = NULL; |
1215 | } else { | 1237 | } else { |
1216 | src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, | 1238 | src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, |
@@ -1218,7 +1240,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) | |||
1218 | src_mb->flags |= MFC_BUF_FLAG_USED; | 1240 | src_mb->flags |= MFC_BUF_FLAG_USED; |
1219 | if (src_mb->b->v4l2_planes[0].bytesused == 0) { | 1241 | if (src_mb->b->v4l2_planes[0].bytesused == 0) { |
1220 | /* send null frame */ | 1242 | /* send null frame */ |
1221 | s5p_mfc_set_enc_frame_buffer(ctx, dev->bank2, | 1243 | s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->bank2, |
1222 | dev->bank2); | 1244 | dev->bank2); |
1223 | ctx->state = MFCINST_FINISHING; | 1245 | ctx->state = MFCINST_FINISHING; |
1224 | } else { | 1246 | } else { |
@@ -1226,7 +1248,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) | |||
1226 | 0); | 1248 | 0); |
1227 | src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, | 1249 | src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, |
1228 | 1); | 1250 | 1); |
1229 | s5p_mfc_set_enc_frame_buffer(ctx, src_y_addr, | 1251 | s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr, |
1230 | src_c_addr); | 1252 | src_c_addr); |
1231 | if (src_mb->flags & MFC_BUF_FLAG_EOS) | 1253 | if (src_mb->flags & MFC_BUF_FLAG_EOS) |
1232 | ctx->state = MFCINST_FINISHING; | 1254 | ctx->state = MFCINST_FINISHING; |
@@ -1236,13 +1258,13 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) | |||
1236 | dst_mb->flags |= MFC_BUF_FLAG_USED; | 1258 | dst_mb->flags |= MFC_BUF_FLAG_USED; |
1237 | dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0); | 1259 | dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0); |
1238 | dst_size = vb2_plane_size(dst_mb->b, 0); | 1260 | dst_size = vb2_plane_size(dst_mb->b, 0); |
1239 | s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size); | 1261 | s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size); |
1240 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1262 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1241 | dev->curr_ctx = ctx->num; | 1263 | dev->curr_ctx = ctx->num; |
1242 | s5p_mfc_clean_ctx_int_flags(ctx); | 1264 | s5p_mfc_clean_ctx_int_flags(ctx); |
1243 | mfc_debug(2, "encoding buffer with index=%d state=%d", | 1265 | mfc_debug(2, "encoding buffer with index=%d state=%d", |
1244 | src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state); | 1266 | src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state); |
1245 | s5p_mfc_encode_one_frame(ctx); | 1267 | s5p_mfc_encode_one_frame_v5(ctx); |
1246 | return 0; | 1268 | return 0; |
1247 | } | 1269 | } |
1248 | 1270 | ||
@@ -1258,13 +1280,13 @@ static void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx) | |||
1258 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); | 1280 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); |
1259 | s5p_mfc_set_dec_desc_buffer(ctx); | 1281 | s5p_mfc_set_dec_desc_buffer(ctx); |
1260 | mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused); | 1282 | mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused); |
1261 | s5p_mfc_set_dec_stream_buffer(ctx, | 1283 | s5p_mfc_set_dec_stream_buffer_v5(ctx, |
1262 | vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), | 1284 | vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), |
1263 | 0, temp_vb->b->v4l2_planes[0].bytesused); | 1285 | 0, temp_vb->b->v4l2_planes[0].bytesused); |
1264 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1286 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1265 | dev->curr_ctx = ctx->num; | 1287 | dev->curr_ctx = ctx->num; |
1266 | s5p_mfc_clean_ctx_int_flags(ctx); | 1288 | s5p_mfc_clean_ctx_int_flags(ctx); |
1267 | s5p_mfc_init_decode(ctx); | 1289 | s5p_mfc_init_decode_v5(ctx); |
1268 | } | 1290 | } |
1269 | 1291 | ||
1270 | static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx) | 1292 | static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx) |
@@ -1275,16 +1297,16 @@ static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx) | |||
1275 | unsigned long dst_addr; | 1297 | unsigned long dst_addr; |
1276 | unsigned int dst_size; | 1298 | unsigned int dst_size; |
1277 | 1299 | ||
1278 | s5p_mfc_set_enc_ref_buffer(ctx); | 1300 | s5p_mfc_set_enc_ref_buffer_v5(ctx); |
1279 | spin_lock_irqsave(&dev->irqlock, flags); | 1301 | spin_lock_irqsave(&dev->irqlock, flags); |
1280 | dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); | 1302 | dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); |
1281 | dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0); | 1303 | dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0); |
1282 | dst_size = vb2_plane_size(dst_mb->b, 0); | 1304 | dst_size = vb2_plane_size(dst_mb->b, 0); |
1283 | s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size); | 1305 | s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size); |
1284 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1306 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1285 | dev->curr_ctx = ctx->num; | 1307 | dev->curr_ctx = ctx->num; |
1286 | s5p_mfc_clean_ctx_int_flags(ctx); | 1308 | s5p_mfc_clean_ctx_int_flags(ctx); |
1287 | s5p_mfc_init_encode(ctx); | 1309 | s5p_mfc_init_encode_v5(ctx); |
1288 | } | 1310 | } |
1289 | 1311 | ||
1290 | static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) | 1312 | static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) |
@@ -1313,13 +1335,13 @@ static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) | |||
1313 | } | 1335 | } |
1314 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); | 1336 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); |
1315 | mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused); | 1337 | mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused); |
1316 | s5p_mfc_set_dec_stream_buffer(ctx, | 1338 | s5p_mfc_set_dec_stream_buffer_v5(ctx, |
1317 | vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), | 1339 | vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), |
1318 | 0, temp_vb->b->v4l2_planes[0].bytesused); | 1340 | 0, temp_vb->b->v4l2_planes[0].bytesused); |
1319 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1341 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1320 | dev->curr_ctx = ctx->num; | 1342 | dev->curr_ctx = ctx->num; |
1321 | s5p_mfc_clean_ctx_int_flags(ctx); | 1343 | s5p_mfc_clean_ctx_int_flags(ctx); |
1322 | ret = s5p_mfc_set_dec_frame_buffer(ctx); | 1344 | ret = s5p_mfc_set_dec_frame_buffer_v5(ctx); |
1323 | if (ret) { | 1345 | if (ret) { |
1324 | mfc_err("Failed to alloc frame mem\n"); | 1346 | mfc_err("Failed to alloc frame mem\n"); |
1325 | ctx->state = MFCINST_ERROR; | 1347 | ctx->state = MFCINST_ERROR; |
@@ -1328,7 +1350,7 @@ static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) | |||
1328 | } | 1350 | } |
1329 | 1351 | ||
1330 | /* Try running an operation on hardware */ | 1352 | /* Try running an operation on hardware */ |
1331 | void s5p_mfc_try_run(struct s5p_mfc_dev *dev) | 1353 | void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) |
1332 | { | 1354 | { |
1333 | struct s5p_mfc_ctx *ctx; | 1355 | struct s5p_mfc_ctx *ctx; |
1334 | int new_ctx; | 1356 | int new_ctx; |
@@ -1373,11 +1395,13 @@ void s5p_mfc_try_run(struct s5p_mfc_dev *dev) | |||
1373 | break; | 1395 | break; |
1374 | case MFCINST_INIT: | 1396 | case MFCINST_INIT: |
1375 | s5p_mfc_clean_ctx_int_flags(ctx); | 1397 | s5p_mfc_clean_ctx_int_flags(ctx); |
1376 | ret = s5p_mfc_open_inst_cmd(ctx); | 1398 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, |
1399 | ctx); | ||
1377 | break; | 1400 | break; |
1378 | case MFCINST_RETURN_INST: | 1401 | case MFCINST_RETURN_INST: |
1379 | s5p_mfc_clean_ctx_int_flags(ctx); | 1402 | s5p_mfc_clean_ctx_int_flags(ctx); |
1380 | ret = s5p_mfc_close_inst_cmd(ctx); | 1403 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, |
1404 | ctx); | ||
1381 | break; | 1405 | break; |
1382 | case MFCINST_GOT_INST: | 1406 | case MFCINST_GOT_INST: |
1383 | s5p_mfc_run_init_dec(ctx); | 1407 | s5p_mfc_run_init_dec(ctx); |
@@ -1409,11 +1433,13 @@ void s5p_mfc_try_run(struct s5p_mfc_dev *dev) | |||
1409 | break; | 1433 | break; |
1410 | case MFCINST_INIT: | 1434 | case MFCINST_INIT: |
1411 | s5p_mfc_clean_ctx_int_flags(ctx); | 1435 | s5p_mfc_clean_ctx_int_flags(ctx); |
1412 | ret = s5p_mfc_open_inst_cmd(ctx); | 1436 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, |
1437 | ctx); | ||
1413 | break; | 1438 | break; |
1414 | case MFCINST_RETURN_INST: | 1439 | case MFCINST_RETURN_INST: |
1415 | s5p_mfc_clean_ctx_int_flags(ctx); | 1440 | s5p_mfc_clean_ctx_int_flags(ctx); |
1416 | ret = s5p_mfc_close_inst_cmd(ctx); | 1441 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, |
1442 | ctx); | ||
1417 | break; | 1443 | break; |
1418 | case MFCINST_GOT_INST: | 1444 | case MFCINST_GOT_INST: |
1419 | s5p_mfc_run_init_enc(ctx); | 1445 | s5p_mfc_run_init_enc(ctx); |
@@ -1440,7 +1466,7 @@ void s5p_mfc_try_run(struct s5p_mfc_dev *dev) | |||
1440 | } | 1466 | } |
1441 | 1467 | ||
1442 | 1468 | ||
1443 | void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq) | 1469 | void s5p_mfc_cleanup_queue_v5(struct list_head *lh, struct vb2_queue *vq) |
1444 | { | 1470 | { |
1445 | struct s5p_mfc_buf *b; | 1471 | struct s5p_mfc_buf *b; |
1446 | int i; | 1472 | int i; |
@@ -1454,3 +1480,250 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq) | |||
1454 | } | 1480 | } |
1455 | } | 1481 | } |
1456 | 1482 | ||
1483 | void s5p_mfc_clear_int_flags_v5(struct s5p_mfc_dev *dev) | ||
1484 | { | ||
1485 | mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT); | ||
1486 | mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD); | ||
1487 | mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID); | ||
1488 | } | ||
1489 | |||
1490 | int s5p_mfc_get_dspl_y_adr_v5(struct s5p_mfc_dev *dev) | ||
1491 | { | ||
1492 | return mfc_read(dev, S5P_FIMV_SI_DISPLAY_Y_ADR) << MFC_OFFSET_SHIFT; | ||
1493 | } | ||
1494 | |||
1495 | int s5p_mfc_get_dec_y_adr_v5(struct s5p_mfc_dev *dev) | ||
1496 | { | ||
1497 | return mfc_read(dev, S5P_FIMV_SI_DECODE_Y_ADR) << MFC_OFFSET_SHIFT; | ||
1498 | } | ||
1499 | |||
1500 | int s5p_mfc_get_dspl_status_v5(struct s5p_mfc_dev *dev) | ||
1501 | { | ||
1502 | return mfc_read(dev, S5P_FIMV_SI_DISPLAY_STATUS); | ||
1503 | } | ||
1504 | |||
1505 | int s5p_mfc_get_dec_status_v5(struct s5p_mfc_dev *dev) | ||
1506 | { | ||
1507 | return mfc_read(dev, S5P_FIMV_SI_DECODE_STATUS); | ||
1508 | } | ||
1509 | |||
1510 | int s5p_mfc_get_dec_frame_type_v5(struct s5p_mfc_dev *dev) | ||
1511 | { | ||
1512 | return mfc_read(dev, S5P_FIMV_DECODE_FRAME_TYPE) & | ||
1513 | S5P_FIMV_DECODE_FRAME_MASK; | ||
1514 | } | ||
1515 | |||
1516 | int s5p_mfc_get_disp_frame_type_v5(struct s5p_mfc_ctx *ctx) | ||
1517 | { | ||
1518 | /* NOP */ | ||
1519 | return -1; | ||
1520 | } | ||
1521 | |||
1522 | int s5p_mfc_get_consumed_stream_v5(struct s5p_mfc_dev *dev) | ||
1523 | { | ||
1524 | return mfc_read(dev, S5P_FIMV_SI_CONSUMED_BYTES); | ||
1525 | } | ||
1526 | |||
1527 | int s5p_mfc_get_int_reason_v5(struct s5p_mfc_dev *dev) | ||
1528 | { | ||
1529 | int reason; | ||
1530 | reason = mfc_read(dev, S5P_FIMV_RISC2HOST_CMD) & | ||
1531 | S5P_FIMV_RISC2HOST_CMD_MASK; | ||
1532 | switch (reason) { | ||
1533 | case S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET: | ||
1534 | reason = S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET; | ||
1535 | break; | ||
1536 | case S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET: | ||
1537 | reason = S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET; | ||
1538 | break; | ||
1539 | case S5P_FIMV_R2H_CMD_SEQ_DONE_RET: | ||
1540 | reason = S5P_MFC_R2H_CMD_SEQ_DONE_RET; | ||
1541 | break; | ||
1542 | case S5P_FIMV_R2H_CMD_FRAME_DONE_RET: | ||
1543 | reason = S5P_MFC_R2H_CMD_FRAME_DONE_RET; | ||
1544 | break; | ||
1545 | case S5P_FIMV_R2H_CMD_SLICE_DONE_RET: | ||
1546 | reason = S5P_MFC_R2H_CMD_SLICE_DONE_RET; | ||
1547 | break; | ||
1548 | case S5P_FIMV_R2H_CMD_SYS_INIT_RET: | ||
1549 | reason = S5P_MFC_R2H_CMD_SYS_INIT_RET; | ||
1550 | break; | ||
1551 | case S5P_FIMV_R2H_CMD_FW_STATUS_RET: | ||
1552 | reason = S5P_MFC_R2H_CMD_FW_STATUS_RET; | ||
1553 | break; | ||
1554 | case S5P_FIMV_R2H_CMD_SLEEP_RET: | ||
1555 | reason = S5P_MFC_R2H_CMD_SLEEP_RET; | ||
1556 | break; | ||
1557 | case S5P_FIMV_R2H_CMD_WAKEUP_RET: | ||
1558 | reason = S5P_MFC_R2H_CMD_WAKEUP_RET; | ||
1559 | break; | ||
1560 | case S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET: | ||
1561 | reason = S5P_MFC_R2H_CMD_INIT_BUFFERS_RET; | ||
1562 | break; | ||
1563 | case S5P_FIMV_R2H_CMD_ENC_COMPLETE_RET: | ||
1564 | reason = S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET; | ||
1565 | break; | ||
1566 | case S5P_FIMV_R2H_CMD_ERR_RET: | ||
1567 | reason = S5P_MFC_R2H_CMD_ERR_RET; | ||
1568 | break; | ||
1569 | default: | ||
1570 | reason = S5P_MFC_R2H_CMD_EMPTY; | ||
1571 | }; | ||
1572 | return reason; | ||
1573 | } | ||
1574 | |||
1575 | int s5p_mfc_get_int_err_v5(struct s5p_mfc_dev *dev) | ||
1576 | { | ||
1577 | return mfc_read(dev, S5P_FIMV_RISC2HOST_ARG2); | ||
1578 | } | ||
1579 | |||
1580 | int s5p_mfc_err_dec_v5(unsigned int err) | ||
1581 | { | ||
1582 | return (err & S5P_FIMV_ERR_DEC_MASK) >> S5P_FIMV_ERR_DEC_SHIFT; | ||
1583 | } | ||
1584 | |||
1585 | int s5p_mfc_err_dspl_v5(unsigned int err) | ||
1586 | { | ||
1587 | return (err & S5P_FIMV_ERR_DSPL_MASK) >> S5P_FIMV_ERR_DSPL_SHIFT; | ||
1588 | } | ||
1589 | |||
1590 | int s5p_mfc_get_img_width_v5(struct s5p_mfc_dev *dev) | ||
1591 | { | ||
1592 | return mfc_read(dev, S5P_FIMV_SI_HRESOL); | ||
1593 | } | ||
1594 | |||
1595 | int s5p_mfc_get_img_height_v5(struct s5p_mfc_dev *dev) | ||
1596 | { | ||
1597 | return mfc_read(dev, S5P_FIMV_SI_VRESOL); | ||
1598 | } | ||
1599 | |||
1600 | int s5p_mfc_get_dpb_count_v5(struct s5p_mfc_dev *dev) | ||
1601 | { | ||
1602 | return mfc_read(dev, S5P_FIMV_SI_BUF_NUMBER); | ||
1603 | } | ||
1604 | |||
1605 | int s5p_mfc_get_mv_count_v5(struct s5p_mfc_dev *dev) | ||
1606 | { | ||
1607 | /* NOP */ | ||
1608 | return -1; | ||
1609 | } | ||
1610 | |||
1611 | int s5p_mfc_get_inst_no_v5(struct s5p_mfc_dev *dev) | ||
1612 | { | ||
1613 | return mfc_read(dev, S5P_FIMV_RISC2HOST_ARG1); | ||
1614 | } | ||
1615 | |||
1616 | int s5p_mfc_get_enc_strm_size_v5(struct s5p_mfc_dev *dev) | ||
1617 | { | ||
1618 | return mfc_read(dev, S5P_FIMV_ENC_SI_STRM_SIZE); | ||
1619 | } | ||
1620 | |||
1621 | int s5p_mfc_get_enc_slice_type_v5(struct s5p_mfc_dev *dev) | ||
1622 | { | ||
1623 | return mfc_read(dev, S5P_FIMV_ENC_SI_SLICE_TYPE); | ||
1624 | } | ||
1625 | |||
1626 | int s5p_mfc_get_enc_dpb_count_v5(struct s5p_mfc_dev *dev) | ||
1627 | { | ||
1628 | return -1; | ||
1629 | } | ||
1630 | |||
1631 | int s5p_mfc_get_enc_pic_count_v5(struct s5p_mfc_dev *dev) | ||
1632 | { | ||
1633 | return mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT); | ||
1634 | } | ||
1635 | |||
1636 | int s5p_mfc_get_sei_avail_status_v5(struct s5p_mfc_ctx *ctx) | ||
1637 | { | ||
1638 | return s5p_mfc_read_info_v5(ctx, FRAME_PACK_SEI_AVAIL); | ||
1639 | } | ||
1640 | |||
1641 | int s5p_mfc_get_mvc_num_views_v5(struct s5p_mfc_dev *dev) | ||
1642 | { | ||
1643 | return -1; | ||
1644 | } | ||
1645 | |||
1646 | int s5p_mfc_get_mvc_view_id_v5(struct s5p_mfc_dev *dev) | ||
1647 | { | ||
1648 | return -1; | ||
1649 | } | ||
1650 | |||
1651 | unsigned int s5p_mfc_get_pic_type_top_v5(struct s5p_mfc_ctx *ctx) | ||
1652 | { | ||
1653 | return s5p_mfc_read_info_v5(ctx, PIC_TIME_TOP); | ||
1654 | } | ||
1655 | |||
1656 | unsigned int s5p_mfc_get_pic_type_bot_v5(struct s5p_mfc_ctx *ctx) | ||
1657 | { | ||
1658 | return s5p_mfc_read_info_v5(ctx, PIC_TIME_BOT); | ||
1659 | } | ||
1660 | |||
1661 | unsigned int s5p_mfc_get_crop_info_h_v5(struct s5p_mfc_ctx *ctx) | ||
1662 | { | ||
1663 | return s5p_mfc_read_info_v5(ctx, CROP_INFO_H); | ||
1664 | } | ||
1665 | |||
1666 | unsigned int s5p_mfc_get_crop_info_v_v5(struct s5p_mfc_ctx *ctx) | ||
1667 | { | ||
1668 | return s5p_mfc_read_info_v5(ctx, CROP_INFO_V); | ||
1669 | } | ||
1670 | |||
1671 | /* Initialize opr function pointers for MFC v5 */ | ||
1672 | static struct s5p_mfc_hw_ops s5p_mfc_ops_v5 = { | ||
1673 | .alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v5, | ||
1674 | .release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v5, | ||
1675 | .alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v5, | ||
1676 | .release_codec_buffers = s5p_mfc_release_codec_buffers_v5, | ||
1677 | .alloc_instance_buffer = s5p_mfc_alloc_instance_buffer_v5, | ||
1678 | .release_instance_buffer = s5p_mfc_release_instance_buffer_v5, | ||
1679 | .alloc_dev_context_buffer = s5p_mfc_alloc_dev_context_buffer_v5, | ||
1680 | .release_dev_context_buffer = s5p_mfc_release_dev_context_buffer_v5, | ||
1681 | .dec_calc_dpb_size = s5p_mfc_dec_calc_dpb_size_v5, | ||
1682 | .enc_calc_src_size = s5p_mfc_enc_calc_src_size_v5, | ||
1683 | .set_dec_stream_buffer = s5p_mfc_set_dec_stream_buffer_v5, | ||
1684 | .set_dec_frame_buffer = s5p_mfc_set_dec_frame_buffer_v5, | ||
1685 | .set_enc_stream_buffer = s5p_mfc_set_enc_stream_buffer_v5, | ||
1686 | .set_enc_frame_buffer = s5p_mfc_set_enc_frame_buffer_v5, | ||
1687 | .get_enc_frame_buffer = s5p_mfc_get_enc_frame_buffer_v5, | ||
1688 | .set_enc_ref_buffer = s5p_mfc_set_enc_ref_buffer_v5, | ||
1689 | .init_decode = s5p_mfc_init_decode_v5, | ||
1690 | .init_encode = s5p_mfc_init_encode_v5, | ||
1691 | .encode_one_frame = s5p_mfc_encode_one_frame_v5, | ||
1692 | .try_run = s5p_mfc_try_run_v5, | ||
1693 | .cleanup_queue = s5p_mfc_cleanup_queue_v5, | ||
1694 | .clear_int_flags = s5p_mfc_clear_int_flags_v5, | ||
1695 | .write_info = s5p_mfc_write_info_v5, | ||
1696 | .read_info = s5p_mfc_read_info_v5, | ||
1697 | .get_dspl_y_adr = s5p_mfc_get_dspl_y_adr_v5, | ||
1698 | .get_dec_y_adr = s5p_mfc_get_dec_y_adr_v5, | ||
1699 | .get_dspl_status = s5p_mfc_get_dspl_status_v5, | ||
1700 | .get_dec_status = s5p_mfc_get_dec_status_v5, | ||
1701 | .get_dec_frame_type = s5p_mfc_get_dec_frame_type_v5, | ||
1702 | .get_disp_frame_type = s5p_mfc_get_disp_frame_type_v5, | ||
1703 | .get_consumed_stream = s5p_mfc_get_consumed_stream_v5, | ||
1704 | .get_int_reason = s5p_mfc_get_int_reason_v5, | ||
1705 | .get_int_err = s5p_mfc_get_int_err_v5, | ||
1706 | .err_dec = s5p_mfc_err_dec_v5, | ||
1707 | .err_dspl = s5p_mfc_err_dspl_v5, | ||
1708 | .get_img_width = s5p_mfc_get_img_width_v5, | ||
1709 | .get_img_height = s5p_mfc_get_img_height_v5, | ||
1710 | .get_dpb_count = s5p_mfc_get_dpb_count_v5, | ||
1711 | .get_mv_count = s5p_mfc_get_mv_count_v5, | ||
1712 | .get_inst_no = s5p_mfc_get_inst_no_v5, | ||
1713 | .get_enc_strm_size = s5p_mfc_get_enc_strm_size_v5, | ||
1714 | .get_enc_slice_type = s5p_mfc_get_enc_slice_type_v5, | ||
1715 | .get_enc_dpb_count = s5p_mfc_get_enc_dpb_count_v5, | ||
1716 | .get_enc_pic_count = s5p_mfc_get_enc_pic_count_v5, | ||
1717 | .get_sei_avail_status = s5p_mfc_get_sei_avail_status_v5, | ||
1718 | .get_mvc_num_views = s5p_mfc_get_mvc_num_views_v5, | ||
1719 | .get_mvc_view_id = s5p_mfc_get_mvc_view_id_v5, | ||
1720 | .get_pic_type_top = s5p_mfc_get_pic_type_top_v5, | ||
1721 | .get_pic_type_bot = s5p_mfc_get_pic_type_bot_v5, | ||
1722 | .get_crop_info_h = s5p_mfc_get_crop_info_h_v5, | ||
1723 | .get_crop_info_v = s5p_mfc_get_crop_info_v_v5, | ||
1724 | }; | ||
1725 | |||
1726 | struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void) | ||
1727 | { | ||
1728 | return &s5p_mfc_ops_v5; | ||
1729 | } | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h index 97c1ecafa0f9..ffee39a127d5 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/media/platform/samsung/mfc5/s5p_mfc_opr.h | 2 | * drivers/media/platform/samsung/mfc5/s5p_mfc_opr_v5.h |
3 | * | 3 | * |
4 | * Header file for Samsung MFC (Multi Function Codec - FIMV) driver | 4 | * Header file for Samsung MFC (Multi Function Codec - FIMV) driver |
5 | * Contains declarations of hw related functions. | 5 | * Contains declarations of hw related functions. |
@@ -12,10 +12,11 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #ifndef S5P_MFC_OPR_H_ | 15 | #ifndef S5P_MFC_OPR_V5_H_ |
16 | #define S5P_MFC_OPR_H_ | 16 | #define S5P_MFC_OPR_V5_H_ |
17 | 17 | ||
18 | #include "s5p_mfc_common.h" | 18 | #include "s5p_mfc_common.h" |
19 | #include "s5p_mfc_opr.h" | ||
19 | 20 | ||
20 | enum MFC_SHM_OFS { | 21 | enum MFC_SHM_OFS { |
21 | EXTENEDED_DECODE_STATUS = 0x00, /* D */ | 22 | EXTENEDED_DECODE_STATUS = 0x00, /* D */ |
@@ -80,84 +81,5 @@ enum MFC_SHM_OFS { | |||
80 | FRAME_PACK_SEI_INFO = 0x17c, /* E */ | 81 | FRAME_PACK_SEI_INFO = 0x17c, /* E */ |
81 | }; | 82 | }; |
82 | 83 | ||
83 | int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx); | 84 | struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void); |
84 | int s5p_mfc_init_encode(struct s5p_mfc_ctx *mfc_ctx); | ||
85 | |||
86 | /* Decoding functions */ | ||
87 | int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx); | ||
88 | int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr, | ||
89 | unsigned int start_num_byte, | ||
90 | unsigned int buf_size); | ||
91 | |||
92 | /* Encoding functions */ | ||
93 | void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx, | ||
94 | unsigned long y_addr, unsigned long c_addr); | ||
95 | int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx, | ||
96 | unsigned long addr, unsigned int size); | ||
97 | void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx, | ||
98 | unsigned long *y_addr, unsigned long *c_addr); | ||
99 | int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *mfc_ctx); | ||
100 | |||
101 | int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx, | ||
102 | enum s5p_mfc_decode_arg last_frame); | ||
103 | int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *mfc_ctx); | ||
104 | |||
105 | /* Memory allocation */ | ||
106 | int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx); | ||
107 | void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx); | ||
108 | void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx); | ||
109 | |||
110 | int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx); | ||
111 | void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx); | ||
112 | |||
113 | int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx); | ||
114 | void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx); | ||
115 | |||
116 | void s5p_mfc_try_run(struct s5p_mfc_dev *dev); | ||
117 | void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq); | ||
118 | |||
119 | /* Shared memory ops */ | ||
120 | void s5p_mfc_write_info_v5(struct s5p_mfc_ctx *ctx, unsigned int data, | ||
121 | unsigned int ofs); | ||
122 | |||
123 | unsigned int s5p_mfc_read_info_v5(struct s5p_mfc_ctx *ctx, | ||
124 | unsigned int ofs); | ||
125 | |||
126 | #define s5p_mfc_get_dspl_y_adr() (readl(dev->regs_base + \ | ||
127 | S5P_FIMV_SI_DISPLAY_Y_ADR) << \ | ||
128 | MFC_OFFSET_SHIFT) | ||
129 | #define s5p_mfc_get_dec_y_adr() (readl(dev->regs_base + \ | ||
130 | S5P_FIMV_SI_DECODE_Y_ADR) << \ | ||
131 | MFC_OFFSET_SHIFT) | ||
132 | #define s5p_mfc_get_dspl_status() readl(dev->regs_base + \ | ||
133 | S5P_FIMV_SI_DISPLAY_STATUS) | ||
134 | #define s5p_mfc_get_dec_status() readl(dev->regs_base + \ | ||
135 | S5P_FIMV_SI_DECODE_STATUS) | ||
136 | #define s5p_mfc_get_frame_type() (readl(dev->regs_base + \ | ||
137 | S5P_FIMV_DECODE_FRAME_TYPE) \ | ||
138 | & S5P_FIMV_DECODE_FRAME_MASK) | ||
139 | #define s5p_mfc_get_consumed_stream() readl(dev->regs_base + \ | ||
140 | S5P_FIMV_SI_CONSUMED_BYTES) | ||
141 | #define s5p_mfc_get_int_reason() (readl(dev->regs_base + \ | ||
142 | S5P_FIMV_RISC2HOST_CMD) & \ | ||
143 | S5P_FIMV_RISC2HOST_CMD_MASK) | ||
144 | #define s5p_mfc_get_int_err() readl(dev->regs_base + \ | ||
145 | S5P_FIMV_RISC2HOST_ARG2) | ||
146 | #define s5p_mfc_err_dec(x) (((x) & S5P_FIMV_ERR_DEC_MASK) >> \ | ||
147 | S5P_FIMV_ERR_DEC_SHIFT) | ||
148 | #define s5p_mfc_err_dspl(x) (((x) & S5P_FIMV_ERR_DSPL_MASK) >> \ | ||
149 | S5P_FIMV_ERR_DSPL_SHIFT) | ||
150 | #define s5p_mfc_get_img_width() readl(dev->regs_base + \ | ||
151 | S5P_FIMV_SI_HRESOL) | ||
152 | #define s5p_mfc_get_img_height() readl(dev->regs_base + \ | ||
153 | S5P_FIMV_SI_VRESOL) | ||
154 | #define s5p_mfc_get_dpb_count() readl(dev->regs_base + \ | ||
155 | S5P_FIMV_SI_BUF_NUMBER) | ||
156 | #define s5p_mfc_get_inst_no() readl(dev->regs_base + \ | ||
157 | S5P_FIMV_RISC2HOST_ARG1) | ||
158 | #define s5p_mfc_get_enc_strm_size() readl(dev->regs_base + \ | ||
159 | S5P_FIMV_ENC_SI_STRM_SIZE) | ||
160 | #define s5p_mfc_get_enc_slice_type() readl(dev->regs_base + \ | ||
161 | S5P_FIMV_ENC_SI_SLICE_TYPE) | ||
162 | |||
163 | #endif /* S5P_MFC_OPR_H_ */ | 85 | #endif /* S5P_MFC_OPR_H_ */ |