diff options
Diffstat (limited to 'drivers/media/platform/s5p-mfc')
-rw-r--r-- | drivers/media/platform/s5p-mfc/regs-mfc-v6.h | 1 | ||||
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc.c | 49 | ||||
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 4 | ||||
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | 122 | ||||
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 12 | ||||
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 65 | ||||
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | 13 | ||||
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 32 |
8 files changed, 196 insertions, 102 deletions
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h index 51cb2dd0e13a..83e01f3466e9 100644 --- a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h +++ b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h | |||
@@ -71,6 +71,7 @@ | |||
71 | #define S5P_FIMV_R2H_CMD_ENC_BUFFER_FUL_RET_V6 16 | 71 | #define S5P_FIMV_R2H_CMD_ENC_BUFFER_FUL_RET_V6 16 |
72 | #define S5P_FIMV_R2H_CMD_ERR_RET_V6 32 | 72 | #define S5P_FIMV_R2H_CMD_ERR_RET_V6 32 |
73 | 73 | ||
74 | #define S5P_FIMV_MFC_BUS_RESET_CTRL 0x7110 | ||
74 | #define S5P_FIMV_FW_VERSION_V6 0xf000 | 75 | #define S5P_FIMV_FW_VERSION_V6 0xf000 |
75 | 76 | ||
76 | #define S5P_FIMV_INSTANCE_ID_V6 0xf008 | 77 | #define S5P_FIMV_INSTANCE_ID_V6 0xf008 |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 363fd8c0a699..b80a576164f1 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c | |||
@@ -159,6 +159,10 @@ static void s5p_mfc_watchdog_worker(struct work_struct *work) | |||
159 | } | 159 | } |
160 | clear_bit(0, &dev->hw_lock); | 160 | clear_bit(0, &dev->hw_lock); |
161 | spin_unlock_irqrestore(&dev->irqlock, flags); | 161 | spin_unlock_irqrestore(&dev->irqlock, flags); |
162 | |||
163 | /* De-init MFC */ | ||
164 | s5p_mfc_deinit_hw(dev); | ||
165 | |||
162 | /* Double check if there is at least one instance running. | 166 | /* Double check if there is at least one instance running. |
163 | * If no instance is in memory than no firmware should be present */ | 167 | * If no instance is in memory than no firmware should be present */ |
164 | if (dev->num_inst > 0) { | 168 | if (dev->num_inst > 0) { |
@@ -220,11 +224,14 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx) | |||
220 | size_t dec_y_addr; | 224 | size_t dec_y_addr; |
221 | unsigned int frame_type; | 225 | unsigned int frame_type; |
222 | 226 | ||
223 | dec_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dec_y_adr, dev); | 227 | /* Make sure we actually have a new frame before continuing. */ |
224 | frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev); | 228 | frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev); |
229 | if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) | ||
230 | return; | ||
231 | dec_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dec_y_adr, dev); | ||
225 | 232 | ||
226 | /* Copy timestamp / timecode from decoded src to dst and set | 233 | /* Copy timestamp / timecode from decoded src to dst and set |
227 | appropriate flags */ | 234 | appropriate flags. */ |
228 | src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); | 235 | src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); |
229 | list_for_each_entry(dst_buf, &ctx->dst_queue, list) { | 236 | list_for_each_entry(dst_buf, &ctx->dst_queue, list) { |
230 | if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dec_y_addr) { | 237 | if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dec_y_addr) { |
@@ -250,6 +257,11 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx) | |||
250 | dst_buf->b->v4l2_buf.flags |= | 257 | dst_buf->b->v4l2_buf.flags |= |
251 | V4L2_BUF_FLAG_BFRAME; | 258 | V4L2_BUF_FLAG_BFRAME; |
252 | break; | 259 | break; |
260 | default: | ||
261 | /* Don't know how to handle | ||
262 | S5P_FIMV_DECODE_FRAME_OTHER_FRAME. */ | ||
263 | mfc_debug(2, "Unexpected frame type: %d\n", | ||
264 | frame_type); | ||
253 | } | 265 | } |
254 | break; | 266 | break; |
255 | } | 267 | } |
@@ -334,8 +346,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, | |||
334 | ctx->state = MFCINST_RES_CHANGE_INIT; | 346 | ctx->state = MFCINST_RES_CHANGE_INIT; |
335 | s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); | 347 | s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); |
336 | wake_up_ctx(ctx, reason, err); | 348 | wake_up_ctx(ctx, reason, err); |
337 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 349 | WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); |
338 | BUG(); | ||
339 | s5p_mfc_clock_off(); | 350 | s5p_mfc_clock_off(); |
340 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); | 351 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); |
341 | return; | 352 | return; |
@@ -407,8 +418,7 @@ leave_handle_frame: | |||
407 | clear_work_bit(ctx); | 418 | clear_work_bit(ctx); |
408 | s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); | 419 | s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); |
409 | wake_up_ctx(ctx, reason, err); | 420 | wake_up_ctx(ctx, reason, err); |
410 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 421 | WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); |
411 | BUG(); | ||
412 | s5p_mfc_clock_off(); | 422 | s5p_mfc_clock_off(); |
413 | /* if suspending, wake up device and do not try_run again*/ | 423 | /* if suspending, wake up device and do not try_run again*/ |
414 | if (test_bit(0, &dev->enter_suspend)) | 424 | if (test_bit(0, &dev->enter_suspend)) |
@@ -455,8 +465,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev, | |||
455 | break; | 465 | break; |
456 | } | 466 | } |
457 | } | 467 | } |
458 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 468 | WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); |
459 | BUG(); | ||
460 | s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); | 469 | s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); |
461 | s5p_mfc_clock_off(); | 470 | s5p_mfc_clock_off(); |
462 | wake_up_dev(dev, reason, err); | 471 | wake_up_dev(dev, reason, err); |
@@ -510,8 +519,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, | |||
510 | } | 519 | } |
511 | s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); | 520 | s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); |
512 | clear_work_bit(ctx); | 521 | clear_work_bit(ctx); |
513 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 522 | WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); |
514 | BUG(); | ||
515 | s5p_mfc_clock_off(); | 523 | s5p_mfc_clock_off(); |
516 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); | 524 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); |
517 | wake_up_ctx(ctx, reason, err); | 525 | wake_up_ctx(ctx, reason, err); |
@@ -549,16 +557,14 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx, | |||
549 | } else { | 557 | } else { |
550 | ctx->dpb_flush_flag = 0; | 558 | ctx->dpb_flush_flag = 0; |
551 | } | 559 | } |
552 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 560 | WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); |
553 | BUG(); | ||
554 | 561 | ||
555 | s5p_mfc_clock_off(); | 562 | s5p_mfc_clock_off(); |
556 | 563 | ||
557 | wake_up(&ctx->queue); | 564 | wake_up(&ctx->queue); |
558 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); | 565 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); |
559 | } else { | 566 | } else { |
560 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 567 | WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); |
561 | BUG(); | ||
562 | 568 | ||
563 | s5p_mfc_clock_off(); | 569 | s5p_mfc_clock_off(); |
564 | 570 | ||
@@ -635,8 +641,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv) | |||
635 | mfc_err("post_frame_start() failed\n"); | 641 | mfc_err("post_frame_start() failed\n"); |
636 | s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); | 642 | s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); |
637 | wake_up_ctx(ctx, reason, err); | 643 | wake_up_ctx(ctx, reason, err); |
638 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 644 | WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); |
639 | BUG(); | ||
640 | s5p_mfc_clock_off(); | 645 | s5p_mfc_clock_off(); |
641 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); | 646 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); |
642 | } else { | 647 | } else { |
@@ -815,7 +820,7 @@ static int s5p_mfc_open(struct file *file) | |||
815 | ret = -ENOENT; | 820 | ret = -ENOENT; |
816 | goto err_queue_init; | 821 | goto err_queue_init; |
817 | } | 822 | } |
818 | q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops; | 823 | q->mem_ops = &vb2_dma_contig_memops; |
819 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; | 824 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; |
820 | ret = vb2_queue_init(q); | 825 | ret = vb2_queue_init(q); |
821 | if (ret) { | 826 | if (ret) { |
@@ -837,7 +842,7 @@ static int s5p_mfc_open(struct file *file) | |||
837 | ret = -ENOENT; | 842 | ret = -ENOENT; |
838 | goto err_queue_init; | 843 | goto err_queue_init; |
839 | } | 844 | } |
840 | q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops; | 845 | q->mem_ops = &vb2_dma_contig_memops; |
841 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; | 846 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; |
842 | ret = vb2_queue_init(q); | 847 | ret = vb2_queue_init(q); |
843 | if (ret) { | 848 | if (ret) { |
@@ -1284,11 +1289,17 @@ static int s5p_mfc_suspend(struct device *dev) | |||
1284 | m_dev->int_cond, msecs_to_jiffies(MFC_INT_TIMEOUT)); | 1289 | m_dev->int_cond, msecs_to_jiffies(MFC_INT_TIMEOUT)); |
1285 | if (ret == 0) { | 1290 | if (ret == 0) { |
1286 | mfc_err("Waiting for hardware to finish timed out\n"); | 1291 | mfc_err("Waiting for hardware to finish timed out\n"); |
1292 | clear_bit(0, &m_dev->enter_suspend); | ||
1287 | return -EIO; | 1293 | return -EIO; |
1288 | } | 1294 | } |
1289 | } | 1295 | } |
1290 | 1296 | ||
1291 | return s5p_mfc_sleep(m_dev); | 1297 | ret = s5p_mfc_sleep(m_dev); |
1298 | if (ret) { | ||
1299 | clear_bit(0, &m_dev->enter_suspend); | ||
1300 | clear_bit(0, &m_dev->hw_lock); | ||
1301 | } | ||
1302 | return ret; | ||
1292 | } | 1303 | } |
1293 | 1304 | ||
1294 | static int s5p_mfc_resume(struct device *dev) | 1305 | static int s5p_mfc_resume(struct device *dev) |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 3e41ca1293ed..15f7663dd9f5 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h | |||
@@ -237,8 +237,6 @@ struct s5p_mfc_variant { | |||
237 | 237 | ||
238 | /** | 238 | /** |
239 | * struct s5p_mfc_priv_buf - represents internal used buffer | 239 | * struct s5p_mfc_priv_buf - represents internal used buffer |
240 | * @alloc: allocation-specific context for each buffer | ||
241 | * (videobuf2 allocator) | ||
242 | * @ofs: offset of each buffer, will be used for MFC | 240 | * @ofs: offset of each buffer, will be used for MFC |
243 | * @virt: kernel virtual address, only valid when the | 241 | * @virt: kernel virtual address, only valid when the |
244 | * buffer accessed by driver | 242 | * buffer accessed by driver |
@@ -246,7 +244,6 @@ struct s5p_mfc_variant { | |||
246 | * @size: size of the buffer | 244 | * @size: size of the buffer |
247 | */ | 245 | */ |
248 | struct s5p_mfc_priv_buf { | 246 | struct s5p_mfc_priv_buf { |
249 | void *alloc; | ||
250 | unsigned long ofs; | 247 | unsigned long ofs; |
251 | void *virt; | 248 | void *virt; |
252 | dma_addr_t dma; | 249 | dma_addr_t dma; |
@@ -340,6 +337,7 @@ struct s5p_mfc_dev { | |||
340 | struct s5p_mfc_hw_cmds *mfc_cmds; | 337 | struct s5p_mfc_hw_cmds *mfc_cmds; |
341 | const struct s5p_mfc_regs *mfc_regs; | 338 | const struct s5p_mfc_regs *mfc_regs; |
342 | enum s5p_mfc_fw_ver fw_ver; | 339 | enum s5p_mfc_fw_ver fw_ver; |
340 | bool risc_on; /* indicates if RISC is on or off */ | ||
343 | }; | 341 | }; |
344 | 342 | ||
345 | /** | 343 | /** |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index 0c885a8a0e9f..40d8a03a141d 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | |||
@@ -129,6 +129,25 @@ int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev) | |||
129 | return 0; | 129 | return 0; |
130 | } | 130 | } |
131 | 131 | ||
132 | static int s5p_mfc_bus_reset(struct s5p_mfc_dev *dev) | ||
133 | { | ||
134 | unsigned int status; | ||
135 | unsigned long timeout; | ||
136 | |||
137 | /* Reset */ | ||
138 | mfc_write(dev, 0x1, S5P_FIMV_MFC_BUS_RESET_CTRL); | ||
139 | timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT); | ||
140 | /* Check bus status */ | ||
141 | do { | ||
142 | if (time_after(jiffies, timeout)) { | ||
143 | mfc_err("Timeout while resetting MFC.\n"); | ||
144 | return -EIO; | ||
145 | } | ||
146 | status = mfc_read(dev, S5P_FIMV_MFC_BUS_RESET_CTRL); | ||
147 | } while ((status & 0x2) == 0); | ||
148 | return 0; | ||
149 | } | ||
150 | |||
132 | /* Reset the device */ | 151 | /* Reset the device */ |
133 | int s5p_mfc_reset(struct s5p_mfc_dev *dev) | 152 | int s5p_mfc_reset(struct s5p_mfc_dev *dev) |
134 | { | 153 | { |
@@ -139,12 +158,6 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev) | |||
139 | mfc_debug_enter(); | 158 | mfc_debug_enter(); |
140 | 159 | ||
141 | if (IS_MFCV6_PLUS(dev)) { | 160 | if (IS_MFCV6_PLUS(dev)) { |
142 | /* Reset IP */ | ||
143 | /* except RISC, reset */ | ||
144 | mfc_write(dev, 0xFEE, S5P_FIMV_MFC_RESET_V6); | ||
145 | /* reset release */ | ||
146 | mfc_write(dev, 0x0, S5P_FIMV_MFC_RESET_V6); | ||
147 | |||
148 | /* Zero Initialization of MFC registers */ | 161 | /* Zero Initialization of MFC registers */ |
149 | mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6); | 162 | mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6); |
150 | mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD_V6); | 163 | mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD_V6); |
@@ -153,8 +166,17 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev) | |||
153 | for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++) | 166 | for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++) |
154 | mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4)); | 167 | mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4)); |
155 | 168 | ||
156 | /* Reset */ | 169 | /* check bus reset control before reset */ |
157 | mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6); | 170 | if (dev->risc_on) |
171 | if (s5p_mfc_bus_reset(dev)) | ||
172 | return -EIO; | ||
173 | /* Reset | ||
174 | * set RISC_ON to 0 during power_on & wake_up. | ||
175 | * V6 needs RISC_ON set to 0 during reset also. | ||
176 | */ | ||
177 | if ((!dev->risc_on) || (!IS_MFCV7_PLUS(dev))) | ||
178 | mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6); | ||
179 | |||
158 | mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6); | 180 | mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6); |
159 | mfc_write(dev, 0, S5P_FIMV_MFC_RESET_V6); | 181 | mfc_write(dev, 0, S5P_FIMV_MFC_RESET_V6); |
160 | } else { | 182 | } else { |
@@ -226,6 +248,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) | |||
226 | /* 0. MFC reset */ | 248 | /* 0. MFC reset */ |
227 | mfc_debug(2, "MFC reset..\n"); | 249 | mfc_debug(2, "MFC reset..\n"); |
228 | s5p_mfc_clock_on(); | 250 | s5p_mfc_clock_on(); |
251 | dev->risc_on = 0; | ||
229 | ret = s5p_mfc_reset(dev); | 252 | ret = s5p_mfc_reset(dev); |
230 | if (ret) { | 253 | if (ret) { |
231 | mfc_err("Failed to reset MFC - timeout\n"); | 254 | mfc_err("Failed to reset MFC - timeout\n"); |
@@ -238,8 +261,10 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) | |||
238 | s5p_mfc_clear_cmds(dev); | 261 | s5p_mfc_clear_cmds(dev); |
239 | /* 3. Release reset signal to the RISC */ | 262 | /* 3. Release reset signal to the RISC */ |
240 | s5p_mfc_clean_dev_int_flags(dev); | 263 | s5p_mfc_clean_dev_int_flags(dev); |
241 | if (IS_MFCV6_PLUS(dev)) | 264 | if (IS_MFCV6_PLUS(dev)) { |
265 | dev->risc_on = 1; | ||
242 | mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); | 266 | mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); |
267 | } | ||
243 | else | 268 | else |
244 | mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); | 269 | mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); |
245 | mfc_debug(2, "Will now wait for completion of firmware transfer\n"); | 270 | mfc_debug(2, "Will now wait for completion of firmware transfer\n"); |
@@ -328,6 +353,58 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev) | |||
328 | return ret; | 353 | return ret; |
329 | } | 354 | } |
330 | 355 | ||
356 | static int s5p_mfc_v8_wait_wakeup(struct s5p_mfc_dev *dev) | ||
357 | { | ||
358 | int ret; | ||
359 | |||
360 | /* Release reset signal to the RISC */ | ||
361 | dev->risc_on = 1; | ||
362 | mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); | ||
363 | |||
364 | if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) { | ||
365 | mfc_err("Failed to reset MFCV8\n"); | ||
366 | return -EIO; | ||
367 | } | ||
368 | mfc_debug(2, "Write command to wakeup MFCV8\n"); | ||
369 | ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev); | ||
370 | if (ret) { | ||
371 | mfc_err("Failed to send command to MFCV8 - timeout\n"); | ||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) { | ||
376 | mfc_err("Failed to wakeup MFC\n"); | ||
377 | return -EIO; | ||
378 | } | ||
379 | return ret; | ||
380 | } | ||
381 | |||
382 | static int s5p_mfc_wait_wakeup(struct s5p_mfc_dev *dev) | ||
383 | { | ||
384 | int ret; | ||
385 | |||
386 | /* Send MFC wakeup command */ | ||
387 | ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev); | ||
388 | if (ret) { | ||
389 | mfc_err("Failed to send command to MFC - timeout\n"); | ||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | /* Release reset signal to the RISC */ | ||
394 | if (IS_MFCV6_PLUS(dev)) { | ||
395 | dev->risc_on = 1; | ||
396 | mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); | ||
397 | } else { | ||
398 | mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); | ||
399 | } | ||
400 | |||
401 | if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) { | ||
402 | mfc_err("Failed to wakeup MFC\n"); | ||
403 | return -EIO; | ||
404 | } | ||
405 | return ret; | ||
406 | } | ||
407 | |||
331 | int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) | 408 | int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) |
332 | { | 409 | { |
333 | int ret; | 410 | int ret; |
@@ -336,9 +413,11 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) | |||
336 | /* 0. MFC reset */ | 413 | /* 0. MFC reset */ |
337 | mfc_debug(2, "MFC reset..\n"); | 414 | mfc_debug(2, "MFC reset..\n"); |
338 | s5p_mfc_clock_on(); | 415 | s5p_mfc_clock_on(); |
416 | dev->risc_on = 0; | ||
339 | ret = s5p_mfc_reset(dev); | 417 | ret = s5p_mfc_reset(dev); |
340 | if (ret) { | 418 | if (ret) { |
341 | mfc_err("Failed to reset MFC - timeout\n"); | 419 | mfc_err("Failed to reset MFC - timeout\n"); |
420 | s5p_mfc_clock_off(); | ||
342 | return ret; | 421 | return ret; |
343 | } | 422 | } |
344 | mfc_debug(2, "Done MFC reset..\n"); | 423 | mfc_debug(2, "Done MFC reset..\n"); |
@@ -347,23 +426,16 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) | |||
347 | /* 2. Initialize registers of channel I/F */ | 426 | /* 2. Initialize registers of channel I/F */ |
348 | s5p_mfc_clear_cmds(dev); | 427 | s5p_mfc_clear_cmds(dev); |
349 | s5p_mfc_clean_dev_int_flags(dev); | 428 | s5p_mfc_clean_dev_int_flags(dev); |
350 | /* 3. Initialize firmware */ | 429 | /* 3. Send MFC wakeup command and wait for completion*/ |
351 | ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev); | 430 | if (IS_MFCV8(dev)) |
352 | if (ret) { | 431 | ret = s5p_mfc_v8_wait_wakeup(dev); |
353 | mfc_err("Failed to send command to MFC - timeout\n"); | ||
354 | return ret; | ||
355 | } | ||
356 | /* 4. Release reset signal to the RISC */ | ||
357 | if (IS_MFCV6_PLUS(dev)) | ||
358 | mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); | ||
359 | else | 432 | else |
360 | mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); | 433 | ret = s5p_mfc_wait_wakeup(dev); |
361 | mfc_debug(2, "Ok, now will write a command to wakeup the system\n"); | 434 | |
362 | if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) { | ||
363 | mfc_err("Failed to load firmware\n"); | ||
364 | return -EIO; | ||
365 | } | ||
366 | s5p_mfc_clock_off(); | 435 | s5p_mfc_clock_off(); |
436 | if (ret) | ||
437 | return ret; | ||
438 | |||
367 | dev->int_cond = 0; | 439 | dev->int_cond = 0; |
368 | if (dev->int_err != 0 || dev->int_type != | 440 | if (dev->int_err != 0 || dev->int_type != |
369 | S5P_MFC_R2H_CMD_WAKEUP_RET) { | 441 | S5P_MFC_R2H_CMD_WAKEUP_RET) { |
@@ -396,7 +468,6 @@ int s5p_mfc_open_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx) | |||
396 | } | 468 | } |
397 | 469 | ||
398 | set_work_bit_irqsave(ctx); | 470 | set_work_bit_irqsave(ctx); |
399 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
400 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); | 471 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); |
401 | if (s5p_mfc_wait_for_done_ctx(ctx, | 472 | if (s5p_mfc_wait_for_done_ctx(ctx, |
402 | S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) { | 473 | S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) { |
@@ -422,7 +493,6 @@ void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx) | |||
422 | { | 493 | { |
423 | ctx->state = MFCINST_RETURN_INST; | 494 | ctx->state = MFCINST_RETURN_INST; |
424 | set_work_bit_irqsave(ctx); | 495 | set_work_bit_irqsave(ctx); |
425 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
426 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); | 496 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); |
427 | /* Wait until instance is returned or timeout occurred */ | 497 | /* Wait until instance is returned or timeout occurred */ |
428 | if (s5p_mfc_wait_for_done_ctx(ctx, | 498 | if (s5p_mfc_wait_for_done_ctx(ctx, |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index a98fe023deaf..c6c3452ccca1 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | |||
@@ -269,15 +269,13 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
269 | strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1); | 269 | strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1); |
270 | strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); | 270 | strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); |
271 | cap->bus_info[0] = 0; | 271 | cap->bus_info[0] = 0; |
272 | cap->version = KERNEL_VERSION(1, 0, 0); | ||
273 | /* | 272 | /* |
274 | * This is only a mem-to-mem video device. The capture and output | 273 | * This is only a mem-to-mem video device. The capture and output |
275 | * device capability flags are left only for backward compatibility | 274 | * device capability flags are left only for backward compatibility |
276 | * and are scheduled for removal. | 275 | * and are scheduled for removal. |
277 | */ | 276 | */ |
278 | cap->capabilities = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING | | 277 | cap->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; |
279 | V4L2_CAP_VIDEO_CAPTURE_MPLANE | | 278 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
280 | V4L2_CAP_VIDEO_OUTPUT_MPLANE; | ||
281 | return 0; | 279 | return 0; |
282 | } | 280 | } |
283 | 281 | ||
@@ -334,7 +332,6 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
334 | MFCINST_RES_CHANGE_END)) { | 332 | MFCINST_RES_CHANGE_END)) { |
335 | /* If the MFC is parsing the header, | 333 | /* If the MFC is parsing the header, |
336 | * so wait until it is finished */ | 334 | * so wait until it is finished */ |
337 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
338 | s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_SEQ_DONE_RET, | 335 | s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_SEQ_DONE_RET, |
339 | 0); | 336 | 0); |
340 | } | 337 | } |
@@ -740,12 +737,12 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl) | |||
740 | ctx->state < MFCINST_ABORT) { | 737 | ctx->state < MFCINST_ABORT) { |
741 | ctrl->val = ctx->pb_count; | 738 | ctrl->val = ctx->pb_count; |
742 | break; | 739 | break; |
743 | } else if (ctx->state != MFCINST_INIT) { | 740 | } else if (ctx->state != MFCINST_INIT && |
741 | ctx->state != MFCINST_RES_CHANGE_END) { | ||
744 | v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n"); | 742 | v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n"); |
745 | return -EINVAL; | 743 | return -EINVAL; |
746 | } | 744 | } |
747 | /* Should wait for the header to be parsed */ | 745 | /* Should wait for the header to be parsed */ |
748 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
749 | s5p_mfc_wait_for_done_ctx(ctx, | 746 | s5p_mfc_wait_for_done_ctx(ctx, |
750 | S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); | 747 | S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); |
751 | if (ctx->state >= MFCINST_HEAD_PARSED && | 748 | if (ctx->state >= MFCINST_HEAD_PARSED && |
@@ -1057,7 +1054,6 @@ static void s5p_mfc_stop_streaming(struct vb2_queue *q) | |||
1057 | if (IS_MFCV6_PLUS(dev) && (ctx->state == MFCINST_RUNNING)) { | 1054 | if (IS_MFCV6_PLUS(dev) && (ctx->state == MFCINST_RUNNING)) { |
1058 | ctx->state = MFCINST_FLUSH; | 1055 | ctx->state = MFCINST_FLUSH; |
1059 | set_work_bit_irqsave(ctx); | 1056 | set_work_bit_irqsave(ctx); |
1060 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1061 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); | 1057 | s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); |
1062 | if (s5p_mfc_wait_for_done_ctx(ctx, | 1058 | if (s5p_mfc_wait_for_done_ctx(ctx, |
1063 | S5P_MFC_R2H_CMD_DPB_FLUSH_RET, 0)) | 1059 | S5P_MFC_R2H_CMD_DPB_FLUSH_RET, 0)) |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index a904a1c7bb21..bd64f1dcbdb5 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "s5p_mfc_intr.h" | 32 | #include "s5p_mfc_intr.h" |
33 | #include "s5p_mfc_opr.h" | 33 | #include "s5p_mfc_opr.h" |
34 | 34 | ||
35 | #define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12MT | 35 | #define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12M |
36 | #define DEF_DST_FMT_ENC V4L2_PIX_FMT_H264 | 36 | #define DEF_DST_FMT_ENC V4L2_PIX_FMT_H264 |
37 | 37 | ||
38 | static struct s5p_mfc_fmt formats[] = { | 38 | static struct s5p_mfc_fmt formats[] = { |
@@ -67,8 +67,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
67 | .codec_mode = S5P_MFC_CODEC_NONE, | 67 | .codec_mode = S5P_MFC_CODEC_NONE, |
68 | .type = MFC_FMT_RAW, | 68 | .type = MFC_FMT_RAW, |
69 | .num_planes = 2, | 69 | .num_planes = 2, |
70 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 70 | .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT, |
71 | MFC_V8_BIT, | ||
72 | }, | 71 | }, |
73 | { | 72 | { |
74 | .name = "H264 Encoded Stream", | 73 | .name = "H264 Encoded Stream", |
@@ -690,6 +689,16 @@ static struct mfc_control controls[] = { | |||
690 | .step = 1, | 689 | .step = 1, |
691 | .default_value = 0, | 690 | .default_value = 0, |
692 | }, | 691 | }, |
692 | { | ||
693 | .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, | ||
694 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
695 | .name = "Minimum number of output bufs", | ||
696 | .minimum = 1, | ||
697 | .maximum = 32, | ||
698 | .step = 1, | ||
699 | .default_value = 1, | ||
700 | .is_volatile = 1, | ||
701 | }, | ||
693 | }; | 702 | }; |
694 | 703 | ||
695 | #define NUM_CTRLS ARRAY_SIZE(controls) | 704 | #define NUM_CTRLS ARRAY_SIZE(controls) |
@@ -938,15 +947,13 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
938 | strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1); | 947 | strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1); |
939 | strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); | 948 | strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); |
940 | cap->bus_info[0] = 0; | 949 | cap->bus_info[0] = 0; |
941 | cap->version = KERNEL_VERSION(1, 0, 0); | ||
942 | /* | 950 | /* |
943 | * This is only a mem-to-mem video device. The capture and output | 951 | * This is only a mem-to-mem video device. The capture and output |
944 | * device capability flags are left only for backward compatibility | 952 | * device capability flags are left only for backward compatibility |
945 | * and are scheduled for removal. | 953 | * and are scheduled for removal. |
946 | */ | 954 | */ |
947 | cap->capabilities = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING | | 955 | cap->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; |
948 | V4L2_CAP_VIDEO_CAPTURE_MPLANE | | 956 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
949 | V4L2_CAP_VIDEO_OUTPUT_MPLANE; | ||
950 | return 0; | 957 | return 0; |
951 | } | 958 | } |
952 | 959 | ||
@@ -1137,6 +1144,11 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1137 | (reqbufs->memory != V4L2_MEMORY_USERPTR)) | 1144 | (reqbufs->memory != V4L2_MEMORY_USERPTR)) |
1138 | return -EINVAL; | 1145 | return -EINVAL; |
1139 | if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 1146 | if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
1147 | if (reqbufs->count == 0) { | ||
1148 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); | ||
1149 | ctx->capture_state = QUEUE_FREE; | ||
1150 | return ret; | ||
1151 | } | ||
1140 | if (ctx->capture_state != QUEUE_FREE) { | 1152 | if (ctx->capture_state != QUEUE_FREE) { |
1141 | mfc_err("invalid capture state: %d\n", | 1153 | mfc_err("invalid capture state: %d\n", |
1142 | ctx->capture_state); | 1154 | ctx->capture_state); |
@@ -1158,6 +1170,14 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1158 | return -ENOMEM; | 1170 | return -ENOMEM; |
1159 | } | 1171 | } |
1160 | } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 1172 | } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
1173 | if (reqbufs->count == 0) { | ||
1174 | mfc_debug(2, "Freeing buffers\n"); | ||
1175 | ret = vb2_reqbufs(&ctx->vq_src, reqbufs); | ||
1176 | s5p_mfc_hw_call_void(dev->mfc_ops, release_codec_buffers, | ||
1177 | ctx); | ||
1178 | ctx->output_state = QUEUE_FREE; | ||
1179 | return ret; | ||
1180 | } | ||
1161 | if (ctx->output_state != QUEUE_FREE) { | 1181 | if (ctx->output_state != QUEUE_FREE) { |
1162 | mfc_err("invalid output state: %d\n", | 1182 | mfc_err("invalid output state: %d\n", |
1163 | ctx->output_state); | 1183 | ctx->output_state); |
@@ -1624,8 +1644,39 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl) | |||
1624 | return ret; | 1644 | return ret; |
1625 | } | 1645 | } |
1626 | 1646 | ||
1647 | static int s5p_mfc_enc_g_v_ctrl(struct v4l2_ctrl *ctrl) | ||
1648 | { | ||
1649 | struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl); | ||
1650 | struct s5p_mfc_dev *dev = ctx->dev; | ||
1651 | |||
1652 | switch (ctrl->id) { | ||
1653 | case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: | ||
1654 | if (ctx->state >= MFCINST_HEAD_PARSED && | ||
1655 | ctx->state < MFCINST_ABORT) { | ||
1656 | ctrl->val = ctx->pb_count; | ||
1657 | break; | ||
1658 | } else if (ctx->state != MFCINST_INIT) { | ||
1659 | v4l2_err(&dev->v4l2_dev, "Encoding not initialised\n"); | ||
1660 | return -EINVAL; | ||
1661 | } | ||
1662 | /* Should wait for the header to be produced */ | ||
1663 | s5p_mfc_wait_for_done_ctx(ctx, | ||
1664 | S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); | ||
1665 | if (ctx->state >= MFCINST_HEAD_PARSED && | ||
1666 | ctx->state < MFCINST_ABORT) { | ||
1667 | ctrl->val = ctx->pb_count; | ||
1668 | } else { | ||
1669 | v4l2_err(&dev->v4l2_dev, "Encoding not initialised\n"); | ||
1670 | return -EINVAL; | ||
1671 | } | ||
1672 | break; | ||
1673 | } | ||
1674 | return 0; | ||
1675 | } | ||
1676 | |||
1627 | static const struct v4l2_ctrl_ops s5p_mfc_enc_ctrl_ops = { | 1677 | static const struct v4l2_ctrl_ops s5p_mfc_enc_ctrl_ops = { |
1628 | .s_ctrl = s5p_mfc_enc_s_ctrl, | 1678 | .s_ctrl = s5p_mfc_enc_s_ctrl, |
1679 | .g_volatile_ctrl = s5p_mfc_enc_g_v_ctrl, | ||
1629 | }; | 1680 | }; |
1630 | 1681 | ||
1631 | static int vidioc_s_parm(struct file *file, void *priv, | 1682 | static int vidioc_s_parm(struct file *file, void *priv, |
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 7cf07963187d..0c4fcf2dfd09 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | |||
@@ -1178,7 +1178,6 @@ static void s5p_mfc_run_res_change(struct s5p_mfc_ctx *ctx) | |||
1178 | 1178 | ||
1179 | s5p_mfc_set_dec_stream_buffer_v5(ctx, 0, 0, 0); | 1179 | s5p_mfc_set_dec_stream_buffer_v5(ctx, 0, 0, 0); |
1180 | dev->curr_ctx = ctx->num; | 1180 | dev->curr_ctx = ctx->num; |
1181 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1182 | s5p_mfc_decode_one_frame_v5(ctx, MFC_DEC_RES_CHANGE); | 1181 | s5p_mfc_decode_one_frame_v5(ctx, MFC_DEC_RES_CHANGE); |
1183 | } | 1182 | } |
1184 | 1183 | ||
@@ -1192,7 +1191,6 @@ static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame) | |||
1192 | last_frame = MFC_DEC_LAST_FRAME; | 1191 | last_frame = MFC_DEC_LAST_FRAME; |
1193 | s5p_mfc_set_dec_stream_buffer_v5(ctx, 0, 0, 0); | 1192 | s5p_mfc_set_dec_stream_buffer_v5(ctx, 0, 0, 0); |
1194 | dev->curr_ctx = ctx->num; | 1193 | dev->curr_ctx = ctx->num; |
1195 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1196 | s5p_mfc_decode_one_frame_v5(ctx, last_frame); | 1194 | s5p_mfc_decode_one_frame_v5(ctx, last_frame); |
1197 | return 0; | 1195 | return 0; |
1198 | } | 1196 | } |
@@ -1212,7 +1210,6 @@ static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame) | |||
1212 | ctx->consumed_stream, temp_vb->b->v4l2_planes[0].bytesused); | 1210 | ctx->consumed_stream, temp_vb->b->v4l2_planes[0].bytesused); |
1213 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1211 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1214 | dev->curr_ctx = ctx->num; | 1212 | dev->curr_ctx = ctx->num; |
1215 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1216 | if (temp_vb->b->v4l2_planes[0].bytesused == 0) { | 1213 | if (temp_vb->b->v4l2_planes[0].bytesused == 0) { |
1217 | last_frame = MFC_DEC_LAST_FRAME; | 1214 | last_frame = MFC_DEC_LAST_FRAME; |
1218 | mfc_debug(2, "Setting ctx->state to FINISHING\n"); | 1215 | mfc_debug(2, "Setting ctx->state to FINISHING\n"); |
@@ -1273,7 +1270,6 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) | |||
1273 | s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size); | 1270 | s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size); |
1274 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1271 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1275 | dev->curr_ctx = ctx->num; | 1272 | dev->curr_ctx = ctx->num; |
1276 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1277 | mfc_debug(2, "encoding buffer with index=%d state=%d\n", | 1273 | mfc_debug(2, "encoding buffer with index=%d state=%d\n", |
1278 | src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state); | 1274 | src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state); |
1279 | s5p_mfc_encode_one_frame_v5(ctx); | 1275 | s5p_mfc_encode_one_frame_v5(ctx); |
@@ -1297,7 +1293,6 @@ static void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx) | |||
1297 | 0, temp_vb->b->v4l2_planes[0].bytesused); | 1293 | 0, temp_vb->b->v4l2_planes[0].bytesused); |
1298 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1294 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1299 | dev->curr_ctx = ctx->num; | 1295 | dev->curr_ctx = ctx->num; |
1300 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1301 | s5p_mfc_init_decode_v5(ctx); | 1296 | s5p_mfc_init_decode_v5(ctx); |
1302 | } | 1297 | } |
1303 | 1298 | ||
@@ -1317,7 +1312,6 @@ static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx) | |||
1317 | s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size); | 1312 | s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size); |
1318 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1313 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1319 | dev->curr_ctx = ctx->num; | 1314 | dev->curr_ctx = ctx->num; |
1320 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1321 | s5p_mfc_init_encode_v5(ctx); | 1315 | s5p_mfc_init_encode_v5(ctx); |
1322 | } | 1316 | } |
1323 | 1317 | ||
@@ -1352,7 +1346,6 @@ static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) | |||
1352 | 0, temp_vb->b->v4l2_planes[0].bytesused); | 1346 | 0, temp_vb->b->v4l2_planes[0].bytesused); |
1353 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1347 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1354 | dev->curr_ctx = ctx->num; | 1348 | dev->curr_ctx = ctx->num; |
1355 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1356 | ret = s5p_mfc_set_dec_frame_buffer_v5(ctx); | 1349 | ret = s5p_mfc_set_dec_frame_buffer_v5(ctx); |
1357 | if (ret) { | 1350 | if (ret) { |
1358 | mfc_err("Failed to alloc frame mem\n"); | 1351 | mfc_err("Failed to alloc frame mem\n"); |
@@ -1396,6 +1389,8 @@ static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) | |||
1396 | * Now obtaining frames from MFC buffer | 1389 | * Now obtaining frames from MFC buffer |
1397 | */ | 1390 | */ |
1398 | s5p_mfc_clock_on(); | 1391 | s5p_mfc_clock_on(); |
1392 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1393 | |||
1399 | if (ctx->type == MFCINST_DECODER) { | 1394 | if (ctx->type == MFCINST_DECODER) { |
1400 | s5p_mfc_set_dec_desc_buffer(ctx); | 1395 | s5p_mfc_set_dec_desc_buffer(ctx); |
1401 | switch (ctx->state) { | 1396 | switch (ctx->state) { |
@@ -1406,12 +1401,10 @@ static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) | |||
1406 | ret = s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME); | 1401 | ret = s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME); |
1407 | break; | 1402 | break; |
1408 | case MFCINST_INIT: | 1403 | case MFCINST_INIT: |
1409 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1410 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, | 1404 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, |
1411 | ctx); | 1405 | ctx); |
1412 | break; | 1406 | break; |
1413 | case MFCINST_RETURN_INST: | 1407 | case MFCINST_RETURN_INST: |
1414 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1415 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, | 1408 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, |
1416 | ctx); | 1409 | ctx); |
1417 | break; | 1410 | break; |
@@ -1444,12 +1437,10 @@ static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) | |||
1444 | ret = s5p_mfc_run_enc_frame(ctx); | 1437 | ret = s5p_mfc_run_enc_frame(ctx); |
1445 | break; | 1438 | break; |
1446 | case MFCINST_INIT: | 1439 | case MFCINST_INIT: |
1447 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1448 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, | 1440 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, |
1449 | ctx); | 1441 | ctx); |
1450 | break; | 1442 | break; |
1451 | case MFCINST_RETURN_INST: | 1443 | case MFCINST_RETURN_INST: |
1452 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1453 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, | 1444 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, |
1454 | ctx); | 1445 | ctx); |
1455 | break; | 1446 | break; |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index 8798b14bacce..9aea179943ce 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | |||
@@ -1394,7 +1394,6 @@ static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush) | |||
1394 | 1394 | ||
1395 | if (flush) { | 1395 | if (flush) { |
1396 | dev->curr_ctx = ctx->num; | 1396 | dev->curr_ctx = ctx->num; |
1397 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1398 | writel(ctx->inst_no, mfc_regs->instance_id); | 1397 | writel(ctx->inst_no, mfc_regs->instance_id); |
1399 | s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, | 1398 | s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, |
1400 | S5P_FIMV_H2R_CMD_FLUSH_V6, NULL); | 1399 | S5P_FIMV_H2R_CMD_FLUSH_V6, NULL); |
@@ -1532,27 +1531,10 @@ static inline int s5p_mfc_get_new_ctx(struct s5p_mfc_dev *dev) | |||
1532 | static inline void s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx) | 1531 | static inline void s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx) |
1533 | { | 1532 | { |
1534 | struct s5p_mfc_dev *dev = ctx->dev; | 1533 | struct s5p_mfc_dev *dev = ctx->dev; |
1535 | struct s5p_mfc_buf *temp_vb; | ||
1536 | unsigned long flags; | ||
1537 | |||
1538 | spin_lock_irqsave(&dev->irqlock, flags); | ||
1539 | |||
1540 | /* Frames are being decoded */ | ||
1541 | if (list_empty(&ctx->src_queue)) { | ||
1542 | mfc_debug(2, "No src buffers.\n"); | ||
1543 | spin_unlock_irqrestore(&dev->irqlock, flags); | ||
1544 | return; | ||
1545 | } | ||
1546 | /* Get the next source buffer */ | ||
1547 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); | ||
1548 | temp_vb->flags |= MFC_BUF_FLAG_USED; | ||
1549 | s5p_mfc_set_dec_stream_buffer_v6(ctx, | ||
1550 | vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0, 0); | ||
1551 | spin_unlock_irqrestore(&dev->irqlock, flags); | ||
1552 | 1534 | ||
1535 | s5p_mfc_set_dec_stream_buffer_v6(ctx, 0, 0, 0); | ||
1553 | dev->curr_ctx = ctx->num; | 1536 | dev->curr_ctx = ctx->num; |
1554 | s5p_mfc_clean_ctx_int_flags(ctx); | 1537 | s5p_mfc_decode_one_frame_v6(ctx, MFC_DEC_LAST_FRAME); |
1555 | s5p_mfc_decode_one_frame_v6(ctx, 1); | ||
1556 | } | 1538 | } |
1557 | 1539 | ||
1558 | static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx) | 1540 | static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx) |
@@ -1588,7 +1570,6 @@ static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx) | |||
1588 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1570 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1589 | 1571 | ||
1590 | dev->curr_ctx = ctx->num; | 1572 | dev->curr_ctx = ctx->num; |
1591 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1592 | if (temp_vb->b->v4l2_planes[0].bytesused == 0) { | 1573 | if (temp_vb->b->v4l2_planes[0].bytesused == 0) { |
1593 | last_frame = 1; | 1574 | last_frame = 1; |
1594 | mfc_debug(2, "Setting ctx->state to FINISHING\n"); | 1575 | mfc_debug(2, "Setting ctx->state to FINISHING\n"); |
@@ -1645,7 +1626,6 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) | |||
1645 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1626 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1646 | 1627 | ||
1647 | dev->curr_ctx = ctx->num; | 1628 | dev->curr_ctx = ctx->num; |
1648 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1649 | s5p_mfc_encode_one_frame_v6(ctx); | 1629 | s5p_mfc_encode_one_frame_v6(ctx); |
1650 | 1630 | ||
1651 | return 0; | 1631 | return 0; |
@@ -1667,7 +1647,6 @@ static inline void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx) | |||
1667 | temp_vb->b->v4l2_planes[0].bytesused); | 1647 | temp_vb->b->v4l2_planes[0].bytesused); |
1668 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1648 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1669 | dev->curr_ctx = ctx->num; | 1649 | dev->curr_ctx = ctx->num; |
1670 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1671 | s5p_mfc_init_decode_v6(ctx); | 1650 | s5p_mfc_init_decode_v6(ctx); |
1672 | } | 1651 | } |
1673 | 1652 | ||
@@ -1687,7 +1666,6 @@ static inline void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx) | |||
1687 | s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size); | 1666 | s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size); |
1688 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1667 | spin_unlock_irqrestore(&dev->irqlock, flags); |
1689 | dev->curr_ctx = ctx->num; | 1668 | dev->curr_ctx = ctx->num; |
1690 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1691 | s5p_mfc_init_encode_v6(ctx); | 1669 | s5p_mfc_init_encode_v6(ctx); |
1692 | } | 1670 | } |
1693 | 1671 | ||
@@ -1707,7 +1685,6 @@ static inline int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) | |||
1707 | } | 1685 | } |
1708 | 1686 | ||
1709 | dev->curr_ctx = ctx->num; | 1687 | dev->curr_ctx = ctx->num; |
1710 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1711 | ret = s5p_mfc_set_dec_frame_buffer_v6(ctx); | 1688 | ret = s5p_mfc_set_dec_frame_buffer_v6(ctx); |
1712 | if (ret) { | 1689 | if (ret) { |
1713 | mfc_err("Failed to alloc frame mem.\n"); | 1690 | mfc_err("Failed to alloc frame mem.\n"); |
@@ -1722,7 +1699,6 @@ static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx) | |||
1722 | int ret; | 1699 | int ret; |
1723 | 1700 | ||
1724 | dev->curr_ctx = ctx->num; | 1701 | dev->curr_ctx = ctx->num; |
1725 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1726 | ret = s5p_mfc_set_enc_ref_buffer_v6(ctx); | 1702 | ret = s5p_mfc_set_enc_ref_buffer_v6(ctx); |
1727 | if (ret) { | 1703 | if (ret) { |
1728 | mfc_err("Failed to alloc frame mem.\n"); | 1704 | mfc_err("Failed to alloc frame mem.\n"); |
@@ -1771,6 +1747,8 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) | |||
1771 | * Now obtaining frames from MFC buffer */ | 1747 | * Now obtaining frames from MFC buffer */ |
1772 | 1748 | ||
1773 | s5p_mfc_clock_on(); | 1749 | s5p_mfc_clock_on(); |
1750 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1751 | |||
1774 | if (ctx->type == MFCINST_DECODER) { | 1752 | if (ctx->type == MFCINST_DECODER) { |
1775 | switch (ctx->state) { | 1753 | switch (ctx->state) { |
1776 | case MFCINST_FINISHING: | 1754 | case MFCINST_FINISHING: |
@@ -1780,12 +1758,10 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) | |||
1780 | ret = s5p_mfc_run_dec_frame(ctx); | 1758 | ret = s5p_mfc_run_dec_frame(ctx); |
1781 | break; | 1759 | break; |
1782 | case MFCINST_INIT: | 1760 | case MFCINST_INIT: |
1783 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1784 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, | 1761 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, |
1785 | ctx); | 1762 | ctx); |
1786 | break; | 1763 | break; |
1787 | case MFCINST_RETURN_INST: | 1764 | case MFCINST_RETURN_INST: |
1788 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
1789 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, | 1765 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, |
1790 | ctx); | 1766 | ctx); |
1791 | break; | 1767 | break; |