aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-10-11 14:07:19 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-10-11 14:07:19 -0400
commitbf3b202b41999f88f091632f13842b7234bd58b7 (patch)
treee2861fcca522cc299e6106fa6c78d85a4a6eedeb /drivers/media/platform
parent782cd9ee985b1523f1ddad57657a24d7855d9e4d (diff)
parent1fdead8ad31d3aa833bc37739273fcde89ace93c (diff)
Merge branch 'staging/for_v3.7' into v4l_for_linus
Applied on the top of changeset 782cd9e, as some of those patches depend on some fixes that went via -arm tree. * staging/for_v3.7: (109 commits) [media] m5mols: Add missing #include <linux/sizes.h> [media] stk1160: Add support for S-Video input Revert "[media] omap3isp: Replace cpu_is_omap3630() with ISP revision check" [media] dvb: LNA implementation changes [media] v4l2-ioctl: fix W=1 warnings [media] v4l2-ioctl: add blocks check for VIDIOC_SUBDEV_G/S_EDID [media] omap3isp: Fix compilation error in ispreg.h [media] rc-msi-digivox-ii: Add full scan keycodes [media] cx25821: testing the wrong variable [media] tda18271-common: hold the I2C adapter during write transfers [media] ds3000: add module parameter to force firmware upload [media] drivers/media: Remove unnecessary semicolon [media] winbond: remove space from driver name [media] iguanair: cannot send data from the stack [media] omap3isp: Replace cpu_is_omap3630() with ISP revision check [media] dvb-usb: print small buffers via %*ph [media] uvc: Add return code check at vb2_queue_init() [media] em28xx: Replace memcpy with struct assignment [media] bt8xx: Add video4linux control V4L2_CID_COLOR_KILLER [media] mem2mem_testdev: Use devm_kzalloc() in probe ...
Diffstat (limited to 'drivers/media/platform')
-rw-r--r--drivers/media/platform/Kconfig4
-rw-r--r--drivers/media/platform/davinci/vpbe.c136
-rw-r--r--drivers/media/platform/davinci/vpbe_display.c80
-rw-r--r--drivers/media/platform/davinci/vpbe_venc.c25
-rw-r--r--drivers/media/platform/davinci/vpfe_capture.c17
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c370
-rw-r--r--drivers/media/platform/davinci/vpif_capture.h16
-rw-r--r--drivers/media/platform/davinci/vpif_display.c275
-rw-r--r--drivers/media/platform/davinci/vpif_display.h18
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-regs.c4
-rw-r--r--drivers/media/platform/fsl-viu.c2
-rw-r--r--drivers/media/platform/mem2mem_testdev.c14
-rw-r--r--drivers/media/platform/omap3isp/ispreg.h6
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-capture.c135
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-core.c19
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-core.h28
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-m2m.c25
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-reg.c23
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-reg.h3
-rw-r--r--drivers/media/platform/s5p-fimc/mipi-csis.c75
-rw-r--r--drivers/media/platform/s5p-g2d/g2d.c2
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c6
-rw-r--r--drivers/media/platform/s5p-mfc/Makefile7
-rw-r--r--drivers/media/platform/s5p-mfc/regs-mfc-v6.h408
-rw-r--r--drivers/media/platform/s5p-mfc/regs-mfc.h41
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c294
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c111
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h17
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c166
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h20
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c156
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h20
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_common.h191
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c202
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h1
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_dec.c258
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_dec.h1
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.c236
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.h1
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_intr.c11
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr.c1418
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr.h137
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c1794
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_shm.h)41
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c1956
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h50
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_pm.c3
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_shm.c47
-rw-r--r--drivers/media/platform/soc_camera/mx2_camera.c7
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c40
50 files changed, 6304 insertions, 2613 deletions
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index f588d6296c76..181c7686e412 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -165,12 +165,12 @@ config VIDEO_SAMSUNG_S5P_JPEG
165 This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec 165 This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec
166 166
167config VIDEO_SAMSUNG_S5P_MFC 167config VIDEO_SAMSUNG_S5P_MFC
168 tristate "Samsung S5P MFC 5.1 Video Codec" 168 tristate "Samsung S5P MFC Video Codec"
169 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P 169 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
170 select VIDEOBUF2_DMA_CONTIG 170 select VIDEOBUF2_DMA_CONTIG
171 default n 171 default n
172 help 172 help
173 MFC 5.1 driver for V4L2. 173 MFC 5.1 and 6.x driver for V4L2
174 174
175config VIDEO_MX2_EMMAPRP 175config VIDEO_MX2_EMMAPRP
176 tristate "MX2 eMMa-PrP support" 176 tristate "MX2 eMMa-PrP support"
diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c
index c4a82a1a8a97..69d7a58c92c3 100644
--- a/drivers/media/platform/davinci/vpbe.c
+++ b/drivers/media/platform/davinci/vpbe.c
@@ -174,26 +174,6 @@ static int vpbe_get_current_mode_info(struct vpbe_device *vpbe_dev,
174 return 0; 174 return 0;
175} 175}
176 176
177static int vpbe_get_dv_preset_info(struct vpbe_device *vpbe_dev,
178 unsigned int dv_preset)
179{
180 struct vpbe_config *cfg = vpbe_dev->cfg;
181 struct vpbe_enc_mode_info var;
182 int curr_output = vpbe_dev->current_out_index;
183 int i;
184
185 for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
186 var = cfg->outputs[curr_output].modes[i];
187 if ((var.timings_type & VPBE_ENC_DV_PRESET) &&
188 (var.timings.dv_preset == dv_preset)) {
189 vpbe_dev->current_timings = var;
190 return 0;
191 }
192 }
193
194 return -EINVAL;
195}
196
197/* Get std by std id */ 177/* Get std by std id */
198static int vpbe_get_std_info(struct vpbe_device *vpbe_dev, 178static int vpbe_get_std_info(struct vpbe_device *vpbe_dev,
199 v4l2_std_id std_id) 179 v4l2_std_id std_id)
@@ -206,7 +186,7 @@ static int vpbe_get_std_info(struct vpbe_device *vpbe_dev,
206 for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) { 186 for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
207 var = cfg->outputs[curr_output].modes[i]; 187 var = cfg->outputs[curr_output].modes[i];
208 if ((var.timings_type & VPBE_ENC_STD) && 188 if ((var.timings_type & VPBE_ENC_STD) &&
209 (var.timings.std_id & std_id)) { 189 (var.std_id & std_id)) {
210 vpbe_dev->current_timings = var; 190 vpbe_dev->current_timings = var;
211 return 0; 191 return 0;
212 } 192 }
@@ -344,38 +324,42 @@ static unsigned int vpbe_get_output(struct vpbe_device *vpbe_dev)
344} 324}
345 325
346/** 326/**
347 * vpbe_s_dv_preset - Set the given preset timings in the encoder 327 * vpbe_s_dv_timings - Set the given preset timings in the encoder
348 * 328 *
349 * Sets the preset if supported by the current encoder. Return the status. 329 * Sets the timings if supported by the current encoder. Return the status.
350 * 0 - success & -EINVAL on error 330 * 0 - success & -EINVAL on error
351 */ 331 */
352static int vpbe_s_dv_preset(struct vpbe_device *vpbe_dev, 332static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev,
353 struct v4l2_dv_preset *dv_preset) 333 struct v4l2_dv_timings *dv_timings)
354{ 334{
355 struct vpbe_config *cfg = vpbe_dev->cfg; 335 struct vpbe_config *cfg = vpbe_dev->cfg;
356 int out_index = vpbe_dev->current_out_index; 336 int out_index = vpbe_dev->current_out_index;
337 struct vpbe_output *output = &cfg->outputs[out_index];
357 int sd_index = vpbe_dev->current_sd_index; 338 int sd_index = vpbe_dev->current_sd_index;
358 int ret; 339 int ret, i;
359 340
360 341
361 if (!(cfg->outputs[out_index].output.capabilities & 342 if (!(cfg->outputs[out_index].output.capabilities &
362 V4L2_OUT_CAP_PRESETS)) 343 V4L2_OUT_CAP_DV_TIMINGS))
363 return -EINVAL; 344 return -EINVAL;
364 345
365 ret = vpbe_get_dv_preset_info(vpbe_dev, dv_preset->preset); 346 for (i = 0; i < output->num_modes; i++) {
366 347 if (output->modes[i].timings_type == VPBE_ENC_CUSTOM_TIMINGS &&
367 if (ret) 348 !memcmp(&output->modes[i].dv_timings,
368 return ret; 349 dv_timings, sizeof(*dv_timings)))
369 350 break;
351 }
352 if (i >= output->num_modes)
353 return -EINVAL;
354 vpbe_dev->current_timings = output->modes[i];
370 mutex_lock(&vpbe_dev->lock); 355 mutex_lock(&vpbe_dev->lock);
371 356
372
373 ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, 357 ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
374 s_dv_preset, dv_preset); 358 s_dv_timings, dv_timings);
375 if (!ret && (vpbe_dev->amp != NULL)) { 359 if (!ret && (vpbe_dev->amp != NULL)) {
376 /* Call amplifier subdevice */ 360 /* Call amplifier subdevice */
377 ret = v4l2_subdev_call(vpbe_dev->amp, video, 361 ret = v4l2_subdev_call(vpbe_dev->amp, video,
378 s_dv_preset, dv_preset); 362 s_dv_timings, dv_timings);
379 } 363 }
380 /* set the lcd controller output for the given mode */ 364 /* set the lcd controller output for the given mode */
381 if (!ret) { 365 if (!ret) {
@@ -392,17 +376,17 @@ static int vpbe_s_dv_preset(struct vpbe_device *vpbe_dev,
392} 376}
393 377
394/** 378/**
395 * vpbe_g_dv_preset - Get the preset in the current encoder 379 * vpbe_g_dv_timings - Get the timings in the current encoder
396 * 380 *
397 * Get the preset in the current encoder. Return the status. 0 - success 381 * Get the timings in the current encoder. Return the status. 0 - success
398 * -EINVAL on error 382 * -EINVAL on error
399 */ 383 */
400static int vpbe_g_dv_preset(struct vpbe_device *vpbe_dev, 384static int vpbe_g_dv_timings(struct vpbe_device *vpbe_dev,
401 struct v4l2_dv_preset *dv_preset) 385 struct v4l2_dv_timings *dv_timings)
402{ 386{
403 if (vpbe_dev->current_timings.timings_type & 387 if (vpbe_dev->current_timings.timings_type &
404 VPBE_ENC_DV_PRESET) { 388 VPBE_ENC_CUSTOM_TIMINGS) {
405 dv_preset->preset = vpbe_dev->current_timings.timings.dv_preset; 389 *dv_timings = vpbe_dev->current_timings.dv_timings;
406 return 0; 390 return 0;
407 } 391 }
408 392
@@ -410,13 +394,13 @@ static int vpbe_g_dv_preset(struct vpbe_device *vpbe_dev,
410} 394}
411 395
412/** 396/**
413 * vpbe_enum_dv_presets - Enumerate the dv presets in the current encoder 397 * vpbe_enum_dv_timings - Enumerate the dv timings in the current encoder
414 * 398 *
415 * Get the preset in the current encoder. Return the status. 0 - success 399 * Get the timings in the current encoder. Return the status. 0 - success
416 * -EINVAL on error 400 * -EINVAL on error
417 */ 401 */
418static int vpbe_enum_dv_presets(struct vpbe_device *vpbe_dev, 402static int vpbe_enum_dv_timings(struct vpbe_device *vpbe_dev,
419 struct v4l2_dv_enum_preset *preset_info) 403 struct v4l2_enum_dv_timings *timings)
420{ 404{
421 struct vpbe_config *cfg = vpbe_dev->cfg; 405 struct vpbe_config *cfg = vpbe_dev->cfg;
422 int out_index = vpbe_dev->current_out_index; 406 int out_index = vpbe_dev->current_out_index;
@@ -424,12 +408,12 @@ static int vpbe_enum_dv_presets(struct vpbe_device *vpbe_dev,
424 int j = 0; 408 int j = 0;
425 int i; 409 int i;
426 410
427 if (!(output->output.capabilities & V4L2_OUT_CAP_PRESETS)) 411 if (!(output->output.capabilities & V4L2_OUT_CAP_DV_TIMINGS))
428 return -EINVAL; 412 return -EINVAL;
429 413
430 for (i = 0; i < output->num_modes; i++) { 414 for (i = 0; i < output->num_modes; i++) {
431 if (output->modes[i].timings_type == VPBE_ENC_DV_PRESET) { 415 if (output->modes[i].timings_type == VPBE_ENC_CUSTOM_TIMINGS) {
432 if (j == preset_info->index) 416 if (j == timings->index)
433 break; 417 break;
434 j++; 418 j++;
435 } 419 }
@@ -437,9 +421,8 @@ static int vpbe_enum_dv_presets(struct vpbe_device *vpbe_dev,
437 421
438 if (i == output->num_modes) 422 if (i == output->num_modes)
439 return -EINVAL; 423 return -EINVAL;
440 424 timings->timings = output->modes[i].dv_timings;
441 return v4l_fill_dv_preset_info(output->modes[i].timings.dv_preset, 425 return 0;
442 preset_info);
443} 426}
444 427
445/** 428/**
@@ -489,10 +472,10 @@ static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
489 */ 472 */
490static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id) 473static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
491{ 474{
492 struct vpbe_enc_mode_info cur_timings = vpbe_dev->current_timings; 475 struct vpbe_enc_mode_info *cur_timings = &vpbe_dev->current_timings;
493 476
494 if (cur_timings.timings_type & VPBE_ENC_STD) { 477 if (cur_timings->timings_type & VPBE_ENC_STD) {
495 *std_id = cur_timings.timings.std_id; 478 *std_id = cur_timings->std_id;
496 return 0; 479 return 0;
497 } 480 }
498 481
@@ -511,7 +494,7 @@ static int vpbe_set_mode(struct vpbe_device *vpbe_dev,
511{ 494{
512 struct vpbe_enc_mode_info *preset_mode = NULL; 495 struct vpbe_enc_mode_info *preset_mode = NULL;
513 struct vpbe_config *cfg = vpbe_dev->cfg; 496 struct vpbe_config *cfg = vpbe_dev->cfg;
514 struct v4l2_dv_preset dv_preset; 497 struct v4l2_dv_timings dv_timings;
515 struct osd_state *osd_device; 498 struct osd_state *osd_device;
516 int out_index = vpbe_dev->current_out_index; 499 int out_index = vpbe_dev->current_out_index;
517 int ret = 0; 500 int ret = 0;
@@ -530,11 +513,12 @@ static int vpbe_set_mode(struct vpbe_device *vpbe_dev,
530 */ 513 */
531 if (preset_mode->timings_type & VPBE_ENC_STD) 514 if (preset_mode->timings_type & VPBE_ENC_STD)
532 return vpbe_s_std(vpbe_dev, 515 return vpbe_s_std(vpbe_dev,
533 &preset_mode->timings.std_id); 516 &preset_mode->std_id);
534 if (preset_mode->timings_type & VPBE_ENC_DV_PRESET) { 517 if (preset_mode->timings_type &
535 dv_preset.preset = 518 VPBE_ENC_CUSTOM_TIMINGS) {
536 preset_mode->timings.dv_preset; 519 dv_timings =
537 return vpbe_s_dv_preset(vpbe_dev, &dv_preset); 520 preset_mode->dv_timings;
521 return vpbe_s_dv_timings(vpbe_dev, &dv_timings);
538 } 522 }
539 } 523 }
540 } 524 }
@@ -626,11 +610,11 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
626 vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac"); 610 vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac");
627 if (IS_ERR(vpbe_dev->dac_clk)) { 611 if (IS_ERR(vpbe_dev->dac_clk)) {
628 ret = PTR_ERR(vpbe_dev->dac_clk); 612 ret = PTR_ERR(vpbe_dev->dac_clk);
629 goto vpbe_unlock; 613 goto fail_mutex_unlock;
630 } 614 }
631 if (clk_enable(vpbe_dev->dac_clk)) { 615 if (clk_enable(vpbe_dev->dac_clk)) {
632 ret = -ENODEV; 616 ret = -ENODEV;
633 goto vpbe_unlock; 617 goto fail_mutex_unlock;
634 } 618 }
635 } 619 }
636 620
@@ -642,7 +626,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
642 if (ret) { 626 if (ret) {
643 v4l2_err(dev->driver, 627 v4l2_err(dev->driver,
644 "Unable to register v4l2 device.\n"); 628 "Unable to register v4l2 device.\n");
645 goto vpbe_fail_clock; 629 goto fail_clk_put;
646 } 630 }
647 v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n"); 631 v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n");
648 632
@@ -658,7 +642,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
658 v4l2_err(&vpbe_dev->v4l2_dev, 642 v4l2_err(&vpbe_dev->v4l2_dev,
659 "vpbe unable to init venc sub device\n"); 643 "vpbe unable to init venc sub device\n");
660 ret = -ENODEV; 644 ret = -ENODEV;
661 goto vpbe_fail_v4l2_device; 645 goto fail_dev_unregister;
662 } 646 }
663 /* initialize osd device */ 647 /* initialize osd device */
664 osd_device = vpbe_dev->osd_device; 648 osd_device = vpbe_dev->osd_device;
@@ -669,7 +653,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
669 v4l2_err(&vpbe_dev->v4l2_dev, 653 v4l2_err(&vpbe_dev->v4l2_dev,
670 "unable to initialize the OSD device"); 654 "unable to initialize the OSD device");
671 err = -ENOMEM; 655 err = -ENOMEM;
672 goto vpbe_fail_v4l2_device; 656 goto fail_dev_unregister;
673 } 657 }
674 } 658 }
675 659
@@ -685,7 +669,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
685 v4l2_err(&vpbe_dev->v4l2_dev, 669 v4l2_err(&vpbe_dev->v4l2_dev,
686 "unable to allocate memory for encoders sub devices"); 670 "unable to allocate memory for encoders sub devices");
687 ret = -ENOMEM; 671 ret = -ENOMEM;
688 goto vpbe_fail_v4l2_device; 672 goto fail_dev_unregister;
689 } 673 }
690 674
691 i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id); 675 i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id);
@@ -711,7 +695,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
711 " failed to register", 695 " failed to register",
712 enc_info->module_name); 696 enc_info->module_name);
713 ret = -ENODEV; 697 ret = -ENODEV;
714 goto vpbe_fail_sd_register; 698 goto fail_kfree_encoders;
715 } 699 }
716 } else 700 } else
717 v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders" 701 v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders"
@@ -730,7 +714,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
730 "amplifier %s failed to register", 714 "amplifier %s failed to register",
731 amp_info->module_name); 715 amp_info->module_name);
732 ret = -ENODEV; 716 ret = -ENODEV;
733 goto vpbe_fail_amp_register; 717 goto fail_kfree_encoders;
734 } 718 }
735 v4l2_info(&vpbe_dev->v4l2_dev, 719 v4l2_info(&vpbe_dev->v4l2_dev,
736 "v4l2 sub device %s registered\n", 720 "v4l2 sub device %s registered\n",
@@ -770,16 +754,14 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
770 /* TBD handling of bootargs for default output and mode */ 754 /* TBD handling of bootargs for default output and mode */
771 return 0; 755 return 0;
772 756
773vpbe_fail_amp_register: 757fail_kfree_encoders:
774 kfree(vpbe_dev->amp);
775vpbe_fail_sd_register:
776 kfree(vpbe_dev->encoders); 758 kfree(vpbe_dev->encoders);
777vpbe_fail_v4l2_device: 759fail_dev_unregister:
778 v4l2_device_unregister(&vpbe_dev->v4l2_dev); 760 v4l2_device_unregister(&vpbe_dev->v4l2_dev);
779vpbe_fail_clock: 761fail_clk_put:
780 if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) 762 if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0)
781 clk_put(vpbe_dev->dac_clk); 763 clk_put(vpbe_dev->dac_clk);
782vpbe_unlock: 764fail_mutex_unlock:
783 mutex_unlock(&vpbe_dev->lock); 765 mutex_unlock(&vpbe_dev->lock);
784 return ret; 766 return ret;
785} 767}
@@ -810,9 +792,9 @@ static struct vpbe_device_ops vpbe_dev_ops = {
810 .enum_outputs = vpbe_enum_outputs, 792 .enum_outputs = vpbe_enum_outputs,
811 .set_output = vpbe_set_output, 793 .set_output = vpbe_set_output,
812 .get_output = vpbe_get_output, 794 .get_output = vpbe_get_output,
813 .s_dv_preset = vpbe_s_dv_preset, 795 .s_dv_timings = vpbe_s_dv_timings,
814 .g_dv_preset = vpbe_g_dv_preset, 796 .g_dv_timings = vpbe_g_dv_timings,
815 .enum_dv_presets = vpbe_enum_dv_presets, 797 .enum_dv_timings = vpbe_enum_dv_timings,
816 .s_std = vpbe_s_std, 798 .s_std = vpbe_s_std,
817 .g_std = vpbe_g_std, 799 .g_std = vpbe_g_std,
818 .initialize = vpbe_initialize, 800 .initialize = vpbe_initialize,
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 239f37bfa313..161c77650e2f 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -393,7 +393,7 @@ vpbe_disp_calculate_scale_factor(struct vpbe_display *disp_dev,
393 int h_scale; 393 int h_scale;
394 int v_scale; 394 int v_scale;
395 395
396 v4l2_std_id standard_id = vpbe_dev->current_timings.timings.std_id; 396 v4l2_std_id standard_id = vpbe_dev->current_timings.std_id;
397 397
398 /* 398 /*
399 * Application initially set the image format. Current display 399 * Application initially set the image format. Current display
@@ -637,7 +637,7 @@ static int vpbe_display_s_crop(struct file *file, void *priv,
637 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev; 637 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
638 struct osd_layer_config *cfg = &layer->layer_info.config; 638 struct osd_layer_config *cfg = &layer->layer_info.config;
639 struct osd_state *osd_device = disp_dev->osd_device; 639 struct osd_state *osd_device = disp_dev->osd_device;
640 struct v4l2_rect *rect = &crop->c; 640 struct v4l2_rect rect = crop->c;
641 int ret; 641 int ret;
642 642
643 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, 643 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
@@ -648,21 +648,21 @@ static int vpbe_display_s_crop(struct file *file, void *priv,
648 return -EINVAL; 648 return -EINVAL;
649 } 649 }
650 650
651 if (rect->top < 0) 651 if (rect.top < 0)
652 rect->top = 0; 652 rect.top = 0;
653 if (rect->left < 0) 653 if (rect.left < 0)
654 rect->left = 0; 654 rect.left = 0;
655 655
656 vpbe_disp_check_window_params(disp_dev, rect); 656 vpbe_disp_check_window_params(disp_dev, &rect);
657 657
658 osd_device->ops.get_layer_config(osd_device, 658 osd_device->ops.get_layer_config(osd_device,
659 layer->layer_info.id, cfg); 659 layer->layer_info.id, cfg);
660 660
661 vpbe_disp_calculate_scale_factor(disp_dev, layer, 661 vpbe_disp_calculate_scale_factor(disp_dev, layer,
662 rect->width, 662 rect.width,
663 rect->height); 663 rect.height);
664 vpbe_disp_adj_position(disp_dev, layer, rect->top, 664 vpbe_disp_adj_position(disp_dev, layer, rect.top,
665 rect->left); 665 rect.left);
666 ret = osd_device->ops.set_layer_config(osd_device, 666 ret = osd_device->ops.set_layer_config(osd_device,
667 layer->layer_info.id, cfg); 667 layer->layer_info.id, cfg);
668 if (ret < 0) { 668 if (ret < 0) {
@@ -943,7 +943,7 @@ static int vpbe_display_g_std(struct file *file, void *priv,
943 943
944 /* Get the standard from the current encoder */ 944 /* Get the standard from the current encoder */
945 if (vpbe_dev->current_timings.timings_type & VPBE_ENC_STD) { 945 if (vpbe_dev->current_timings.timings_type & VPBE_ENC_STD) {
946 *std_id = vpbe_dev->current_timings.timings.std_id; 946 *std_id = vpbe_dev->current_timings.std_id;
947 return 0; 947 return 0;
948 } 948 }
949 949
@@ -1029,29 +1029,29 @@ static int vpbe_display_g_output(struct file *file, void *priv,
1029} 1029}
1030 1030
1031/** 1031/**
1032 * vpbe_display_enum_dv_presets - Enumerate the dv presets 1032 * vpbe_display_enum_dv_timings - Enumerate the dv timings
1033 * 1033 *
1034 * enum the preset in the current encoder. Return the status. 0 - success 1034 * enum the timings in the current encoder. Return the status. 0 - success
1035 * -EINVAL on error 1035 * -EINVAL on error
1036 */ 1036 */
1037static int 1037static int
1038vpbe_display_enum_dv_presets(struct file *file, void *priv, 1038vpbe_display_enum_dv_timings(struct file *file, void *priv,
1039 struct v4l2_dv_enum_preset *preset) 1039 struct v4l2_enum_dv_timings *timings)
1040{ 1040{
1041 struct vpbe_fh *fh = priv; 1041 struct vpbe_fh *fh = priv;
1042 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; 1042 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1043 int ret; 1043 int ret;
1044 1044
1045 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_PRESETS\n"); 1045 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_TIMINGS\n");
1046 1046
1047 /* Enumerate outputs */ 1047 /* Enumerate outputs */
1048 if (NULL == vpbe_dev->ops.enum_dv_presets) 1048 if (NULL == vpbe_dev->ops.enum_dv_timings)
1049 return -EINVAL; 1049 return -EINVAL;
1050 1050
1051 ret = vpbe_dev->ops.enum_dv_presets(vpbe_dev, preset); 1051 ret = vpbe_dev->ops.enum_dv_timings(vpbe_dev, timings);
1052 if (ret) { 1052 if (ret) {
1053 v4l2_err(&vpbe_dev->v4l2_dev, 1053 v4l2_err(&vpbe_dev->v4l2_dev,
1054 "Failed to enumerate dv presets info\n"); 1054 "Failed to enumerate dv timings info\n");
1055 return -EINVAL; 1055 return -EINVAL;
1056 } 1056 }
1057 1057
@@ -1059,21 +1059,21 @@ vpbe_display_enum_dv_presets(struct file *file, void *priv,
1059} 1059}
1060 1060
1061/** 1061/**
1062 * vpbe_display_s_dv_preset - Set the dv presets 1062 * vpbe_display_s_dv_timings - Set the dv timings
1063 * 1063 *
1064 * Set the preset in the current encoder. Return the status. 0 - success 1064 * Set the timings in the current encoder. Return the status. 0 - success
1065 * -EINVAL on error 1065 * -EINVAL on error
1066 */ 1066 */
1067static int 1067static int
1068vpbe_display_s_dv_preset(struct file *file, void *priv, 1068vpbe_display_s_dv_timings(struct file *file, void *priv,
1069 struct v4l2_dv_preset *preset) 1069 struct v4l2_dv_timings *timings)
1070{ 1070{
1071 struct vpbe_fh *fh = priv; 1071 struct vpbe_fh *fh = priv;
1072 struct vpbe_layer *layer = fh->layer; 1072 struct vpbe_layer *layer = fh->layer;
1073 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; 1073 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1074 int ret; 1074 int ret;
1075 1075
1076 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_PRESETS\n"); 1076 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_TIMINGS\n");
1077 1077
1078 1078
1079 /* If streaming is started, return error */ 1079 /* If streaming is started, return error */
@@ -1083,13 +1083,13 @@ vpbe_display_s_dv_preset(struct file *file, void *priv,
1083 } 1083 }
1084 1084
1085 /* Set the given standard in the encoder */ 1085 /* Set the given standard in the encoder */
1086 if (!vpbe_dev->ops.s_dv_preset) 1086 if (!vpbe_dev->ops.s_dv_timings)
1087 return -EINVAL; 1087 return -EINVAL;
1088 1088
1089 ret = vpbe_dev->ops.s_dv_preset(vpbe_dev, preset); 1089 ret = vpbe_dev->ops.s_dv_timings(vpbe_dev, timings);
1090 if (ret) { 1090 if (ret) {
1091 v4l2_err(&vpbe_dev->v4l2_dev, 1091 v4l2_err(&vpbe_dev->v4l2_dev,
1092 "Failed to set the dv presets info\n"); 1092 "Failed to set the dv timings info\n");
1093 return -EINVAL; 1093 return -EINVAL;
1094 } 1094 }
1095 /* set the current norm to zero to be consistent. If STD is used 1095 /* set the current norm to zero to be consistent. If STD is used
@@ -1101,26 +1101,25 @@ vpbe_display_s_dv_preset(struct file *file, void *priv,
1101} 1101}
1102 1102
1103/** 1103/**
1104 * vpbe_display_g_dv_preset - Set the dv presets 1104 * vpbe_display_g_dv_timings - Set the dv timings
1105 * 1105 *
1106 * Get the preset in the current encoder. Return the status. 0 - success 1106 * Get the timings in the current encoder. Return the status. 0 - success
1107 * -EINVAL on error 1107 * -EINVAL on error
1108 */ 1108 */
1109static int 1109static int
1110vpbe_display_g_dv_preset(struct file *file, void *priv, 1110vpbe_display_g_dv_timings(struct file *file, void *priv,
1111 struct v4l2_dv_preset *dv_preset) 1111 struct v4l2_dv_timings *dv_timings)
1112{ 1112{
1113 struct vpbe_fh *fh = priv; 1113 struct vpbe_fh *fh = priv;
1114 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; 1114 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1115 1115
1116 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_PRESETS\n"); 1116 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_TIMINGS\n");
1117 1117
1118 /* Get the given standard in the encoder */ 1118 /* Get the given standard in the encoder */
1119 1119
1120 if (vpbe_dev->current_timings.timings_type & 1120 if (vpbe_dev->current_timings.timings_type &
1121 VPBE_ENC_DV_PRESET) { 1121 VPBE_ENC_CUSTOM_TIMINGS) {
1122 dv_preset->preset = 1122 *dv_timings = vpbe_dev->current_timings.dv_timings;
1123 vpbe_dev->current_timings.timings.dv_preset;
1124 } else { 1123 } else {
1125 return -EINVAL; 1124 return -EINVAL;
1126 } 1125 }
@@ -1572,9 +1571,9 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
1572 .vidioc_enum_output = vpbe_display_enum_output, 1571 .vidioc_enum_output = vpbe_display_enum_output,
1573 .vidioc_s_output = vpbe_display_s_output, 1572 .vidioc_s_output = vpbe_display_s_output,
1574 .vidioc_g_output = vpbe_display_g_output, 1573 .vidioc_g_output = vpbe_display_g_output,
1575 .vidioc_s_dv_preset = vpbe_display_s_dv_preset, 1574 .vidioc_s_dv_timings = vpbe_display_s_dv_timings,
1576 .vidioc_g_dv_preset = vpbe_display_g_dv_preset, 1575 .vidioc_g_dv_timings = vpbe_display_g_dv_timings,
1577 .vidioc_enum_dv_presets = vpbe_display_enum_dv_presets, 1576 .vidioc_enum_dv_timings = vpbe_display_enum_dv_timings,
1578#ifdef CONFIG_VIDEO_ADV_DEBUG 1577#ifdef CONFIG_VIDEO_ADV_DEBUG
1579 .vidioc_g_register = vpbe_display_g_register, 1578 .vidioc_g_register = vpbe_display_g_register,
1580 .vidioc_s_register = vpbe_display_s_register, 1579 .vidioc_s_register = vpbe_display_s_register,
@@ -1639,8 +1638,7 @@ static __devinit int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
1639 VPBE_ENC_STD) { 1638 VPBE_ENC_STD) {
1640 vbd->tvnorms = (V4L2_STD_525_60 | V4L2_STD_625_50); 1639 vbd->tvnorms = (V4L2_STD_525_60 | V4L2_STD_625_50);
1641 vbd->current_norm = 1640 vbd->current_norm =
1642 disp_dev->vpbe_dev-> 1641 disp_dev->vpbe_dev->current_timings.std_id;
1643 current_timings.timings.std_id;
1644 } else 1642 } else
1645 vbd->current_norm = 0; 1643 vbd->current_norm = 0;
1646 1644
diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c
index 0302669622d6..aed7369b962a 100644
--- a/drivers/media/platform/davinci/vpbe_venc.c
+++ b/drivers/media/platform/davinci/vpbe_venc.c
@@ -298,7 +298,7 @@ static int venc_set_480p59_94(struct v4l2_subdev *sd)
298 return -EINVAL; 298 return -EINVAL;
299 299
300 /* Setup clock at VPSS & VENC for SD */ 300 /* Setup clock at VPSS & VENC for SD */
301 if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_480P59_94) < 0) 301 if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 27000000) < 0)
302 return -EINVAL; 302 return -EINVAL;
303 303
304 venc_enabledigitaloutput(sd, 0); 304 venc_enabledigitaloutput(sd, 0);
@@ -345,7 +345,7 @@ static int venc_set_576p50(struct v4l2_subdev *sd)
345 (pdata->venc_type != VPBE_VERSION_2)) 345 (pdata->venc_type != VPBE_VERSION_2))
346 return -EINVAL; 346 return -EINVAL;
347 /* Setup clock at VPSS & VENC for SD */ 347 /* Setup clock at VPSS & VENC for SD */
348 if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_576P50) < 0) 348 if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 27000000) < 0)
349 return -EINVAL; 349 return -EINVAL;
350 350
351 venc_enabledigitaloutput(sd, 0); 351 venc_enabledigitaloutput(sd, 0);
@@ -385,7 +385,7 @@ static int venc_set_720p60_internal(struct v4l2_subdev *sd)
385 struct venc_state *venc = to_state(sd); 385 struct venc_state *venc = to_state(sd);
386 struct venc_platform_data *pdata = venc->pdata; 386 struct venc_platform_data *pdata = venc->pdata;
387 387
388 if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_720P60) < 0) 388 if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 74250000) < 0)
389 return -EINVAL; 389 return -EINVAL;
390 390
391 venc_enabledigitaloutput(sd, 0); 391 venc_enabledigitaloutput(sd, 0);
@@ -413,7 +413,7 @@ static int venc_set_1080i30_internal(struct v4l2_subdev *sd)
413 struct venc_state *venc = to_state(sd); 413 struct venc_state *venc = to_state(sd);
414 struct venc_platform_data *pdata = venc->pdata; 414 struct venc_platform_data *pdata = venc->pdata;
415 415
416 if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_1080P30) < 0) 416 if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 74250000) < 0)
417 return -EINVAL; 417 return -EINVAL;
418 418
419 venc_enabledigitaloutput(sd, 0); 419 venc_enabledigitaloutput(sd, 0);
@@ -446,26 +446,27 @@ static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
446 return -EINVAL; 446 return -EINVAL;
447} 447}
448 448
449static int venc_s_dv_preset(struct v4l2_subdev *sd, 449static int venc_s_dv_timings(struct v4l2_subdev *sd,
450 struct v4l2_dv_preset *dv_preset) 450 struct v4l2_dv_timings *dv_timings)
451{ 451{
452 struct venc_state *venc = to_state(sd); 452 struct venc_state *venc = to_state(sd);
453 u32 height = dv_timings->bt.height;
453 int ret; 454 int ret;
454 455
455 v4l2_dbg(debug, 1, sd, "venc_s_dv_preset\n"); 456 v4l2_dbg(debug, 1, sd, "venc_s_dv_timings\n");
456 457
457 if (dv_preset->preset == V4L2_DV_576P50) 458 if (height == 576)
458 return venc_set_576p50(sd); 459 return venc_set_576p50(sd);
459 else if (dv_preset->preset == V4L2_DV_480P59_94) 460 else if (height == 480)
460 return venc_set_480p59_94(sd); 461 return venc_set_480p59_94(sd);
461 else if ((dv_preset->preset == V4L2_DV_720P60) && 462 else if ((height == 720) &&
462 (venc->pdata->venc_type == VPBE_VERSION_2)) { 463 (venc->pdata->venc_type == VPBE_VERSION_2)) {
463 /* TBD setup internal 720p mode here */ 464 /* TBD setup internal 720p mode here */
464 ret = venc_set_720p60_internal(sd); 465 ret = venc_set_720p60_internal(sd);
465 /* for DM365 VPBE, there is DAC inside */ 466 /* for DM365 VPBE, there is DAC inside */
466 vdaccfg_write(sd, VDAC_CONFIG_HD_V2); 467 vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
467 return ret; 468 return ret;
468 } else if ((dv_preset->preset == V4L2_DV_1080I30) && 469 } else if ((height == 1080) &&
469 (venc->pdata->venc_type == VPBE_VERSION_2)) { 470 (venc->pdata->venc_type == VPBE_VERSION_2)) {
470 /* TBD setup internal 1080i mode here */ 471 /* TBD setup internal 1080i mode here */
471 ret = venc_set_1080i30_internal(sd); 472 ret = venc_set_1080i30_internal(sd);
@@ -518,7 +519,7 @@ static const struct v4l2_subdev_core_ops venc_core_ops = {
518static const struct v4l2_subdev_video_ops venc_video_ops = { 519static const struct v4l2_subdev_video_ops venc_video_ops = {
519 .s_routing = venc_s_routing, 520 .s_routing = venc_s_routing,
520 .s_std_output = venc_s_std_output, 521 .s_std_output = venc_s_std_output,
521 .s_dv_preset = venc_s_dv_preset, 522 .s_dv_timings = venc_s_dv_timings,
522}; 523};
523 524
524static const struct v4l2_subdev_ops venc_ops = { 525static const struct v4l2_subdev_ops venc_ops = {
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index 48052cbffc2b..8be492cd8ed4 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -1669,6 +1669,7 @@ static int vpfe_s_crop(struct file *file, void *priv,
1669 const struct v4l2_crop *crop) 1669 const struct v4l2_crop *crop)
1670{ 1670{
1671 struct vpfe_device *vpfe_dev = video_drvdata(file); 1671 struct vpfe_device *vpfe_dev = video_drvdata(file);
1672 struct v4l2_rect rect = crop->c;
1672 int ret = 0; 1673 int ret = 0;
1673 1674
1674 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_crop\n"); 1675 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_crop\n");
@@ -1684,7 +1685,7 @@ static int vpfe_s_crop(struct file *file, void *priv,
1684 if (ret) 1685 if (ret)
1685 return ret; 1686 return ret;
1686 1687
1687 if (crop->c.top < 0 || crop->c.left < 0) { 1688 if (rect.top < 0 || rect.left < 0) {
1688 v4l2_err(&vpfe_dev->v4l2_dev, 1689 v4l2_err(&vpfe_dev->v4l2_dev,
1689 "doesn't support negative values for top & left\n"); 1690 "doesn't support negative values for top & left\n");
1690 ret = -EINVAL; 1691 ret = -EINVAL;
@@ -1692,26 +1693,26 @@ static int vpfe_s_crop(struct file *file, void *priv,
1692 } 1693 }
1693 1694
1694 /* adjust the width to 16 pixel boundary */ 1695 /* adjust the width to 16 pixel boundary */
1695 crop->c.width = ((crop->c.width + 15) & ~0xf); 1696 rect.width = ((rect.width + 15) & ~0xf);
1696 1697
1697 /* make sure parameters are valid */ 1698 /* make sure parameters are valid */
1698 if ((crop->c.left + crop->c.width > 1699 if ((rect.left + rect.width >
1699 vpfe_dev->std_info.active_pixels) || 1700 vpfe_dev->std_info.active_pixels) ||
1700 (crop->c.top + crop->c.height > 1701 (rect.top + rect.height >
1701 vpfe_dev->std_info.active_lines)) { 1702 vpfe_dev->std_info.active_lines)) {
1702 v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_CROP params\n"); 1703 v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_CROP params\n");
1703 ret = -EINVAL; 1704 ret = -EINVAL;
1704 goto unlock_out; 1705 goto unlock_out;
1705 } 1706 }
1706 ccdc_dev->hw_ops.set_image_window(&crop->c); 1707 ccdc_dev->hw_ops.set_image_window(&rect);
1707 vpfe_dev->fmt.fmt.pix.width = crop->c.width; 1708 vpfe_dev->fmt.fmt.pix.width = rect.width;
1708 vpfe_dev->fmt.fmt.pix.height = crop->c.height; 1709 vpfe_dev->fmt.fmt.pix.height = rect.height;
1709 vpfe_dev->fmt.fmt.pix.bytesperline = 1710 vpfe_dev->fmt.fmt.pix.bytesperline =
1710 ccdc_dev->hw_ops.get_line_length(); 1711 ccdc_dev->hw_ops.get_line_length();
1711 vpfe_dev->fmt.fmt.pix.sizeimage = 1712 vpfe_dev->fmt.fmt.pix.sizeimage =
1712 vpfe_dev->fmt.fmt.pix.bytesperline * 1713 vpfe_dev->fmt.fmt.pix.bytesperline *
1713 vpfe_dev->fmt.fmt.pix.height; 1714 vpfe_dev->fmt.fmt.pix.height;
1714 vpfe_dev->crop = crop->c; 1715 vpfe_dev->crop = rect;
1715unlock_out: 1716unlock_out:
1716 mutex_unlock(&vpfe_dev->lock); 1717 mutex_unlock(&vpfe_dev->lock);
1717 return ret; 1718 return ret;
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 0bafecac4923..fcabc023885d 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -311,12 +311,13 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
311 } 311 }
312 312
313 /* configure 1 or 2 channel mode */ 313 /* configure 1 or 2 channel mode */
314 ret = vpif_config_data->setup_input_channel_mode 314 if (vpif_config_data->setup_input_channel_mode) {
315 (vpif->std_info.ycmux_mode); 315 ret = vpif_config_data->
316 316 setup_input_channel_mode(vpif->std_info.ycmux_mode);
317 if (ret < 0) { 317 if (ret < 0) {
318 vpif_dbg(1, debug, "can't set vpif channel mode\n"); 318 vpif_dbg(1, debug, "can't set vpif channel mode\n");
319 return ret; 319 return ret;
320 }
320 } 321 }
321 322
322 /* Call vpif_set_params function to set the parameters and addresses */ 323 /* Call vpif_set_params function to set the parameters and addresses */
@@ -863,13 +864,11 @@ static unsigned int vpif_poll(struct file *filep, poll_table * wait)
863 */ 864 */
864static int vpif_open(struct file *filep) 865static int vpif_open(struct file *filep)
865{ 866{
866 struct vpif_capture_config *config = vpif_dev->platform_data;
867 struct video_device *vdev = video_devdata(filep); 867 struct video_device *vdev = video_devdata(filep);
868 struct common_obj *common; 868 struct common_obj *common;
869 struct video_obj *vid_ch; 869 struct video_obj *vid_ch;
870 struct channel_obj *ch; 870 struct channel_obj *ch;
871 struct vpif_fh *fh; 871 struct vpif_fh *fh;
872 int i;
873 872
874 vpif_dbg(2, debug, "vpif_open\n"); 873 vpif_dbg(2, debug, "vpif_open\n");
875 874
@@ -878,26 +877,6 @@ static int vpif_open(struct file *filep)
878 vid_ch = &ch->video; 877 vid_ch = &ch->video;
879 common = &ch->common[VPIF_VIDEO_INDEX]; 878 common = &ch->common[VPIF_VIDEO_INDEX];
880 879
881 if (NULL == ch->curr_subdev_info) {
882 /**
883 * search through the sub device to see a registered
884 * sub device and make it as current sub device
885 */
886 for (i = 0; i < config->subdev_count; i++) {
887 if (vpif_obj.sd[i]) {
888 /* the sub device is registered */
889 ch->curr_subdev_info = &config->subdev_info[i];
890 /* make first input as the current input */
891 vid_ch->input_idx = 0;
892 break;
893 }
894 }
895 if (i == config->subdev_count) {
896 vpif_err("No sub device registered\n");
897 return -ENOENT;
898 }
899 }
900
901 /* Allocate memory for the file handle object */ 880 /* Allocate memory for the file handle object */
902 fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL); 881 fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
903 if (NULL == fh) { 882 if (NULL == fh) {
@@ -997,6 +976,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
997 struct common_obj *common; 976 struct common_obj *common;
998 u8 index = 0; 977 u8 index = 0;
999 struct vb2_queue *q; 978 struct vb2_queue *q;
979 int ret;
1000 980
1001 vpif_dbg(2, debug, "vpif_reqbufs\n"); 981 vpif_dbg(2, debug, "vpif_reqbufs\n");
1002 982
@@ -1036,8 +1016,12 @@ static int vpif_reqbufs(struct file *file, void *priv,
1036 q->mem_ops = &vb2_dma_contig_memops; 1016 q->mem_ops = &vb2_dma_contig_memops;
1037 q->buf_struct_size = sizeof(struct vpif_cap_buffer); 1017 q->buf_struct_size = sizeof(struct vpif_cap_buffer);
1038 1018
1039 vb2_queue_init(q); 1019 ret = vb2_queue_init(q);
1040 1020 if (ret) {
1021 vpif_err("vpif_capture: vb2_queue_init() failed\n");
1022 vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
1023 return ret;
1024 }
1041 /* Set io allowed member of file handle to TRUE */ 1025 /* Set io allowed member of file handle to TRUE */
1042 fh->io_allowed[index] = 1; 1026 fh->io_allowed[index] = 1;
1043 /* Increment io usrs member of channel object to 1 */ 1027 /* Increment io usrs member of channel object to 1 */
@@ -1175,10 +1159,9 @@ static int vpif_streamon(struct file *file, void *priv,
1175 return ret; 1159 return ret;
1176 1160
1177 /* Enable streamon on the sub device */ 1161 /* Enable streamon on the sub device */
1178 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video, 1162 ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);
1179 s_stream, 1);
1180 1163
1181 if (ret && (ret != -ENOIOCTLCMD)) { 1164 if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
1182 vpif_dbg(1, debug, "stream on failed in subdev\n"); 1165 vpif_dbg(1, debug, "stream on failed in subdev\n");
1183 return ret; 1166 return ret;
1184 } 1167 }
@@ -1238,73 +1221,105 @@ static int vpif_streamoff(struct file *file, void *priv,
1238 1221
1239 common->started = 0; 1222 common->started = 0;
1240 1223
1241 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video, 1224 ret = v4l2_subdev_call(ch->sd, video, s_stream, 0);
1242 s_stream, 0);
1243 1225
1244 if (ret && (ret != -ENOIOCTLCMD)) 1226 if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
1245 vpif_dbg(1, debug, "stream off failed in subdev\n"); 1227 vpif_dbg(1, debug, "stream off failed in subdev\n");
1246 1228
1247 return vb2_streamoff(&common->buffer_queue, buftype); 1229 return vb2_streamoff(&common->buffer_queue, buftype);
1248} 1230}
1249 1231
1250/** 1232/**
1251 * vpif_map_sub_device_to_input() - Maps sub device to input 1233 * vpif_input_to_subdev() - Maps input to sub device
1252 * @ch - ptr to channel 1234 * @vpif_cfg - global config ptr
1253 * @config - ptr to capture configuration 1235 * @chan_cfg - channel config ptr
1254 * @input_index - Given input index from application 1236 * @input_index - Given input index from application
1255 * @sub_device_index - index into sd table
1256 * 1237 *
1257 * lookup the sub device information for a given input index. 1238 * lookup the sub device information for a given input index.
1258 * we report all the inputs to application. inputs table also 1239 * we report all the inputs to application. inputs table also
1259 * has sub device name for the each input 1240 * has sub device name for the each input
1260 */ 1241 */
1261static struct vpif_subdev_info *vpif_map_sub_device_to_input( 1242static int vpif_input_to_subdev(
1262 struct channel_obj *ch, 1243 struct vpif_capture_config *vpif_cfg,
1263 struct vpif_capture_config *vpif_cfg, 1244 struct vpif_capture_chan_config *chan_cfg,
1264 int input_index, 1245 int input_index)
1265 int *sub_device_index)
1266{ 1246{
1267 struct vpif_capture_chan_config *chan_cfg; 1247 struct vpif_subdev_info *subdev_info;
1268 struct vpif_subdev_info *subdev_info = NULL; 1248 const char *subdev_name;
1269 const char *subdev_name = NULL;
1270 int i; 1249 int i;
1271 1250
1272 vpif_dbg(2, debug, "vpif_map_sub_device_to_input\n"); 1251 vpif_dbg(2, debug, "vpif_input_to_subdev\n");
1273 1252
1274 chan_cfg = &vpif_cfg->chan_config[ch->channel_id]; 1253 subdev_name = chan_cfg->inputs[input_index].subdev_name;
1275 1254 if (subdev_name == NULL)
1276 /** 1255 return -1;
1277 * search through the inputs to find the sub device supporting
1278 * the input
1279 */
1280 for (i = 0; i < chan_cfg->input_count; i++) {
1281 /* For each sub device, loop through input */
1282 if (i == input_index) {
1283 subdev_name = chan_cfg->inputs[i].subdev_name;
1284 break;
1285 }
1286 }
1287
1288 /* if reached maximum. return null */
1289 if (i == chan_cfg->input_count || (NULL == subdev_name))
1290 return subdev_info;
1291 1256
1292 /* loop through the sub device list to get the sub device info */ 1257 /* loop through the sub device list to get the sub device info */
1293 for (i = 0; i < vpif_cfg->subdev_count; i++) { 1258 for (i = 0; i < vpif_cfg->subdev_count; i++) {
1294 subdev_info = &vpif_cfg->subdev_info[i]; 1259 subdev_info = &vpif_cfg->subdev_info[i];
1295 if (!strcmp(subdev_info->name, subdev_name)) 1260 if (!strcmp(subdev_info->name, subdev_name))
1296 break; 1261 return i;
1262 }
1263 return -1;
1264}
1265
1266/**
1267 * vpif_set_input() - Select an input
1268 * @vpif_cfg - global config ptr
1269 * @ch - channel
1270 * @_index - Given input index from application
1271 *
1272 * Select the given input.
1273 */
1274static int vpif_set_input(
1275 struct vpif_capture_config *vpif_cfg,
1276 struct channel_obj *ch,
1277 int index)
1278{
1279 struct vpif_capture_chan_config *chan_cfg =
1280 &vpif_cfg->chan_config[ch->channel_id];
1281 struct vpif_subdev_info *subdev_info = NULL;
1282 struct v4l2_subdev *sd = NULL;
1283 u32 input = 0, output = 0;
1284 int sd_index;
1285 int ret;
1286
1287 sd_index = vpif_input_to_subdev(vpif_cfg, chan_cfg, index);
1288 if (sd_index >= 0) {
1289 sd = vpif_obj.sd[sd_index];
1290 subdev_info = &vpif_cfg->subdev_info[sd_index];
1297 } 1291 }
1298 1292
1299 if (i == vpif_cfg->subdev_count) 1293 /* first setup input path from sub device to vpif */
1300 return subdev_info; 1294 if (sd && vpif_cfg->setup_input_path) {
1295 ret = vpif_cfg->setup_input_path(ch->channel_id,
1296 subdev_info->name);
1297 if (ret < 0) {
1298 vpif_dbg(1, debug, "couldn't setup input path for the" \
1299 " sub device %s, for input index %d\n",
1300 subdev_info->name, index);
1301 return ret;
1302 }
1303 }
1301 1304
1302 /* check if the sub device is registered */ 1305 if (sd) {
1303 if (NULL == vpif_obj.sd[i]) 1306 input = chan_cfg->inputs[index].input_route;
1304 return NULL; 1307 output = chan_cfg->inputs[index].output_route;
1308 ret = v4l2_subdev_call(sd, video, s_routing,
1309 input, output, 0);
1310 if (ret < 0 && ret != -ENOIOCTLCMD) {
1311 vpif_dbg(1, debug, "Failed to set input\n");
1312 return ret;
1313 }
1314 }
1315 ch->input_idx = index;
1316 ch->sd = sd;
1317 /* copy interface parameters to vpif */
1318 ch->vpifparams.iface = chan_cfg->vpif_if;
1305 1319
1306 *sub_device_index = i; 1320 /* update tvnorms from the sub device input info */
1307 return subdev_info; 1321 ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
1322 return 0;
1308} 1323}
1309 1324
1310/** 1325/**
@@ -1324,12 +1339,16 @@ static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
1324 vpif_dbg(2, debug, "vpif_querystd\n"); 1339 vpif_dbg(2, debug, "vpif_querystd\n");
1325 1340
1326 /* Call querystd function of decoder device */ 1341 /* Call querystd function of decoder device */
1327 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video, 1342 ret = v4l2_subdev_call(ch->sd, video, querystd, std_id);
1328 querystd, std_id);
1329 if (ret < 0)
1330 vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
1331 1343
1332 return ret; 1344 if (ret == -ENOIOCTLCMD || ret == -ENODEV)
1345 return -ENODATA;
1346 if (ret) {
1347 vpif_dbg(1, debug, "Failed to query standard for sub devices\n");
1348 return ret;
1349 }
1350
1351 return 0;
1333} 1352}
1334 1353
1335/** 1354/**
@@ -1397,11 +1416,12 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
1397 vpif_config_format(ch); 1416 vpif_config_format(ch);
1398 1417
1399 /* set standard in the sub device */ 1418 /* set standard in the sub device */
1400 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core, 1419 ret = v4l2_subdev_call(ch->sd, core, s_std, *std_id);
1401 s_std, *std_id); 1420 if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
1402 if (ret < 0)
1403 vpif_dbg(1, debug, "Failed to set standard for sub devices\n"); 1421 vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
1404 return ret; 1422 return ret;
1423 }
1424 return 0;
1405} 1425}
1406 1426
1407/** 1427/**
@@ -1441,10 +1461,8 @@ static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
1441{ 1461{
1442 struct vpif_fh *fh = priv; 1462 struct vpif_fh *fh = priv;
1443 struct channel_obj *ch = fh->channel; 1463 struct channel_obj *ch = fh->channel;
1444 struct video_obj *vid_ch = &ch->video;
1445
1446 *index = vid_ch->input_idx;
1447 1464
1465 *index = ch->input_idx;
1448 return 0; 1466 return 0;
1449} 1467}
1450 1468
@@ -1461,13 +1479,13 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
1461 struct vpif_fh *fh = priv; 1479 struct vpif_fh *fh = priv;
1462 struct channel_obj *ch = fh->channel; 1480 struct channel_obj *ch = fh->channel;
1463 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; 1481 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1464 struct video_obj *vid_ch = &ch->video; 1482 int ret;
1465 struct vpif_subdev_info *subdev_info;
1466 int ret = 0, sd_index = 0;
1467 u32 input = 0, output = 0;
1468 1483
1469 chan_cfg = &config->chan_config[ch->channel_id]; 1484 chan_cfg = &config->chan_config[ch->channel_id];
1470 1485
1486 if (index >= chan_cfg->input_count)
1487 return -EINVAL;
1488
1471 if (common->started) { 1489 if (common->started) {
1472 vpif_err("Streaming in progress\n"); 1490 vpif_err("Streaming in progress\n");
1473 return -EBUSY; 1491 return -EBUSY;
@@ -1486,45 +1504,7 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
1486 return ret; 1504 return ret;
1487 1505
1488 fh->initialized = 1; 1506 fh->initialized = 1;
1489 subdev_info = vpif_map_sub_device_to_input(ch, config, index, 1507 return vpif_set_input(config, ch, index);
1490 &sd_index);
1491 if (NULL == subdev_info) {
1492 vpif_dbg(1, debug,
1493 "couldn't lookup sub device for the input index\n");
1494 return -EINVAL;
1495 }
1496
1497 /* first setup input path from sub device to vpif */
1498 if (config->setup_input_path) {
1499 ret = config->setup_input_path(ch->channel_id,
1500 subdev_info->name);
1501 if (ret < 0) {
1502 vpif_dbg(1, debug, "couldn't setup input path for the"
1503 " sub device %s, for input index %d\n",
1504 subdev_info->name, index);
1505 return ret;
1506 }
1507 }
1508
1509 if (subdev_info->can_route) {
1510 input = subdev_info->input;
1511 output = subdev_info->output;
1512 ret = v4l2_subdev_call(vpif_obj.sd[sd_index], video, s_routing,
1513 input, output, 0);
1514 if (ret < 0) {
1515 vpif_dbg(1, debug, "Failed to set input\n");
1516 return ret;
1517 }
1518 }
1519 vid_ch->input_idx = index;
1520 ch->curr_subdev_info = subdev_info;
1521 ch->curr_sd_index = sd_index;
1522 /* copy interface parameters to vpif */
1523 ch->vpifparams.iface = subdev_info->vpif_if;
1524
1525 /* update tvnorms from the sub device input info */
1526 ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
1527 return ret;
1528} 1508}
1529 1509
1530/** 1510/**
@@ -1655,9 +1635,11 @@ static int vpif_querycap(struct file *file, void *priv,
1655{ 1635{
1656 struct vpif_capture_config *config = vpif_dev->platform_data; 1636 struct vpif_capture_config *config = vpif_dev->platform_data;
1657 1637
1658 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 1638 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1659 strlcpy(cap->driver, "vpif capture", sizeof(cap->driver)); 1639 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1660 strlcpy(cap->bus_info, "VPIF Platform", sizeof(cap->bus_info)); 1640 snprintf(cap->driver, sizeof(cap->driver), "%s", dev_name(vpif_dev));
1641 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1642 dev_name(vpif_dev));
1661 strlcpy(cap->card, config->card_name, sizeof(cap->card)); 1643 strlcpy(cap->card, config->card_name, sizeof(cap->card));
1662 1644
1663 return 0; 1645 return 0;
@@ -1730,9 +1712,12 @@ vpif_enum_dv_timings(struct file *file, void *priv,
1730{ 1712{
1731 struct vpif_fh *fh = priv; 1713 struct vpif_fh *fh = priv;
1732 struct channel_obj *ch = fh->channel; 1714 struct channel_obj *ch = fh->channel;
1715 int ret;
1733 1716
1734 return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], 1717 ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
1735 video, enum_dv_timings, timings); 1718 if (ret == -ENOIOCTLCMD && ret == -ENODEV)
1719 return -EINVAL;
1720 return ret;
1736} 1721}
1737 1722
1738/** 1723/**
@@ -1747,9 +1732,12 @@ vpif_query_dv_timings(struct file *file, void *priv,
1747{ 1732{
1748 struct vpif_fh *fh = priv; 1733 struct vpif_fh *fh = priv;
1749 struct channel_obj *ch = fh->channel; 1734 struct channel_obj *ch = fh->channel;
1735 int ret;
1750 1736
1751 return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], 1737 ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings);
1752 video, query_dv_timings, timings); 1738 if (ret == -ENOIOCTLCMD && ret == -ENODEV)
1739 return -ENODATA;
1740 return ret;
1753} 1741}
1754 1742
1755/** 1743/**
@@ -1775,13 +1763,9 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
1775 } 1763 }
1776 1764
1777 /* Configure subdevice timings, if any */ 1765 /* Configure subdevice timings, if any */
1778 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], 1766 ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
1779 video, s_dv_timings, timings); 1767 if (ret == -ENOIOCTLCMD || ret == -ENODEV)
1780 if (ret == -ENOIOCTLCMD) { 1768 ret = 0;
1781 vpif_dbg(2, debug, "Custom DV timings not supported by "
1782 "subdevice\n");
1783 return -EINVAL;
1784 }
1785 if (ret < 0) { 1769 if (ret < 0) {
1786 vpif_dbg(2, debug, "Error setting custom DV timings\n"); 1770 vpif_dbg(2, debug, "Error setting custom DV timings\n");
1787 return ret; 1771 return ret;
@@ -1906,8 +1890,7 @@ static int vpif_dbg_g_register(struct file *file, void *priv,
1906 struct vpif_fh *fh = priv; 1890 struct vpif_fh *fh = priv;
1907 struct channel_obj *ch = fh->channel; 1891 struct channel_obj *ch = fh->channel;
1908 1892
1909 return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core, 1893 return v4l2_subdev_call(ch->sd, core, g_register, reg);
1910 g_register, reg);
1911} 1894}
1912 1895
1913/* 1896/*
@@ -1924,8 +1907,7 @@ static int vpif_dbg_s_register(struct file *file, void *priv,
1924 struct vpif_fh *fh = priv; 1907 struct vpif_fh *fh = priv;
1925 struct channel_obj *ch = fh->channel; 1908 struct channel_obj *ch = fh->channel;
1926 1909
1927 return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core, 1910 return v4l2_subdev_call(ch->sd, core, s_register, reg);
1928 s_register, reg);
1929} 1911}
1930#endif 1912#endif
1931 1913
@@ -2063,7 +2045,8 @@ static __init int vpif_probe(struct platform_device *pdev)
2063{ 2045{
2064 struct vpif_subdev_info *subdevdata; 2046 struct vpif_subdev_info *subdevdata;
2065 struct vpif_capture_config *config; 2047 struct vpif_capture_config *config;
2066 int i, j, k, m, q, err; 2048 int i, j, k, err;
2049 int res_idx = 0;
2067 struct i2c_adapter *i2c_adap; 2050 struct i2c_adapter *i2c_adap;
2068 struct channel_obj *ch; 2051 struct channel_obj *ch;
2069 struct common_obj *common; 2052 struct common_obj *common;
@@ -2086,18 +2069,19 @@ static __init int vpif_probe(struct platform_device *pdev)
2086 return err; 2069 return err;
2087 } 2070 }
2088 2071
2089 k = 0; 2072 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
2090 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
2091 for (i = res->start; i <= res->end; i++) { 2073 for (i = res->start; i <= res->end; i++) {
2092 if (request_irq(i, vpif_channel_isr, IRQF_SHARED, 2074 if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
2093 "VPIF_Capture", 2075 "VPIF_Capture", (void *)
2094 (void *)(&vpif_obj.dev[k]->channel_id))) { 2076 (&vpif_obj.dev[res_idx]->channel_id))) {
2095 err = -EBUSY; 2077 err = -EBUSY;
2096 i--; 2078 for (j = 0; j < i; j++)
2079 free_irq(j, (void *)
2080 (&vpif_obj.dev[res_idx]->channel_id));
2097 goto vpif_int_err; 2081 goto vpif_int_err;
2098 } 2082 }
2099 } 2083 }
2100 k++; 2084 res_idx++;
2101 } 2085 }
2102 2086
2103 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { 2087 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
@@ -2111,7 +2095,7 @@ static __init int vpif_probe(struct platform_device *pdev)
2111 video_device_release(ch->video_dev); 2095 video_device_release(ch->video_dev);
2112 } 2096 }
2113 err = -ENOMEM; 2097 err = -ENOMEM;
2114 goto vpif_dev_alloc_err; 2098 goto vpif_int_err;
2115 } 2099 }
2116 2100
2117 /* Initialize field of video device */ 2101 /* Initialize field of video device */
@@ -2142,24 +2126,6 @@ static __init int vpif_probe(struct platform_device *pdev)
2142 } 2126 }
2143 } 2127 }
2144 2128
2145 for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
2146 ch = vpif_obj.dev[j];
2147 ch->channel_id = j;
2148 common = &(ch->common[VPIF_VIDEO_INDEX]);
2149 spin_lock_init(&common->irqlock);
2150 mutex_init(&common->lock);
2151 ch->video_dev->lock = &common->lock;
2152 /* Initialize prio member of channel object */
2153 v4l2_prio_init(&ch->prio);
2154 err = video_register_device(ch->video_dev,
2155 VFL_TYPE_GRABBER, (j ? 1 : 0));
2156 if (err)
2157 goto probe_out;
2158
2159 video_set_drvdata(ch->video_dev, ch);
2160
2161 }
2162
2163 i2c_adap = i2c_get_adapter(1); 2129 i2c_adap = i2c_get_adapter(1);
2164 config = pdev->dev.platform_data; 2130 config = pdev->dev.platform_data;
2165 2131
@@ -2169,7 +2135,7 @@ static __init int vpif_probe(struct platform_device *pdev)
2169 if (vpif_obj.sd == NULL) { 2135 if (vpif_obj.sd == NULL) {
2170 vpif_err("unable to allocate memory for subdevice pointers\n"); 2136 vpif_err("unable to allocate memory for subdevice pointers\n");
2171 err = -ENOMEM; 2137 err = -ENOMEM;
2172 goto probe_out; 2138 goto vpif_sd_error;
2173 } 2139 }
2174 2140
2175 for (i = 0; i < subdev_count; i++) { 2141 for (i = 0; i < subdev_count; i++) {
@@ -2186,19 +2152,32 @@ static __init int vpif_probe(struct platform_device *pdev)
2186 } 2152 }
2187 v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n", 2153 v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
2188 subdevdata->name); 2154 subdevdata->name);
2189
2190 if (vpif_obj.sd[i])
2191 vpif_obj.sd[i]->grp_id = 1 << i;
2192 } 2155 }
2193 2156
2157 for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
2158 ch = vpif_obj.dev[j];
2159 ch->channel_id = j;
2160 common = &(ch->common[VPIF_VIDEO_INDEX]);
2161 spin_lock_init(&common->irqlock);
2162 mutex_init(&common->lock);
2163 ch->video_dev->lock = &common->lock;
2164 /* Initialize prio member of channel object */
2165 v4l2_prio_init(&ch->prio);
2166 video_set_drvdata(ch->video_dev, ch);
2167
2168 /* select input 0 */
2169 err = vpif_set_input(config, ch, 0);
2170 if (err)
2171 goto probe_out;
2172
2173 err = video_register_device(ch->video_dev,
2174 VFL_TYPE_GRABBER, (j ? 1 : 0));
2175 if (err)
2176 goto probe_out;
2177 }
2194 v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n"); 2178 v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n");
2195 return 0; 2179 return 0;
2196 2180
2197probe_subdev_out:
2198 /* free sub devices memory */
2199 kfree(vpif_obj.sd);
2200
2201 j = VPIF_CAPTURE_MAX_DEVICES;
2202probe_out: 2181probe_out:
2203 for (k = 0; k < j; k++) { 2182 for (k = 0; k < j; k++) {
2204 /* Get the pointer to the channel object */ 2183 /* Get the pointer to the channel object */
@@ -2206,22 +2185,23 @@ probe_out:
2206 /* Unregister video device */ 2185 /* Unregister video device */
2207 video_unregister_device(ch->video_dev); 2186 video_unregister_device(ch->video_dev);
2208 } 2187 }
2188probe_subdev_out:
2189 /* free sub devices memory */
2190 kfree(vpif_obj.sd);
2209 2191
2210vpif_dev_alloc_err: 2192vpif_sd_error:
2211 k = VPIF_CAPTURE_MAX_DEVICES-1; 2193 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2212 res = platform_get_resource(pdev, IORESOURCE_IRQ, k); 2194 ch = vpif_obj.dev[i];
2213 i = res->end; 2195 /* Note: does nothing if ch->video_dev == NULL */
2214 2196 video_device_release(ch->video_dev);
2215vpif_int_err:
2216 for (q = k; q >= 0; q--) {
2217 for (m = i; m >= (int)res->start; m--)
2218 free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id));
2219
2220 res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1);
2221 if (res)
2222 i = res->end;
2223 } 2197 }
2198vpif_int_err:
2224 v4l2_device_unregister(&vpif_obj.v4l2_dev); 2199 v4l2_device_unregister(&vpif_obj.v4l2_dev);
2200 for (i = 0; i < res_idx; i++) {
2201 res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
2202 for (j = res->start; j <= res->end; j++)
2203 free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id));
2204 }
2225 return err; 2205 return err;
2226} 2206}
2227 2207
diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h
index d24efc17e4c8..3d3c1e5cd5d4 100644
--- a/drivers/media/platform/davinci/vpif_capture.h
+++ b/drivers/media/platform/davinci/vpif_capture.h
@@ -54,8 +54,6 @@ struct video_obj {
54 /* Currently selected or default standard */ 54 /* Currently selected or default standard */
55 v4l2_std_id stdid; 55 v4l2_std_id stdid;
56 struct v4l2_dv_timings dv_timings; 56 struct v4l2_dv_timings dv_timings;
57 /* This is to track the last input that is passed to application */
58 u32 input_idx;
59}; 57};
60 58
61struct vpif_cap_buffer { 59struct vpif_cap_buffer {
@@ -119,10 +117,10 @@ struct channel_obj {
119 u8 initialized; 117 u8 initialized;
120 /* Identifies channel */ 118 /* Identifies channel */
121 enum vpif_channel_id channel_id; 119 enum vpif_channel_id channel_id;
122 /* index into sd table */ 120 /* Current input */
123 int curr_sd_index; 121 u32 input_idx;
124 /* ptr to current sub device information */ 122 /* subdev corresponding to the current input, may be NULL */
125 struct vpif_subdev_info *curr_subdev_info; 123 struct v4l2_subdev *sd;
126 /* vpif configuration params */ 124 /* vpif configuration params */
127 struct vpif_params vpifparams; 125 struct vpif_params vpifparams;
128 /* common object array */ 126 /* common object array */
@@ -159,10 +157,6 @@ struct vpif_config_params {
159 u32 video_limit[VPIF_CAPTURE_NUM_CHANNELS]; 157 u32 video_limit[VPIF_CAPTURE_NUM_CHANNELS];
160 u8 max_device_type; 158 u8 max_device_type;
161}; 159};
162/* Struct which keeps track of the line numbers for the sliced vbi service */ 160
163struct vpif_service_line {
164 u16 service_id;
165 u16 service_line[2];
166};
167#endif /* End of __KERNEL__ */ 161#endif /* End of __KERNEL__ */
168#endif /* VPIF_CAPTURE_H */ 162#endif /* VPIF_CAPTURE_H */
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index a5b88689abad..b716fbd4241f 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -280,12 +280,13 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
280 } 280 }
281 281
282 /* clock settings */ 282 /* clock settings */
283 ret = 283 if (vpif_config_data->set_clock) {
284 vpif_config_data->set_clock(ch->vpifparams.std_info.ycmux_mode, 284 ret = vpif_config_data->set_clock(ch->vpifparams.std_info.
285 ch->vpifparams.std_info.hd_sd); 285 ycmux_mode, ch->vpifparams.std_info.hd_sd);
286 if (ret < 0) { 286 if (ret < 0) {
287 vpif_err("can't set clock\n"); 287 vpif_err("can't set clock\n");
288 return ret; 288 return ret;
289 }
289 } 290 }
290 291
291 /* set the parameters and addresses */ 292 /* set the parameters and addresses */
@@ -307,7 +308,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
307 channel2_intr_assert(); 308 channel2_intr_assert();
308 channel2_intr_enable(1); 309 channel2_intr_enable(1);
309 enable_channel2(1); 310 enable_channel2(1);
310 if (vpif_config_data->ch2_clip_en) 311 if (vpif_config_data->chan_config[VPIF_CHANNEL2_VIDEO].clip_en)
311 channel2_clipping_enable(1); 312 channel2_clipping_enable(1);
312 } 313 }
313 314
@@ -316,7 +317,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
316 channel3_intr_assert(); 317 channel3_intr_assert();
317 channel3_intr_enable(1); 318 channel3_intr_enable(1);
318 enable_channel3(1); 319 enable_channel3(1);
319 if (vpif_config_data->ch3_clip_en) 320 if (vpif_config_data->chan_config[VPIF_CHANNEL3_VIDEO].clip_en)
320 channel3_clipping_enable(1); 321 channel3_clipping_enable(1);
321 } 322 }
322 323
@@ -826,9 +827,11 @@ static int vpif_querycap(struct file *file, void *priv,
826{ 827{
827 struct vpif_display_config *config = vpif_dev->platform_data; 828 struct vpif_display_config *config = vpif_dev->platform_data;
828 829
829 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; 830 cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
830 strlcpy(cap->driver, "vpif display", sizeof(cap->driver)); 831 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
831 strlcpy(cap->bus_info, "Platform", sizeof(cap->bus_info)); 832 snprintf(cap->driver, sizeof(cap->driver), "%s", dev_name(vpif_dev));
833 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
834 dev_name(vpif_dev));
832 strlcpy(cap->card, config->card_name, sizeof(cap->card)); 835 strlcpy(cap->card, config->card_name, sizeof(cap->card));
833 836
834 return 0; 837 return 0;
@@ -935,6 +938,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
935 enum v4l2_field field; 938 enum v4l2_field field;
936 struct vb2_queue *q; 939 struct vb2_queue *q;
937 u8 index = 0; 940 u8 index = 0;
941 int ret;
938 942
939 /* This file handle has not initialized the channel, 943 /* This file handle has not initialized the channel,
940 It is not allowed to do settings */ 944 It is not allowed to do settings */
@@ -980,8 +984,12 @@ static int vpif_reqbufs(struct file *file, void *priv,
980 q->mem_ops = &vb2_dma_contig_memops; 984 q->mem_ops = &vb2_dma_contig_memops;
981 q->buf_struct_size = sizeof(struct vpif_disp_buffer); 985 q->buf_struct_size = sizeof(struct vpif_disp_buffer);
982 986
983 vb2_queue_init(q); 987 ret = vb2_queue_init(q);
984 988 if (ret) {
989 vpif_err("vpif_display: vb2_queue_init() failed\n");
990 vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
991 return ret;
992 }
985 /* Set io allowed member of file handle to TRUE */ 993 /* Set io allowed member of file handle to TRUE */
986 fh->io_allowed[index] = 1; 994 fh->io_allowed[index] = 1;
987 /* Increment io usrs member of channel object to 1 */ 995 /* Increment io usrs member of channel object to 1 */
@@ -1173,14 +1181,16 @@ static int vpif_streamoff(struct file *file, void *priv,
1173 if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 1181 if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1174 /* disable channel */ 1182 /* disable channel */
1175 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) { 1183 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
1176 if (vpif_config_data->ch2_clip_en) 1184 if (vpif_config_data->
1185 chan_config[VPIF_CHANNEL2_VIDEO].clip_en)
1177 channel2_clipping_enable(0); 1186 channel2_clipping_enable(0);
1178 enable_channel2(0); 1187 enable_channel2(0);
1179 channel2_intr_enable(0); 1188 channel2_intr_enable(0);
1180 } 1189 }
1181 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) || 1190 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
1182 (2 == common->started)) { 1191 (2 == common->started)) {
1183 if (vpif_config_data->ch3_clip_en) 1192 if (vpif_config_data->
1193 chan_config[VPIF_CHANNEL3_VIDEO].clip_en)
1184 channel3_clipping_enable(0); 1194 channel3_clipping_enable(0);
1185 enable_channel3(0); 1195 enable_channel3(0);
1186 channel3_intr_enable(0); 1196 channel3_intr_enable(0);
@@ -1213,49 +1223,126 @@ static int vpif_enum_output(struct file *file, void *fh,
1213{ 1223{
1214 1224
1215 struct vpif_display_config *config = vpif_dev->platform_data; 1225 struct vpif_display_config *config = vpif_dev->platform_data;
1226 struct vpif_display_chan_config *chan_cfg;
1227 struct vpif_fh *vpif_handler = fh;
1228 struct channel_obj *ch = vpif_handler->channel;
1216 1229
1217 if (output->index >= config->output_count) { 1230 chan_cfg = &config->chan_config[ch->channel_id];
1231 if (output->index >= chan_cfg->output_count) {
1218 vpif_dbg(1, debug, "Invalid output index\n"); 1232 vpif_dbg(1, debug, "Invalid output index\n");
1219 return -EINVAL; 1233 return -EINVAL;
1220 } 1234 }
1221 1235
1222 strcpy(output->name, config->output[output->index]); 1236 *output = chan_cfg->outputs[output->index].output;
1223 output->type = V4L2_OUTPUT_TYPE_ANALOG; 1237 return 0;
1224 output->std = VPIF_V4L2_STD; 1238}
1239
1240/**
1241 * vpif_output_to_subdev() - Maps output to sub device
1242 * @vpif_cfg - global config ptr
1243 * @chan_cfg - channel config ptr
1244 * @index - Given output index from application
1245 *
1246 * lookup the sub device information for a given output index.
1247 * we report all the output to application. output table also
1248 * has sub device name for the each output
1249 */
1250static int
1251vpif_output_to_subdev(struct vpif_display_config *vpif_cfg,
1252 struct vpif_display_chan_config *chan_cfg, int index)
1253{
1254 struct vpif_subdev_info *subdev_info;
1255 const char *subdev_name;
1256 int i;
1257
1258 vpif_dbg(2, debug, "vpif_output_to_subdev\n");
1259
1260 if (chan_cfg->outputs == NULL)
1261 return -1;
1262
1263 subdev_name = chan_cfg->outputs[index].subdev_name;
1264 if (subdev_name == NULL)
1265 return -1;
1266
1267 /* loop through the sub device list to get the sub device info */
1268 for (i = 0; i < vpif_cfg->subdev_count; i++) {
1269 subdev_info = &vpif_cfg->subdevinfo[i];
1270 if (!strcmp(subdev_info->name, subdev_name))
1271 return i;
1272 }
1273 return -1;
1274}
1275
1276/**
1277 * vpif_set_output() - Select an output
1278 * @vpif_cfg - global config ptr
1279 * @ch - channel
1280 * @index - Given output index from application
1281 *
1282 * Select the given output.
1283 */
1284static int vpif_set_output(struct vpif_display_config *vpif_cfg,
1285 struct channel_obj *ch, int index)
1286{
1287 struct vpif_display_chan_config *chan_cfg =
1288 &vpif_cfg->chan_config[ch->channel_id];
1289 struct vpif_subdev_info *subdev_info = NULL;
1290 struct v4l2_subdev *sd = NULL;
1291 u32 input = 0, output = 0;
1292 int sd_index;
1293 int ret;
1294
1295 sd_index = vpif_output_to_subdev(vpif_cfg, chan_cfg, index);
1296 if (sd_index >= 0) {
1297 sd = vpif_obj.sd[sd_index];
1298 subdev_info = &vpif_cfg->subdevinfo[sd_index];
1299 }
1300
1301 if (sd) {
1302 input = chan_cfg->outputs[index].input_route;
1303 output = chan_cfg->outputs[index].output_route;
1304 ret = v4l2_subdev_call(sd, video, s_routing, input, output, 0);
1305 if (ret < 0 && ret != -ENOIOCTLCMD) {
1306 vpif_err("Failed to set output\n");
1307 return ret;
1308 }
1225 1309
1310 }
1311 ch->output_idx = index;
1312 ch->sd = sd;
1313 if (chan_cfg->outputs != NULL)
1314 /* update tvnorms from the sub device output info */
1315 ch->video_dev->tvnorms = chan_cfg->outputs[index].output.std;
1226 return 0; 1316 return 0;
1227} 1317}
1228 1318
1229static int vpif_s_output(struct file *file, void *priv, unsigned int i) 1319static int vpif_s_output(struct file *file, void *priv, unsigned int i)
1230{ 1320{
1321 struct vpif_display_config *config = vpif_dev->platform_data;
1322 struct vpif_display_chan_config *chan_cfg;
1231 struct vpif_fh *fh = priv; 1323 struct vpif_fh *fh = priv;
1232 struct channel_obj *ch = fh->channel; 1324 struct channel_obj *ch = fh->channel;
1233 struct video_obj *vid_ch = &ch->video;
1234 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; 1325 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1235 int ret = 0; 1326
1327 chan_cfg = &config->chan_config[ch->channel_id];
1328
1329 if (i >= chan_cfg->output_count)
1330 return -EINVAL;
1236 1331
1237 if (common->started) { 1332 if (common->started) {
1238 vpif_err("Streaming in progress\n"); 1333 vpif_err("Streaming in progress\n");
1239 return -EBUSY; 1334 return -EBUSY;
1240 } 1335 }
1241 1336
1242 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video, 1337 return vpif_set_output(config, ch, i);
1243 s_routing, 0, i, 0);
1244
1245 if (ret < 0)
1246 vpif_err("Failed to set output standard\n");
1247
1248 vid_ch->output_id = i;
1249 return ret;
1250} 1338}
1251 1339
1252static int vpif_g_output(struct file *file, void *priv, unsigned int *i) 1340static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
1253{ 1341{
1254 struct vpif_fh *fh = priv; 1342 struct vpif_fh *fh = priv;
1255 struct channel_obj *ch = fh->channel; 1343 struct channel_obj *ch = fh->channel;
1256 struct video_obj *vid_ch = &ch->video;
1257 1344
1258 *i = vid_ch->output_id; 1345 *i = ch->output_idx;
1259 1346
1260 return 0; 1347 return 0;
1261} 1348}
@@ -1290,10 +1377,12 @@ vpif_enum_dv_timings(struct file *file, void *priv,
1290{ 1377{
1291 struct vpif_fh *fh = priv; 1378 struct vpif_fh *fh = priv;
1292 struct channel_obj *ch = fh->channel; 1379 struct channel_obj *ch = fh->channel;
1293 struct video_obj *vid_ch = &ch->video; 1380 int ret;
1294 1381
1295 return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], 1382 ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
1296 video, enum_dv_timings, timings); 1383 if (ret == -ENOIOCTLCMD && ret == -ENODEV)
1384 return -EINVAL;
1385 return ret;
1297} 1386}
1298 1387
1299/** 1388/**
@@ -1319,13 +1408,9 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
1319 } 1408 }
1320 1409
1321 /* Configure subdevice timings, if any */ 1410 /* Configure subdevice timings, if any */
1322 ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], 1411 ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
1323 video, s_dv_timings, timings); 1412 if (ret == -ENOIOCTLCMD || ret == -ENODEV)
1324 if (ret == -ENOIOCTLCMD) { 1413 ret = 0;
1325 vpif_dbg(2, debug, "Custom DV timings not supported by "
1326 "subdevice\n");
1327 return -EINVAL;
1328 }
1329 if (ret < 0) { 1414 if (ret < 0) {
1330 vpif_dbg(2, debug, "Error setting custom DV timings\n"); 1415 vpif_dbg(2, debug, "Error setting custom DV timings\n");
1331 return ret; 1416 return ret;
@@ -1450,10 +1535,8 @@ static int vpif_dbg_g_register(struct file *file, void *priv,
1450 struct v4l2_dbg_register *reg){ 1535 struct v4l2_dbg_register *reg){
1451 struct vpif_fh *fh = priv; 1536 struct vpif_fh *fh = priv;
1452 struct channel_obj *ch = fh->channel; 1537 struct channel_obj *ch = fh->channel;
1453 struct video_obj *vid_ch = &ch->video;
1454 1538
1455 return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core, 1539 return v4l2_subdev_call(ch->sd, core, g_register, reg);
1456 g_register, reg);
1457} 1540}
1458 1541
1459/* 1542/*
@@ -1469,10 +1552,8 @@ static int vpif_dbg_s_register(struct file *file, void *priv,
1469 struct v4l2_dbg_register *reg){ 1552 struct v4l2_dbg_register *reg){
1470 struct vpif_fh *fh = priv; 1553 struct vpif_fh *fh = priv;
1471 struct channel_obj *ch = fh->channel; 1554 struct channel_obj *ch = fh->channel;
1472 struct video_obj *vid_ch = &ch->video;
1473 1555
1474 return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core, 1556 return v4l2_subdev_call(ch->sd, core, s_register, reg);
1475 s_register, reg);
1476} 1557}
1477#endif 1558#endif
1478 1559
@@ -1536,9 +1617,6 @@ static struct video_device vpif_video_template = {
1536 .name = "vpif", 1617 .name = "vpif",
1537 .fops = &vpif_fops, 1618 .fops = &vpif_fops,
1538 .ioctl_ops = &vpif_ioctl_ops, 1619 .ioctl_ops = &vpif_ioctl_ops,
1539 .tvnorms = VPIF_V4L2_STD,
1540 .current_norm = V4L2_STD_625_50,
1541
1542}; 1620};
1543 1621
1544/*Configure the channels, buffer sizei, request irq */ 1622/*Configure the channels, buffer sizei, request irq */
@@ -1611,7 +1689,8 @@ static __init int vpif_probe(struct platform_device *pdev)
1611{ 1689{
1612 struct vpif_subdev_info *subdevdata; 1690 struct vpif_subdev_info *subdevdata;
1613 struct vpif_display_config *config; 1691 struct vpif_display_config *config;
1614 int i, j = 0, k, q, m, err = 0; 1692 int i, j = 0, k, err = 0;
1693 int res_idx = 0;
1615 struct i2c_adapter *i2c_adap; 1694 struct i2c_adapter *i2c_adap;
1616 struct common_obj *common; 1695 struct common_obj *common;
1617 struct channel_obj *ch; 1696 struct channel_obj *ch;
@@ -1634,21 +1713,22 @@ static __init int vpif_probe(struct platform_device *pdev)
1634 return err; 1713 return err;
1635 } 1714 }
1636 1715
1637 k = 0; 1716 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
1638 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
1639 for (i = res->start; i <= res->end; i++) { 1717 for (i = res->start; i <= res->end; i++) {
1640 if (request_irq(i, vpif_channel_isr, IRQF_SHARED, 1718 if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
1641 "VPIF_Display", 1719 "VPIF_Display", (void *)
1642 (void *)(&vpif_obj.dev[k]->channel_id))) { 1720 (&vpif_obj.dev[res_idx]->channel_id))) {
1643 err = -EBUSY; 1721 err = -EBUSY;
1722 for (j = 0; j < i; j++)
1723 free_irq(j, (void *)
1724 (&vpif_obj.dev[res_idx]->channel_id));
1644 goto vpif_int_err; 1725 goto vpif_int_err;
1645 } 1726 }
1646 } 1727 }
1647 k++; 1728 res_idx++;
1648 } 1729 }
1649 1730
1650 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { 1731 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1651
1652 /* Get the pointer to the channel object */ 1732 /* Get the pointer to the channel object */
1653 ch = vpif_obj.dev[i]; 1733 ch = vpif_obj.dev[i];
1654 1734
@@ -1694,6 +1774,32 @@ static __init int vpif_probe(struct platform_device *pdev)
1694 } 1774 }
1695 } 1775 }
1696 1776
1777 i2c_adap = i2c_get_adapter(1);
1778 config = pdev->dev.platform_data;
1779 subdev_count = config->subdev_count;
1780 subdevdata = config->subdevinfo;
1781 vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count,
1782 GFP_KERNEL);
1783 if (vpif_obj.sd == NULL) {
1784 vpif_err("unable to allocate memory for subdevice pointers\n");
1785 err = -ENOMEM;
1786 goto vpif_sd_error;
1787 }
1788
1789 for (i = 0; i < subdev_count; i++) {
1790 vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
1791 i2c_adap,
1792 &subdevdata[i].board_info,
1793 NULL);
1794 if (!vpif_obj.sd[i]) {
1795 vpif_err("Error registering v4l2 subdevice\n");
1796 goto probe_subdev_out;
1797 }
1798
1799 if (vpif_obj.sd[i])
1800 vpif_obj.sd[i]->grp_id = 1 << i;
1801 }
1802
1697 for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) { 1803 for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
1698 ch = vpif_obj.dev[j]; 1804 ch = vpif_obj.dev[j];
1699 /* Initialize field of the channel objects */ 1805 /* Initialize field of the channel objects */
@@ -1715,6 +1821,8 @@ static __init int vpif_probe(struct platform_device *pdev)
1715 1821
1716 } 1822 }
1717 ch->initialized = 0; 1823 ch->initialized = 0;
1824 if (subdev_count)
1825 ch->sd = vpif_obj.sd[0];
1718 ch->channel_id = j; 1826 ch->channel_id = j;
1719 if (j < 2) 1827 if (j < 2)
1720 ch->common[VPIF_VIDEO_INDEX].numbuffers = 1828 ch->common[VPIF_VIDEO_INDEX].numbuffers =
@@ -1729,6 +1837,12 @@ static __init int vpif_probe(struct platform_device *pdev)
1729 ch->common[VPIF_VIDEO_INDEX].fmt.type = 1837 ch->common[VPIF_VIDEO_INDEX].fmt.type =
1730 V4L2_BUF_TYPE_VIDEO_OUTPUT; 1838 V4L2_BUF_TYPE_VIDEO_OUTPUT;
1731 ch->video_dev->lock = &common->lock; 1839 ch->video_dev->lock = &common->lock;
1840 video_set_drvdata(ch->video_dev, ch);
1841
1842 /* select output 0 */
1843 err = vpif_set_output(config, ch, 0);
1844 if (err)
1845 goto probe_out;
1732 1846
1733 /* register video device */ 1847 /* register video device */
1734 vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n", 1848 vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
@@ -1738,42 +1852,12 @@ static __init int vpif_probe(struct platform_device *pdev)
1738 VFL_TYPE_GRABBER, (j ? 3 : 2)); 1852 VFL_TYPE_GRABBER, (j ? 3 : 2));
1739 if (err < 0) 1853 if (err < 0)
1740 goto probe_out; 1854 goto probe_out;
1741
1742 video_set_drvdata(ch->video_dev, ch);
1743 }
1744
1745 i2c_adap = i2c_get_adapter(1);
1746 config = pdev->dev.platform_data;
1747 subdev_count = config->subdev_count;
1748 subdevdata = config->subdevinfo;
1749 vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count,
1750 GFP_KERNEL);
1751 if (vpif_obj.sd == NULL) {
1752 vpif_err("unable to allocate memory for subdevice pointers\n");
1753 err = -ENOMEM;
1754 goto probe_out;
1755 }
1756
1757 for (i = 0; i < subdev_count; i++) {
1758 vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
1759 i2c_adap,
1760 &subdevdata[i].board_info,
1761 NULL);
1762 if (!vpif_obj.sd[i]) {
1763 vpif_err("Error registering v4l2 subdevice\n");
1764 goto probe_subdev_out;
1765 }
1766
1767 if (vpif_obj.sd[i])
1768 vpif_obj.sd[i]->grp_id = 1 << i;
1769 } 1855 }
1770 1856
1771 v4l2_info(&vpif_obj.v4l2_dev, 1857 v4l2_info(&vpif_obj.v4l2_dev,
1772 " VPIF display driver initialized\n"); 1858 " VPIF display driver initialized\n");
1773 return 0; 1859 return 0;
1774 1860
1775probe_subdev_out:
1776 kfree(vpif_obj.sd);
1777probe_out: 1861probe_out:
1778 for (k = 0; k < j; k++) { 1862 for (k = 0; k < j; k++) {
1779 ch = vpif_obj.dev[k]; 1863 ch = vpif_obj.dev[k];
@@ -1781,14 +1865,21 @@ probe_out:
1781 video_device_release(ch->video_dev); 1865 video_device_release(ch->video_dev);
1782 ch->video_dev = NULL; 1866 ch->video_dev = NULL;
1783 } 1867 }
1868probe_subdev_out:
1869 kfree(vpif_obj.sd);
1870vpif_sd_error:
1871 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1872 ch = vpif_obj.dev[i];
1873 /* Note: does nothing if ch->video_dev == NULL */
1874 video_device_release(ch->video_dev);
1875 }
1784vpif_int_err: 1876vpif_int_err:
1785 v4l2_device_unregister(&vpif_obj.v4l2_dev); 1877 v4l2_device_unregister(&vpif_obj.v4l2_dev);
1786 vpif_err("VPIF IRQ request failed\n"); 1878 vpif_err("VPIF IRQ request failed\n");
1787 for (q = k; k >= 0; k--) { 1879 for (i = 0; i < res_idx; i++) {
1788 for (m = i; m >= res->start; m--) 1880 res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
1789 free_irq(m, (void *)(&vpif_obj.dev[k]->channel_id)); 1881 for (j = res->start; j <= res->end; j++)
1790 res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1); 1882 free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id));
1791 m = res->end;
1792 } 1883 }
1793 1884
1794 return err; 1885 return err;
diff --git a/drivers/media/platform/davinci/vpif_display.h b/drivers/media/platform/davinci/vpif_display.h
index f628ebcf3674..a5a18f74395c 100644
--- a/drivers/media/platform/davinci/vpif_display.h
+++ b/drivers/media/platform/davinci/vpif_display.h
@@ -62,13 +62,6 @@ struct video_obj {
62 v4l2_std_id stdid; /* Currently selected or default 62 v4l2_std_id stdid; /* Currently selected or default
63 * standard */ 63 * standard */
64 struct v4l2_dv_timings dv_timings; 64 struct v4l2_dv_timings dv_timings;
65 u32 output_id; /* Current output id */
66};
67
68struct vbi_obj {
69 int num_services;
70 struct vpif_vbi_params vbiparams; /* vpif parameters for the raw
71 * vbi data */
72}; 65};
73 66
74struct vpif_disp_buffer { 67struct vpif_disp_buffer {
@@ -131,12 +124,13 @@ struct channel_obj {
131 * which is being displayed */ 124 * which is being displayed */
132 u8 initialized; /* flag to indicate whether 125 u8 initialized; /* flag to indicate whether
133 * encoder is initialized */ 126 * encoder is initialized */
127 u32 output_idx; /* Current output index */
128 struct v4l2_subdev *sd; /* Current output subdev(may be NULL) */
134 129
135 enum vpif_channel_id channel_id;/* Identifies channel */ 130 enum vpif_channel_id channel_id;/* Identifies channel */
136 struct vpif_params vpifparams; 131 struct vpif_params vpifparams;
137 struct common_obj common[VPIF_NUMOBJECTS]; 132 struct common_obj common[VPIF_NUMOBJECTS];
138 struct video_obj video; 133 struct video_obj video;
139 struct vbi_obj vbi;
140}; 134};
141 135
142/* File handle structure */ 136/* File handle structure */
@@ -168,12 +162,4 @@ struct vpif_config_params {
168 u8 min_numbuffers; 162 u8 min_numbuffers;
169}; 163};
170 164
171/* Struct which keeps track of the line numbers for the sliced vbi service */
172struct vpif_service_line {
173 u16 service_id;
174 u16 service_line[2];
175 u16 enc_service_id;
176 u8 bytestowrite;
177};
178
179#endif /* DAVINCIHD_DISPLAY_H */ 165#endif /* DAVINCIHD_DISPLAY_H */
diff --git a/drivers/media/platform/exynos-gsc/gsc-regs.c b/drivers/media/platform/exynos-gsc/gsc-regs.c
index 0d8625f03a32..0146b354dc22 100644
--- a/drivers/media/platform/exynos-gsc/gsc-regs.c
+++ b/drivers/media/platform/exynos-gsc/gsc-regs.c
@@ -212,7 +212,7 @@ void gsc_hw_set_in_image_format(struct gsc_ctx *ctx)
212 else 212 else
213 cfg |= GSC_IN_YUV422_3P; 213 cfg |= GSC_IN_YUV422_3P;
214 break; 214 break;
215 }; 215 }
216 216
217 writel(cfg, dev->regs + GSC_IN_CON); 217 writel(cfg, dev->regs + GSC_IN_CON);
218} 218}
@@ -332,7 +332,7 @@ void gsc_hw_set_out_image_format(struct gsc_ctx *ctx)
332 case 3: 332 case 3:
333 cfg |= GSC_OUT_YUV420_3P; 333 cfg |= GSC_OUT_YUV420_3P;
334 break; 334 break;
335 }; 335 }
336 336
337end_set: 337end_set:
338 writel(cfg, dev->regs + GSC_OUT_CON); 338 writel(cfg, dev->regs + GSC_OUT_CON);
diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c
index 897250b88647..31ac4dc69247 100644
--- a/drivers/media/platform/fsl-viu.c
+++ b/drivers/media/platform/fsl-viu.c
@@ -864,7 +864,7 @@ int vidioc_s_fbuf(struct file *file, void *priv, const struct v4l2_framebuffer *
864{ 864{
865 struct viu_fh *fh = priv; 865 struct viu_fh *fh = priv;
866 struct viu_dev *dev = fh->dev; 866 struct viu_dev *dev = fh->dev;
867 struct v4l2_framebuffer *fb = arg; 867 const struct v4l2_framebuffer *fb = arg;
868 struct viu_fmt *fmt; 868 struct viu_fmt *fmt;
869 869
870 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) 870 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
diff --git a/drivers/media/platform/mem2mem_testdev.c b/drivers/media/platform/mem2mem_testdev.c
index d03637537118..2e2121e98133 100644
--- a/drivers/media/platform/mem2mem_testdev.c
+++ b/drivers/media/platform/mem2mem_testdev.c
@@ -397,8 +397,7 @@ static void device_isr(unsigned long priv)
397 curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev); 397 curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev);
398 398
399 if (NULL == curr_ctx) { 399 if (NULL == curr_ctx) {
400 printk(KERN_ERR 400 pr_err("Instance released before the end of transaction\n");
401 "Instance released before the end of transaction\n");
402 return; 401 return;
403 } 402 }
404 403
@@ -894,7 +893,7 @@ static int m2mtest_open(struct file *file)
894 893
895 if (mutex_lock_interruptible(&dev->dev_mutex)) 894 if (mutex_lock_interruptible(&dev->dev_mutex))
896 return -ERESTARTSYS; 895 return -ERESTARTSYS;
897 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 896 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
898 if (!ctx) { 897 if (!ctx) {
899 rc = -ENOMEM; 898 rc = -ENOMEM;
900 goto open_unlock; 899 goto open_unlock;
@@ -1020,7 +1019,7 @@ static int m2mtest_probe(struct platform_device *pdev)
1020 struct video_device *vfd; 1019 struct video_device *vfd;
1021 int ret; 1020 int ret;
1022 1021
1023 dev = kzalloc(sizeof *dev, GFP_KERNEL); 1022 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
1024 if (!dev) 1023 if (!dev)
1025 return -ENOMEM; 1024 return -ENOMEM;
1026 1025
@@ -1028,7 +1027,7 @@ static int m2mtest_probe(struct platform_device *pdev)
1028 1027
1029 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); 1028 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
1030 if (ret) 1029 if (ret)
1031 goto free_dev; 1030 return ret;
1032 1031
1033 atomic_set(&dev->num_inst, 0); 1032 atomic_set(&dev->num_inst, 0);
1034 mutex_init(&dev->dev_mutex); 1033 mutex_init(&dev->dev_mutex);
@@ -1067,15 +1066,13 @@ static int m2mtest_probe(struct platform_device *pdev)
1067 1066
1068 return 0; 1067 return 0;
1069 1068
1070 v4l2_m2m_release(dev->m2m_dev);
1071err_m2m: 1069err_m2m:
1070 v4l2_m2m_release(dev->m2m_dev);
1072 video_unregister_device(dev->vfd); 1071 video_unregister_device(dev->vfd);
1073rel_vdev: 1072rel_vdev:
1074 video_device_release(vfd); 1073 video_device_release(vfd);
1075unreg_dev: 1074unreg_dev:
1076 v4l2_device_unregister(&dev->v4l2_dev); 1075 v4l2_device_unregister(&dev->v4l2_dev);
1077free_dev:
1078 kfree(dev);
1079 1076
1080 return ret; 1077 return ret;
1081} 1078}
@@ -1090,7 +1087,6 @@ static int m2mtest_remove(struct platform_device *pdev)
1090 del_timer_sync(&dev->timer); 1087 del_timer_sync(&dev->timer);
1091 video_unregister_device(dev->vfd); 1088 video_unregister_device(dev->vfd);
1092 v4l2_device_unregister(&dev->v4l2_dev); 1089 v4l2_device_unregister(&dev->v4l2_dev);
1093 kfree(dev);
1094 1090
1095 return 0; 1091 return 0;
1096} 1092}
diff --git a/drivers/media/platform/omap3isp/ispreg.h b/drivers/media/platform/omap3isp/ispreg.h
index 084ea77d65a7..e2c57f334c5d 100644
--- a/drivers/media/platform/omap3isp/ispreg.h
+++ b/drivers/media/platform/omap3isp/ispreg.h
@@ -27,13 +27,13 @@
27#ifndef OMAP3_ISP_REG_H 27#ifndef OMAP3_ISP_REG_H
28#define OMAP3_ISP_REG_H 28#define OMAP3_ISP_REG_H
29 29
30#include <plat/omap34xx.h>
31
32
33#define CM_CAM_MCLK_HZ 172800000 /* Hz */ 30#define CM_CAM_MCLK_HZ 172800000 /* Hz */
34 31
35/* ISP Submodules offset */ 32/* ISP Submodules offset */
36 33
34#define L4_34XX_BASE 0x48000000
35#define OMAP3430_ISP_BASE (L4_34XX_BASE + 0xBC000)
36
37#define OMAP3ISP_REG_BASE OMAP3430_ISP_BASE 37#define OMAP3ISP_REG_BASE OMAP3430_ISP_BASE
38#define OMAP3ISP_REG(offset) (OMAP3ISP_REG_BASE + (offset)) 38#define OMAP3ISP_REG(offset) (OMAP3ISP_REG_BASE + (offset))
39 39
diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c
index dded98815220..367efd164d0f 100644
--- a/drivers/media/platform/s5p-fimc/fimc-capture.c
+++ b/drivers/media/platform/s5p-fimc/fimc-capture.c
@@ -177,7 +177,9 @@ static int fimc_capture_config_update(struct fimc_ctx *ctx)
177 177
178void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf) 178void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
179{ 179{
180 struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS];
180 struct fimc_vid_cap *cap = &fimc->vid_cap; 181 struct fimc_vid_cap *cap = &fimc->vid_cap;
182 struct fimc_frame *f = &cap->ctx->d_frame;
181 struct fimc_vid_buffer *v_buf; 183 struct fimc_vid_buffer *v_buf;
182 struct timeval *tv; 184 struct timeval *tv;
183 struct timespec ts; 185 struct timespec ts;
@@ -216,6 +218,25 @@ void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
216 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS) 218 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
217 cap->buf_index = 0; 219 cap->buf_index = 0;
218 } 220 }
221 /*
222 * Set up a buffer at MIPI-CSIS if current image format
223 * requires the frame embedded data capture.
224 */
225 if (f->fmt->mdataplanes && !list_empty(&cap->active_buf_q)) {
226 unsigned int plane = ffs(f->fmt->mdataplanes) - 1;
227 unsigned int size = f->payload[plane];
228 s32 index = fimc_hw_get_frame_index(fimc);
229 void *vaddr;
230
231 list_for_each_entry(v_buf, &cap->active_buf_q, list) {
232 if (v_buf->index != index)
233 continue;
234 vaddr = vb2_plane_vaddr(&v_buf->vb, plane);
235 v4l2_subdev_call(csis, video, s_rx_buffer,
236 vaddr, &size);
237 break;
238 }
239 }
219 240
220 if (cap->active_buf_cnt == 0) { 241 if (cap->active_buf_cnt == 0) {
221 if (deq_buf) 242 if (deq_buf)
@@ -351,6 +372,8 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
351 unsigned int size = (wh * fmt->depth[i]) / 8; 372 unsigned int size = (wh * fmt->depth[i]) / 8;
352 if (pixm) 373 if (pixm)
353 sizes[i] = max(size, pixm->plane_fmt[i].sizeimage); 374 sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
375 else if (fimc_fmt_is_user_defined(fmt->color))
376 sizes[i] = frame->payload[i];
354 else 377 else
355 sizes[i] = max_t(u32, size, frame->payload[i]); 378 sizes[i] = max_t(u32, size, frame->payload[i]);
356 379
@@ -611,10 +634,10 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
611 u32 mask = FMT_FLAGS_CAM; 634 u32 mask = FMT_FLAGS_CAM;
612 struct fimc_fmt *ffmt; 635 struct fimc_fmt *ffmt;
613 636
614 /* Color conversion from/to JPEG is not supported */ 637 /* Conversion from/to JPEG or User Defined format is not supported */
615 if (code && ctx->s_frame.fmt && pad == FIMC_SD_PAD_SOURCE && 638 if (code && ctx->s_frame.fmt && pad == FIMC_SD_PAD_SOURCE &&
616 fimc_fmt_is_jpeg(ctx->s_frame.fmt->color)) 639 fimc_fmt_is_user_defined(ctx->s_frame.fmt->color))
617 *code = V4L2_MBUS_FMT_JPEG_1X8; 640 *code = ctx->s_frame.fmt->mbus_code;
618 641
619 if (fourcc && *fourcc != V4L2_PIX_FMT_JPEG && pad != FIMC_SD_PAD_SINK) 642 if (fourcc && *fourcc != V4L2_PIX_FMT_JPEG && pad != FIMC_SD_PAD_SINK)
620 mask |= FMT_FLAGS_M2M; 643 mask |= FMT_FLAGS_M2M;
@@ -628,18 +651,19 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
628 *fourcc = ffmt->fourcc; 651 *fourcc = ffmt->fourcc;
629 652
630 if (pad == FIMC_SD_PAD_SINK) { 653 if (pad == FIMC_SD_PAD_SINK) {
631 max_w = fimc_fmt_is_jpeg(ffmt->color) ? 654 max_w = fimc_fmt_is_user_defined(ffmt->color) ?
632 pl->scaler_dis_w : pl->scaler_en_w; 655 pl->scaler_dis_w : pl->scaler_en_w;
633 /* Apply the camera input interface pixel constraints */ 656 /* Apply the camera input interface pixel constraints */
634 v4l_bound_align_image(width, max_t(u32, *width, 32), max_w, 4, 657 v4l_bound_align_image(width, max_t(u32, *width, 32), max_w, 4,
635 height, max_t(u32, *height, 32), 658 height, max_t(u32, *height, 32),
636 FIMC_CAMIF_MAX_HEIGHT, 659 FIMC_CAMIF_MAX_HEIGHT,
637 fimc_fmt_is_jpeg(ffmt->color) ? 3 : 1, 660 fimc_fmt_is_user_defined(ffmt->color) ?
661 3 : 1,
638 0); 662 0);
639 return ffmt; 663 return ffmt;
640 } 664 }
641 /* Can't scale or crop in transparent (JPEG) transfer mode */ 665 /* Can't scale or crop in transparent (JPEG) transfer mode */
642 if (fimc_fmt_is_jpeg(ffmt->color)) { 666 if (fimc_fmt_is_user_defined(ffmt->color)) {
643 *width = ctx->s_frame.f_width; 667 *width = ctx->s_frame.f_width;
644 *height = ctx->s_frame.f_height; 668 *height = ctx->s_frame.f_height;
645 return ffmt; 669 return ffmt;
@@ -684,7 +708,7 @@ static void fimc_capture_try_selection(struct fimc_ctx *ctx,
684 u32 max_sc_h, max_sc_v; 708 u32 max_sc_h, max_sc_v;
685 709
686 /* In JPEG transparent transfer mode cropping is not supported */ 710 /* In JPEG transparent transfer mode cropping is not supported */
687 if (fimc_fmt_is_jpeg(ctx->d_frame.fmt->color)) { 711 if (fimc_fmt_is_user_defined(ctx->d_frame.fmt->color)) {
688 r->width = sink->f_width; 712 r->width = sink->f_width;
689 r->height = sink->f_height; 713 r->height = sink->f_height;
690 r->left = r->top = 0; 714 r->left = r->top = 0;
@@ -847,6 +871,48 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
847 return 0; 871 return 0;
848} 872}
849 873
874/**
875 * fimc_get_sensor_frame_desc - query the sensor for media bus frame parameters
876 * @sensor: pointer to the sensor subdev
877 * @plane_fmt: provides plane sizes corresponding to the frame layout entries
878 * @try: true to set the frame parameters, false to query only
879 *
880 * This function is used by this driver only for compressed/blob data formats.
881 */
882static int fimc_get_sensor_frame_desc(struct v4l2_subdev *sensor,
883 struct v4l2_plane_pix_format *plane_fmt,
884 unsigned int num_planes, bool try)
885{
886 struct v4l2_mbus_frame_desc fd;
887 int i, ret;
888
889 for (i = 0; i < num_planes; i++)
890 fd.entry[i].length = plane_fmt[i].sizeimage;
891
892 if (try)
893 ret = v4l2_subdev_call(sensor, pad, set_frame_desc, 0, &fd);
894 else
895 ret = v4l2_subdev_call(sensor, pad, get_frame_desc, 0, &fd);
896
897 if (ret < 0)
898 return ret;
899
900 if (num_planes != fd.num_entries)
901 return -EINVAL;
902
903 for (i = 0; i < num_planes; i++)
904 plane_fmt[i].sizeimage = fd.entry[i].length;
905
906 if (fd.entry[0].length > FIMC_MAX_JPEG_BUF_SIZE) {
907 v4l2_err(sensor->v4l2_dev, "Unsupported buffer size: %u\n",
908 fd.entry[0].length);
909
910 return -EINVAL;
911 }
912
913 return 0;
914}
915
850static int fimc_cap_g_fmt_mplane(struct file *file, void *fh, 916static int fimc_cap_g_fmt_mplane(struct file *file, void *fh,
851 struct v4l2_format *f) 917 struct v4l2_format *f)
852{ 918{
@@ -865,7 +931,7 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
865 struct v4l2_mbus_framefmt mf; 931 struct v4l2_mbus_framefmt mf;
866 struct fimc_fmt *ffmt = NULL; 932 struct fimc_fmt *ffmt = NULL;
867 933
868 if (pix->pixelformat == V4L2_PIX_FMT_JPEG) { 934 if (fimc_jpeg_fourcc(pix->pixelformat)) {
869 fimc_capture_try_format(ctx, &pix->width, &pix->height, 935 fimc_capture_try_format(ctx, &pix->width, &pix->height,
870 NULL, &pix->pixelformat, 936 NULL, &pix->pixelformat,
871 FIMC_SD_PAD_SINK); 937 FIMC_SD_PAD_SINK);
@@ -879,25 +945,32 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
879 return -EINVAL; 945 return -EINVAL;
880 946
881 if (!fimc->vid_cap.user_subdev_api) { 947 if (!fimc->vid_cap.user_subdev_api) {
882 mf.width = pix->width; 948 mf.width = pix->width;
883 mf.height = pix->height; 949 mf.height = pix->height;
884 mf.code = ffmt->mbus_code; 950 mf.code = ffmt->mbus_code;
885 fimc_md_graph_lock(fimc); 951 fimc_md_graph_lock(fimc);
886 fimc_pipeline_try_format(ctx, &mf, &ffmt, false); 952 fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
887 fimc_md_graph_unlock(fimc); 953 fimc_md_graph_unlock(fimc);
888 954 pix->width = mf.width;
889 pix->width = mf.width; 955 pix->height = mf.height;
890 pix->height = mf.height;
891 if (ffmt) 956 if (ffmt)
892 pix->pixelformat = ffmt->fourcc; 957 pix->pixelformat = ffmt->fourcc;
893 } 958 }
894 959
895 fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix); 960 fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix);
961
962 if (ffmt->flags & FMT_FLAGS_COMPRESSED)
963 fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
964 pix->plane_fmt, ffmt->memplanes, true);
965
896 return 0; 966 return 0;
897} 967}
898 968
899static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx, bool jpeg) 969static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx,
970 enum fimc_color_fmt color)
900{ 971{
972 bool jpeg = fimc_fmt_is_user_defined(color);
973
901 ctx->scaler.enabled = !jpeg; 974 ctx->scaler.enabled = !jpeg;
902 fimc_ctrls_activate(ctx, !jpeg); 975 fimc_ctrls_activate(ctx, !jpeg);
903 976
@@ -920,7 +993,7 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
920 return -EBUSY; 993 return -EBUSY;
921 994
922 /* Pre-configure format at camera interface input, for JPEG only */ 995 /* Pre-configure format at camera interface input, for JPEG only */
923 if (pix->pixelformat == V4L2_PIX_FMT_JPEG) { 996 if (fimc_jpeg_fourcc(pix->pixelformat)) {
924 fimc_capture_try_format(ctx, &pix->width, &pix->height, 997 fimc_capture_try_format(ctx, &pix->width, &pix->height,
925 NULL, &pix->pixelformat, 998 NULL, &pix->pixelformat,
926 FIMC_SD_PAD_SINK); 999 FIMC_SD_PAD_SINK);
@@ -953,7 +1026,16 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
953 } 1026 }
954 1027
955 fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix); 1028 fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix);
956 for (i = 0; i < ff->fmt->colplanes; i++) 1029
1030 if (ff->fmt->flags & FMT_FLAGS_COMPRESSED) {
1031 ret = fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
1032 pix->plane_fmt, ff->fmt->memplanes,
1033 true);
1034 if (ret < 0)
1035 return ret;
1036 }
1037
1038 for (i = 0; i < ff->fmt->memplanes; i++)
957 ff->payload[i] = pix->plane_fmt[i].sizeimage; 1039 ff->payload[i] = pix->plane_fmt[i].sizeimage;
958 1040
959 set_frame_bounds(ff, pix->width, pix->height); 1041 set_frame_bounds(ff, pix->width, pix->height);
@@ -961,7 +1043,7 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
961 if (!(ctx->state & FIMC_COMPOSE)) 1043 if (!(ctx->state & FIMC_COMPOSE))
962 set_frame_crop(ff, 0, 0, pix->width, pix->height); 1044 set_frame_crop(ff, 0, 0, pix->width, pix->height);
963 1045
964 fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ff->fmt->color)); 1046 fimc_capture_mark_jpeg_xfer(ctx, ff->fmt->color);
965 1047
966 /* Reset cropping and set format at the camera interface input */ 1048 /* Reset cropping and set format at the camera interface input */
967 if (!fimc->vid_cap.user_subdev_api) { 1049 if (!fimc->vid_cap.user_subdev_api) {
@@ -1063,6 +1145,23 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
1063 src_fmt.format.height != sink_fmt.format.height || 1145 src_fmt.format.height != sink_fmt.format.height ||
1064 src_fmt.format.code != sink_fmt.format.code) 1146 src_fmt.format.code != sink_fmt.format.code)
1065 return -EPIPE; 1147 return -EPIPE;
1148
1149 if (sd == fimc->pipeline.subdevs[IDX_SENSOR] &&
1150 fimc_user_defined_mbus_fmt(src_fmt.format.code)) {
1151 struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES];
1152 struct fimc_frame *frame = &vid_cap->ctx->d_frame;
1153 unsigned int i;
1154
1155 ret = fimc_get_sensor_frame_desc(sd, plane_fmt,
1156 frame->fmt->memplanes,
1157 false);
1158 if (ret < 0)
1159 return -EPIPE;
1160
1161 for (i = 0; i < frame->fmt->memplanes; i++)
1162 if (frame->payload[i] < plane_fmt[i].sizeimage)
1163 return -EPIPE;
1164 }
1066 } 1165 }
1067 return 0; 1166 return 0;
1068} 1167}
@@ -1424,7 +1523,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
1424 /* Update RGB Alpha control state and value range */ 1523 /* Update RGB Alpha control state and value range */
1425 fimc_alpha_ctrl_update(ctx); 1524 fimc_alpha_ctrl_update(ctx);
1426 1525
1427 fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ffmt->color)); 1526 fimc_capture_mark_jpeg_xfer(ctx, ffmt->color);
1428 1527
1429 ff = fmt->pad == FIMC_SD_PAD_SINK ? 1528 ff = fmt->pad == FIMC_SD_PAD_SINK ?
1430 &ctx->s_frame : &ctx->d_frame; 1529 &ctx->s_frame : &ctx->d_frame;
diff --git a/drivers/media/platform/s5p-fimc/fimc-core.c b/drivers/media/platform/s5p-fimc/fimc-core.c
index 1a445404e73d..8d0d2b94a135 100644
--- a/drivers/media/platform/s5p-fimc/fimc-core.c
+++ b/drivers/media/platform/s5p-fimc/fimc-core.c
@@ -184,7 +184,17 @@ static struct fimc_fmt fimc_formats[] = {
184 .memplanes = 1, 184 .memplanes = 1,
185 .colplanes = 1, 185 .colplanes = 1,
186 .mbus_code = V4L2_MBUS_FMT_JPEG_1X8, 186 .mbus_code = V4L2_MBUS_FMT_JPEG_1X8,
187 .flags = FMT_FLAGS_CAM, 187 .flags = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED,
188 }, {
189 .name = "S5C73MX interleaved UYVY/JPEG",
190 .fourcc = V4L2_PIX_FMT_S5C_UYVY_JPG,
191 .color = FIMC_FMT_YUYV_JPEG,
192 .depth = { 8 },
193 .memplanes = 2,
194 .colplanes = 1,
195 .mdataplanes = 0x2, /* plane 1 holds frame meta data */
196 .mbus_code = V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8,
197 .flags = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED,
188 }, 198 },
189}; 199};
190 200
@@ -371,7 +381,7 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
371 default: 381 default:
372 return -EINVAL; 382 return -EINVAL;
373 } 383 }
374 } else { 384 } else if (!frame->fmt->mdataplanes) {
375 if (frame->fmt->memplanes >= 2) 385 if (frame->fmt->memplanes >= 2)
376 paddr->cb = vb2_dma_contig_plane_dma_addr(vb, 1); 386 paddr->cb = vb2_dma_contig_plane_dma_addr(vb, 1);
377 387
@@ -698,6 +708,11 @@ int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f)
698 if (frame->fmt->colplanes == 1) /* packed formats */ 708 if (frame->fmt->colplanes == 1) /* packed formats */
699 bpl = (bpl * frame->fmt->depth[0]) / 8; 709 bpl = (bpl * frame->fmt->depth[0]) / 8;
700 pixm->plane_fmt[i].bytesperline = bpl; 710 pixm->plane_fmt[i].bytesperline = bpl;
711
712 if (frame->fmt->flags & FMT_FLAGS_COMPRESSED) {
713 pixm->plane_fmt[i].sizeimage = frame->payload[i];
714 continue;
715 }
701 pixm->plane_fmt[i].sizeimage = (frame->o_width * 716 pixm->plane_fmt[i].sizeimage = (frame->o_width *
702 frame->o_height * frame->fmt->depth[i]) / 8; 717 frame->o_height * frame->fmt->depth[i]) / 8;
703 } 718 }
diff --git a/drivers/media/platform/s5p-fimc/fimc-core.h b/drivers/media/platform/s5p-fimc/fimc-core.h
index cd716ba6015f..c0040d792499 100644
--- a/drivers/media/platform/s5p-fimc/fimc-core.h
+++ b/drivers/media/platform/s5p-fimc/fimc-core.h
@@ -40,6 +40,8 @@
40#define SCALER_MAX_VRATIO 64 40#define SCALER_MAX_VRATIO 64
41#define DMA_MIN_SIZE 8 41#define DMA_MIN_SIZE 8
42#define FIMC_CAMIF_MAX_HEIGHT 0x2000 42#define FIMC_CAMIF_MAX_HEIGHT 0x2000
43#define FIMC_MAX_JPEG_BUF_SIZE (10 * SZ_1M)
44#define FIMC_MAX_PLANES 3
43 45
44/* indices to the clocks array */ 46/* indices to the clocks array */
45enum { 47enum {
@@ -83,7 +85,7 @@ enum fimc_datapath {
83}; 85};
84 86
85enum fimc_color_fmt { 87enum fimc_color_fmt {
86 FIMC_FMT_RGB444 = 0x10, 88 FIMC_FMT_RGB444 = 0x10,
87 FIMC_FMT_RGB555, 89 FIMC_FMT_RGB555,
88 FIMC_FMT_RGB565, 90 FIMC_FMT_RGB565,
89 FIMC_FMT_RGB666, 91 FIMC_FMT_RGB666,
@@ -95,14 +97,15 @@ enum fimc_color_fmt {
95 FIMC_FMT_CBYCRY422, 97 FIMC_FMT_CBYCRY422,
96 FIMC_FMT_CRYCBY422, 98 FIMC_FMT_CRYCBY422,
97 FIMC_FMT_YCBCR444_LOCAL, 99 FIMC_FMT_YCBCR444_LOCAL,
98 FIMC_FMT_JPEG = 0x40, 100 FIMC_FMT_RAW8 = 0x40,
99 FIMC_FMT_RAW8 = 0x80,
100 FIMC_FMT_RAW10, 101 FIMC_FMT_RAW10,
101 FIMC_FMT_RAW12, 102 FIMC_FMT_RAW12,
103 FIMC_FMT_JPEG = 0x80,
104 FIMC_FMT_YUYV_JPEG = 0x100,
102}; 105};
103 106
107#define fimc_fmt_is_user_defined(x) (!!((x) & 0x180))
104#define fimc_fmt_is_rgb(x) (!!((x) & 0x10)) 108#define fimc_fmt_is_rgb(x) (!!((x) & 0x10))
105#define fimc_fmt_is_jpeg(x) (!!((x) & 0x40))
106 109
107#define IS_M2M(__strt) ((__strt) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || \ 110#define IS_M2M(__strt) ((__strt) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || \
108 __strt == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 111 __strt == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
@@ -139,6 +142,7 @@ enum fimc_color_fmt {
139 * @memplanes: number of physically non-contiguous data planes 142 * @memplanes: number of physically non-contiguous data planes
140 * @colplanes: number of physically contiguous data planes 143 * @colplanes: number of physically contiguous data planes
141 * @depth: per plane driver's private 'number of bits per pixel' 144 * @depth: per plane driver's private 'number of bits per pixel'
145 * @mdataplanes: bitmask indicating meta data plane(s), (1 << plane_no)
142 * @flags: flags indicating which operation mode format applies to 146 * @flags: flags indicating which operation mode format applies to
143 */ 147 */
144struct fimc_fmt { 148struct fimc_fmt {
@@ -149,12 +153,14 @@ struct fimc_fmt {
149 u16 memplanes; 153 u16 memplanes;
150 u16 colplanes; 154 u16 colplanes;
151 u8 depth[VIDEO_MAX_PLANES]; 155 u8 depth[VIDEO_MAX_PLANES];
156 u16 mdataplanes;
152 u16 flags; 157 u16 flags;
153#define FMT_FLAGS_CAM (1 << 0) 158#define FMT_FLAGS_CAM (1 << 0)
154#define FMT_FLAGS_M2M_IN (1 << 1) 159#define FMT_FLAGS_M2M_IN (1 << 1)
155#define FMT_FLAGS_M2M_OUT (1 << 2) 160#define FMT_FLAGS_M2M_OUT (1 << 2)
156#define FMT_FLAGS_M2M (1 << 1 | 1 << 2) 161#define FMT_FLAGS_M2M (1 << 1 | 1 << 2)
157#define FMT_HAS_ALPHA (1 << 3) 162#define FMT_HAS_ALPHA (1 << 3)
163#define FMT_FLAGS_COMPRESSED (1 << 4)
158}; 164};
159 165
160/** 166/**
@@ -272,7 +278,7 @@ struct fimc_frame {
272 u32 offs_v; 278 u32 offs_v;
273 u32 width; 279 u32 width;
274 u32 height; 280 u32 height;
275 unsigned long payload[VIDEO_MAX_PLANES]; 281 unsigned int payload[VIDEO_MAX_PLANES];
276 struct fimc_addr paddr; 282 struct fimc_addr paddr;
277 struct fimc_dma_offset dma_offset; 283 struct fimc_dma_offset dma_offset;
278 struct fimc_fmt *fmt; 284 struct fimc_fmt *fmt;
@@ -577,6 +583,18 @@ static inline int tiled_fmt(struct fimc_fmt *fmt)
577 return fmt->fourcc == V4L2_PIX_FMT_NV12MT; 583 return fmt->fourcc == V4L2_PIX_FMT_NV12MT;
578} 584}
579 585
586static inline bool fimc_jpeg_fourcc(u32 pixelformat)
587{
588 return (pixelformat == V4L2_PIX_FMT_JPEG ||
589 pixelformat == V4L2_PIX_FMT_S5C_UYVY_JPG);
590}
591
592static inline bool fimc_user_defined_mbus_fmt(u32 code)
593{
594 return (code == V4L2_MBUS_FMT_JPEG_1X8 ||
595 code == V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8);
596}
597
580/* Return the alpha component bit mask */ 598/* Return the alpha component bit mask */
581static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt) 599static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt)
582{ 600{
diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c b/drivers/media/platform/s5p-fimc/fimc-m2m.c
index 6b71d953fd15..4500e44f6857 100644
--- a/drivers/media/platform/s5p-fimc/fimc-m2m.c
+++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c
@@ -551,30 +551,31 @@ static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
551 return 0; 551 return 0;
552} 552}
553 553
554static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop *cr) 554static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
555{ 555{
556 struct fimc_ctx *ctx = fh_to_ctx(fh); 556 struct fimc_ctx *ctx = fh_to_ctx(fh);
557 struct fimc_dev *fimc = ctx->fimc_dev; 557 struct fimc_dev *fimc = ctx->fimc_dev;
558 struct v4l2_crop cr = *crop;
558 struct fimc_frame *f; 559 struct fimc_frame *f;
559 int ret; 560 int ret;
560 561
561 ret = fimc_m2m_try_crop(ctx, cr); 562 ret = fimc_m2m_try_crop(ctx, &cr);
562 if (ret) 563 if (ret)
563 return ret; 564 return ret;
564 565
565 f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? 566 f = (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
566 &ctx->s_frame : &ctx->d_frame; 567 &ctx->s_frame : &ctx->d_frame;
567 568
568 /* Check to see if scaling ratio is within supported range */ 569 /* Check to see if scaling ratio is within supported range */
569 if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) { 570 if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
570 if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 571 if (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
571 ret = fimc_check_scaler_ratio(ctx, cr->c.width, 572 ret = fimc_check_scaler_ratio(ctx, cr.c.width,
572 cr->c.height, ctx->d_frame.width, 573 cr.c.height, ctx->d_frame.width,
573 ctx->d_frame.height, ctx->rotation); 574 ctx->d_frame.height, ctx->rotation);
574 } else { 575 } else {
575 ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width, 576 ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
576 ctx->s_frame.height, cr->c.width, 577 ctx->s_frame.height, cr.c.width,
577 cr->c.height, ctx->rotation); 578 cr.c.height, ctx->rotation);
578 } 579 }
579 if (ret) { 580 if (ret) {
580 v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n"); 581 v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n");
@@ -582,10 +583,10 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop *
582 } 583 }
583 } 584 }
584 585
585 f->offs_h = cr->c.left; 586 f->offs_h = cr.c.left;
586 f->offs_v = cr->c.top; 587 f->offs_v = cr.c.top;
587 f->width = cr->c.width; 588 f->width = cr.c.width;
588 f->height = cr->c.height; 589 f->height = cr.c.height;
589 590
590 fimc_ctx_state_set(FIMC_PARAMS, ctx); 591 fimc_ctx_state_set(FIMC_PARAMS, ctx);
591 592
diff --git a/drivers/media/platform/s5p-fimc/fimc-reg.c b/drivers/media/platform/s5p-fimc/fimc-reg.c
index 783408fd7d56..2c9d0c06c9e8 100644
--- a/drivers/media/platform/s5p-fimc/fimc-reg.c
+++ b/drivers/media/platform/s5p-fimc/fimc-reg.c
@@ -625,7 +625,7 @@ int fimc_hw_set_camera_source(struct fimc_dev *fimc,
625 cfg |= FIMC_REG_CISRCFMT_ITU601_16BIT; 625 cfg |= FIMC_REG_CISRCFMT_ITU601_16BIT;
626 } /* else defaults to ITU-R BT.656 8-bit */ 626 } /* else defaults to ITU-R BT.656 8-bit */
627 } else if (cam->bus_type == FIMC_MIPI_CSI2) { 627 } else if (cam->bus_type == FIMC_MIPI_CSI2) {
628 if (fimc_fmt_is_jpeg(f->fmt->color)) 628 if (fimc_fmt_is_user_defined(f->fmt->color))
629 cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT; 629 cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
630 } 630 }
631 631
@@ -680,6 +680,7 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
680 tmp = FIMC_REG_CSIIMGFMT_YCBCR422_8BIT; 680 tmp = FIMC_REG_CSIIMGFMT_YCBCR422_8BIT;
681 break; 681 break;
682 case V4L2_MBUS_FMT_JPEG_1X8: 682 case V4L2_MBUS_FMT_JPEG_1X8:
683 case V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8:
683 tmp = FIMC_REG_CSIIMGFMT_USER(1); 684 tmp = FIMC_REG_CSIIMGFMT_USER(1);
684 cfg |= FIMC_REG_CIGCTRL_CAM_JPEG; 685 cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
685 break; 686 break;
@@ -744,13 +745,13 @@ void fimc_hw_dis_capture(struct fimc_dev *dev)
744} 745}
745 746
746/* Return an index to the buffer actually being written. */ 747/* Return an index to the buffer actually being written. */
747u32 fimc_hw_get_frame_index(struct fimc_dev *dev) 748s32 fimc_hw_get_frame_index(struct fimc_dev *dev)
748{ 749{
749 u32 reg; 750 s32 reg;
750 751
751 if (dev->variant->has_cistatus2) { 752 if (dev->variant->has_cistatus2) {
752 reg = readl(dev->regs + FIMC_REG_CISTATUS2) & 0x3F; 753 reg = readl(dev->regs + FIMC_REG_CISTATUS2) & 0x3f;
753 return reg > 0 ? --reg : reg; 754 return reg - 1;
754 } 755 }
755 756
756 reg = readl(dev->regs + FIMC_REG_CISTATUS); 757 reg = readl(dev->regs + FIMC_REG_CISTATUS);
@@ -759,6 +760,18 @@ u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
759 FIMC_REG_CISTATUS_FRAMECNT_SHIFT; 760 FIMC_REG_CISTATUS_FRAMECNT_SHIFT;
760} 761}
761 762
763/* Return an index to the buffer being written previously. */
764s32 fimc_hw_get_prev_frame_index(struct fimc_dev *dev)
765{
766 s32 reg;
767
768 if (!dev->variant->has_cistatus2)
769 return -1;
770
771 reg = readl(dev->regs + FIMC_REG_CISTATUS2);
772 return ((reg >> 7) & 0x3f) - 1;
773}
774
762/* Locking: the caller holds fimc->slock */ 775/* Locking: the caller holds fimc->slock */
763void fimc_activate_capture(struct fimc_ctx *ctx) 776void fimc_activate_capture(struct fimc_ctx *ctx)
764{ 777{
diff --git a/drivers/media/platform/s5p-fimc/fimc-reg.h b/drivers/media/platform/s5p-fimc/fimc-reg.h
index 579ac8ac03de..b6abfc7b72ac 100644
--- a/drivers/media/platform/s5p-fimc/fimc-reg.h
+++ b/drivers/media/platform/s5p-fimc/fimc-reg.h
@@ -307,7 +307,8 @@ void fimc_hw_clear_irq(struct fimc_dev *dev);
307void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on); 307void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on);
308void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on); 308void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on);
309void fimc_hw_dis_capture(struct fimc_dev *dev); 309void fimc_hw_dis_capture(struct fimc_dev *dev);
310u32 fimc_hw_get_frame_index(struct fimc_dev *dev); 310s32 fimc_hw_get_frame_index(struct fimc_dev *dev);
311s32 fimc_hw_get_prev_frame_index(struct fimc_dev *dev);
311void fimc_activate_capture(struct fimc_ctx *ctx); 312void fimc_activate_capture(struct fimc_ctx *ctx);
312void fimc_deactivate_capture(struct fimc_dev *fimc); 313void fimc_deactivate_capture(struct fimc_dev *fimc);
313 314
diff --git a/drivers/media/platform/s5p-fimc/mipi-csis.c b/drivers/media/platform/s5p-fimc/mipi-csis.c
index e92236ac5cfe..4c961b1b68e6 100644
--- a/drivers/media/platform/s5p-fimc/mipi-csis.c
+++ b/drivers/media/platform/s5p-fimc/mipi-csis.c
@@ -2,7 +2,7 @@
2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver 2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
3 * 3 *
4 * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. 4 * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki, <s.nawrocki@samsung.com> 5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -98,6 +98,11 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
98#define CSIS_MAX_PIX_WIDTH 0xffff 98#define CSIS_MAX_PIX_WIDTH 0xffff
99#define CSIS_MAX_PIX_HEIGHT 0xffff 99#define CSIS_MAX_PIX_HEIGHT 0xffff
100 100
101/* Non-image packet data buffers */
102#define S5PCSIS_PKTDATA_ODD 0x2000
103#define S5PCSIS_PKTDATA_EVEN 0x3000
104#define S5PCSIS_PKTDATA_SIZE SZ_4K
105
101enum { 106enum {
102 CSIS_CLK_MUX, 107 CSIS_CLK_MUX,
103 CSIS_CLK_GATE, 108 CSIS_CLK_GATE,
@@ -110,8 +115,8 @@ static char *csi_clock_name[] = {
110#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name) 115#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
111 116
112static const char * const csis_supply_name[] = { 117static const char * const csis_supply_name[] = {
113 "vdd11", /* 1.1V or 1.2V (s5pc100) MIPI CSI suppply */ 118 "vddcore", /* CSIS Core (1.0V, 1.1V or 1.2V) suppply */
114 "vdd18", /* VDD 1.8V and MIPI CSI PLL supply */ 119 "vddio", /* CSIS I/O and PLL (1.8V) supply */
115}; 120};
116#define CSIS_NUM_SUPPLIES ARRAY_SIZE(csis_supply_name) 121#define CSIS_NUM_SUPPLIES ARRAY_SIZE(csis_supply_name)
117 122
@@ -144,12 +149,18 @@ static const struct s5pcsis_event s5pcsis_events[] = {
144}; 149};
145#define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events) 150#define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events)
146 151
152struct csis_pktbuf {
153 u32 *data;
154 unsigned int len;
155};
156
147/** 157/**
148 * struct csis_state - the driver's internal state data structure 158 * struct csis_state - the driver's internal state data structure
149 * @lock: mutex serializing the subdev and power management operations, 159 * @lock: mutex serializing the subdev and power management operations,
150 * protecting @format and @flags members 160 * protecting @format and @flags members
151 * @pads: CSIS pads array 161 * @pads: CSIS pads array
152 * @sd: v4l2_subdev associated with CSIS device instance 162 * @sd: v4l2_subdev associated with CSIS device instance
163 * @index: the hardware instance index
153 * @pdev: CSIS platform device 164 * @pdev: CSIS platform device
154 * @regs: mmaped I/O registers memory 165 * @regs: mmaped I/O registers memory
155 * @supplies: CSIS regulator supplies 166 * @supplies: CSIS regulator supplies
@@ -159,12 +170,14 @@ static const struct s5pcsis_event s5pcsis_events[] = {
159 * @csis_fmt: current CSIS pixel format 170 * @csis_fmt: current CSIS pixel format
160 * @format: common media bus format for the source and sink pad 171 * @format: common media bus format for the source and sink pad
161 * @slock: spinlock protecting structure members below 172 * @slock: spinlock protecting structure members below
173 * @pkt_buf: the frame embedded (non-image) data buffer
162 * @events: MIPI-CSIS event (error) counters 174 * @events: MIPI-CSIS event (error) counters
163 */ 175 */
164struct csis_state { 176struct csis_state {
165 struct mutex lock; 177 struct mutex lock;
166 struct media_pad pads[CSIS_PADS_NUM]; 178 struct media_pad pads[CSIS_PADS_NUM];
167 struct v4l2_subdev sd; 179 struct v4l2_subdev sd;
180 u8 index;
168 struct platform_device *pdev; 181 struct platform_device *pdev;
169 void __iomem *regs; 182 void __iomem *regs;
170 struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES]; 183 struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
@@ -175,6 +188,7 @@ struct csis_state {
175 struct v4l2_mbus_framefmt format; 188 struct v4l2_mbus_framefmt format;
176 189
177 struct spinlock slock; 190 struct spinlock slock;
191 struct csis_pktbuf pkt_buf;
178 struct s5pcsis_event events[S5PCSIS_NUM_EVENTS]; 192 struct s5pcsis_event events[S5PCSIS_NUM_EVENTS];
179}; 193};
180 194
@@ -202,7 +216,11 @@ static const struct csis_pix_format s5pcsis_formats[] = {
202 .code = V4L2_MBUS_FMT_JPEG_1X8, 216 .code = V4L2_MBUS_FMT_JPEG_1X8,
203 .fmt_reg = S5PCSIS_CFG_FMT_USER(1), 217 .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
204 .data_alignment = 32, 218 .data_alignment = 32,
205 }, 219 }, {
220 .code = V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8,
221 .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
222 .data_alignment = 32,
223 }
206}; 224};
207 225
208#define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r) 226#define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
@@ -266,7 +284,7 @@ static void __s5pcsis_set_format(struct csis_state *state)
266 struct v4l2_mbus_framefmt *mf = &state->format; 284 struct v4l2_mbus_framefmt *mf = &state->format;
267 u32 val; 285 u32 val;
268 286
269 v4l2_dbg(1, debug, &state->sd, "fmt: %d, %d x %d\n", 287 v4l2_dbg(1, debug, &state->sd, "fmt: %#x, %d x %d\n",
270 mf->code, mf->width, mf->height); 288 mf->code, mf->width, mf->height);
271 289
272 /* Color format */ 290 /* Color format */
@@ -304,8 +322,10 @@ static void s5pcsis_set_params(struct csis_state *state)
304 val |= S5PCSIS_CTRL_ALIGN_32BIT; 322 val |= S5PCSIS_CTRL_ALIGN_32BIT;
305 else /* 24-bits */ 323 else /* 24-bits */
306 val &= ~S5PCSIS_CTRL_ALIGN_32BIT; 324 val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
307 /* Not using external clock. */ 325
308 val &= ~S5PCSIS_CTRL_WCLK_EXTCLK; 326 val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
327 if (pdata->wclk_source)
328 val |= S5PCSIS_CTRL_WCLK_EXTCLK;
309 s5pcsis_write(state, S5PCSIS_CTRL, val); 329 s5pcsis_write(state, S5PCSIS_CTRL, val);
310 330
311 /* Update the shadow register. */ 331 /* Update the shadow register. */
@@ -529,6 +549,22 @@ static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
529 return 0; 549 return 0;
530} 550}
531 551
552static int s5pcsis_s_rx_buffer(struct v4l2_subdev *sd, void *buf,
553 unsigned int *size)
554{
555 struct csis_state *state = sd_to_csis_state(sd);
556 unsigned long flags;
557
558 *size = min_t(unsigned int, *size, S5PCSIS_PKTDATA_SIZE);
559
560 spin_lock_irqsave(&state->slock, flags);
561 state->pkt_buf.data = buf;
562 state->pkt_buf.len = *size;
563 spin_unlock_irqrestore(&state->slock, flags);
564
565 return 0;
566}
567
532static int s5pcsis_log_status(struct v4l2_subdev *sd) 568static int s5pcsis_log_status(struct v4l2_subdev *sd)
533{ 569{
534 struct csis_state *state = sd_to_csis_state(sd); 570 struct csis_state *state = sd_to_csis_state(sd);
@@ -566,6 +602,7 @@ static struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
566}; 602};
567 603
568static struct v4l2_subdev_video_ops s5pcsis_video_ops = { 604static struct v4l2_subdev_video_ops s5pcsis_video_ops = {
605 .s_rx_buffer = s5pcsis_s_rx_buffer,
569 .s_stream = s5pcsis_s_stream, 606 .s_stream = s5pcsis_s_stream,
570}; 607};
571 608
@@ -578,13 +615,26 @@ static struct v4l2_subdev_ops s5pcsis_subdev_ops = {
578static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id) 615static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
579{ 616{
580 struct csis_state *state = dev_id; 617 struct csis_state *state = dev_id;
618 struct csis_pktbuf *pktbuf = &state->pkt_buf;
581 unsigned long flags; 619 unsigned long flags;
582 u32 status; 620 u32 status;
583 621
584 status = s5pcsis_read(state, S5PCSIS_INTSRC); 622 status = s5pcsis_read(state, S5PCSIS_INTSRC);
585
586 spin_lock_irqsave(&state->slock, flags); 623 spin_lock_irqsave(&state->slock, flags);
587 624
625 if ((status & S5PCSIS_INTSRC_NON_IMAGE_DATA) && pktbuf->data) {
626 u32 offset;
627
628 if (status & S5PCSIS_INTSRC_EVEN)
629 offset = S5PCSIS_PKTDATA_EVEN;
630 else
631 offset = S5PCSIS_PKTDATA_ODD;
632
633 memcpy(pktbuf->data, state->regs + offset, pktbuf->len);
634 pktbuf->data = NULL;
635 rmb();
636 }
637
588 /* Update the event/error counters */ 638 /* Update the event/error counters */
589 if ((status & S5PCSIS_INTSRC_ERRORS) || debug) { 639 if ((status & S5PCSIS_INTSRC_ERRORS) || debug) {
590 int i; 640 int i;
@@ -620,14 +670,15 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
620 spin_lock_init(&state->slock); 670 spin_lock_init(&state->slock);
621 671
622 state->pdev = pdev; 672 state->pdev = pdev;
673 state->index = max(0, pdev->id);
623 674
624 pdata = pdev->dev.platform_data; 675 pdata = pdev->dev.platform_data;
625 if (pdata == NULL || pdata->phy_enable == NULL) { 676 if (pdata == NULL) {
626 dev_err(&pdev->dev, "Platform data not fully specified\n"); 677 dev_err(&pdev->dev, "Platform data not fully specified\n");
627 return -EINVAL; 678 return -EINVAL;
628 } 679 }
629 680
630 if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) || 681 if ((state->index == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
631 pdata->lanes > CSIS0_MAX_LANES) { 682 pdata->lanes > CSIS0_MAX_LANES) {
632 dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n", 683 dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
633 pdata->lanes); 684 pdata->lanes);
@@ -710,7 +761,6 @@ e_clkput:
710 761
711static int s5pcsis_pm_suspend(struct device *dev, bool runtime) 762static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
712{ 763{
713 struct s5p_platform_mipi_csis *pdata = dev->platform_data;
714 struct platform_device *pdev = to_platform_device(dev); 764 struct platform_device *pdev = to_platform_device(dev);
715 struct v4l2_subdev *sd = platform_get_drvdata(pdev); 765 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
716 struct csis_state *state = sd_to_csis_state(sd); 766 struct csis_state *state = sd_to_csis_state(sd);
@@ -722,7 +772,7 @@ static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
722 mutex_lock(&state->lock); 772 mutex_lock(&state->lock);
723 if (state->flags & ST_POWERED) { 773 if (state->flags & ST_POWERED) {
724 s5pcsis_stop_stream(state); 774 s5pcsis_stop_stream(state);
725 ret = pdata->phy_enable(state->pdev, false); 775 ret = s5p_csis_phy_enable(state->index, false);
726 if (ret) 776 if (ret)
727 goto unlock; 777 goto unlock;
728 ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES, 778 ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
@@ -741,7 +791,6 @@ static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
741 791
742static int s5pcsis_pm_resume(struct device *dev, bool runtime) 792static int s5pcsis_pm_resume(struct device *dev, bool runtime)
743{ 793{
744 struct s5p_platform_mipi_csis *pdata = dev->platform_data;
745 struct platform_device *pdev = to_platform_device(dev); 794 struct platform_device *pdev = to_platform_device(dev);
746 struct v4l2_subdev *sd = platform_get_drvdata(pdev); 795 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
747 struct csis_state *state = sd_to_csis_state(sd); 796 struct csis_state *state = sd_to_csis_state(sd);
@@ -759,7 +808,7 @@ static int s5pcsis_pm_resume(struct device *dev, bool runtime)
759 state->supplies); 808 state->supplies);
760 if (ret) 809 if (ret)
761 goto unlock; 810 goto unlock;
762 ret = pdata->phy_enable(state->pdev, true); 811 ret = s5p_csis_phy_enable(state->index, true);
763 if (!ret) { 812 if (!ret) {
764 state->flags |= ST_POWERED; 813 state->flags |= ST_POWERED;
765 } else { 814 } else {
diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
index 1e3b9dd014c0..1bfbc325836b 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -507,7 +507,7 @@ static int vidioc_g_crop(struct file *file, void *prv, struct v4l2_crop *cr)
507 return 0; 507 return 0;
508} 508}
509 509
510static int vidioc_try_crop(struct file *file, void *prv, struct v4l2_crop *cr) 510static int vidioc_try_crop(struct file *file, void *prv, const struct v4l2_crop *cr)
511{ 511{
512 struct g2d_ctx *ctx = prv; 512 struct g2d_ctx *ctx = prv;
513 struct g2d_dev *dev = ctx->dev; 513 struct g2d_dev *dev = ctx->dev;
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 394775ae5774..17983c4c9a9a 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1353,7 +1353,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1353 return ret; 1353 return ret;
1354 } 1354 }
1355 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk); 1355 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
1356 clk_enable(jpeg->clk); 1356 clk_prepare_enable(jpeg->clk);
1357 1357
1358 /* v4l2 device */ 1358 /* v4l2 device */
1359 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev); 1359 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
@@ -1460,7 +1460,7 @@ device_register_rollback:
1460 v4l2_device_unregister(&jpeg->v4l2_dev); 1460 v4l2_device_unregister(&jpeg->v4l2_dev);
1461 1461
1462clk_get_rollback: 1462clk_get_rollback:
1463 clk_disable(jpeg->clk); 1463 clk_disable_unprepare(jpeg->clk);
1464 clk_put(jpeg->clk); 1464 clk_put(jpeg->clk);
1465 1465
1466 return ret; 1466 return ret;
@@ -1480,7 +1480,7 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
1480 v4l2_m2m_release(jpeg->m2m_dev); 1480 v4l2_m2m_release(jpeg->m2m_dev);
1481 v4l2_device_unregister(&jpeg->v4l2_dev); 1481 v4l2_device_unregister(&jpeg->v4l2_dev);
1482 1482
1483 clk_disable(jpeg->clk); 1483 clk_disable_unprepare(jpeg->clk);
1484 clk_put(jpeg->clk); 1484 clk_put(jpeg->clk);
1485 1485
1486 return 0; 1486 return 0;
diff --git a/drivers/media/platform/s5p-mfc/Makefile b/drivers/media/platform/s5p-mfc/Makefile
index d0663409af00..379008c6d09a 100644
--- a/drivers/media/platform/s5p-mfc/Makefile
+++ b/drivers/media/platform/s5p-mfc/Makefile
@@ -1,5 +1,6 @@
1obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o 1obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o
2s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o s5p_mfc_opr.o 2s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o
3s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o 3s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o
4s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_cmd.o 4s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_pm.o
5s5p-mfc-y += s5p_mfc_pm.o s5p_mfc_shm.o 5s5p-mfc-y += s5p_mfc_opr.o s5p_mfc_opr_v5.o s5p_mfc_opr_v6.o
6s5p-mfc-y += s5p_mfc_cmd.o s5p_mfc_cmd_v5.o s5p_mfc_cmd_v6.o
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h
new file mode 100644
index 000000000000..363a97cc7681
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h
@@ -0,0 +1,408 @@
1/*
2 * Register definition file for Samsung MFC V6.x Interface (FIMV) driver
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 version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _REGS_FIMV_V6_H
13#define _REGS_FIMV_V6_H
14
15#include <linux/kernel.h>
16#include <linux/sizes.h>
17
18#define S5P_FIMV_REG_SIZE_V6 (S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR)
19#define S5P_FIMV_REG_COUNT_V6 ((S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) / 4)
20
21/* Number of bits that the buffer address should be shifted for particular
22 * MFC buffers. */
23#define S5P_FIMV_MEM_OFFSET_V6 0
24
25#define S5P_FIMV_START_ADDR_V6 0x0000
26#define S5P_FIMV_END_ADDR_V6 0xfd80
27
28#define S5P_FIMV_REG_CLEAR_BEGIN_V6 0xf000
29#define S5P_FIMV_REG_CLEAR_COUNT_V6 1024
30
31/* Codec Common Registers */
32#define S5P_FIMV_RISC_ON_V6 0x0000
33#define S5P_FIMV_RISC2HOST_INT_V6 0x003C
34#define S5P_FIMV_HOST2RISC_INT_V6 0x0044
35#define S5P_FIMV_RISC_BASE_ADDRESS_V6 0x0054
36
37#define S5P_FIMV_MFC_RESET_V6 0x1070
38
39#define S5P_FIMV_HOST2RISC_CMD_V6 0x1100
40#define S5P_FIMV_H2R_CMD_EMPTY_V6 0
41#define S5P_FIMV_H2R_CMD_SYS_INIT_V6 1
42#define S5P_FIMV_H2R_CMD_OPEN_INSTANCE_V6 2
43#define S5P_FIMV_CH_SEQ_HEADER_V6 3
44#define S5P_FIMV_CH_INIT_BUFS_V6 4
45#define S5P_FIMV_CH_FRAME_START_V6 5
46#define S5P_FIMV_H2R_CMD_CLOSE_INSTANCE_V6 6
47#define S5P_FIMV_H2R_CMD_SLEEP_V6 7
48#define S5P_FIMV_H2R_CMD_WAKEUP_V6 8
49#define S5P_FIMV_CH_LAST_FRAME_V6 9
50#define S5P_FIMV_H2R_CMD_FLUSH_V6 10
51/* RMVME: REALLOC used? */
52#define S5P_FIMV_CH_FRAME_START_REALLOC_V6 5
53
54#define S5P_FIMV_RISC2HOST_CMD_V6 0x1104
55#define S5P_FIMV_R2H_CMD_EMPTY_V6 0
56#define S5P_FIMV_R2H_CMD_SYS_INIT_RET_V6 1
57#define S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET_V6 2
58#define S5P_FIMV_R2H_CMD_SEQ_DONE_RET_V6 3
59#define S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET_V6 4
60
61#define S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET_V6 6
62#define S5P_FIMV_R2H_CMD_SLEEP_RET_V6 7
63#define S5P_FIMV_R2H_CMD_WAKEUP_RET_V6 8
64#define S5P_FIMV_R2H_CMD_COMPLETE_SEQ_RET_V6 9
65#define S5P_FIMV_R2H_CMD_DPB_FLUSH_RET_V6 10
66#define S5P_FIMV_R2H_CMD_NAL_ABORT_RET_V6 11
67#define S5P_FIMV_R2H_CMD_FW_STATUS_RET_V6 12
68#define S5P_FIMV_R2H_CMD_FRAME_DONE_RET_V6 13
69#define S5P_FIMV_R2H_CMD_FIELD_DONE_RET_V6 14
70#define S5P_FIMV_R2H_CMD_SLICE_DONE_RET_V6 15
71#define S5P_FIMV_R2H_CMD_ENC_BUFFER_FUL_RET_V6 16
72#define S5P_FIMV_R2H_CMD_ERR_RET_V6 32
73
74#define S5P_FIMV_FW_VERSION_V6 0xf000
75
76#define S5P_FIMV_INSTANCE_ID_V6 0xf008
77#define S5P_FIMV_CODEC_TYPE_V6 0xf00c
78#define S5P_FIMV_CONTEXT_MEM_ADDR_V6 0xf014
79#define S5P_FIMV_CONTEXT_MEM_SIZE_V6 0xf018
80#define S5P_FIMV_PIXEL_FORMAT_V6 0xf020
81
82#define S5P_FIMV_METADATA_ENABLE_V6 0xf024
83#define S5P_FIMV_DBG_BUFFER_ADDR_V6 0xf030
84#define S5P_FIMV_DBG_BUFFER_SIZE_V6 0xf034
85#define S5P_FIMV_RET_INSTANCE_ID_V6 0xf070
86
87#define S5P_FIMV_ERROR_CODE_V6 0xf074
88#define S5P_FIMV_ERR_WARNINGS_START_V6 160
89#define S5P_FIMV_ERR_DEC_MASK_V6 0xffff
90#define S5P_FIMV_ERR_DEC_SHIFT_V6 0
91#define S5P_FIMV_ERR_DSPL_MASK_V6 0xffff0000
92#define S5P_FIMV_ERR_DSPL_SHIFT_V6 16
93
94#define S5P_FIMV_DBG_BUFFER_OUTPUT_SIZE_V6 0xf078
95#define S5P_FIMV_METADATA_STATUS_V6 0xf07C
96#define S5P_FIMV_METADATA_ADDR_MB_INFO_V6 0xf080
97#define S5P_FIMV_METADATA_SIZE_MB_INFO_V6 0xf084
98
99/* Decoder Registers */
100#define S5P_FIMV_D_CRC_CTRL_V6 0xf0b0
101#define S5P_FIMV_D_DEC_OPTIONS_V6 0xf0b4
102#define S5P_FIMV_D_OPT_FMO_ASO_CTRL_MASK_V6 4
103#define S5P_FIMV_D_OPT_DDELAY_EN_SHIFT_V6 3
104#define S5P_FIMV_D_OPT_LF_CTRL_SHIFT_V6 1
105#define S5P_FIMV_D_OPT_LF_CTRL_MASK_V6 0x3
106#define S5P_FIMV_D_OPT_TILE_MODE_SHIFT_V6 0
107
108#define S5P_FIMV_D_DISPLAY_DELAY_V6 0xf0b8
109
110#define S5P_FIMV_D_SET_FRAME_WIDTH_V6 0xf0bc
111#define S5P_FIMV_D_SET_FRAME_HEIGHT_V6 0xf0c0
112
113#define S5P_FIMV_D_SEI_ENABLE_V6 0xf0c4
114
115/* Buffer setting registers */
116#define S5P_FIMV_D_MIN_NUM_DPB_V6 0xf0f0
117#define S5P_FIMV_D_MIN_LUMA_DPB_SIZE_V6 0xf0f4
118#define S5P_FIMV_D_MIN_CHROMA_DPB_SIZE_V6 0xf0f8
119#define S5P_FIMV_D_MVC_NUM_VIEWS_V6 0xf0fc
120#define S5P_FIMV_D_MIN_NUM_MV_V6 0xf100
121#define S5P_FIMV_D_NUM_DPB_V6 0xf130
122#define S5P_FIMV_D_LUMA_DPB_SIZE_V6 0xf134
123#define S5P_FIMV_D_CHROMA_DPB_SIZE_V6 0xf138
124#define S5P_FIMV_D_MV_BUFFER_SIZE_V6 0xf13c
125
126#define S5P_FIMV_D_LUMA_DPB_V6 0xf140
127#define S5P_FIMV_D_CHROMA_DPB_V6 0xf240
128#define S5P_FIMV_D_MV_BUFFER_V6 0xf340
129
130#define S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V6 0xf440
131#define S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V6 0xf444
132#define S5P_FIMV_D_METADATA_BUFFER_ADDR_V6 0xf448
133#define S5P_FIMV_D_METADATA_BUFFER_SIZE_V6 0xf44c
134#define S5P_FIMV_D_NUM_MV_V6 0xf478
135#define S5P_FIMV_D_CPB_BUFFER_ADDR_V6 0xf4b0
136#define S5P_FIMV_D_CPB_BUFFER_SIZE_V6 0xf4b4
137
138#define S5P_FIMV_D_AVAILABLE_DPB_FLAG_UPPER_V6 0xf4b8
139#define S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V6 0xf4bc
140#define S5P_FIMV_D_CPB_BUFFER_OFFSET_V6 0xf4c0
141#define S5P_FIMV_D_SLICE_IF_ENABLE_V6 0xf4c4
142#define S5P_FIMV_D_PICTURE_TAG_V6 0xf4c8
143#define S5P_FIMV_D_STREAM_DATA_SIZE_V6 0xf4d0
144
145/* Display information register */
146#define S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V6 0xf500
147#define S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V6 0xf504
148
149/* Display status */
150#define S5P_FIMV_D_DISPLAY_STATUS_V6 0xf508
151
152#define S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6 0xf50c
153#define S5P_FIMV_D_DISPLAY_CHROMA_ADDR_V6 0xf510
154
155#define S5P_FIMV_D_DISPLAY_FRAME_TYPE_V6 0xf514
156
157#define S5P_FIMV_D_DISPLAY_CROP_INFO1_V6 0xf518
158#define S5P_FIMV_D_DISPLAY_CROP_INFO2_V6 0xf51c
159#define S5P_FIMV_D_DISPLAY_PICTURE_PROFILE_V6 0xf520
160#define S5P_FIMV_D_DISPLAY_LUMA_CRC_TOP_V6 0xf524
161#define S5P_FIMV_D_DISPLAY_CHROMA_CRC_TOP_V6 0xf528
162#define S5P_FIMV_D_DISPLAY_LUMA_CRC_BOT_V6 0xf52c
163#define S5P_FIMV_D_DISPLAY_CHROMA_CRC_BOT_V6 0xf530
164#define S5P_FIMV_D_DISPLAY_ASPECT_RATIO_V6 0xf534
165#define S5P_FIMV_D_DISPLAY_EXTENDED_AR_V6 0xf538
166
167/* Decoded picture information register */
168#define S5P_FIMV_D_DECODED_FRAME_WIDTH_V6 0xf53c
169#define S5P_FIMV_D_DECODED_FRAME_HEIGHT_V6 0xf540
170#define S5P_FIMV_D_DECODED_STATUS_V6 0xf544
171#define S5P_FIMV_DEC_CRC_GEN_MASK_V6 0x1
172#define S5P_FIMV_DEC_CRC_GEN_SHIFT_V6 6
173
174#define S5P_FIMV_D_DECODED_LUMA_ADDR_V6 0xf548
175#define S5P_FIMV_D_DECODED_CHROMA_ADDR_V6 0xf54c
176
177#define S5P_FIMV_D_DECODED_FRAME_TYPE_V6 0xf550
178#define S5P_FIMV_DECODE_FRAME_MASK_V6 7
179
180#define S5P_FIMV_D_DECODED_CROP_INFO1_V6 0xf554
181#define S5P_FIMV_D_DECODED_CROP_INFO2_V6 0xf558
182#define S5P_FIMV_D_DECODED_PICTURE_PROFILE_V6 0xf55c
183#define S5P_FIMV_D_DECODED_NAL_SIZE_V6 0xf560
184#define S5P_FIMV_D_DECODED_LUMA_CRC_TOP_V6 0xf564
185#define S5P_FIMV_D_DECODED_CHROMA_CRC_TOP_V6 0xf568
186#define S5P_FIMV_D_DECODED_LUMA_CRC_BOT_V6 0xf56c
187#define S5P_FIMV_D_DECODED_CHROMA_CRC_BOT_V6 0xf570
188
189/* Returned value register for specific setting */
190#define S5P_FIMV_D_RET_PICTURE_TAG_TOP_V6 0xf574
191#define S5P_FIMV_D_RET_PICTURE_TAG_BOT_V6 0xf578
192#define S5P_FIMV_D_RET_PICTURE_TIME_TOP_V6 0xf57c
193#define S5P_FIMV_D_RET_PICTURE_TIME_BOT_V6 0xf580
194#define S5P_FIMV_D_CHROMA_FORMAT_V6 0xf588
195#define S5P_FIMV_D_MPEG4_INFO_V6 0xf58c
196#define S5P_FIMV_D_H264_INFO_V6 0xf590
197
198#define S5P_FIMV_D_METADATA_ADDR_CONCEALED_MB_V6 0xf594
199#define S5P_FIMV_D_METADATA_SIZE_CONCEALED_MB_V6 0xf598
200#define S5P_FIMV_D_METADATA_ADDR_VC1_PARAM_V6 0xf59c
201#define S5P_FIMV_D_METADATA_SIZE_VC1_PARAM_V6 0xf5a0
202#define S5P_FIMV_D_METADATA_ADDR_SEI_NAL_V6 0xf5a4
203#define S5P_FIMV_D_METADATA_SIZE_SEI_NAL_V6 0xf5a8
204#define S5P_FIMV_D_METADATA_ADDR_VUI_V6 0xf5ac
205#define S5P_FIMV_D_METADATA_SIZE_VUI_V6 0xf5b0
206
207#define S5P_FIMV_D_MVC_VIEW_ID_V6 0xf5b4
208
209/* SEI related information */
210#define S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V6 0xf5f0
211#define S5P_FIMV_D_FRAME_PACK_ARRGMENT_ID_V6 0xf5f4
212#define S5P_FIMV_D_FRAME_PACK_SEI_INFO_V6 0xf5f8
213#define S5P_FIMV_D_FRAME_PACK_GRID_POS_V6 0xf5fc
214
215/* Encoder Registers */
216#define S5P_FIMV_E_FRAME_WIDTH_V6 0xf770
217#define S5P_FIMV_E_FRAME_HEIGHT_V6 0xf774
218#define S5P_FIMV_E_CROPPED_FRAME_WIDTH_V6 0xf778
219#define S5P_FIMV_E_CROPPED_FRAME_HEIGHT_V6 0xf77c
220#define S5P_FIMV_E_FRAME_CROP_OFFSET_V6 0xf780
221#define S5P_FIMV_E_ENC_OPTIONS_V6 0xf784
222#define S5P_FIMV_E_PICTURE_PROFILE_V6 0xf788
223#define S5P_FIMV_E_FIXED_PICTURE_QP_V6 0xf790
224
225#define S5P_FIMV_E_RC_CONFIG_V6 0xf794
226#define S5P_FIMV_E_RC_QP_BOUND_V6 0xf798
227#define S5P_FIMV_E_RC_RPARAM_V6 0xf79c
228#define S5P_FIMV_E_MB_RC_CONFIG_V6 0xf7a0
229#define S5P_FIMV_E_PADDING_CTRL_V6 0xf7a4
230#define S5P_FIMV_E_MV_HOR_RANGE_V6 0xf7ac
231#define S5P_FIMV_E_MV_VER_RANGE_V6 0xf7b0
232
233#define S5P_FIMV_E_VBV_BUFFER_SIZE_V6 0xf84c
234#define S5P_FIMV_E_VBV_INIT_DELAY_V6 0xf850
235#define S5P_FIMV_E_NUM_DPB_V6 0xf890
236#define S5P_FIMV_E_LUMA_DPB_V6 0xf8c0
237#define S5P_FIMV_E_CHROMA_DPB_V6 0xf904
238#define S5P_FIMV_E_ME_BUFFER_V6 0xf948
239
240#define S5P_FIMV_E_SCRATCH_BUFFER_ADDR_V6 0xf98c
241#define S5P_FIMV_E_SCRATCH_BUFFER_SIZE_V6 0xf990
242#define S5P_FIMV_E_TMV_BUFFER0_V6 0xf994
243#define S5P_FIMV_E_TMV_BUFFER1_V6 0xf998
244#define S5P_FIMV_E_SOURCE_LUMA_ADDR_V6 0xf9f0
245#define S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6 0xf9f4
246#define S5P_FIMV_E_STREAM_BUFFER_ADDR_V6 0xf9f8
247#define S5P_FIMV_E_STREAM_BUFFER_SIZE_V6 0xf9fc
248#define S5P_FIMV_E_ROI_BUFFER_ADDR_V6 0xfA00
249
250#define S5P_FIMV_E_PARAM_CHANGE_V6 0xfa04
251#define S5P_FIMV_E_IR_SIZE_V6 0xfa08
252#define S5P_FIMV_E_GOP_CONFIG_V6 0xfa0c
253#define S5P_FIMV_E_MSLICE_MODE_V6 0xfa10
254#define S5P_FIMV_E_MSLICE_SIZE_MB_V6 0xfa14
255#define S5P_FIMV_E_MSLICE_SIZE_BITS_V6 0xfa18
256#define S5P_FIMV_E_FRAME_INSERTION_V6 0xfa1c
257
258#define S5P_FIMV_E_RC_FRAME_RATE_V6 0xfa20
259#define S5P_FIMV_E_RC_BIT_RATE_V6 0xfa24
260#define S5P_FIMV_E_RC_QP_OFFSET_V6 0xfa28
261#define S5P_FIMV_E_RC_ROI_CTRL_V6 0xfa2c
262#define S5P_FIMV_E_PICTURE_TAG_V6 0xfa30
263#define S5P_FIMV_E_BIT_COUNT_ENABLE_V6 0xfa34
264#define S5P_FIMV_E_MAX_BIT_COUNT_V6 0xfa38
265#define S5P_FIMV_E_MIN_BIT_COUNT_V6 0xfa3c
266
267#define S5P_FIMV_E_METADATA_BUFFER_ADDR_V6 0xfa40
268#define S5P_FIMV_E_METADATA_BUFFER_SIZE_V6 0xfa44
269#define S5P_FIMV_E_STREAM_SIZE_V6 0xfa80
270#define S5P_FIMV_E_SLICE_TYPE_V6 0xfa84
271#define S5P_FIMV_E_PICTURE_COUNT_V6 0xfa88
272#define S5P_FIMV_E_RET_PICTURE_TAG_V6 0xfa8c
273#define S5P_FIMV_E_STREAM_BUFFER_WRITE_POINTER_V6 0xfa90
274
275#define S5P_FIMV_E_ENCODED_SOURCE_LUMA_ADDR_V6 0xfa94
276#define S5P_FIMV_E_ENCODED_SOURCE_CHROMA_ADDR_V6 0xfa98
277#define S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6 0xfa9c
278#define S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6 0xfaa0
279#define S5P_FIMV_E_METADATA_ADDR_ENC_SLICE_V6 0xfaa4
280#define S5P_FIMV_E_METADATA_SIZE_ENC_SLICE_V6 0xfaa8
281
282#define S5P_FIMV_E_MPEG4_OPTIONS_V6 0xfb10
283#define S5P_FIMV_E_MPEG4_HEC_PERIOD_V6 0xfb14
284#define S5P_FIMV_E_ASPECT_RATIO_V6 0xfb50
285#define S5P_FIMV_E_EXTENDED_SAR_V6 0xfb54
286
287#define S5P_FIMV_E_H264_OPTIONS_V6 0xfb58
288#define S5P_FIMV_E_H264_LF_ALPHA_OFFSET_V6 0xfb5c
289#define S5P_FIMV_E_H264_LF_BETA_OFFSET_V6 0xfb60
290#define S5P_FIMV_E_H264_I_PERIOD_V6 0xfb64
291
292#define S5P_FIMV_E_H264_FMO_SLICE_GRP_MAP_TYPE_V6 0xfb68
293#define S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1_V6 0xfb6c
294#define S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_DIR_V6 0xfb70
295#define S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1_V6 0xfb74
296#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_0_V6 0xfb78
297#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_1_V6 0xfb7c
298#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_2_V6 0xfb80
299#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_3_V6 0xfb84
300
301#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_0_V6 0xfb88
302#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_1_V6 0xfb8c
303#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_2_V6 0xfb90
304#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_3_V6 0xfb94
305#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_4_V6 0xfb98
306#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_5_V6 0xfb9c
307#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_6_V6 0xfba0
308#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_7_V6 0xfba4
309
310#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET_V6 0xfba8
311#define S5P_FIMV_E_H264_NUM_T_LAYER_V6 0xfbac
312
313#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0_V6 0xfbb0
314#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER1_V6 0xfbb4
315#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER2_V6 0xfbb8
316#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER3_V6 0xfbbc
317#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER4_V6 0xfbc0
318#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER5_V6 0xfbc4
319#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER6_V6 0xfbc8
320
321#define S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO_V6 0xfc4c
322#define S5P_FIMV_ENC_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE_V6 0
323#define S5P_FIMV_ENC_FP_ARRANGEMENT_TYPE_TOP_BOTTOM_V6 1
324#define S5P_FIMV_ENC_FP_ARRANGEMENT_TYPE_TEMPORAL_V6 2
325
326#define S5P_FIMV_E_MVC_FRAME_QP_VIEW1_V6 0xfd40
327#define S5P_FIMV_E_MVC_RC_FRAME_RATE_VIEW1_V6 0xfd44
328#define S5P_FIMV_E_MVC_RC_BIT_RATE_VIEW1_V6 0xfd48
329#define S5P_FIMV_E_MVC_RC_QBOUND_VIEW1_V6 0xfd4c
330#define S5P_FIMV_E_MVC_RC_RPARA_VIEW1_V6 0xfd50
331#define S5P_FIMV_E_MVC_INTER_VIEW_PREDICTION_ON_V6 0xfd80
332
333/* Codec numbers */
334#define S5P_FIMV_CODEC_NONE_V6 -1
335
336
337#define S5P_FIMV_CODEC_H264_DEC_V6 0
338#define S5P_FIMV_CODEC_H264_MVC_DEC_V6 1
339
340#define S5P_FIMV_CODEC_MPEG4_DEC_V6 3
341#define S5P_FIMV_CODEC_FIMV1_DEC_V6 4
342#define S5P_FIMV_CODEC_FIMV2_DEC_V6 5
343#define S5P_FIMV_CODEC_FIMV3_DEC_V6 6
344#define S5P_FIMV_CODEC_FIMV4_DEC_V6 7
345#define S5P_FIMV_CODEC_H263_DEC_V6 8
346#define S5P_FIMV_CODEC_VC1RCV_DEC_V6 9
347#define S5P_FIMV_CODEC_VC1_DEC_V6 10
348/* FIXME: Add 11~12 */
349#define S5P_FIMV_CODEC_MPEG2_DEC_V6 13
350#define S5P_FIMV_CODEC_VP8_DEC_V6 14
351/* FIXME: Add 15~16 */
352#define S5P_FIMV_CODEC_H264_ENC_V6 20
353#define S5P_FIMV_CODEC_H264_MVC_ENC_V6 21
354
355#define S5P_FIMV_CODEC_MPEG4_ENC_V6 23
356#define S5P_FIMV_CODEC_H263_ENC_V6 24
357
358#define S5P_FIMV_NV12M_HALIGN_V6 16
359#define S5P_FIMV_NV12MT_HALIGN_V6 16
360#define S5P_FIMV_NV12MT_VALIGN_V6 16
361
362#define S5P_FIMV_TMV_BUFFER_ALIGN_V6 16
363#define S5P_FIMV_LUMA_DPB_BUFFER_ALIGN_V6 256
364#define S5P_FIMV_CHROMA_DPB_BUFFER_ALIGN_V6 256
365#define S5P_FIMV_ME_BUFFER_ALIGN_V6 256
366#define S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6 256
367
368#define S5P_FIMV_LUMA_MB_TO_PIXEL_V6 256
369#define S5P_FIMV_CHROMA_MB_TO_PIXEL_V6 128
370#define S5P_FIMV_NUM_TMV_BUFFERS_V6 2
371
372#define S5P_FIMV_MAX_FRAME_SIZE_V6 (2 * SZ_1M)
373#define S5P_FIMV_NUM_PIXELS_IN_MB_ROW_V6 16
374#define S5P_FIMV_NUM_PIXELS_IN_MB_COL_V6 16
375
376/* Buffer size requirements defined by hardware */
377#define S5P_FIMV_TMV_BUFFER_SIZE_V6(w, h) (((w) + 1) * ((h) + 1) * 8)
378#define S5P_FIMV_ME_BUFFER_SIZE_V6(imw, imh, mbw, mbh) \
379 ((DIV_ROUND_UP(imw, 64) * DIV_ROUND_UP(imh, 64) * 256) + \
380 (DIV_ROUND_UP((mbw) * (mbh), 32) * 16))
381#define S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V6(w, h) (((w) * 192) + 64)
382#define S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V6(w, h) \
383 ((w) * ((h) * 64 + 144) + (2048/16 * (h) * 64) + \
384 (2048/16 * 256 + 8320))
385#define S5P_FIMV_SCRATCH_BUF_SIZE_VC1_DEC_V6(w, h) \
386 (2096 * ((w) + (h) + 1))
387#define S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6(w, h) ((w) * 400)
388#define S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V6(w, h) \
389 ((w) * 32 + (h) * 128 + (((w) + 1) / 2) * 64 + 2112)
390#define S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V6(w, h) \
391 (((w) * 64) + (((w) + 1) * 16) + (4096 * 16))
392#define S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_ENC_V6(w, h) \
393 (((w) * 16) + (((w) + 1) * 16))
394
395/* MFC Context buffer sizes */
396#define MFC_CTX_BUF_SIZE_V6 (28 * SZ_1K) /* 28KB */
397#define MFC_H264_DEC_CTX_BUF_SIZE_V6 (2 * SZ_1M) /* 2MB */
398#define MFC_OTHER_DEC_CTX_BUF_SIZE_V6 (20 * SZ_1K) /* 20KB */
399#define MFC_H264_ENC_CTX_BUF_SIZE_V6 (100 * SZ_1K) /* 100KB */
400#define MFC_OTHER_ENC_CTX_BUF_SIZE_V6 (12 * SZ_1K) /* 12KB */
401
402/* MFCv6 variant defines */
403#define MAX_FW_SIZE_V6 (SZ_1M) /* 1MB */
404#define MAX_CPB_SIZE_V6 (3 * SZ_1M) /* 3MB */
405#define MFC_VERSION_V6 0x61
406#define MFC_NUM_PORTS_V6 1
407
408#endif /* _REGS_FIMV_V6_H */
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc.h b/drivers/media/platform/s5p-mfc/regs-mfc.h
index a19bece41ba9..9319e93599ae 100644
--- a/drivers/media/platform/s5p-mfc/regs-mfc.h
+++ b/drivers/media/platform/s5p-mfc/regs-mfc.h
@@ -12,6 +12,9 @@
12#ifndef _REGS_FIMV_H 12#ifndef _REGS_FIMV_H
13#define _REGS_FIMV_H 13#define _REGS_FIMV_H
14 14
15#include <linux/kernel.h>
16#include <linux/sizes.h>
17
15#define S5P_FIMV_REG_SIZE (S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) 18#define S5P_FIMV_REG_SIZE (S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR)
16#define S5P_FIMV_REG_COUNT ((S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) / 4) 19#define S5P_FIMV_REG_COUNT ((S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) / 4)
17 20
@@ -144,6 +147,7 @@
144#define S5P_FIMV_ENC_PROFILE_H264_MAIN 0 147#define S5P_FIMV_ENC_PROFILE_H264_MAIN 0
145#define S5P_FIMV_ENC_PROFILE_H264_HIGH 1 148#define S5P_FIMV_ENC_PROFILE_H264_HIGH 1
146#define S5P_FIMV_ENC_PROFILE_H264_BASELINE 2 149#define S5P_FIMV_ENC_PROFILE_H264_BASELINE 2
150#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE 3
147#define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE 0 151#define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE 0
148#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE 1 152#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE 1
149#define S5P_FIMV_ENC_PIC_STRUCT 0x083c /* picture field/frame flag */ 153#define S5P_FIMV_ENC_PIC_STRUCT 0x083c /* picture field/frame flag */
@@ -213,6 +217,7 @@
213#define S5P_FIMV_DEC_STATUS_RESOLUTION_MASK (3<<4) 217#define S5P_FIMV_DEC_STATUS_RESOLUTION_MASK (3<<4)
214#define S5P_FIMV_DEC_STATUS_RESOLUTION_INC (1<<4) 218#define S5P_FIMV_DEC_STATUS_RESOLUTION_INC (1<<4)
215#define S5P_FIMV_DEC_STATUS_RESOLUTION_DEC (2<<4) 219#define S5P_FIMV_DEC_STATUS_RESOLUTION_DEC (2<<4)
220#define S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT 4
216 221
217/* Decode frame address */ 222/* Decode frame address */
218#define S5P_FIMV_DECODE_Y_ADR 0x2024 223#define S5P_FIMV_DECODE_Y_ADR 0x2024
@@ -377,6 +382,16 @@
377#define S5P_FIMV_R2H_CMD_EDFU_INIT_RET 16 382#define S5P_FIMV_R2H_CMD_EDFU_INIT_RET 16
378#define S5P_FIMV_R2H_CMD_ERR_RET 32 383#define S5P_FIMV_R2H_CMD_ERR_RET 32
379 384
385/* Dummy definition for MFCv6 compatibilty */
386#define S5P_FIMV_CODEC_H264_MVC_DEC -1
387#define S5P_FIMV_R2H_CMD_FIELD_DONE_RET -1
388#define S5P_FIMV_MFC_RESET -1
389#define S5P_FIMV_RISC_ON -1
390#define S5P_FIMV_RISC_BASE_ADDRESS -1
391#define S5P_FIMV_CODEC_VP8_DEC -1
392#define S5P_FIMV_REG_CLEAR_BEGIN 0
393#define S5P_FIMV_REG_CLEAR_COUNT 0
394
380/* Error handling defines */ 395/* Error handling defines */
381#define S5P_FIMV_ERR_WARNINGS_START 145 396#define S5P_FIMV_ERR_WARNINGS_START 145
382#define S5P_FIMV_ERR_DEC_MASK 0xFFFF 397#define S5P_FIMV_ERR_DEC_MASK 0xFFFF
@@ -414,5 +429,31 @@
414#define S5P_FIMV_SHARED_EXTENDED_SAR 0x0078 429#define S5P_FIMV_SHARED_EXTENDED_SAR 0x0078
415#define S5P_FIMV_SHARED_H264_I_PERIOD 0x009C 430#define S5P_FIMV_SHARED_H264_I_PERIOD 0x009C
416#define S5P_FIMV_SHARED_RC_CONTROL_CONFIG 0x00A0 431#define S5P_FIMV_SHARED_RC_CONTROL_CONFIG 0x00A0
432#define S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT 2
433
434/* Offset used by the hardware to store addresses */
435#define MFC_OFFSET_SHIFT 11
436
437#define FIRMWARE_ALIGN (128 * SZ_1K) /* 128KB */
438#define MFC_H264_CTX_BUF_SIZE (600 * SZ_1K) /* 600KB per H264 instance */
439#define MFC_CTX_BUF_SIZE (10 * SZ_1K) /* 10KB per instance */
440#define DESC_BUF_SIZE (128 * SZ_1K) /* 128KB for DESC buffer */
441#define SHARED_BUF_SIZE (8 * SZ_1K) /* 8KB for shared buffer */
442
443#define DEF_CPB_SIZE (256 * SZ_1K) /* 256KB */
444#define MAX_CPB_SIZE (4 * SZ_1M) /* 4MB */
445#define MAX_FW_SIZE (384 * SZ_1K)
446
447#define MFC_VERSION 0x51
448#define MFC_NUM_PORTS 2
449
450#define S5P_FIMV_SHARED_FRAME_PACK_SEI_AVAIL 0x16C
451#define S5P_FIMV_SHARED_FRAME_PACK_ARRGMENT_ID 0x170
452#define S5P_FIMV_SHARED_FRAME_PACK_SEI_INFO 0x174
453#define S5P_FIMV_SHARED_FRAME_PACK_GRID_POS 0x178
454
455/* Values for resolution change in display status */
456#define S5P_FIMV_RES_INCREASE 1
457#define S5P_FIMV_RES_DECREASE 2
417 458
418#endif /* _REGS_FIMV_H */ 459#endif /* _REGS_FIMV_H */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 5587ef15ca4f..130f4ac8649e 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -22,15 +22,15 @@
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.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#include "s5p_mfc_shm.h"
34 34
35#define S5P_MFC_NAME "s5p-mfc" 35#define S5P_MFC_NAME "s5p-mfc"
36#define S5P_MFC_DEC_NAME "s5p-mfc-dec" 36#define S5P_MFC_DEC_NAME "s5p-mfc-dec"
@@ -149,10 +149,12 @@ static void s5p_mfc_watchdog_worker(struct work_struct *work)
149 if (!ctx) 149 if (!ctx)
150 continue; 150 continue;
151 ctx->state = MFCINST_ERROR; 151 ctx->state = MFCINST_ERROR;
152 s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst); 152 s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
153 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);
154 clear_work_bit(ctx); 156 clear_work_bit(ctx);
155 wake_up_ctx(ctx, S5P_FIMV_R2H_CMD_ERR_RET, 0); 157 wake_up_ctx(ctx, S5P_MFC_R2H_CMD_ERR_RET, 0);
156 } 158 }
157 clear_bit(0, &dev->hw_lock); 159 clear_bit(0, &dev->hw_lock);
158 spin_unlock_irqrestore(&dev->irqlock, flags); 160 spin_unlock_irqrestore(&dev->irqlock, flags);
@@ -199,6 +201,7 @@ static void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev)
199static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx) 201static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
200{ 202{
201 struct s5p_mfc_buf *dst_buf; 203 struct s5p_mfc_buf *dst_buf;
204 struct s5p_mfc_dev *dev = ctx->dev;
202 205
203 ctx->state = MFCINST_FINISHED; 206 ctx->state = MFCINST_FINISHED;
204 ctx->sequence++; 207 ctx->sequence++;
@@ -213,8 +216,8 @@ static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
213 ctx->dst_queue_cnt--; 216 ctx->dst_queue_cnt--;
214 dst_buf->b->v4l2_buf.sequence = (ctx->sequence++); 217 dst_buf->b->v4l2_buf.sequence = (ctx->sequence++);
215 218
216 if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) == 219 if (s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_top, ctx) ==
217 s5p_mfc_read_shm(ctx, PIC_TIME_BOT)) 220 s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_bot, ctx))
218 dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE; 221 dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
219 else 222 else
220 dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED; 223 dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED;
@@ -228,8 +231,11 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx)
228{ 231{
229 struct s5p_mfc_dev *dev = ctx->dev; 232 struct s5p_mfc_dev *dev = ctx->dev;
230 struct s5p_mfc_buf *dst_buf, *src_buf; 233 struct s5p_mfc_buf *dst_buf, *src_buf;
231 size_t dec_y_addr = s5p_mfc_get_dec_y_adr(); 234 size_t dec_y_addr;
232 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);
233 239
234 /* Copy timestamp / timecode from decoded src to dst and set 240 /* Copy timestamp / timecode from decoded src to dst and set
235 appropraite flags */ 241 appropraite flags */
@@ -265,10 +271,13 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
265{ 271{
266 struct s5p_mfc_dev *dev = ctx->dev; 272 struct s5p_mfc_dev *dev = ctx->dev;
267 struct s5p_mfc_buf *dst_buf; 273 struct s5p_mfc_buf *dst_buf;
268 size_t dspl_y_addr = s5p_mfc_get_dspl_y_adr(); 274 size_t dspl_y_addr;
269 unsigned int frame_type = s5p_mfc_get_frame_type(); 275 unsigned int frame_type;
270 unsigned int index; 276 unsigned int index;
271 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
272 /* 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 */
273 if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) { 282 if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) {
274 if (!ctx->after_packed_pb) 283 if (!ctx->after_packed_pb)
@@ -285,8 +294,10 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
285 list_del(&dst_buf->list); 294 list_del(&dst_buf->list);
286 ctx->dst_queue_cnt--; 295 ctx->dst_queue_cnt--;
287 dst_buf->b->v4l2_buf.sequence = ctx->sequence; 296 dst_buf->b->v4l2_buf.sequence = ctx->sequence;
288 if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) == 297 if (s5p_mfc_hw_call(dev->mfc_ops,
289 s5p_mfc_read_shm(ctx, PIC_TIME_BOT)) 298 get_pic_type_top, ctx) ==
299 s5p_mfc_hw_call(dev->mfc_ops,
300 get_pic_type_bot, ctx))
290 dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE; 301 dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
291 else 302 else
292 dst_buf->b->v4l2_buf.field = 303 dst_buf->b->v4l2_buf.field =
@@ -317,21 +328,23 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
317 328
318 unsigned int index; 329 unsigned int index;
319 330
320 dst_frame_status = s5p_mfc_get_dspl_status() 331 dst_frame_status = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
321 & S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK; 332 & S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK;
322 res_change = s5p_mfc_get_dspl_status() 333 res_change = (s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
323 & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK; 334 & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK)
335 >> S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT;
324 mfc_debug(2, "Frame Status: %x\n", dst_frame_status); 336 mfc_debug(2, "Frame Status: %x\n", dst_frame_status);
325 if (ctx->state == MFCINST_RES_CHANGE_INIT) 337 if (ctx->state == MFCINST_RES_CHANGE_INIT)
326 ctx->state = MFCINST_RES_CHANGE_FLUSH; 338 ctx->state = MFCINST_RES_CHANGE_FLUSH;
327 if (res_change) { 339 if (res_change == S5P_FIMV_RES_INCREASE ||
340 res_change == S5P_FIMV_RES_DECREASE) {
328 ctx->state = MFCINST_RES_CHANGE_INIT; 341 ctx->state = MFCINST_RES_CHANGE_INIT;
329 s5p_mfc_clear_int_flags(dev); 342 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
330 wake_up_ctx(ctx, reason, err); 343 wake_up_ctx(ctx, reason, err);
331 if (test_and_clear_bit(0, &dev->hw_lock) == 0) 344 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
332 BUG(); 345 BUG();
333 s5p_mfc_clock_off(); 346 s5p_mfc_clock_off();
334 s5p_mfc_try_run(dev); 347 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
335 return; 348 return;
336 } 349 }
337 if (ctx->dpb_flush_flag) 350 if (ctx->dpb_flush_flag)
@@ -365,9 +378,12 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
365 && !list_empty(&ctx->src_queue)) { 378 && !list_empty(&ctx->src_queue)) {
366 src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, 379 src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
367 list); 380 list);
368 ctx->consumed_stream += s5p_mfc_get_consumed_stream(); 381 ctx->consumed_stream += s5p_mfc_hw_call(dev->mfc_ops,
369 if (ctx->codec_mode != S5P_FIMV_CODEC_H264_DEC && 382 get_consumed_stream, dev);
370 s5p_mfc_get_frame_type() == S5P_FIMV_DECODE_FRAME_P_FRAME 383 if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC &&
384 s5p_mfc_hw_call(dev->mfc_ops,
385 get_dec_frame_type, dev) ==
386 S5P_FIMV_DECODE_FRAME_P_FRAME
371 && ctx->consumed_stream + STUFF_BYTE < 387 && ctx->consumed_stream + STUFF_BYTE <
372 src_buf->b->v4l2_planes[0].bytesused) { 388 src_buf->b->v4l2_planes[0].bytesused) {
373 /* Run MFC again on the same buffer */ 389 /* Run MFC again on the same buffer */
@@ -379,7 +395,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
379 ctx->consumed_stream = 0; 395 ctx->consumed_stream = 0;
380 list_del(&src_buf->list); 396 list_del(&src_buf->list);
381 ctx->src_queue_cnt--; 397 ctx->src_queue_cnt--;
382 if (s5p_mfc_err_dec(err) > 0) 398 if (s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) > 0)
383 vb2_buffer_done(src_buf->b, VB2_BUF_STATE_ERROR); 399 vb2_buffer_done(src_buf->b, VB2_BUF_STATE_ERROR);
384 else 400 else
385 vb2_buffer_done(src_buf->b, VB2_BUF_STATE_DONE); 401 vb2_buffer_done(src_buf->b, VB2_BUF_STATE_DONE);
@@ -390,12 +406,12 @@ leave_handle_frame:
390 if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING) 406 if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING)
391 || ctx->dst_queue_cnt < ctx->dpb_count) 407 || ctx->dst_queue_cnt < ctx->dpb_count)
392 clear_work_bit(ctx); 408 clear_work_bit(ctx);
393 s5p_mfc_clear_int_flags(dev); 409 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
394 wake_up_ctx(ctx, reason, err); 410 wake_up_ctx(ctx, reason, err);
395 if (test_and_clear_bit(0, &dev->hw_lock) == 0) 411 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
396 BUG(); 412 BUG();
397 s5p_mfc_clock_off(); 413 s5p_mfc_clock_off();
398 s5p_mfc_try_run(dev); 414 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
399} 415}
400 416
401/* Error handling for interrupt */ 417/* Error handling for interrupt */
@@ -412,7 +428,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
412 428
413 dev = ctx->dev; 429 dev = ctx->dev;
414 mfc_err("Interrupt Error: %08x\n", err); 430 mfc_err("Interrupt Error: %08x\n", err);
415 s5p_mfc_clear_int_flags(dev); 431 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
416 wake_up_dev(dev, reason, err); 432 wake_up_dev(dev, reason, err);
417 433
418 /* Error recovery is dependent on the state of context */ 434 /* Error recovery is dependent on the state of context */
@@ -441,9 +457,11 @@ static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
441 ctx->state = MFCINST_ERROR; 457 ctx->state = MFCINST_ERROR;
442 /* Mark all dst buffers as having an error */ 458 /* Mark all dst buffers as having an error */
443 spin_lock_irqsave(&dev->irqlock, flags); 459 spin_lock_irqsave(&dev->irqlock, flags);
444 s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst); 460 s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
461 &ctx->vq_dst);
445 /* Mark all src buffers as having an error */ 462 /* Mark all src buffers as having an error */
446 s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src); 463 s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
464 &ctx->vq_src);
447 spin_unlock_irqrestore(&dev->irqlock, flags); 465 spin_unlock_irqrestore(&dev->irqlock, flags);
448 if (test_and_clear_bit(0, &dev->hw_lock) == 0) 466 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
449 BUG(); 467 BUG();
@@ -461,7 +479,6 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
461 unsigned int reason, unsigned int err) 479 unsigned int reason, unsigned int err)
462{ 480{
463 struct s5p_mfc_dev *dev; 481 struct s5p_mfc_dev *dev;
464 unsigned int guard_width, guard_height;
465 482
466 if (ctx == NULL) 483 if (ctx == NULL)
467 return; 484 return;
@@ -470,55 +487,44 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
470 if (ctx->c_ops->post_seq_start(ctx)) 487 if (ctx->c_ops->post_seq_start(ctx))
471 mfc_err("post_seq_start() failed\n"); 488 mfc_err("post_seq_start() failed\n");
472 } else { 489 } else {
473 ctx->img_width = s5p_mfc_get_img_width(); 490 ctx->img_width = s5p_mfc_hw_call(dev->mfc_ops, get_img_width,
474 ctx->img_height = s5p_mfc_get_img_height(); 491 dev);
475 492 ctx->img_height = s5p_mfc_hw_call(dev->mfc_ops, get_img_height,
476 ctx->buf_width = ALIGN(ctx->img_width, 493 dev);
477 S5P_FIMV_NV12MT_HALIGN); 494
478 ctx->buf_height = ALIGN(ctx->img_height, 495 s5p_mfc_hw_call(dev->mfc_ops, dec_calc_dpb_size, ctx);
479 S5P_FIMV_NV12MT_VALIGN); 496
480 mfc_debug(2, "SEQ Done: Movie dimensions %dx%d, " 497 ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count,
481 "buffer dimensions: %dx%d\n", ctx->img_width, 498 dev);
482 ctx->img_height, ctx->buf_width, 499 ctx->mv_count = s5p_mfc_hw_call(dev->mfc_ops, get_mv_count,
483 ctx->buf_height); 500 dev);
484 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
485 ctx->luma_size = ALIGN(ctx->buf_width *
486 ctx->buf_height, S5P_FIMV_DEC_BUF_ALIGN);
487 ctx->chroma_size = ALIGN(ctx->buf_width *
488 ALIGN((ctx->img_height >> 1),
489 S5P_FIMV_NV12MT_VALIGN),
490 S5P_FIMV_DEC_BUF_ALIGN);
491 ctx->mv_size = ALIGN(ctx->buf_width *
492 ALIGN((ctx->buf_height >> 2),
493 S5P_FIMV_NV12MT_VALIGN),
494 S5P_FIMV_DEC_BUF_ALIGN);
495 } else {
496 guard_width = ALIGN(ctx->img_width + 24,
497 S5P_FIMV_NV12MT_HALIGN);
498 guard_height = ALIGN(ctx->img_height + 16,
499 S5P_FIMV_NV12MT_VALIGN);
500 ctx->luma_size = ALIGN(guard_width *
501 guard_height, S5P_FIMV_DEC_BUF_ALIGN);
502 guard_width = ALIGN(ctx->img_width + 16,
503 S5P_FIMV_NV12MT_HALIGN);
504 guard_height = ALIGN((ctx->img_height >> 1) + 4,
505 S5P_FIMV_NV12MT_VALIGN);
506 ctx->chroma_size = ALIGN(guard_width *
507 guard_height, S5P_FIMV_DEC_BUF_ALIGN);
508 ctx->mv_size = 0;
509 }
510 ctx->dpb_count = s5p_mfc_get_dpb_count();
511 if (ctx->img_width == 0 || ctx->img_height == 0) 501 if (ctx->img_width == 0 || ctx->img_height == 0)
512 ctx->state = MFCINST_ERROR; 502 ctx->state = MFCINST_ERROR;
513 else 503 else
514 ctx->state = MFCINST_HEAD_PARSED; 504 ctx->state = MFCINST_HEAD_PARSED;
505
506 if ((ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
507 ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) &&
508 !list_empty(&ctx->src_queue)) {
509 struct s5p_mfc_buf *src_buf;
510 src_buf = list_entry(ctx->src_queue.next,
511 struct s5p_mfc_buf, list);
512 if (s5p_mfc_hw_call(dev->mfc_ops, get_consumed_stream,
513 dev) <
514 src_buf->b->v4l2_planes[0].bytesused)
515 ctx->head_processed = 0;
516 else
517 ctx->head_processed = 1;
518 } else {
519 ctx->head_processed = 1;
520 }
515 } 521 }
516 s5p_mfc_clear_int_flags(dev); 522 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
517 clear_work_bit(ctx); 523 clear_work_bit(ctx);
518 if (test_and_clear_bit(0, &dev->hw_lock) == 0) 524 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
519 BUG(); 525 BUG();
520 s5p_mfc_clock_off(); 526 s5p_mfc_clock_off();
521 s5p_mfc_try_run(dev); 527 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
522 wake_up_ctx(ctx, reason, err); 528 wake_up_ctx(ctx, reason, err);
523} 529}
524 530
@@ -533,14 +539,14 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
533 if (ctx == NULL) 539 if (ctx == NULL)
534 return; 540 return;
535 dev = ctx->dev; 541 dev = ctx->dev;
536 s5p_mfc_clear_int_flags(dev); 542 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
537 ctx->int_type = reason; 543 ctx->int_type = reason;
538 ctx->int_err = err; 544 ctx->int_err = err;
539 ctx->int_cond = 1; 545 ctx->int_cond = 1;
540 clear_work_bit(ctx); 546 clear_work_bit(ctx);
541 if (err == 0) { 547 if (err == 0) {
542 ctx->state = MFCINST_RUNNING; 548 ctx->state = MFCINST_RUNNING;
543 if (!ctx->dpb_flush_flag) { 549 if (!ctx->dpb_flush_flag && ctx->head_processed) {
544 spin_lock_irqsave(&dev->irqlock, flags); 550 spin_lock_irqsave(&dev->irqlock, flags);
545 if (!list_empty(&ctx->src_queue)) { 551 if (!list_empty(&ctx->src_queue)) {
546 src_buf = list_entry(ctx->src_queue.next, 552 src_buf = list_entry(ctx->src_queue.next,
@@ -560,7 +566,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
560 s5p_mfc_clock_off(); 566 s5p_mfc_clock_off();
561 567
562 wake_up(&ctx->queue); 568 wake_up(&ctx->queue);
563 s5p_mfc_try_run(dev); 569 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
564 } else { 570 } else {
565 if (test_and_clear_bit(0, &dev->hw_lock) == 0) 571 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
566 BUG(); 572 BUG();
@@ -602,7 +608,7 @@ static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx,
602 608
603 s5p_mfc_clock_off(); 609 s5p_mfc_clock_off();
604 wake_up(&ctx->queue); 610 wake_up(&ctx->queue);
605 s5p_mfc_try_run(dev); 611 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
606} 612}
607 613
608/* Interrupt processing */ 614/* Interrupt processing */
@@ -618,81 +624,83 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
618 atomic_set(&dev->watchdog_cnt, 0); 624 atomic_set(&dev->watchdog_cnt, 0);
619 ctx = dev->ctx[dev->curr_ctx]; 625 ctx = dev->ctx[dev->curr_ctx];
620 /* Get the reason of interrupt and the error code */ 626 /* Get the reason of interrupt and the error code */
621 reason = s5p_mfc_get_int_reason(); 627 reason = s5p_mfc_hw_call(dev->mfc_ops, get_int_reason, dev);
622 err = s5p_mfc_get_int_err(); 628 err = s5p_mfc_hw_call(dev->mfc_ops, get_int_err, dev);
623 mfc_debug(1, "Int reason: %d (err: %08x)\n", reason, err); 629 mfc_debug(1, "Int reason: %d (err: %08x)\n", reason, err);
624 switch (reason) { 630 switch (reason) {
625 case S5P_FIMV_R2H_CMD_ERR_RET: 631 case S5P_MFC_R2H_CMD_ERR_RET:
626 /* An error has occured */ 632 /* An error has occured */
627 if (ctx->state == MFCINST_RUNNING && 633 if (ctx->state == MFCINST_RUNNING &&
628 s5p_mfc_err_dec(err) >= S5P_FIMV_ERR_WARNINGS_START) 634 s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) >=
635 dev->warn_start)
629 s5p_mfc_handle_frame(ctx, reason, err); 636 s5p_mfc_handle_frame(ctx, reason, err);
630 else 637 else
631 s5p_mfc_handle_error(ctx, reason, err); 638 s5p_mfc_handle_error(ctx, reason, err);
632 clear_bit(0, &dev->enter_suspend); 639 clear_bit(0, &dev->enter_suspend);
633 break; 640 break;
634 641
635 case S5P_FIMV_R2H_CMD_SLICE_DONE_RET: 642 case S5P_MFC_R2H_CMD_SLICE_DONE_RET:
636 case S5P_FIMV_R2H_CMD_FRAME_DONE_RET: 643 case S5P_MFC_R2H_CMD_FIELD_DONE_RET:
644 case S5P_MFC_R2H_CMD_FRAME_DONE_RET:
637 if (ctx->c_ops->post_frame_start) { 645 if (ctx->c_ops->post_frame_start) {
638 if (ctx->c_ops->post_frame_start(ctx)) 646 if (ctx->c_ops->post_frame_start(ctx))
639 mfc_err("post_frame_start() failed\n"); 647 mfc_err("post_frame_start() failed\n");
640 s5p_mfc_clear_int_flags(dev); 648 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
641 wake_up_ctx(ctx, reason, err); 649 wake_up_ctx(ctx, reason, err);
642 if (test_and_clear_bit(0, &dev->hw_lock) == 0) 650 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
643 BUG(); 651 BUG();
644 s5p_mfc_clock_off(); 652 s5p_mfc_clock_off();
645 s5p_mfc_try_run(dev); 653 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
646 } else { 654 } else {
647 s5p_mfc_handle_frame(ctx, reason, err); 655 s5p_mfc_handle_frame(ctx, reason, err);
648 } 656 }
649 break; 657 break;
650 658
651 case S5P_FIMV_R2H_CMD_SEQ_DONE_RET: 659 case S5P_MFC_R2H_CMD_SEQ_DONE_RET:
652 s5p_mfc_handle_seq_done(ctx, reason, err); 660 s5p_mfc_handle_seq_done(ctx, reason, err);
653 break; 661 break;
654 662
655 case S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET: 663 case S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET:
656 ctx->inst_no = s5p_mfc_get_inst_no(); 664 ctx->inst_no = s5p_mfc_hw_call(dev->mfc_ops, get_inst_no, dev);
657 ctx->state = MFCINST_GOT_INST; 665 ctx->state = MFCINST_GOT_INST;
658 clear_work_bit(ctx); 666 clear_work_bit(ctx);
659 wake_up(&ctx->queue); 667 wake_up(&ctx->queue);
660 goto irq_cleanup_hw; 668 goto irq_cleanup_hw;
661 669
662 case S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET: 670 case S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET:
663 clear_work_bit(ctx); 671 clear_work_bit(ctx);
664 ctx->state = MFCINST_FREE; 672 ctx->state = MFCINST_FREE;
665 wake_up(&ctx->queue); 673 wake_up(&ctx->queue);
666 goto irq_cleanup_hw; 674 goto irq_cleanup_hw;
667 675
668 case S5P_FIMV_R2H_CMD_SYS_INIT_RET: 676 case S5P_MFC_R2H_CMD_SYS_INIT_RET:
669 case S5P_FIMV_R2H_CMD_FW_STATUS_RET: 677 case S5P_MFC_R2H_CMD_FW_STATUS_RET:
670 case S5P_FIMV_R2H_CMD_SLEEP_RET: 678 case S5P_MFC_R2H_CMD_SLEEP_RET:
671 case S5P_FIMV_R2H_CMD_WAKEUP_RET: 679 case S5P_MFC_R2H_CMD_WAKEUP_RET:
672 if (ctx) 680 if (ctx)
673 clear_work_bit(ctx); 681 clear_work_bit(ctx);
674 s5p_mfc_clear_int_flags(dev); 682 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
675 wake_up_dev(dev, reason, err); 683 wake_up_dev(dev, reason, err);
676 clear_bit(0, &dev->hw_lock); 684 clear_bit(0, &dev->hw_lock);
677 clear_bit(0, &dev->enter_suspend); 685 clear_bit(0, &dev->enter_suspend);
678 break; 686 break;
679 687
680 case S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET: 688 case S5P_MFC_R2H_CMD_INIT_BUFFERS_RET:
681 s5p_mfc_handle_init_buffers(ctx, reason, err); 689 s5p_mfc_handle_init_buffers(ctx, reason, err);
682 break; 690 break;
683 691
684 case S5P_FIMV_R2H_CMD_ENC_COMPLETE_RET: 692 case S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET:
685 s5p_mfc_handle_stream_complete(ctx, reason, err); 693 s5p_mfc_handle_stream_complete(ctx, reason, err);
686 break; 694 break;
687 695
688 default: 696 default:
689 mfc_debug(2, "Unknown int reason\n"); 697 mfc_debug(2, "Unknown int reason\n");
690 s5p_mfc_clear_int_flags(dev); 698 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
691 } 699 }
692 mfc_debug_leave(); 700 mfc_debug_leave();
693 return IRQ_HANDLED; 701 return IRQ_HANDLED;
694irq_cleanup_hw: 702irq_cleanup_hw:
695 s5p_mfc_clear_int_flags(dev); 703 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
696 ctx->int_type = reason; 704 ctx->int_type = reason;
697 ctx->int_err = err; 705 ctx->int_err = err;
698 ctx->int_cond = 1; 706 ctx->int_cond = 1;
@@ -701,7 +709,7 @@ irq_cleanup_hw:
701 709
702 s5p_mfc_clock_off(); 710 s5p_mfc_clock_off();
703 711
704 s5p_mfc_try_run(dev); 712 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
705 mfc_debug(2, "Exit via irq_cleanup_hw\n"); 713 mfc_debug(2, "Exit via irq_cleanup_hw\n");
706 return IRQ_HANDLED; 714 return IRQ_HANDLED;
707} 715}
@@ -749,6 +757,7 @@ static int s5p_mfc_open(struct file *file)
749 if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) { 757 if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
750 ctx->type = MFCINST_DECODER; 758 ctx->type = MFCINST_DECODER;
751 ctx->c_ops = get_dec_codec_ops(); 759 ctx->c_ops = get_dec_codec_ops();
760 s5p_mfc_dec_init(ctx);
752 /* Setup ctrl handler */ 761 /* Setup ctrl handler */
753 ret = s5p_mfc_dec_ctrls_setup(ctx); 762 ret = s5p_mfc_dec_ctrls_setup(ctx);
754 if (ret) { 763 if (ret) {
@@ -761,6 +770,7 @@ static int s5p_mfc_open(struct file *file)
761 /* only for encoder */ 770 /* only for encoder */
762 INIT_LIST_HEAD(&ctx->ref_queue); 771 INIT_LIST_HEAD(&ctx->ref_queue);
763 ctx->ref_queue_cnt = 0; 772 ctx->ref_queue_cnt = 0;
773 s5p_mfc_enc_init(ctx);
764 /* Setup ctrl handler */ 774 /* Setup ctrl handler */
765 ret = s5p_mfc_enc_ctrls_setup(ctx); 775 ret = s5p_mfc_enc_ctrls_setup(ctx);
766 if (ret) { 776 if (ret) {
@@ -886,19 +896,20 @@ static int s5p_mfc_release(struct file *file)
886 ctx->state = MFCINST_RETURN_INST; 896 ctx->state = MFCINST_RETURN_INST;
887 set_work_bit_irqsave(ctx); 897 set_work_bit_irqsave(ctx);
888 s5p_mfc_clean_ctx_int_flags(ctx); 898 s5p_mfc_clean_ctx_int_flags(ctx);
889 s5p_mfc_try_run(dev); 899 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
890 /* Wait until instance is returned or timeout occured */ 900 /* Wait until instance is returned or timeout occured */
891 if (s5p_mfc_wait_for_done_ctx 901 if (s5p_mfc_wait_for_done_ctx
892 (ctx, S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET, 0)) { 902 (ctx, S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)) {
893 s5p_mfc_clock_off(); 903 s5p_mfc_clock_off();
894 mfc_err("Err returning instance\n"); 904 mfc_err("Err returning instance\n");
895 } 905 }
896 mfc_debug(2, "After free instance\n"); 906 mfc_debug(2, "After free instance\n");
897 /* Free resources */ 907 /* Free resources */
898 s5p_mfc_release_codec_buffers(ctx); 908 s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
899 s5p_mfc_release_instance_buffer(ctx); 909 s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx);
900 if (ctx->type == MFCINST_DECODER) 910 if (ctx->type == MFCINST_DECODER)
901 s5p_mfc_release_dec_desc_buffer(ctx); 911 s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer,
912 ctx);
902 913
903 ctx->inst_no = MFC_NO_INSTANCE_SET; 914 ctx->inst_no = MFC_NO_INSTANCE_SET;
904 } 915 }
@@ -910,6 +921,7 @@ static int s5p_mfc_release(struct file *file)
910 mfc_debug(2, "Last instance - release firmware\n"); 921 mfc_debug(2, "Last instance - release firmware\n");
911 /* reset <-> F/W release */ 922 /* reset <-> F/W release */
912 s5p_mfc_reset(dev); 923 s5p_mfc_reset(dev);
924 s5p_mfc_deinit_hw(dev);
913 s5p_mfc_release_firmware(dev); 925 s5p_mfc_release_firmware(dev);
914 del_timer_sync(&dev->watchdog_timer); 926 del_timer_sync(&dev->watchdog_timer);
915 if (s5p_mfc_power_off() < 0) 927 if (s5p_mfc_power_off() < 0)
@@ -1041,6 +1053,9 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1041 return -ENODEV; 1053 return -ENODEV;
1042 } 1054 }
1043 1055
1056 dev->variant = (struct s5p_mfc_variant *)
1057 platform_get_device_id(pdev)->driver_data;
1058
1044 ret = s5p_mfc_init_pm(dev); 1059 ret = s5p_mfc_init_pm(dev);
1045 if (ret < 0) { 1060 if (ret < 0) {
1046 dev_err(&pdev->dev, "failed to get mfc clock source\n"); 1061 dev_err(&pdev->dev, "failed to get mfc clock source\n");
@@ -1076,6 +1091,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1076 ret = -ENODEV; 1091 ret = -ENODEV;
1077 goto err_res; 1092 goto err_res;
1078 } 1093 }
1094
1079 dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, "s5p-mfc-r", 1095 dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, "s5p-mfc-r",
1080 match_child); 1096 match_child);
1081 if (!dev->mem_dev_r) { 1097 if (!dev->mem_dev_r) {
@@ -1139,6 +1155,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1139 vfd->release = video_device_release, 1155 vfd->release = video_device_release,
1140 vfd->lock = &dev->mfc_mutex; 1156 vfd->lock = &dev->mfc_mutex;
1141 vfd->v4l2_dev = &dev->v4l2_dev; 1157 vfd->v4l2_dev = &dev->v4l2_dev;
1158 vfd->vfl_dir = VFL_DIR_M2M;
1142 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_ENC_NAME); 1159 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_ENC_NAME);
1143 dev->vfd_enc = vfd; 1160 dev->vfd_enc = vfd;
1144 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); 1161 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
@@ -1160,6 +1177,10 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1160 dev->watchdog_timer.data = (unsigned long)dev; 1177 dev->watchdog_timer.data = (unsigned long)dev;
1161 dev->watchdog_timer.function = s5p_mfc_watchdog; 1178 dev->watchdog_timer.function = s5p_mfc_watchdog;
1162 1179
1180 /* Initialize HW ops and commands based on MFC version */
1181 s5p_mfc_init_hw_ops(dev);
1182 s5p_mfc_init_hw_cmds(dev);
1183
1163 pr_debug("%s--\n", __func__); 1184 pr_debug("%s--\n", __func__);
1164 return 0; 1185 return 0;
1165 1186
@@ -1280,9 +1301,78 @@ static const struct dev_pm_ops s5p_mfc_pm_ops = {
1280 NULL) 1301 NULL)
1281}; 1302};
1282 1303
1304struct s5p_mfc_buf_size_v5 mfc_buf_size_v5 = {
1305 .h264_ctx = MFC_H264_CTX_BUF_SIZE,
1306 .non_h264_ctx = MFC_CTX_BUF_SIZE,
1307 .dsc = DESC_BUF_SIZE,
1308 .shm = SHARED_BUF_SIZE,
1309};
1310
1311struct s5p_mfc_buf_size buf_size_v5 = {
1312 .fw = MAX_FW_SIZE,
1313 .cpb = MAX_CPB_SIZE,
1314 .priv = &mfc_buf_size_v5,
1315};
1316
1317struct s5p_mfc_buf_align mfc_buf_align_v5 = {
1318 .base = MFC_BASE_ALIGN_ORDER,
1319};
1320
1321static struct s5p_mfc_variant mfc_drvdata_v5 = {
1322 .version = MFC_VERSION,
1323 .port_num = MFC_NUM_PORTS,
1324 .buf_size = &buf_size_v5,
1325 .buf_align = &mfc_buf_align_v5,
1326 .mclk_name = "sclk_mfc",
1327 .fw_name = "s5p-mfc.fw",
1328};
1329
1330struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = {
1331 .dev_ctx = MFC_CTX_BUF_SIZE_V6,
1332 .h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V6,
1333 .other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V6,
1334 .h264_enc_ctx = MFC_H264_ENC_CTX_BUF_SIZE_V6,
1335 .other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V6,
1336};
1337
1338struct s5p_mfc_buf_size buf_size_v6 = {
1339 .fw = MAX_FW_SIZE_V6,
1340 .cpb = MAX_CPB_SIZE_V6,
1341 .priv = &mfc_buf_size_v6,
1342};
1343
1344struct s5p_mfc_buf_align mfc_buf_align_v6 = {
1345 .base = 0,
1346};
1347
1348static struct s5p_mfc_variant mfc_drvdata_v6 = {
1349 .version = MFC_VERSION_V6,
1350 .port_num = MFC_NUM_PORTS_V6,
1351 .buf_size = &buf_size_v6,
1352 .buf_align = &mfc_buf_align_v6,
1353 .mclk_name = "aclk_333",
1354 .fw_name = "s5p-mfc-v6.fw",
1355};
1356
1357static struct platform_device_id mfc_driver_ids[] = {
1358 {
1359 .name = "s5p-mfc",
1360 .driver_data = (unsigned long)&mfc_drvdata_v5,
1361 }, {
1362 .name = "s5p-mfc-v5",
1363 .driver_data = (unsigned long)&mfc_drvdata_v5,
1364 }, {
1365 .name = "s5p-mfc-v6",
1366 .driver_data = (unsigned long)&mfc_drvdata_v6,
1367 },
1368 {},
1369};
1370MODULE_DEVICE_TABLE(platform, mfc_driver_ids);
1371
1283static struct platform_driver s5p_mfc_driver = { 1372static struct platform_driver s5p_mfc_driver = {
1284 .probe = s5p_mfc_probe, 1373 .probe = s5p_mfc_probe,
1285 .remove = __devexit_p(s5p_mfc_remove), 1374 .remove = __devexit_p(s5p_mfc_remove),
1375 .id_table = mfc_driver_ids,
1286 .driver = { 1376 .driver = {
1287 .name = S5P_MFC_NAME, 1377 .name = S5P_MFC_NAME,
1288 .owner = THIS_MODULE, 1378 .owner = THIS_MODULE,
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c
index 91a415573bd2..f0a41c95df84 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c 2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c
3 * 3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd. 4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/ 5 * http://www.samsung.com/
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -10,111 +10,20 @@
10 * (at your option) any later version. 10 * (at your option) any later version.
11 */ 11 */
12 12
13#include "regs-mfc.h"
14#include "s5p_mfc_cmd.h" 13#include "s5p_mfc_cmd.h"
15#include "s5p_mfc_common.h" 14#include "s5p_mfc_common.h"
16#include "s5p_mfc_debug.h" 15#include "s5p_mfc_debug.h"
16#include "s5p_mfc_cmd_v5.h"
17#include "s5p_mfc_cmd_v6.h"
17 18
18/* This function is used to send a command to the MFC */ 19static struct s5p_mfc_hw_cmds *s5p_mfc_cmds;
19static int s5p_mfc_cmd_host2risc(struct s5p_mfc_dev *dev, int cmd,
20 struct s5p_mfc_cmd_args *args)
21{
22 int cur_cmd;
23 unsigned long timeout;
24
25 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
26 /* wait until host to risc command register becomes 'H2R_CMD_EMPTY' */
27 do {
28 if (time_after(jiffies, timeout)) {
29 mfc_err("Timeout while waiting for hardware\n");
30 return -EIO;
31 }
32 cur_cmd = mfc_read(dev, S5P_FIMV_HOST2RISC_CMD);
33 } while (cur_cmd != S5P_FIMV_H2R_CMD_EMPTY);
34 mfc_write(dev, args->arg[0], S5P_FIMV_HOST2RISC_ARG1);
35 mfc_write(dev, args->arg[1], S5P_FIMV_HOST2RISC_ARG2);
36 mfc_write(dev, args->arg[2], S5P_FIMV_HOST2RISC_ARG3);
37 mfc_write(dev, args->arg[3], S5P_FIMV_HOST2RISC_ARG4);
38 /* Issue the command */
39 mfc_write(dev, cmd, S5P_FIMV_HOST2RISC_CMD);
40 return 0;
41}
42
43/* Initialize the MFC */
44int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev)
45{
46 struct s5p_mfc_cmd_args h2r_args;
47
48 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
49 h2r_args.arg[0] = dev->fw_size;
50 return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SYS_INIT, &h2r_args);
51}
52
53/* Suspend the MFC hardware */
54int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev)
55{
56 struct s5p_mfc_cmd_args h2r_args;
57
58 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}
61 20
62/* Wake up the MFC hardware */ 21void s5p_mfc_init_hw_cmds(struct s5p_mfc_dev *dev)
63int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev)
64{ 22{
65 struct s5p_mfc_cmd_args h2r_args; 23 if (IS_MFCV6(dev))
24 s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v6();
25 else
26 s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v5();
66 27
67 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); 28 dev->mfc_cmds = s5p_mfc_cmds;
68 return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_WAKEUP, &h2r_args);
69} 29}
70
71
72int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx)
73{
74 struct s5p_mfc_dev *dev = ctx->dev;
75 struct s5p_mfc_cmd_args h2r_args;
76 int ret;
77
78 /* Preparing decoding - getting instance number */
79 mfc_debug(2, "Getting instance number (codec: %d)\n", ctx->codec_mode);
80 dev->curr_ctx = ctx->num;
81 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
82 h2r_args.arg[0] = ctx->codec_mode;
83 h2r_args.arg[1] = 0; /* no crc & no pixelcache */
84 h2r_args.arg[2] = ctx->ctx_ofs;
85 h2r_args.arg[3] = ctx->ctx_size;
86 ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE,
87 &h2r_args);
88 if (ret) {
89 mfc_err("Failed to create a new instance\n");
90 ctx->state = MFCINST_ERROR;
91 }
92 return ret;
93}
94
95int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx)
96{
97 struct s5p_mfc_dev *dev = ctx->dev;
98 struct s5p_mfc_cmd_args h2r_args;
99 int ret;
100
101 if (ctx->state == MFCINST_FREE) {
102 mfc_err("Instance already returned\n");
103 ctx->state = MFCINST_ERROR;
104 return -EINVAL;
105 }
106 /* Closing decoding instance */
107 mfc_debug(2, "Returning instance number %d\n", ctx->inst_no);
108 dev->curr_ctx = ctx->num;
109 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
110 h2r_args.arg[0] = ctx->inst_no;
111 ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_CLOSE_INSTANCE,
112 &h2r_args);
113 if (ret) {
114 mfc_err("Failed to return an instance\n");
115 ctx->state = MFCINST_ERROR;
116 return -EINVAL;
117 }
118 return 0;
119}
120
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h
index 8b090d3723e7..282e6c780702 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h 2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h
3 * 3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd. 4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/ 5 * http://www.samsung.com/
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -21,10 +21,15 @@ struct s5p_mfc_cmd_args {
21 unsigned int arg[MAX_H2R_ARG]; 21 unsigned int arg[MAX_H2R_ARG];
22}; 22};
23 23
24int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev); 24struct s5p_mfc_hw_cmds {
25int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev); 25 int (*cmd_host2risc)(struct s5p_mfc_dev *dev, int cmd,
26int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev); 26 struct s5p_mfc_cmd_args *args);
27int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx); 27 int (*sys_init_cmd)(struct s5p_mfc_dev *dev);
28int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx); 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};
29 33
34void s5p_mfc_init_hw_cmds(struct s5p_mfc_dev *dev);
30#endif /* S5P_MFC_CMD_H_ */ 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
new file mode 100644
index 000000000000..138778083c63
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c
@@ -0,0 +1,166 @@
1/*
2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c
3 *
4 * Copyright (C) 2011 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 "regs-mfc.h"
14#include "s5p_mfc_cmd.h"
15#include "s5p_mfc_common.h"
16#include "s5p_mfc_debug.h"
17
18/* This function is used to send a command to the MFC */
19int s5p_mfc_cmd_host2risc_v5(struct s5p_mfc_dev *dev, int cmd,
20 struct s5p_mfc_cmd_args *args)
21{
22 int cur_cmd;
23 unsigned long timeout;
24
25 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
26 /* wait until host to risc command register becomes 'H2R_CMD_EMPTY' */
27 do {
28 if (time_after(jiffies, timeout)) {
29 mfc_err("Timeout while waiting for hardware\n");
30 return -EIO;
31 }
32 cur_cmd = mfc_read(dev, S5P_FIMV_HOST2RISC_CMD);
33 } while (cur_cmd != S5P_FIMV_H2R_CMD_EMPTY);
34 mfc_write(dev, args->arg[0], S5P_FIMV_HOST2RISC_ARG1);
35 mfc_write(dev, args->arg[1], S5P_FIMV_HOST2RISC_ARG2);
36 mfc_write(dev, args->arg[2], S5P_FIMV_HOST2RISC_ARG3);
37 mfc_write(dev, args->arg[3], S5P_FIMV_HOST2RISC_ARG4);
38 /* Issue the command */
39 mfc_write(dev, cmd, S5P_FIMV_HOST2RISC_CMD);
40 return 0;
41}
42
43/* Initialize the MFC */
44int s5p_mfc_sys_init_cmd_v5(struct s5p_mfc_dev *dev)
45{
46 struct s5p_mfc_cmd_args h2r_args;
47
48 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
49 h2r_args.arg[0] = dev->fw_size;
50 return s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_SYS_INIT,
51 &h2r_args);
52}
53
54/* Suspend the MFC hardware */
55int s5p_mfc_sleep_cmd_v5(struct s5p_mfc_dev *dev)
56{
57 struct s5p_mfc_cmd_args h2r_args;
58
59 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
60 return s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_SLEEP, &h2r_args);
61}
62
63/* Wake up the MFC hardware */
64int s5p_mfc_wakeup_cmd_v5(struct s5p_mfc_dev *dev)
65{
66 struct s5p_mfc_cmd_args h2r_args;
67
68 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
69 return s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_WAKEUP,
70 &h2r_args);
71}
72
73
74int s5p_mfc_open_inst_cmd_v5(struct s5p_mfc_ctx *ctx)
75{
76 struct s5p_mfc_dev *dev = ctx->dev;
77 struct s5p_mfc_cmd_args h2r_args;
78 int ret;
79
80 /* Preparing decoding - getting instance number */
81 mfc_debug(2, "Getting instance number (codec: %d)\n", ctx->codec_mode);
82 dev->curr_ctx = ctx->num;
83 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
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 };
115 h2r_args.arg[1] = 0; /* no crc & no pixelcache */
116 h2r_args.arg[2] = ctx->ctx.ofs;
117 h2r_args.arg[3] = ctx->ctx.size;
118 ret = s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE,
119 &h2r_args);
120 if (ret) {
121 mfc_err("Failed to create a new instance\n");
122 ctx->state = MFCINST_ERROR;
123 }
124 return ret;
125}
126
127int s5p_mfc_close_inst_cmd_v5(struct s5p_mfc_ctx *ctx)
128{
129 struct s5p_mfc_dev *dev = ctx->dev;
130 struct s5p_mfc_cmd_args h2r_args;
131 int ret;
132
133 if (ctx->state == MFCINST_FREE) {
134 mfc_err("Instance already returned\n");
135 ctx->state = MFCINST_ERROR;
136 return -EINVAL;
137 }
138 /* Closing decoding instance */
139 mfc_debug(2, "Returning instance number %d\n", ctx->inst_no);
140 dev->curr_ctx = ctx->num;
141 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
142 h2r_args.arg[0] = ctx->inst_no;
143 ret = s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_CLOSE_INSTANCE,
144 &h2r_args);
145 if (ret) {
146 mfc_err("Failed to return an instance\n");
147 ctx->state = MFCINST_ERROR;
148 return -EINVAL;
149 }
150 return 0;
151}
152
153/* Initialize cmd function pointers for MFC v5 */
154static 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
163struct 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
new file mode 100644
index 000000000000..6928a5514c1b
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h
@@ -0,0 +1,20 @@
1/*
2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h
3 *
4 * Copyright (C) 2011 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_V5_H_
14#define S5P_MFC_CMD_V5_H_
15
16#include "s5p_mfc_common.h"
17
18struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void);
19
20#endif /* S5P_MFC_CMD_H_ */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
new file mode 100644
index 000000000000..754bfbcb1c43
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
@@ -0,0 +1,156 @@
1/*
2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.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_common.h"
14
15#include "s5p_mfc_cmd.h"
16#include "s5p_mfc_debug.h"
17#include "s5p_mfc_intr.h"
18#include "s5p_mfc_opr.h"
19
20int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd,
21 struct s5p_mfc_cmd_args *args)
22{
23 mfc_debug(2, "Issue the command: %d\n", cmd);
24
25 /* Reset RISC2HOST command */
26 mfc_write(dev, 0x0, S5P_FIMV_RISC2HOST_CMD_V6);
27
28 /* Issue the command */
29 mfc_write(dev, cmd, S5P_FIMV_HOST2RISC_CMD_V6);
30 mfc_write(dev, 0x1, S5P_FIMV_HOST2RISC_INT_V6);
31
32 return 0;
33}
34
35int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev)
36{
37 struct s5p_mfc_cmd_args h2r_args;
38 struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
39
40 s5p_mfc_hw_call(dev->mfc_ops, alloc_dev_context_buffer, dev);
41 mfc_write(dev, dev->ctx_buf.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6);
42 mfc_write(dev, buf_size->dev_ctx, S5P_FIMV_CONTEXT_MEM_SIZE_V6);
43 return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SYS_INIT_V6,
44 &h2r_args);
45}
46
47int s5p_mfc_sleep_cmd_v6(struct s5p_mfc_dev *dev)
48{
49 struct s5p_mfc_cmd_args h2r_args;
50
51 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
52 return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SLEEP_V6,
53 &h2r_args);
54}
55
56int s5p_mfc_wakeup_cmd_v6(struct s5p_mfc_dev *dev)
57{
58 struct s5p_mfc_cmd_args h2r_args;
59
60 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
61 return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_WAKEUP_V6,
62 &h2r_args);
63}
64
65/* Open a new instance and get its number */
66int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
67{
68 struct s5p_mfc_dev *dev = ctx->dev;
69 struct s5p_mfc_cmd_args h2r_args;
70 int codec_type;
71
72 mfc_debug(2, "Requested codec mode: %d\n", ctx->codec_mode);
73 dev->curr_ctx = ctx->num;
74 switch (ctx->codec_mode) {
75 case S5P_MFC_CODEC_H264_DEC:
76 codec_type = S5P_FIMV_CODEC_H264_DEC_V6;
77 break;
78 case S5P_MFC_CODEC_H264_MVC_DEC:
79 codec_type = S5P_FIMV_CODEC_H264_MVC_DEC_V6;
80 break;
81 case S5P_MFC_CODEC_VC1_DEC:
82 codec_type = S5P_FIMV_CODEC_VC1_DEC_V6;
83 break;
84 case S5P_MFC_CODEC_MPEG4_DEC:
85 codec_type = S5P_FIMV_CODEC_MPEG4_DEC_V6;
86 break;
87 case S5P_MFC_CODEC_MPEG2_DEC:
88 codec_type = S5P_FIMV_CODEC_MPEG2_DEC_V6;
89 break;
90 case S5P_MFC_CODEC_H263_DEC:
91 codec_type = S5P_FIMV_CODEC_H263_DEC_V6;
92 break;
93 case S5P_MFC_CODEC_VC1RCV_DEC:
94 codec_type = S5P_FIMV_CODEC_VC1RCV_DEC_V6;
95 break;
96 case S5P_MFC_CODEC_VP8_DEC:
97 codec_type = S5P_FIMV_CODEC_VP8_DEC_V6;
98 break;
99 case S5P_MFC_CODEC_H264_ENC:
100 codec_type = S5P_FIMV_CODEC_H264_ENC_V6;
101 break;
102 case S5P_MFC_CODEC_H264_MVC_ENC:
103 codec_type = S5P_FIMV_CODEC_H264_MVC_ENC_V6;
104 break;
105 case S5P_MFC_CODEC_MPEG4_ENC:
106 codec_type = S5P_FIMV_CODEC_MPEG4_ENC_V6;
107 break;
108 case S5P_MFC_CODEC_H263_ENC:
109 codec_type = S5P_FIMV_CODEC_H263_ENC_V6;
110 break;
111 default:
112 codec_type = S5P_FIMV_CODEC_NONE_V6;
113 };
114 mfc_write(dev, codec_type, S5P_FIMV_CODEC_TYPE_V6);
115 mfc_write(dev, ctx->ctx.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6);
116 mfc_write(dev, ctx->ctx.size, S5P_FIMV_CONTEXT_MEM_SIZE_V6);
117 mfc_write(dev, 0, S5P_FIMV_D_CRC_CTRL_V6); /* no crc */
118
119 return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE_V6,
120 &h2r_args);
121}
122
123/* Close instance */
124int s5p_mfc_close_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
125{
126 struct s5p_mfc_dev *dev = ctx->dev;
127 struct s5p_mfc_cmd_args h2r_args;
128 int ret = 0;
129
130 dev->curr_ctx = ctx->num;
131 if (ctx->state != MFCINST_FREE) {
132 mfc_write(dev, ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
133 ret = s5p_mfc_cmd_host2risc_v6(dev,
134 S5P_FIMV_H2R_CMD_CLOSE_INSTANCE_V6,
135 &h2r_args);
136 } else {
137 ret = -EINVAL;
138 }
139
140 return ret;
141}
142
143/* Initialize cmd function pointers for MFC v6 */
144static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v6 = {
145 .cmd_host2risc = s5p_mfc_cmd_host2risc_v6,
146 .sys_init_cmd = s5p_mfc_sys_init_cmd_v6,
147 .sleep_cmd = s5p_mfc_sleep_cmd_v6,
148 .wakeup_cmd = s5p_mfc_wakeup_cmd_v6,
149 .open_inst_cmd = s5p_mfc_open_inst_cmd_v6,
150 .close_inst_cmd = s5p_mfc_close_inst_cmd_v6,
151};
152
153struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void)
154{
155 return &s5p_mfc_cmds_v6;
156}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h
new file mode 100644
index 000000000000..b7a8e57837b5
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h
@@ -0,0 +1,20 @@
1/*
2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h
3 *
4 * Copyright (C) 2011 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_V6_H_
14#define S5P_MFC_CMD_V6_H_
15
16#include "s5p_mfc_common.h"
17
18struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void);
19
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..f02e0497ca98 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -16,13 +16,14 @@
16#ifndef S5P_MFC_COMMON_H_ 16#ifndef S5P_MFC_COMMON_H_
17#define S5P_MFC_COMMON_H_ 17#define S5P_MFC_COMMON_H_
18 18
19#include "regs-mfc.h"
20#include <linux/platform_device.h> 19#include <linux/platform_device.h>
21#include <linux/videodev2.h> 20#include <linux/videodev2.h>
22#include <media/v4l2-ctrls.h> 21#include <media/v4l2-ctrls.h>
23#include <media/v4l2-device.h> 22#include <media/v4l2-device.h>
24#include <media/v4l2-ioctl.h> 23#include <media/v4l2-ioctl.h>
25#include <media/videobuf2-core.h> 24#include <media/videobuf2-core.h>
25#include "regs-mfc.h"
26#include "regs-mfc-v6.h"
26 27
27/* Definitions related to MFC memory */ 28/* Definitions related to MFC memory */
28 29
@@ -30,17 +31,6 @@
30* while mmaping */ 31* while mmaping */
31#define DST_QUEUE_OFF_BASE (TASK_SIZE / 2) 32#define DST_QUEUE_OFF_BASE (TASK_SIZE / 2)
32 33
33/* Offset used by the hardware to store addresses */
34#define MFC_OFFSET_SHIFT 11
35
36#define FIRMWARE_ALIGN 0x20000 /* 128KB */
37#define MFC_H264_CTX_BUF_SIZE 0x96000 /* 600KB per H264 instance */
38#define MFC_CTX_BUF_SIZE 0x2800 /* 10KB per instance */
39#define DESC_BUF_SIZE 0x20000 /* 128KB for DESC buffer */
40#define SHARED_BUF_SIZE 0x2000 /* 8KB for shared buffer */
41
42#define DEF_CPB_SIZE 0x40000 /* 512KB */
43
44#define MFC_BANK1_ALLOC_CTX 0 34#define MFC_BANK1_ALLOC_CTX 0
45#define MFC_BANK2_ALLOC_CTX 1 35#define MFC_BANK2_ALLOC_CTX 1
46 36
@@ -74,7 +64,40 @@ static inline dma_addr_t s5p_mfc_mem_cookie(void *a, void *b)
74#define MFC_ENC_CAP_PLANE_COUNT 1 64#define MFC_ENC_CAP_PLANE_COUNT 1
75#define MFC_ENC_OUT_PLANE_COUNT 2 65#define MFC_ENC_OUT_PLANE_COUNT 2
76#define STUFF_BYTE 4 66#define STUFF_BYTE 4
77#define MFC_MAX_CTRLS 64 67#define MFC_MAX_CTRLS 70
68
69#define S5P_MFC_CODEC_NONE -1
70#define S5P_MFC_CODEC_H264_DEC 0
71#define S5P_MFC_CODEC_H264_MVC_DEC 1
72#define S5P_MFC_CODEC_VC1_DEC 2
73#define S5P_MFC_CODEC_MPEG4_DEC 3
74#define S5P_MFC_CODEC_MPEG2_DEC 4
75#define S5P_MFC_CODEC_H263_DEC 5
76#define S5P_MFC_CODEC_VC1RCV_DEC 6
77#define S5P_MFC_CODEC_VP8_DEC 7
78
79#define S5P_MFC_CODEC_H264_ENC 20
80#define S5P_MFC_CODEC_H264_MVC_ENC 21
81#define S5P_MFC_CODEC_MPEG4_ENC 22
82#define S5P_MFC_CODEC_H263_ENC 23
83
84#define S5P_MFC_R2H_CMD_EMPTY 0
85#define S5P_MFC_R2H_CMD_SYS_INIT_RET 1
86#define S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET 2
87#define S5P_MFC_R2H_CMD_SEQ_DONE_RET 3
88#define S5P_MFC_R2H_CMD_INIT_BUFFERS_RET 4
89#define S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET 6
90#define S5P_MFC_R2H_CMD_SLEEP_RET 7
91#define S5P_MFC_R2H_CMD_WAKEUP_RET 8
92#define S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET 9
93#define S5P_MFC_R2H_CMD_DPB_FLUSH_RET 10
94#define S5P_MFC_R2H_CMD_NAL_ABORT_RET 11
95#define S5P_MFC_R2H_CMD_FW_STATUS_RET 12
96#define S5P_MFC_R2H_CMD_FRAME_DONE_RET 13
97#define S5P_MFC_R2H_CMD_FIELD_DONE_RET 14
98#define S5P_MFC_R2H_CMD_SLICE_DONE_RET 15
99#define S5P_MFC_R2H_CMD_ENC_BUFFER_FUL_RET 16
100#define S5P_MFC_R2H_CMD_ERR_RET 32
78 101
79#define mfc_read(dev, offset) readl(dev->regs_base + (offset)) 102#define mfc_read(dev, offset) readl(dev->regs_base + (offset))
80#define mfc_write(dev, data, offset) writel((data), dev->regs_base + \ 103#define mfc_write(dev, data, offset) writel((data), dev->regs_base + \
@@ -177,6 +200,58 @@ struct s5p_mfc_pm {
177 struct device *device; 200 struct device *device;
178}; 201};
179 202
203struct s5p_mfc_buf_size_v5 {
204 unsigned int h264_ctx;
205 unsigned int non_h264_ctx;
206 unsigned int dsc;
207 unsigned int shm;
208};
209
210struct s5p_mfc_buf_size_v6 {
211 unsigned int dev_ctx;
212 unsigned int h264_dec_ctx;
213 unsigned int other_dec_ctx;
214 unsigned int h264_enc_ctx;
215 unsigned int other_enc_ctx;
216};
217
218struct s5p_mfc_buf_size {
219 unsigned int fw;
220 unsigned int cpb;
221 void *priv;
222};
223
224struct s5p_mfc_buf_align {
225 unsigned int base;
226};
227
228struct s5p_mfc_variant {
229 unsigned int version;
230 unsigned int port_num;
231 struct s5p_mfc_buf_size *buf_size;
232 struct s5p_mfc_buf_align *buf_align;
233 char *mclk_name;
234 char *fw_name;
235};
236
237/**
238 * struct s5p_mfc_priv_buf - represents internal used buffer
239 * @alloc: allocation-specific context for each buffer
240 * (videobuf2 allocator)
241 * @ofs: offset of each buffer, will be used for MFC
242 * @virt: kernel virtual address, only valid when the
243 * buffer accessed by driver
244 * @dma: DMA address, only valid when kernel DMA API used
245 * @size: size of the buffer
246 */
247struct s5p_mfc_priv_buf {
248 void *alloc;
249 unsigned long ofs;
250 void *virt;
251 dma_addr_t dma;
252 size_t size;
253};
254
180/** 255/**
181 * struct s5p_mfc_dev - The struct containing driver internal parameters. 256 * struct s5p_mfc_dev - The struct containing driver internal parameters.
182 * 257 *
@@ -191,6 +266,7 @@ struct s5p_mfc_pm {
191 * @dec_ctrl_handler: control framework handler for decoding 266 * @dec_ctrl_handler: control framework handler for decoding
192 * @enc_ctrl_handler: control framework handler for encoding 267 * @enc_ctrl_handler: control framework handler for encoding
193 * @pm: power management control 268 * @pm: power management control
269 * @variant: MFC hardware variant information
194 * @num_inst: couter of active MFC instances 270 * @num_inst: couter of active MFC instances
195 * @irqlock: lock for operations on videobuf2 queues 271 * @irqlock: lock for operations on videobuf2 queues
196 * @condlock: lock for changing/checking if a context is ready to be 272 * @condlock: lock for changing/checking if a context is ready to be
@@ -212,6 +288,10 @@ struct s5p_mfc_pm {
212 * @watchdog_work: worker for the watchdog 288 * @watchdog_work: worker for the watchdog
213 * @alloc_ctx: videobuf2 allocator contexts for two memory banks 289 * @alloc_ctx: videobuf2 allocator contexts for two memory banks
214 * @enter_suspend: flag set when entering suspend 290 * @enter_suspend: flag set when entering suspend
291 * @ctx_buf: common context memory (MFCv6)
292 * @warn_start: hardware error code from which warnings start
293 * @mfc_ops: ops structure holding HW operation function pointers
294 * @mfc_cmds: cmd structure holding HW commands function pointers
215 * 295 *
216 */ 296 */
217struct s5p_mfc_dev { 297struct s5p_mfc_dev {
@@ -226,6 +306,7 @@ struct s5p_mfc_dev {
226 struct v4l2_ctrl_handler dec_ctrl_handler; 306 struct v4l2_ctrl_handler dec_ctrl_handler;
227 struct v4l2_ctrl_handler enc_ctrl_handler; 307 struct v4l2_ctrl_handler enc_ctrl_handler;
228 struct s5p_mfc_pm pm; 308 struct s5p_mfc_pm pm;
309 struct s5p_mfc_variant *variant;
229 int num_inst; 310 int num_inst;
230 spinlock_t irqlock; /* lock when operating on videobuf2 queues */ 311 spinlock_t irqlock; /* lock when operating on videobuf2 queues */
231 spinlock_t condlock; /* lock when changing/checking if a context is 312 spinlock_t condlock; /* lock when changing/checking if a context is
@@ -248,6 +329,11 @@ struct s5p_mfc_dev {
248 struct work_struct watchdog_work; 329 struct work_struct watchdog_work;
249 void *alloc_ctx[2]; 330 void *alloc_ctx[2];
250 unsigned long enter_suspend; 331 unsigned long enter_suspend;
332
333 struct s5p_mfc_priv_buf ctx_buf;
334 int warn_start;
335 struct s5p_mfc_hw_ops *mfc_ops;
336 struct s5p_mfc_hw_cmds *mfc_cmds;
251}; 337};
252 338
253/** 339/**
@@ -262,7 +348,6 @@ struct s5p_mfc_h264_enc_params {
262 u8 max_ref_pic; 348 u8 max_ref_pic;
263 u8 num_ref_pic_4p; 349 u8 num_ref_pic_4p;
264 int _8x8_transform; 350 int _8x8_transform;
265 int rc_mb;
266 int rc_mb_dark; 351 int rc_mb_dark;
267 int rc_mb_smooth; 352 int rc_mb_smooth;
268 int rc_mb_static; 353 int rc_mb_static;
@@ -281,6 +366,23 @@ struct s5p_mfc_h264_enc_params {
281 enum v4l2_mpeg_video_h264_level level_v4l2; 366 enum v4l2_mpeg_video_h264_level level_v4l2;
282 int level; 367 int level;
283 u16 cpb_size; 368 u16 cpb_size;
369 int interlace;
370 u8 hier_qp;
371 u8 hier_qp_type;
372 u8 hier_qp_layer;
373 u8 hier_qp_layer_qp[7];
374 u8 sei_frame_packing;
375 u8 sei_fp_curr_frame_0;
376 u8 sei_fp_arrangement_type;
377
378 u8 fmo;
379 u8 fmo_map_type;
380 u8 fmo_slice_grp;
381 u8 fmo_chg_dir;
382 u32 fmo_chg_rate;
383 u32 fmo_run_len[4];
384 u8 aso;
385 u32 aso_slice_order[8];
284}; 386};
285 387
286/** 388/**
@@ -319,9 +421,11 @@ struct s5p_mfc_enc_params {
319 u8 pad_cb; 421 u8 pad_cb;
320 u8 pad_cr; 422 u8 pad_cr;
321 int rc_frame; 423 int rc_frame;
424 int rc_mb;
322 u32 rc_bitrate; 425 u32 rc_bitrate;
323 u16 rc_reaction_coeff; 426 u16 rc_reaction_coeff;
324 u16 vbv_size; 427 u16 vbv_size;
428 u32 vbv_delay;
325 429
326 enum v4l2_mpeg_video_header_mode seq_hdr_mode; 430 enum v4l2_mpeg_video_header_mode seq_hdr_mode;
327 enum v4l2_mpeg_mfc51_video_frame_skip_mode frame_skip_mode; 431 enum v4l2_mpeg_mfc51_video_frame_skip_mode frame_skip_mode;
@@ -330,7 +434,6 @@ struct s5p_mfc_enc_params {
330 u8 num_b_frame; 434 u8 num_b_frame;
331 u32 rc_framerate_num; 435 u32 rc_framerate_num;
332 u32 rc_framerate_denom; 436 u32 rc_framerate_denom;
333 int interlace;
334 437
335 union { 438 union {
336 struct s5p_mfc_h264_enc_params h264; 439 struct s5p_mfc_h264_enc_params h264;
@@ -388,6 +491,8 @@ struct s5p_mfc_codec_ops {
388 * decoding buffer 491 * decoding buffer
389 * @dpb_flush_flag: flag used to indicate that a DPB buffers are being 492 * @dpb_flush_flag: flag used to indicate that a DPB buffers are being
390 * flushed 493 * flushed
494 * @head_processed: flag mentioning whether the header data is processed
495 * completely or not
391 * @bank1_buf: handle to memory allocated for temporary buffers from 496 * @bank1_buf: handle to memory allocated for temporary buffers from
392 * memory bank 1 497 * memory bank 1
393 * @bank1_phys: address of the temporary buffers from memory bank 1 498 * @bank1_phys: address of the temporary buffers from memory bank 1
@@ -412,19 +517,20 @@ struct s5p_mfc_codec_ops {
412 * @display_delay_enable: display delay for H264 enable flag 517 * @display_delay_enable: display delay for H264 enable flag
413 * @after_packed_pb: flag used to track buffer when stream is in 518 * @after_packed_pb: flag used to track buffer when stream is in
414 * Packed PB format 519 * Packed PB format
520 * @sei_fp_parse: enable/disable parsing of frame packing SEI information
415 * @dpb_count: count of the DPB buffers required by MFC hw 521 * @dpb_count: count of the DPB buffers required by MFC hw
416 * @total_dpb_count: count of DPB buffers with additional buffers 522 * @total_dpb_count: count of DPB buffers with additional buffers
417 * requested by the application 523 * requested by the application
418 * @ctx_buf: handle to the memory associated with this context 524 * @ctx: context buffer information
419 * @ctx_phys: address of the memory associated with this context 525 * @dsc: descriptor buffer information
420 * @ctx_size: size of the memory associated with this context 526 * @shm: shared memory buffer information
421 * @desc_buf: description buffer for decoding handle 527 * @mv_count: number of MV buffers allocated for decoding
422 * @desc_phys: description buffer for decoding address
423 * @shm_alloc: handle for the shared memory buffer
424 * @shm: virtual address for the shared memory buffer
425 * @shm_ofs: address offset for shared memory
426 * @enc_params: encoding parameters for MFC 528 * @enc_params: encoding parameters for MFC
427 * @enc_dst_buf_size: size of the buffers for encoder output 529 * @enc_dst_buf_size: size of the buffers for encoder output
530 * @luma_dpb_size: dpb buffer size for luma
531 * @chroma_dpb_size: dpb buffer size for chroma
532 * @me_buffer_size: size of the motion estimation buffer
533 * @tmv_buffer_size: size of temporal predictor motion vector buffer
428 * @frame_type: used to force the type of the next encoded frame 534 * @frame_type: used to force the type of the next encoded frame
429 * @ref_queue: list of the reference buffers for encoding 535 * @ref_queue: list of the reference buffers for encoding
430 * @ref_queue_cnt: number of the buffers in the reference list 536 * @ref_queue_cnt: number of the buffers in the reference list
@@ -473,6 +579,7 @@ struct s5p_mfc_ctx {
473 unsigned long consumed_stream; 579 unsigned long consumed_stream;
474 580
475 unsigned int dpb_flush_flag; 581 unsigned int dpb_flush_flag;
582 unsigned int head_processed;
476 583
477 /* Buffers */ 584 /* Buffers */
478 void *bank1_buf; 585 void *bank1_buf;
@@ -502,37 +609,41 @@ struct s5p_mfc_ctx {
502 int display_delay; 609 int display_delay;
503 int display_delay_enable; 610 int display_delay_enable;
504 int after_packed_pb; 611 int after_packed_pb;
612 int sei_fp_parse;
505 613
506 int dpb_count; 614 int dpb_count;
507 int total_dpb_count; 615 int total_dpb_count;
508 616 int mv_count;
509 /* Buffers */ 617 /* Buffers */
510 void *ctx_buf; 618 struct s5p_mfc_priv_buf ctx;
511 size_t ctx_phys; 619 struct s5p_mfc_priv_buf dsc;
512 size_t ctx_ofs; 620 struct s5p_mfc_priv_buf shm;
513 size_t ctx_size;
514
515 void *desc_buf;
516 size_t desc_phys;
517
518
519 void *shm_alloc;
520 void *shm;
521 size_t shm_ofs;
522 621
523 struct s5p_mfc_enc_params enc_params; 622 struct s5p_mfc_enc_params enc_params;
524 623
525 size_t enc_dst_buf_size; 624 size_t enc_dst_buf_size;
625 size_t luma_dpb_size;
626 size_t chroma_dpb_size;
627 size_t me_buffer_size;
628 size_t tmv_buffer_size;
526 629
527 enum v4l2_mpeg_mfc51_video_force_frame_type force_frame_type; 630 enum v4l2_mpeg_mfc51_video_force_frame_type force_frame_type;
528 631
529 struct list_head ref_queue; 632 struct list_head ref_queue;
530 unsigned int ref_queue_cnt; 633 unsigned int ref_queue_cnt;
531 634
635 enum v4l2_mpeg_video_multi_slice_mode slice_mode;
636 union {
637 unsigned int mb;
638 unsigned int bits;
639 } slice_size;
640
532 struct s5p_mfc_codec_ops *c_ops; 641 struct s5p_mfc_codec_ops *c_ops;
533 642
534 struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS]; 643 struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
535 struct v4l2_ctrl_handler ctrl_handler; 644 struct v4l2_ctrl_handler ctrl_handler;
645 unsigned int frame_tag;
646 size_t scratch_buf_size;
536}; 647};
537 648
538/* 649/*
@@ -565,6 +676,9 @@ struct mfc_control {
565 __u8 is_volatile; 676 __u8 is_volatile;
566}; 677};
567 678
679/* Macro for making hardware specific calls */
680#define s5p_mfc_hw_call(f, op, args...) \
681 ((f && f->op) ? f->op(args) : -ENODEV)
568 682
569#define fh_to_ctx(__fh) container_of(__fh, struct s5p_mfc_ctx, fh) 683#define fh_to_ctx(__fh) container_of(__fh, struct s5p_mfc_ctx, fh)
570#define ctrl_to_ctx(__ctrl) \ 684#define ctrl_to_ctx(__ctrl) \
@@ -575,4 +689,9 @@ void set_work_bit(struct s5p_mfc_ctx *ctx);
575void clear_work_bit_irqsave(struct s5p_mfc_ctx *ctx); 689void clear_work_bit_irqsave(struct s5p_mfc_ctx *ctx);
576void set_work_bit_irqsave(struct s5p_mfc_ctx *ctx); 690void set_work_bit_irqsave(struct s5p_mfc_ctx *ctx);
577 691
692#define HAS_PORTNUM(dev) (dev ? (dev->variant ? \
693 (dev->variant->port_num ? 1 : 0) : 0) : 0)
694#define IS_TWOPORT(dev) (dev->variant->port_num == 2 ? 1 : 0)
695#define IS_MFCV6(dev) (dev->variant->version >= 0x60 ? 1 : 0)
696
578#endif /* S5P_MFC_COMMON_H_ */ 697#endif /* S5P_MFC_COMMON_H_ */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
index 0deba6bc687c..585b7b0ed8ec 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"
19#include "s5p_mfc_cmd.h" 18#include "s5p_mfc_cmd.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
25static void *s5p_mfc_bitproc_buf; 25static void *s5p_mfc_bitproc_buf;
@@ -37,13 +37,19 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
37 /* Firmare has to be present as a separate file or compiled 37 /* Firmare has to be present as a separate file or compiled
38 * into kernel. */ 38 * into kernel. */
39 mfc_debug_enter(); 39 mfc_debug_enter();
40
40 err = request_firmware((const struct firmware **)&fw_blob, 41 err = request_firmware((const struct firmware **)&fw_blob,
41 "s5p-mfc.fw", dev->v4l2_dev.dev); 42 dev->variant->fw_name, dev->v4l2_dev.dev);
42 if (err != 0) { 43 if (err != 0) {
43 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); 44 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
44 return -EINVAL; 45 return -EINVAL;
45 } 46 }
46 dev->fw_size = ALIGN(fw_blob->size, FIRMWARE_ALIGN); 47 dev->fw_size = dev->variant->buf_size->fw;
48 if (fw_blob->size > dev->fw_size) {
49 mfc_err("MFC firmware is too big to be loaded\n");
50 release_firmware(fw_blob);
51 return -ENOMEM;
52 }
47 if (s5p_mfc_bitproc_buf) { 53 if (s5p_mfc_bitproc_buf) {
48 mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n"); 54 mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n");
49 release_firmware(fw_blob); 55 release_firmware(fw_blob);
@@ -77,32 +83,37 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
77 return -EIO; 83 return -EIO;
78 } 84 }
79 dev->bank1 = s5p_mfc_bitproc_phys; 85 dev->bank1 = s5p_mfc_bitproc_phys;
80 b_base = vb2_dma_contig_memops.alloc( 86 if (HAS_PORTNUM(dev) && IS_TWOPORT(dev)) {
81 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], 1 << MFC_BASE_ALIGN_ORDER); 87 b_base = vb2_dma_contig_memops.alloc(
82 if (IS_ERR(b_base)) { 88 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX],
83 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf); 89 1 << MFC_BASE_ALIGN_ORDER);
84 s5p_mfc_bitproc_phys = 0; 90 if (IS_ERR(b_base)) {
85 s5p_mfc_bitproc_buf = NULL; 91 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
86 mfc_err("Allocating bank2 base failed\n"); 92 s5p_mfc_bitproc_phys = 0;
87 release_firmware(fw_blob); 93 s5p_mfc_bitproc_buf = NULL;
88 return -ENOMEM; 94 mfc_err("Allocating bank2 base failed\n");
89 } 95 release_firmware(fw_blob);
90 bank2_base_phys = s5p_mfc_mem_cookie( 96 return -ENOMEM;
91 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base); 97 }
92 vb2_dma_contig_memops.put(b_base); 98 bank2_base_phys = s5p_mfc_mem_cookie(
93 if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) { 99 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base);
94 mfc_err("The base memory for bank 2 is not aligned to 128KB\n"); 100 vb2_dma_contig_memops.put(b_base);
95 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf); 101 if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
96 s5p_mfc_bitproc_phys = 0; 102 mfc_err("The base memory for bank 2 is not aligned to 128KB\n");
97 s5p_mfc_bitproc_buf = NULL; 103 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
98 release_firmware(fw_blob); 104 s5p_mfc_bitproc_phys = 0;
99 return -EIO; 105 s5p_mfc_bitproc_buf = NULL;
106 release_firmware(fw_blob);
107 return -EIO;
108 }
109 /* Valid buffers passed to MFC encoder with LAST_FRAME command
110 * should not have address of bank2 - MFC will treat it as a null frame.
111 * To avoid such situation we set bank2 address below the pool address.
112 */
113 dev->bank2 = bank2_base_phys - (1 << MFC_BASE_ALIGN_ORDER);
114 } else {
115 dev->bank2 = dev->bank1;
100 } 116 }
101 /* Valid buffers passed to MFC encoder with LAST_FRAME command
102 * should not have address of bank2 - MFC will treat it as a null frame.
103 * To avoid such situation we set bank2 address below the pool address.
104 */
105 dev->bank2 = bank2_base_phys - (1 << MFC_BASE_ALIGN_ORDER);
106 memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size); 117 memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
107 wmb(); 118 wmb();
108 release_firmware(fw_blob); 119 release_firmware(fw_blob);
@@ -119,8 +130,9 @@ int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
119 /* Firmare has to be present as a separate file or compiled 130 /* Firmare has to be present as a separate file or compiled
120 * into kernel. */ 131 * into kernel. */
121 mfc_debug_enter(); 132 mfc_debug_enter();
133
122 err = request_firmware((const struct firmware **)&fw_blob, 134 err = request_firmware((const struct firmware **)&fw_blob,
123 "s5p-mfc.fw", dev->v4l2_dev.dev); 135 dev->variant->fw_name, dev->v4l2_dev.dev);
124 if (err != 0) { 136 if (err != 0) {
125 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); 137 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
126 return -EINVAL; 138 return -EINVAL;
@@ -161,46 +173,81 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
161{ 173{
162 unsigned int mc_status; 174 unsigned int mc_status;
163 unsigned long timeout; 175 unsigned long timeout;
176 int i;
164 177
165 mfc_debug_enter(); 178 mfc_debug_enter();
166 /* Stop procedure */
167 /* reset RISC */
168 mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
169 /* All reset except for MC */
170 mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
171 mdelay(10);
172
173 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
174 /* Check MC status */
175 do {
176 if (time_after(jiffies, timeout)) {
177 mfc_err("Timeout while resetting MFC\n");
178 return -EIO;
179 }
180 179
181 mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS); 180 if (IS_MFCV6(dev)) {
181 /* Reset IP */
182 /* except RISC, reset */
183 mfc_write(dev, 0xFEE, S5P_FIMV_MFC_RESET_V6);
184 /* reset release */
185 mfc_write(dev, 0x0, S5P_FIMV_MFC_RESET_V6);
186
187 /* Zero Initialization of MFC registers */
188 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6);
189 mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD_V6);
190 mfc_write(dev, 0, S5P_FIMV_FW_VERSION_V6);
191
192 for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++)
193 mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));
182 194
183 } while (mc_status & 0x3); 195 /* Reset */
196 mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6);
197 mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6);
198 mfc_write(dev, 0, S5P_FIMV_MFC_RESET_V6);
199 } else {
200 /* Stop procedure */
201 /* reset RISC */
202 mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
203 /* All reset except for MC */
204 mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
205 mdelay(10);
206
207 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
208 /* Check MC status */
209 do {
210 if (time_after(jiffies, timeout)) {
211 mfc_err("Timeout while resetting MFC\n");
212 return -EIO;
213 }
214
215 mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);
216
217 } while (mc_status & 0x3);
218
219 mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
220 mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
221 }
184 222
185 mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
186 mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
187 mfc_debug_leave(); 223 mfc_debug_leave();
188 return 0; 224 return 0;
189} 225}
190 226
191static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev) 227static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev)
192{ 228{
193 mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A); 229 if (IS_MFCV6(dev)) {
194 mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B); 230 mfc_write(dev, dev->bank1, S5P_FIMV_RISC_BASE_ADDRESS_V6);
195 mfc_debug(2, "Bank1: %08x, Bank2: %08x\n", dev->bank1, dev->bank2); 231 mfc_debug(2, "Base Address : %08x\n", dev->bank1);
232 } else {
233 mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A);
234 mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B);
235 mfc_debug(2, "Bank1: %08x, Bank2: %08x\n",
236 dev->bank1, dev->bank2);
237 }
196} 238}
197 239
198static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev) 240static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev)
199{ 241{
200 mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID); 242 if (IS_MFCV6(dev)) {
201 mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID); 243 /* Zero initialization should be done before RESET.
202 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD); 244 * Nothing to do here. */
203 mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD); 245 } else {
246 mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
247 mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
248 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
249 mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD);
250 }
204} 251}
205 252
206/* Initialize hardware */ 253/* Initialize hardware */
@@ -228,9 +275,12 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
228 s5p_mfc_clear_cmds(dev); 275 s5p_mfc_clear_cmds(dev);
229 /* 3. Release reset signal to the RISC */ 276 /* 3. Release reset signal to the RISC */
230 s5p_mfc_clean_dev_int_flags(dev); 277 s5p_mfc_clean_dev_int_flags(dev);
231 mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); 278 if (IS_MFCV6(dev))
279 mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
280 else
281 mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
232 mfc_debug(2, "Will now wait for completion of firmware transfer\n"); 282 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)) { 283 if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) {
234 mfc_err("Failed to load firmware\n"); 284 mfc_err("Failed to load firmware\n");
235 s5p_mfc_reset(dev); 285 s5p_mfc_reset(dev);
236 s5p_mfc_clock_off(); 286 s5p_mfc_clock_off();
@@ -238,7 +288,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
238 } 288 }
239 s5p_mfc_clean_dev_int_flags(dev); 289 s5p_mfc_clean_dev_int_flags(dev);
240 /* 4. Initialize firmware */ 290 /* 4. Initialize firmware */
241 ret = s5p_mfc_sys_init_cmd(dev); 291 ret = s5p_mfc_hw_call(dev->mfc_cmds, sys_init_cmd, dev);
242 if (ret) { 292 if (ret) {
243 mfc_err("Failed to send command to MFC - timeout\n"); 293 mfc_err("Failed to send command to MFC - timeout\n");
244 s5p_mfc_reset(dev); 294 s5p_mfc_reset(dev);
@@ -246,7 +296,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
246 return ret; 296 return ret;
247 } 297 }
248 mfc_debug(2, "Ok, now will write a command to init the system\n"); 298 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)) { 299 if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SYS_INIT_RET)) {
250 mfc_err("Failed to load firmware\n"); 300 mfc_err("Failed to load firmware\n");
251 s5p_mfc_reset(dev); 301 s5p_mfc_reset(dev);
252 s5p_mfc_clock_off(); 302 s5p_mfc_clock_off();
@@ -254,7 +304,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
254 } 304 }
255 dev->int_cond = 0; 305 dev->int_cond = 0;
256 if (dev->int_err != 0 || dev->int_type != 306 if (dev->int_err != 0 || dev->int_type !=
257 S5P_FIMV_R2H_CMD_SYS_INIT_RET) { 307 S5P_MFC_R2H_CMD_SYS_INIT_RET) {
258 /* Failure. */ 308 /* Failure. */
259 mfc_err("Failed to init firmware - error: %d int: %d\n", 309 mfc_err("Failed to init firmware - error: %d int: %d\n",
260 dev->int_err, dev->int_type); 310 dev->int_err, dev->int_type);
@@ -262,7 +312,11 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
262 s5p_mfc_clock_off(); 312 s5p_mfc_clock_off();
263 return -EIO; 313 return -EIO;
264 } 314 }
265 ver = mfc_read(dev, S5P_FIMV_FW_VERSION); 315 if (IS_MFCV6(dev))
316 ver = mfc_read(dev, S5P_FIMV_FW_VERSION_V6);
317 else
318 ver = mfc_read(dev, S5P_FIMV_FW_VERSION);
319
266 mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n", 320 mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n",
267 (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF); 321 (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
268 s5p_mfc_clock_off(); 322 s5p_mfc_clock_off();
@@ -271,6 +325,17 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
271} 325}
272 326
273 327
328/* Deinitialize hardware */
329void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev)
330{
331 s5p_mfc_clock_on();
332
333 s5p_mfc_reset(dev);
334 s5p_mfc_hw_call(dev->mfc_ops, release_dev_context_buffer, dev);
335
336 s5p_mfc_clock_off();
337}
338
274int s5p_mfc_sleep(struct s5p_mfc_dev *dev) 339int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
275{ 340{
276 int ret; 341 int ret;
@@ -278,19 +343,19 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
278 mfc_debug_enter(); 343 mfc_debug_enter();
279 s5p_mfc_clock_on(); 344 s5p_mfc_clock_on();
280 s5p_mfc_clean_dev_int_flags(dev); 345 s5p_mfc_clean_dev_int_flags(dev);
281 ret = s5p_mfc_sleep_cmd(dev); 346 ret = s5p_mfc_hw_call(dev->mfc_cmds, sleep_cmd, dev);
282 if (ret) { 347 if (ret) {
283 mfc_err("Failed to send command to MFC - timeout\n"); 348 mfc_err("Failed to send command to MFC - timeout\n");
284 return ret; 349 return ret;
285 } 350 }
286 if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SLEEP_RET)) { 351 if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SLEEP_RET)) {
287 mfc_err("Failed to sleep\n"); 352 mfc_err("Failed to sleep\n");
288 return -EIO; 353 return -EIO;
289 } 354 }
290 s5p_mfc_clock_off(); 355 s5p_mfc_clock_off();
291 dev->int_cond = 0; 356 dev->int_cond = 0;
292 if (dev->int_err != 0 || dev->int_type != 357 if (dev->int_err != 0 || dev->int_type !=
293 S5P_FIMV_R2H_CMD_SLEEP_RET) { 358 S5P_MFC_R2H_CMD_SLEEP_RET) {
294 /* Failure. */ 359 /* Failure. */
295 mfc_err("Failed to sleep - error: %d int: %d\n", dev->int_err, 360 mfc_err("Failed to sleep - error: %d int: %d\n", dev->int_err,
296 dev->int_type); 361 dev->int_type);
@@ -320,22 +385,25 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
320 s5p_mfc_clear_cmds(dev); 385 s5p_mfc_clear_cmds(dev);
321 s5p_mfc_clean_dev_int_flags(dev); 386 s5p_mfc_clean_dev_int_flags(dev);
322 /* 3. Initialize firmware */ 387 /* 3. Initialize firmware */
323 ret = s5p_mfc_wakeup_cmd(dev); 388 ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev);
324 if (ret) { 389 if (ret) {
325 mfc_err("Failed to send command to MFC - timeout\n"); 390 mfc_err("Failed to send command to MFC - timeout\n");
326 return ret; 391 return ret;
327 } 392 }
328 /* 4. Release reset signal to the RISC */ 393 /* 4. Release reset signal to the RISC */
329 mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); 394 if (IS_MFCV6(dev))
395 mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
396 else
397 mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
330 mfc_debug(2, "Ok, now will write a command to wakeup the system\n"); 398 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)) { 399 if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) {
332 mfc_err("Failed to load firmware\n"); 400 mfc_err("Failed to load firmware\n");
333 return -EIO; 401 return -EIO;
334 } 402 }
335 s5p_mfc_clock_off(); 403 s5p_mfc_clock_off();
336 dev->int_cond = 0; 404 dev->int_cond = 0;
337 if (dev->int_err != 0 || dev->int_type != 405 if (dev->int_err != 0 || dev->int_type !=
338 S5P_FIMV_R2H_CMD_WAKEUP_RET) { 406 S5P_MFC_R2H_CMD_WAKEUP_RET) {
339 /* Failure. */ 407 /* Failure. */
340 mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err, 408 mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err,
341 dev->int_type); 409 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);
20int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev); 20int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev);
21 21
22int s5p_mfc_init_hw(struct s5p_mfc_dev *dev); 22int s5p_mfc_init_hw(struct s5p_mfc_dev *dev);
23void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev);
23 24
24int s5p_mfc_sleep(struct s5p_mfc_dev *dev); 25int s5p_mfc_sleep(struct s5p_mfc_dev *dev);
25int s5p_mfc_wakeup(struct s5p_mfc_dev *dev); 26int 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 6ee21bb71398..eb6a70b0f821 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
@@ -23,85 +23,114 @@
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.h" 30#include "s5p_mfc_opr.h"
32#include "s5p_mfc_pm.h" 31#include "s5p_mfc_pm.h"
33#include "s5p_mfc_shm.h" 32
33#define DEF_SRC_FMT_DEC V4L2_PIX_FMT_H264
34#define DEF_DST_FMT_DEC V4L2_PIX_FMT_NV12MT_16X16
34 35
35static struct s5p_mfc_fmt formats[] = { 36static struct s5p_mfc_fmt formats[] = {
36 { 37 {
38 .name = "4:2:0 2 Planes 16x16 Tiles",
39 .fourcc = V4L2_PIX_FMT_NV12MT_16X16,
40 .codec_mode = S5P_MFC_CODEC_NONE,
41 .type = MFC_FMT_RAW,
42 .num_planes = 2,
43 },
44 {
37 .name = "4:2:0 2 Planes 64x32 Tiles", 45 .name = "4:2:0 2 Planes 64x32 Tiles",
38 .fourcc = V4L2_PIX_FMT_NV12MT, 46 .fourcc = V4L2_PIX_FMT_NV12MT,
39 .codec_mode = S5P_FIMV_CODEC_NONE, 47 .codec_mode = S5P_MFC_CODEC_NONE,
40 .type = MFC_FMT_RAW, 48 .type = MFC_FMT_RAW,
41 .num_planes = 2, 49 .num_planes = 2,
42 }, 50 },
43 { 51 {
44 .name = "4:2:0 2 Planes", 52 .name = "4:2:0 2 Planes Y/CbCr",
45 .fourcc = V4L2_PIX_FMT_NV12M, 53 .fourcc = V4L2_PIX_FMT_NV12M,
46 .codec_mode = S5P_FIMV_CODEC_NONE, 54 .codec_mode = S5P_MFC_CODEC_NONE,
47 .type = MFC_FMT_RAW, 55 .type = MFC_FMT_RAW,
48 .num_planes = 2, 56 .num_planes = 2,
57 },
58 {
59 .name = "4:2:0 2 Planes Y/CrCb",
60 .fourcc = V4L2_PIX_FMT_NV21M,
61 .codec_mode = S5P_MFC_CODEC_NONE,
62 .type = MFC_FMT_RAW,
63 .num_planes = 2,
49 }, 64 },
50 { 65 {
51 .name = "H264 Encoded Stream", 66 .name = "H264 Encoded Stream",
52 .fourcc = V4L2_PIX_FMT_H264, 67 .fourcc = V4L2_PIX_FMT_H264,
53 .codec_mode = S5P_FIMV_CODEC_H264_DEC, 68 .codec_mode = S5P_MFC_CODEC_H264_DEC,
54 .type = MFC_FMT_DEC, 69 .type = MFC_FMT_DEC,
55 .num_planes = 1, 70 .num_planes = 1,
56 }, 71 },
57 { 72 {
58 .name = "H263 Encoded Stream", 73 .name = "H264/MVC Encoded Stream",
59 .fourcc = V4L2_PIX_FMT_H263, 74 .fourcc = V4L2_PIX_FMT_H264_MVC,
60 .codec_mode = S5P_FIMV_CODEC_H263_DEC, 75 .codec_mode = S5P_MFC_CODEC_H264_MVC_DEC,
61 .type = MFC_FMT_DEC, 76 .type = MFC_FMT_DEC,
62 .num_planes = 1, 77 .num_planes = 1,
63 }, 78 },
64 { 79 {
65 .name = "MPEG1 Encoded Stream", 80 .name = "H263 Encoded Stream",
66 .fourcc = V4L2_PIX_FMT_MPEG1, 81 .fourcc = V4L2_PIX_FMT_H263,
67 .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC, 82 .codec_mode = S5P_MFC_CODEC_H263_DEC,
68 .type = MFC_FMT_DEC, 83 .type = MFC_FMT_DEC,
69 .num_planes = 1, 84 .num_planes = 1,
70 }, 85 },
71 { 86 {
72 .name = "MPEG2 Encoded Stream", 87 .name = "MPEG1 Encoded Stream",
73 .fourcc = V4L2_PIX_FMT_MPEG2, 88 .fourcc = V4L2_PIX_FMT_MPEG1,
74 .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC, 89 .codec_mode = S5P_MFC_CODEC_MPEG2_DEC,
75 .type = MFC_FMT_DEC, 90 .type = MFC_FMT_DEC,
76 .num_planes = 1, 91 .num_planes = 1,
77 }, 92 },
78 { 93 {
79 .name = "MPEG4 Encoded Stream", 94 .name = "MPEG2 Encoded Stream",
80 .fourcc = V4L2_PIX_FMT_MPEG4, 95 .fourcc = V4L2_PIX_FMT_MPEG2,
81 .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC, 96 .codec_mode = S5P_MFC_CODEC_MPEG2_DEC,
82 .type = MFC_FMT_DEC, 97 .type = MFC_FMT_DEC,
83 .num_planes = 1, 98 .num_planes = 1,
84 }, 99 },
85 { 100 {
86 .name = "XviD Encoded Stream", 101 .name = "MPEG4 Encoded Stream",
87 .fourcc = V4L2_PIX_FMT_XVID, 102 .fourcc = V4L2_PIX_FMT_MPEG4,
88 .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC, 103 .codec_mode = S5P_MFC_CODEC_MPEG4_DEC,
89 .type = MFC_FMT_DEC, 104 .type = MFC_FMT_DEC,
90 .num_planes = 1, 105 .num_planes = 1,
91 }, 106 },
92 { 107 {
93 .name = "VC1 Encoded Stream", 108 .name = "XviD Encoded Stream",
94 .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G, 109 .fourcc = V4L2_PIX_FMT_XVID,
95 .codec_mode = S5P_FIMV_CODEC_VC1_DEC, 110 .codec_mode = S5P_MFC_CODEC_MPEG4_DEC,
96 .type = MFC_FMT_DEC, 111 .type = MFC_FMT_DEC,
97 .num_planes = 1, 112 .num_planes = 1,
98 }, 113 },
99 { 114 {
100 .name = "VC1 RCV Encoded Stream", 115 .name = "VC1 Encoded Stream",
101 .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L, 116 .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
102 .codec_mode = S5P_FIMV_CODEC_VC1RCV_DEC, 117 .codec_mode = S5P_MFC_CODEC_VC1_DEC,
103 .type = MFC_FMT_DEC, 118 .type = MFC_FMT_DEC,
104 .num_planes = 1, 119 .num_planes = 1,
120 },
121 {
122 .name = "VC1 RCV Encoded Stream",
123 .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
124 .codec_mode = S5P_MFC_CODEC_VC1RCV_DEC,
125 .type = MFC_FMT_DEC,
126 .num_planes = 1,
127 },
128 {
129 .name = "VP8 Encoded Stream",
130 .fourcc = V4L2_PIX_FMT_VP8,
131 .codec_mode = S5P_MFC_CODEC_VP8_DEC,
132 .type = MFC_FMT_DEC,
133 .num_planes = 1,
105 }, 134 },
106}; 135};
107 136
@@ -297,7 +326,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
297 /* If the MFC is parsing the header, 326 /* If the MFC is parsing the header,
298 * so wait until it is finished */ 327 * so wait until it is finished */
299 s5p_mfc_clean_ctx_int_flags(ctx); 328 s5p_mfc_clean_ctx_int_flags(ctx);
300 s5p_mfc_wait_for_done_ctx(ctx, S5P_FIMV_R2H_CMD_SEQ_DONE_RET, 329 s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_SEQ_DONE_RET,
301 0); 330 0);
302 } 331 }
303 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 332 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
@@ -342,21 +371,36 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
342/* Try format */ 371/* Try format */
343static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) 372static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
344{ 373{
374 struct s5p_mfc_dev *dev = video_drvdata(file);
345 struct s5p_mfc_fmt *fmt; 375 struct s5p_mfc_fmt *fmt;
346 376
347 if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 377 mfc_debug(2, "Type is %d\n", f->type);
348 mfc_err("This node supports decoding only\n"); 378 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
349 return -EINVAL; 379 fmt = find_format(f, MFC_FMT_DEC);
350 } 380 if (!fmt) {
351 fmt = find_format(f, MFC_FMT_DEC); 381 mfc_err("Unsupported format for source.\n");
352 if (!fmt) { 382 return -EINVAL;
353 mfc_err("Unsupported format\n"); 383 }
354 return -EINVAL; 384 if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
355 } 385 mfc_err("Not supported format.\n");
356 if (fmt->type != MFC_FMT_DEC) { 386 return -EINVAL;
357 mfc_err("\n"); 387 }
358 return -EINVAL; 388 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
389 fmt = find_format(f, MFC_FMT_RAW);
390 if (!fmt) {
391 mfc_err("Unsupported format for destination.\n");
392 return -EINVAL;
393 }
394 if (IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
395 mfc_err("Not supported format.\n");
396 return -EINVAL;
397 } else if (!IS_MFCV6(dev) &&
398 (fmt->fourcc != V4L2_PIX_FMT_NV12MT)) {
399 mfc_err("Not supported format.\n");
400 return -EINVAL;
401 }
359 } 402 }
403
360 return 0; 404 return 0;
361} 405}
362 406
@@ -379,8 +423,29 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
379 ret = -EBUSY; 423 ret = -EBUSY;
380 goto out; 424 goto out;
381 } 425 }
426 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
427 fmt = find_format(f, MFC_FMT_RAW);
428 if (!fmt) {
429 mfc_err("Unsupported format for source.\n");
430 return -EINVAL;
431 }
432 if (!IS_MFCV6(dev) && (fmt->fourcc != V4L2_PIX_FMT_NV12MT)) {
433 mfc_err("Not supported format.\n");
434 return -EINVAL;
435 } else if (IS_MFCV6(dev) &&
436 (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
437 mfc_err("Not supported format.\n");
438 return -EINVAL;
439 }
440 ctx->dst_fmt = fmt;
441 mfc_debug_leave();
442 return ret;
443 } else if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
444 mfc_err("Wrong type error for S_FMT : %d", f->type);
445 return -EINVAL;
446 }
382 fmt = find_format(f, MFC_FMT_DEC); 447 fmt = find_format(f, MFC_FMT_DEC);
383 if (!fmt || fmt->codec_mode == S5P_FIMV_CODEC_NONE) { 448 if (!fmt || fmt->codec_mode == S5P_MFC_CODEC_NONE) {
384 mfc_err("Unknown codec\n"); 449 mfc_err("Unknown codec\n");
385 ret = -EINVAL; 450 ret = -EINVAL;
386 goto out; 451 goto out;
@@ -391,6 +456,10 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
391 ret = -EINVAL; 456 ret = -EINVAL;
392 goto out; 457 goto out;
393 } 458 }
459 if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
460 mfc_err("Not supported format.\n");
461 return -EINVAL;
462 }
394 ctx->src_fmt = fmt; 463 ctx->src_fmt = fmt;
395 ctx->codec_mode = fmt->codec_mode; 464 ctx->codec_mode = fmt->codec_mode;
396 mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode); 465 mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
@@ -476,7 +545,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
476 return -ENOMEM; 545 return -ENOMEM;
477 } 546 }
478 ctx->total_dpb_count = reqbufs->count; 547 ctx->total_dpb_count = reqbufs->count;
479 ret = s5p_mfc_alloc_codec_buffers(ctx); 548 ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_codec_buffers, ctx);
480 if (ret) { 549 if (ret) {
481 mfc_err("Failed to allocate decoding buffers\n"); 550 mfc_err("Failed to allocate decoding buffers\n");
482 reqbufs->count = 0; 551 reqbufs->count = 0;
@@ -492,15 +561,16 @@ static int vidioc_reqbufs(struct file *file, void *priv,
492 reqbufs->count = 0; 561 reqbufs->count = 0;
493 s5p_mfc_clock_on(); 562 s5p_mfc_clock_on();
494 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); 563 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
495 s5p_mfc_release_codec_buffers(ctx); 564 s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers,
565 ctx);
496 s5p_mfc_clock_off(); 566 s5p_mfc_clock_off();
497 return -ENOMEM; 567 return -ENOMEM;
498 } 568 }
499 if (s5p_mfc_ctx_ready(ctx)) 569 if (s5p_mfc_ctx_ready(ctx))
500 set_work_bit_irqsave(ctx); 570 set_work_bit_irqsave(ctx);
501 s5p_mfc_try_run(dev); 571 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
502 s5p_mfc_wait_for_done_ctx(ctx, 572 s5p_mfc_wait_for_done_ctx(ctx,
503 S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET, 0); 573 S5P_MFC_R2H_CMD_INIT_BUFFERS_RET, 0);
504 } 574 }
505 return ret; 575 return ret;
506} 576}
@@ -582,18 +652,22 @@ static int vidioc_streamon(struct file *file, void *priv,
582 ctx->src_bufs_cnt = 0; 652 ctx->src_bufs_cnt = 0;
583 ctx->capture_state = QUEUE_FREE; 653 ctx->capture_state = QUEUE_FREE;
584 ctx->output_state = QUEUE_FREE; 654 ctx->output_state = QUEUE_FREE;
585 s5p_mfc_alloc_instance_buffer(ctx); 655 s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer,
586 s5p_mfc_alloc_dec_temp_buffers(ctx); 656 ctx);
657 s5p_mfc_hw_call(dev->mfc_ops, alloc_dec_temp_buffers,
658 ctx);
587 set_work_bit_irqsave(ctx); 659 set_work_bit_irqsave(ctx);
588 s5p_mfc_clean_ctx_int_flags(ctx); 660 s5p_mfc_clean_ctx_int_flags(ctx);
589 s5p_mfc_try_run(dev); 661 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
590 662
591 if (s5p_mfc_wait_for_done_ctx(ctx, 663 if (s5p_mfc_wait_for_done_ctx(ctx,
592 S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET, 0)) { 664 S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) {
593 /* Error or timeout */ 665 /* Error or timeout */
594 mfc_err("Error getting instance from hardware\n"); 666 mfc_err("Error getting instance from hardware\n");
595 s5p_mfc_release_instance_buffer(ctx); 667 s5p_mfc_hw_call(dev->mfc_ops,
596 s5p_mfc_release_dec_desc_buffer(ctx); 668 release_instance_buffer, ctx);
669 s5p_mfc_hw_call(dev->mfc_ops,
670 release_dec_desc_buffer, ctx);
597 return -EIO; 671 return -EIO;
598 } 672 }
599 mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); 673 mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
@@ -662,7 +736,7 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl)
662 /* Should wait for the header to be parsed */ 736 /* Should wait for the header to be parsed */
663 s5p_mfc_clean_ctx_int_flags(ctx); 737 s5p_mfc_clean_ctx_int_flags(ctx);
664 s5p_mfc_wait_for_done_ctx(ctx, 738 s5p_mfc_wait_for_done_ctx(ctx,
665 S5P_FIMV_R2H_CMD_SEQ_DONE_RET, 0); 739 S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0);
666 if (ctx->state >= MFCINST_HEAD_PARSED && 740 if (ctx->state >= MFCINST_HEAD_PARSED &&
667 ctx->state < MFCINST_ABORT) { 741 ctx->state < MFCINST_ABORT) {
668 ctrl->val = ctx->dpb_count; 742 ctrl->val = ctx->dpb_count;
@@ -686,6 +760,7 @@ static int vidioc_g_crop(struct file *file, void *priv,
686 struct v4l2_crop *cr) 760 struct v4l2_crop *cr)
687{ 761{
688 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); 762 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
763 struct s5p_mfc_dev *dev = ctx->dev;
689 u32 left, right, top, bottom; 764 u32 left, right, top, bottom;
690 765
691 if (ctx->state != MFCINST_HEAD_PARSED && 766 if (ctx->state != MFCINST_HEAD_PARSED &&
@@ -695,10 +770,10 @@ static int vidioc_g_crop(struct file *file, void *priv,
695 return -EINVAL; 770 return -EINVAL;
696 } 771 }
697 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264) { 772 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264) {
698 left = s5p_mfc_read_shm(ctx, CROP_INFO_H); 773 left = s5p_mfc_hw_call(dev->mfc_ops, get_crop_info_h, ctx);
699 right = left >> S5P_FIMV_SHARED_CROP_RIGHT_SHIFT; 774 right = left >> S5P_FIMV_SHARED_CROP_RIGHT_SHIFT;
700 left = left & S5P_FIMV_SHARED_CROP_LEFT_MASK; 775 left = left & S5P_FIMV_SHARED_CROP_LEFT_MASK;
701 top = s5p_mfc_read_shm(ctx, CROP_INFO_V); 776 top = s5p_mfc_hw_call(dev->mfc_ops, get_crop_info_v, ctx);
702 bottom = top >> S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT; 777 bottom = top >> S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT;
703 top = top & S5P_FIMV_SHARED_CROP_TOP_MASK; 778 top = top & S5P_FIMV_SHARED_CROP_TOP_MASK;
704 cr->c.left = left; 779 cr->c.left = left;
@@ -749,6 +824,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
749 void *allocators[]) 824 void *allocators[])
750{ 825{
751 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); 826 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
827 struct s5p_mfc_dev *dev = ctx->dev;
752 828
753 /* Video output for decoding (source) 829 /* Video output for decoding (source)
754 * this can be set after getting an instance */ 830 * this can be set after getting an instance */
@@ -784,7 +860,13 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
784 vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 860 vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
785 psize[0] = ctx->luma_size; 861 psize[0] = ctx->luma_size;
786 psize[1] = ctx->chroma_size; 862 psize[1] = ctx->chroma_size;
787 allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX]; 863
864 if (IS_MFCV6(dev))
865 allocators[0] =
866 ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
867 else
868 allocators[0] =
869 ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
788 allocators[1] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX]; 870 allocators[1] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
789 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 871 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
790 ctx->state == MFCINST_INIT) { 872 ctx->state == MFCINST_INIT) {
@@ -876,7 +958,7 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
876 /* If context is ready then dev = work->data;schedule it to run */ 958 /* If context is ready then dev = work->data;schedule it to run */
877 if (s5p_mfc_ctx_ready(ctx)) 959 if (s5p_mfc_ctx_ready(ctx))
878 set_work_bit_irqsave(ctx); 960 set_work_bit_irqsave(ctx);
879 s5p_mfc_try_run(dev); 961 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
880 return 0; 962 return 0;
881} 963}
882 964
@@ -892,19 +974,21 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
892 dev->curr_ctx == ctx->num && dev->hw_lock) { 974 dev->curr_ctx == ctx->num && dev->hw_lock) {
893 ctx->state = MFCINST_ABORT; 975 ctx->state = MFCINST_ABORT;
894 s5p_mfc_wait_for_done_ctx(ctx, 976 s5p_mfc_wait_for_done_ctx(ctx,
895 S5P_FIMV_R2H_CMD_FRAME_DONE_RET, 0); 977 S5P_MFC_R2H_CMD_FRAME_DONE_RET, 0);
896 aborted = 1; 978 aborted = 1;
897 } 979 }
898 spin_lock_irqsave(&dev->irqlock, flags); 980 spin_lock_irqsave(&dev->irqlock, flags);
899 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 981 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
900 s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst); 982 s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
983 &ctx->vq_dst);
901 INIT_LIST_HEAD(&ctx->dst_queue); 984 INIT_LIST_HEAD(&ctx->dst_queue);
902 ctx->dst_queue_cnt = 0; 985 ctx->dst_queue_cnt = 0;
903 ctx->dpb_flush_flag = 1; 986 ctx->dpb_flush_flag = 1;
904 ctx->dec_dst_flag = 0; 987 ctx->dec_dst_flag = 0;
905 } 988 }
906 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 989 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
907 s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src); 990 s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
991 &ctx->vq_src);
908 INIT_LIST_HEAD(&ctx->src_queue); 992 INIT_LIST_HEAD(&ctx->src_queue);
909 ctx->src_queue_cnt = 0; 993 ctx->src_queue_cnt = 0;
910 } 994 }
@@ -944,7 +1028,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
944 } 1028 }
945 if (s5p_mfc_ctx_ready(ctx)) 1029 if (s5p_mfc_ctx_ready(ctx))
946 set_work_bit_irqsave(ctx); 1030 set_work_bit_irqsave(ctx);
947 s5p_mfc_try_run(dev); 1031 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
948} 1032}
949 1033
950static struct vb2_ops s5p_mfc_dec_qops = { 1034static struct vb2_ops s5p_mfc_dec_qops = {
@@ -1028,3 +1112,13 @@ void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx)
1028 ctx->ctrls[i] = NULL; 1112 ctx->ctrls[i] = NULL;
1029} 1113}
1030 1114
1115void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx)
1116{
1117 struct v4l2_format f;
1118 f.fmt.pix_mp.pixelformat = DEF_SRC_FMT_DEC;
1119 ctx->src_fmt = find_format(&f, MFC_FMT_DEC);
1120 f.fmt.pix_mp.pixelformat = DEF_DST_FMT_DEC;
1121 ctx->dst_fmt = find_format(&f, MFC_FMT_RAW);
1122 mfc_debug(2, "Default src_fmt is %x, dest_fmt is %x\n",
1123 (unsigned int)ctx->src_fmt, (unsigned int)ctx->dst_fmt);
1124}
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);
19struct s5p_mfc_fmt *get_dec_def_fmt(bool src); 19struct s5p_mfc_fmt *get_dec_def_fmt(bool src);
20int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx); 20int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx);
21void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx); 21void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx);
22void 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 179e4db60b15..2af6d522f4ac 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -25,48 +25,64 @@
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.h" 32#include "s5p_mfc_opr.h"
34 33
34#define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12MT
35#define DEF_DST_FMT_ENC V4L2_PIX_FMT_H264
36
35static struct s5p_mfc_fmt formats[] = { 37static struct s5p_mfc_fmt formats[] = {
36 { 38 {
37 .name = "4:2:0 2 Planes 64x32 Tiles", 39 .name = "4:2:0 2 Planes 16x16 Tiles",
38 .fourcc = V4L2_PIX_FMT_NV12MT, 40 .fourcc = V4L2_PIX_FMT_NV12MT_16X16,
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,
44 },
45 {
46 .name = "4:2:0 2 Planes 64x32 Tiles",
47 .fourcc = V4L2_PIX_FMT_NV12MT,
48 .codec_mode = S5P_MFC_CODEC_NONE,
49 .type = MFC_FMT_RAW,
50 .num_planes = 2,
51 },
52 {
53 .name = "4:2:0 2 Planes Y/CbCr",
54 .fourcc = V4L2_PIX_FMT_NV12M,
55 .codec_mode = S5P_MFC_CODEC_NONE,
56 .type = MFC_FMT_RAW,
57 .num_planes = 2,
42 }, 58 },
43 { 59 {
44 .name = "4:2:0 2 Planes", 60 .name = "4:2:0 2 Planes Y/CrCb",
45 .fourcc = V4L2_PIX_FMT_NV12M, 61 .fourcc = V4L2_PIX_FMT_NV21M,
46 .codec_mode = S5P_FIMV_CODEC_NONE, 62 .codec_mode = S5P_MFC_CODEC_NONE,
47 .type = MFC_FMT_RAW, 63 .type = MFC_FMT_RAW,
48 .num_planes = 2, 64 .num_planes = 2,
49 }, 65 },
50 { 66 {
51 .name = "H264 Encoded Stream", 67 .name = "H264 Encoded Stream",
52 .fourcc = V4L2_PIX_FMT_H264, 68 .fourcc = V4L2_PIX_FMT_H264,
53 .codec_mode = S5P_FIMV_CODEC_H264_ENC, 69 .codec_mode = S5P_MFC_CODEC_H264_ENC,
54 .type = MFC_FMT_ENC, 70 .type = MFC_FMT_ENC,
55 .num_planes = 1, 71 .num_planes = 1,
56 }, 72 },
57 { 73 {
58 .name = "MPEG4 Encoded Stream", 74 .name = "MPEG4 Encoded Stream",
59 .fourcc = V4L2_PIX_FMT_MPEG4, 75 .fourcc = V4L2_PIX_FMT_MPEG4,
60 .codec_mode = S5P_FIMV_CODEC_MPEG4_ENC, 76 .codec_mode = S5P_MFC_CODEC_MPEG4_ENC,
61 .type = MFC_FMT_ENC, 77 .type = MFC_FMT_ENC,
62 .num_planes = 1, 78 .num_planes = 1,
63 }, 79 },
64 { 80 {
65 .name = "H263 Encoded Stream", 81 .name = "H263 Encoded Stream",
66 .fourcc = V4L2_PIX_FMT_H263, 82 .fourcc = V4L2_PIX_FMT_H263,
67 .codec_mode = S5P_FIMV_CODEC_H263_ENC, 83 .codec_mode = S5P_MFC_CODEC_H263_ENC,
68 .type = MFC_FMT_ENC, 84 .type = MFC_FMT_ENC,
69 .num_planes = 1, 85 .num_planes = 1,
70 }, 86 },
71}; 87};
72 88
@@ -574,7 +590,8 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
574 if (ctx->state == MFCINST_GOT_INST && ctx->dst_queue_cnt >= 1) 590 if (ctx->state == MFCINST_GOT_INST && ctx->dst_queue_cnt >= 1)
575 return 1; 591 return 1;
576 /* context is ready to encode a frame */ 592 /* context is ready to encode a frame */
577 if (ctx->state == MFCINST_RUNNING && 593 if ((ctx->state == MFCINST_RUNNING ||
594 ctx->state == MFCINST_HEAD_PARSED) &&
578 ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1) 595 ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
579 return 1; 596 return 1;
580 /* context is ready to encode remaining frames */ 597 /* context is ready to encode remaining frames */
@@ -619,7 +636,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); 636 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); 637 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
621 dst_size = vb2_plane_size(dst_mb->b, 0); 638 dst_size = vb2_plane_size(dst_mb->b, 0);
622 s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size); 639 s5p_mfc_hw_call(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr,
640 dst_size);
623 spin_unlock_irqrestore(&dev->irqlock, flags); 641 spin_unlock_irqrestore(&dev->irqlock, flags);
624 return 0; 642 return 0;
625} 643}
@@ -638,14 +656,23 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
638 list_del(&dst_mb->list); 656 list_del(&dst_mb->list);
639 ctx->dst_queue_cnt--; 657 ctx->dst_queue_cnt--;
640 vb2_set_plane_payload(dst_mb->b, 0, 658 vb2_set_plane_payload(dst_mb->b, 0,
641 s5p_mfc_get_enc_strm_size()); 659 s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev));
642 vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); 660 vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE);
643 spin_unlock_irqrestore(&dev->irqlock, flags); 661 spin_unlock_irqrestore(&dev->irqlock, flags);
644 } 662 }
645 ctx->state = MFCINST_RUNNING; 663 if (IS_MFCV6(dev)) {
646 if (s5p_mfc_ctx_ready(ctx)) 664 ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */
647 set_work_bit_irqsave(ctx); 665 } else {
648 s5p_mfc_try_run(dev); 666 ctx->state = MFCINST_RUNNING;
667 if (s5p_mfc_ctx_ready(ctx))
668 set_work_bit_irqsave(ctx);
669 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
670 }
671
672 if (IS_MFCV6(dev))
673 ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops,
674 get_enc_dpb_count, dev);
675
649 return 0; 676 return 0;
650} 677}
651 678
@@ -662,14 +689,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); 689 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); 690 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); 691 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); 692 s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx, src_y_addr,
693 src_c_addr);
666 spin_unlock_irqrestore(&dev->irqlock, flags); 694 spin_unlock_irqrestore(&dev->irqlock, flags);
667 695
668 spin_lock_irqsave(&dev->irqlock, flags); 696 spin_lock_irqsave(&dev->irqlock, flags);
669 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); 697 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); 698 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
671 dst_size = vb2_plane_size(dst_mb->b, 0); 699 dst_size = vb2_plane_size(dst_mb->b, 0);
672 s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size); 700 s5p_mfc_hw_call(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr,
701 dst_size);
673 spin_unlock_irqrestore(&dev->irqlock, flags); 702 spin_unlock_irqrestore(&dev->irqlock, flags);
674 703
675 return 0; 704 return 0;
@@ -685,15 +714,16 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
685 unsigned int strm_size; 714 unsigned int strm_size;
686 unsigned long flags; 715 unsigned long flags;
687 716
688 slice_type = s5p_mfc_get_enc_slice_type(); 717 slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev);
689 strm_size = s5p_mfc_get_enc_strm_size(); 718 strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev);
690 mfc_debug(2, "Encoded slice type: %d", slice_type); 719 mfc_debug(2, "Encoded slice type: %d", slice_type);
691 mfc_debug(2, "Encoded stream size: %d", strm_size); 720 mfc_debug(2, "Encoded stream size: %d", strm_size);
692 mfc_debug(2, "Display order: %d", 721 mfc_debug(2, "Display order: %d",
693 mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT)); 722 mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
694 spin_lock_irqsave(&dev->irqlock, flags); 723 spin_lock_irqsave(&dev->irqlock, flags);
695 if (slice_type >= 0) { 724 if (slice_type >= 0) {
696 s5p_mfc_get_enc_frame_buffer(ctx, &enc_y_addr, &enc_c_addr); 725 s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx,
726 &enc_y_addr, &enc_c_addr);
697 list_for_each_entry(mb_entry, &ctx->src_queue, list) { 727 list_for_each_entry(mb_entry, &ctx->src_queue, list) {
698 mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0); 728 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); 729 mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1);
@@ -939,15 +969,16 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
939 pix_fmt_mp->plane_fmt[0].bytesperline = 0; 969 pix_fmt_mp->plane_fmt[0].bytesperline = 0;
940 ctx->dst_bufs_cnt = 0; 970 ctx->dst_bufs_cnt = 0;
941 ctx->capture_state = QUEUE_FREE; 971 ctx->capture_state = QUEUE_FREE;
942 s5p_mfc_alloc_instance_buffer(ctx); 972 s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx);
943 set_work_bit_irqsave(ctx); 973 set_work_bit_irqsave(ctx);
944 s5p_mfc_clean_ctx_int_flags(ctx); 974 s5p_mfc_clean_ctx_int_flags(ctx);
945 s5p_mfc_try_run(dev); 975 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
946 if (s5p_mfc_wait_for_done_ctx(ctx, \ 976 if (s5p_mfc_wait_for_done_ctx(ctx, \
947 S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET, 1)) { 977 S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 1)) {
948 /* Error or timeout */ 978 /* Error or timeout */
949 mfc_err("Error getting instance from hardware\n"); 979 mfc_err("Error getting instance from hardware\n");
950 s5p_mfc_release_instance_buffer(ctx); 980 s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer,
981 ctx);
951 ret = -EIO; 982 ret = -EIO;
952 goto out; 983 goto out;
953 } 984 }
@@ -958,6 +989,17 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
958 mfc_err("failed to set output format\n"); 989 mfc_err("failed to set output format\n");
959 return -EINVAL; 990 return -EINVAL;
960 } 991 }
992
993 if (!IS_MFCV6(dev) &&
994 (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)) {
995 mfc_err("Not supported format.\n");
996 return -EINVAL;
997 } else if (IS_MFCV6(dev) &&
998 (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
999 mfc_err("Not supported format.\n");
1000 return -EINVAL;
1001 }
1002
961 if (fmt->num_planes != pix_fmt_mp->num_planes) { 1003 if (fmt->num_planes != pix_fmt_mp->num_planes) {
962 mfc_err("failed to set output format\n"); 1004 mfc_err("failed to set output format\n");
963 ret = -EINVAL; 1005 ret = -EINVAL;
@@ -970,45 +1012,13 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
970 mfc_debug(2, "fmt - w: %d, h: %d, ctx - w: %d, h: %d\n", 1012 mfc_debug(2, "fmt - w: %d, h: %d, ctx - w: %d, h: %d\n",
971 pix_fmt_mp->width, pix_fmt_mp->height, 1013 pix_fmt_mp->width, pix_fmt_mp->height,
972 ctx->img_width, ctx->img_height); 1014 ctx->img_width, ctx->img_height);
973 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) { 1015
974 ctx->buf_width = ALIGN(ctx->img_width, 1016 s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
975 S5P_FIMV_NV12M_HALIGN); 1017 pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
976 ctx->luma_size = ALIGN(ctx->img_width, 1018 pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
977 S5P_FIMV_NV12M_HALIGN) * ALIGN(ctx->img_height, 1019 pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
978 S5P_FIMV_NV12M_LVALIGN); 1020 pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
979 ctx->chroma_size = ALIGN(ctx->img_width, 1021
980 S5P_FIMV_NV12M_HALIGN) * ALIGN((ctx->img_height
981 >> 1), S5P_FIMV_NV12M_CVALIGN);
982
983 ctx->luma_size = ALIGN(ctx->luma_size,
984 S5P_FIMV_NV12M_SALIGN);
985 ctx->chroma_size = ALIGN(ctx->chroma_size,
986 S5P_FIMV_NV12M_SALIGN);
987
988 pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
989 pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
990 pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
991 pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
992
993 } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) {
994 ctx->buf_width = ALIGN(ctx->img_width,
995 S5P_FIMV_NV12MT_HALIGN);
996 ctx->luma_size = ALIGN(ctx->img_width,
997 S5P_FIMV_NV12MT_HALIGN) * ALIGN(ctx->img_height,
998 S5P_FIMV_NV12MT_VALIGN);
999 ctx->chroma_size = ALIGN(ctx->img_width,
1000 S5P_FIMV_NV12MT_HALIGN) * ALIGN((ctx->img_height
1001 >> 1), S5P_FIMV_NV12MT_VALIGN);
1002 ctx->luma_size = ALIGN(ctx->luma_size,
1003 S5P_FIMV_NV12MT_SALIGN);
1004 ctx->chroma_size = ALIGN(ctx->chroma_size,
1005 S5P_FIMV_NV12MT_SALIGN);
1006
1007 pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
1008 pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
1009 pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
1010 pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
1011 }
1012 ctx->src_bufs_cnt = 0; 1022 ctx->src_bufs_cnt = 0;
1013 ctx->output_state = QUEUE_FREE; 1023 ctx->output_state = QUEUE_FREE;
1014 } else { 1024 } else {
@@ -1023,6 +1033,7 @@ out:
1023static int vidioc_reqbufs(struct file *file, void *priv, 1033static int vidioc_reqbufs(struct file *file, void *priv,
1024 struct v4l2_requestbuffers *reqbufs) 1034 struct v4l2_requestbuffers *reqbufs)
1025{ 1035{
1036 struct s5p_mfc_dev *dev = video_drvdata(file);
1026 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); 1037 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
1027 int ret = 0; 1038 int ret = 0;
1028 1039
@@ -1042,12 +1053,16 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1042 return ret; 1053 return ret;
1043 } 1054 }
1044 ctx->capture_state = QUEUE_BUFS_REQUESTED; 1055 ctx->capture_state = QUEUE_BUFS_REQUESTED;
1045 ret = s5p_mfc_alloc_codec_buffers(ctx); 1056
1046 if (ret) { 1057 if (!IS_MFCV6(dev)) {
1047 mfc_err("Failed to allocate encoding buffers\n"); 1058 ret = s5p_mfc_hw_call(ctx->dev->mfc_ops,
1048 reqbufs->count = 0; 1059 alloc_codec_buffers, ctx);
1049 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); 1060 if (ret) {
1050 return -ENOMEM; 1061 mfc_err("Failed to allocate encoding buffers\n");
1062 reqbufs->count = 0;
1063 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
1064 return -ENOMEM;
1065 }
1051 } 1066 }
1052 } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 1067 } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1053 if (ctx->output_state != QUEUE_FREE) { 1068 if (ctx->output_state != QUEUE_FREE) {
@@ -1310,6 +1325,13 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
1310 p->codec.h264.profile = 1325 p->codec.h264.profile =
1311 S5P_FIMV_ENC_PROFILE_H264_BASELINE; 1326 S5P_FIMV_ENC_PROFILE_H264_BASELINE;
1312 break; 1327 break;
1328 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
1329 if (IS_MFCV6(dev))
1330 p->codec.h264.profile =
1331 S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE;
1332 else
1333 ret = -EINVAL;
1334 break;
1313 default: 1335 default:
1314 ret = -EINVAL; 1336 ret = -EINVAL;
1315 } 1337 }
@@ -1349,7 +1371,7 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
1349 p->codec.h264._8x8_transform = ctrl->val; 1371 p->codec.h264._8x8_transform = ctrl->val;
1350 break; 1372 break;
1351 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: 1373 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
1352 p->codec.h264.rc_mb = ctrl->val; 1374 p->rc_mb = ctrl->val;
1353 break; 1375 break;
1354 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: 1376 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
1355 p->codec.h264.rc_frame_qp = ctrl->val; 1377 p->codec.h264.rc_frame_qp = ctrl->val;
@@ -1500,7 +1522,7 @@ int vidioc_encoder_cmd(struct file *file, void *priv,
1500 mfc_debug(2, "EOS: empty src queue, entering finishing state"); 1522 mfc_debug(2, "EOS: empty src queue, entering finishing state");
1501 ctx->state = MFCINST_FINISHING; 1523 ctx->state = MFCINST_FINISHING;
1502 spin_unlock_irqrestore(&dev->irqlock, flags); 1524 spin_unlock_irqrestore(&dev->irqlock, flags);
1503 s5p_mfc_try_run(dev); 1525 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
1504 } else { 1526 } else {
1505 mfc_debug(2, "EOS: marking last buffer of stream"); 1527 mfc_debug(2, "EOS: marking last buffer of stream");
1506 buf = list_entry(ctx->src_queue.prev, 1528 buf = list_entry(ctx->src_queue.prev,
@@ -1583,6 +1605,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
1583 unsigned int psize[], void *allocators[]) 1605 unsigned int psize[], void *allocators[])
1584{ 1606{
1585 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); 1607 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
1608 struct s5p_mfc_dev *dev = ctx->dev;
1586 1609
1587 if (ctx->state != MFCINST_GOT_INST) { 1610 if (ctx->state != MFCINST_GOT_INST) {
1588 mfc_err("inavlid state: %d\n", ctx->state); 1611 mfc_err("inavlid state: %d\n", ctx->state);
@@ -1611,8 +1634,17 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
1611 *buf_count = MFC_MAX_BUFFERS; 1634 *buf_count = MFC_MAX_BUFFERS;
1612 psize[0] = ctx->luma_size; 1635 psize[0] = ctx->luma_size;
1613 psize[1] = ctx->chroma_size; 1636 psize[1] = ctx->chroma_size;
1614 allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX]; 1637 if (IS_MFCV6(dev)) {
1615 allocators[1] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX]; 1638 allocators[0] =
1639 ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
1640 allocators[1] =
1641 ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
1642 } else {
1643 allocators[0] =
1644 ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
1645 allocators[1] =
1646 ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
1647 }
1616 } else { 1648 } else {
1617 mfc_err("inavlid queue type: %d\n", vq->type); 1649 mfc_err("inavlid queue type: %d\n", vq->type);
1618 return -EINVAL; 1650 return -EINVAL;
@@ -1715,7 +1747,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 */ 1747 /* If context is ready then dev = work->data;schedule it to run */
1716 if (s5p_mfc_ctx_ready(ctx)) 1748 if (s5p_mfc_ctx_ready(ctx))
1717 set_work_bit_irqsave(ctx); 1749 set_work_bit_irqsave(ctx);
1718 s5p_mfc_try_run(dev); 1750 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
1719 return 0; 1751 return 0;
1720} 1752}
1721 1753
@@ -1729,19 +1761,21 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
1729 ctx->state == MFCINST_RUNNING) && 1761 ctx->state == MFCINST_RUNNING) &&
1730 dev->curr_ctx == ctx->num && dev->hw_lock) { 1762 dev->curr_ctx == ctx->num && dev->hw_lock) {
1731 ctx->state = MFCINST_ABORT; 1763 ctx->state = MFCINST_ABORT;
1732 s5p_mfc_wait_for_done_ctx(ctx, S5P_FIMV_R2H_CMD_FRAME_DONE_RET, 1764 s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_FRAME_DONE_RET,
1733 0); 1765 0);
1734 } 1766 }
1735 ctx->state = MFCINST_FINISHED; 1767 ctx->state = MFCINST_FINISHED;
1736 spin_lock_irqsave(&dev->irqlock, flags); 1768 spin_lock_irqsave(&dev->irqlock, flags);
1737 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 1769 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1738 s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst); 1770 s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
1771 &ctx->vq_dst);
1739 INIT_LIST_HEAD(&ctx->dst_queue); 1772 INIT_LIST_HEAD(&ctx->dst_queue);
1740 ctx->dst_queue_cnt = 0; 1773 ctx->dst_queue_cnt = 0;
1741 } 1774 }
1742 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 1775 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1743 cleanup_ref_queue(ctx); 1776 cleanup_ref_queue(ctx);
1744 s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src); 1777 s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
1778 &ctx->vq_src);
1745 INIT_LIST_HEAD(&ctx->src_queue); 1779 INIT_LIST_HEAD(&ctx->src_queue);
1746 ctx->src_queue_cnt = 0; 1780 ctx->src_queue_cnt = 0;
1747 } 1781 }
@@ -1782,7 +1816,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
1782 } 1816 }
1783 if (s5p_mfc_ctx_ready(ctx)) 1817 if (s5p_mfc_ctx_ready(ctx))
1784 set_work_bit_irqsave(ctx); 1818 set_work_bit_irqsave(ctx);
1785 s5p_mfc_try_run(dev); 1819 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
1786} 1820}
1787 1821
1788static struct vb2_ops s5p_mfc_enc_qops = { 1822static struct vb2_ops s5p_mfc_enc_qops = {
@@ -1880,3 +1914,13 @@ void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx)
1880 for (i = 0; i < NUM_CTRLS; i++) 1914 for (i = 0; i < NUM_CTRLS; i++)
1881 ctx->ctrls[i] = NULL; 1915 ctx->ctrls[i] = NULL;
1882} 1916}
1917
1918void s5p_mfc_enc_init(struct s5p_mfc_ctx *ctx)
1919{
1920 struct v4l2_format f;
1921 f.fmt.pix_mp.pixelformat = DEF_SRC_FMT_ENC;
1922 ctx->src_fmt = find_format(&f, MFC_FMT_RAW);
1923 f.fmt.pix_mp.pixelformat = DEF_DST_FMT_ENC;
1924 ctx->dst_fmt = find_format(&f, MFC_FMT_ENC);
1925}
1926
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);
19struct s5p_mfc_fmt *get_enc_def_fmt(bool src); 19struct s5p_mfc_fmt *get_enc_def_fmt(bool src);
20int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx); 20int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx);
21void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx); 21void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx);
22void 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
index 767a51271dc2..6932e90d4065 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * drivers/media/platform/samsung/mfc5/s5p_mfc_opr.c 2 * drivers/media/platform/s5p-mfc/s5p_mfc_opr.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.
6 * 6 *
7 * Kamil Debski, Copyright (c) 2011 Samsung Electronics 7 * Kamil Debski, Copyright (c) 2012 Samsung Electronics Co., Ltd.
8 * http://www.samsung.com/ 8 * http://www.samsung.com/
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
@@ -12,1414 +12,20 @@
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.h"
17#include "s5p_mfc_common.h"
18#include "s5p_mfc_ctrl.h"
19#include "s5p_mfc_debug.h"
20#include "s5p_mfc_intr.h"
21#include "s5p_mfc_opr.h" 15#include "s5p_mfc_opr.h"
22#include "s5p_mfc_pm.h" 16#include "s5p_mfc_opr_v5.h"
23#include "s5p_mfc_shm.h" 17#include "s5p_mfc_opr_v6.h"
24#include <asm/cacheflush.h>
25#include <linux/delay.h>
26#include <linux/dma-mapping.h>
27#include <linux/err.h>
28#include <linux/firmware.h>
29#include <linux/io.h>
30#include <linux/jiffies.h>
31#include <linux/mm.h>
32#include <linux/sched.h>
33 18
34#define OFFSETA(x) (((x) - dev->bank1) >> MFC_OFFSET_SHIFT) 19static struct s5p_mfc_hw_ops *s5p_mfc_ops;
35#define OFFSETB(x) (((x) - dev->bank2) >> MFC_OFFSET_SHIFT)
36 20
37/* Allocate temporary buffers for decoding */ 21void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev)
38int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx)
39{ 22{
40 void *desc_virt; 23 if (IS_MFCV6(dev)) {
41 struct s5p_mfc_dev *dev = ctx->dev; 24 s5p_mfc_ops = s5p_mfc_init_hw_ops_v6();
42 25 dev->warn_start = S5P_FIMV_ERR_WARNINGS_START_V6;
43 ctx->desc_buf = vb2_dma_contig_memops.alloc(
44 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], DESC_BUF_SIZE);
45 if (IS_ERR_VALUE((int)ctx->desc_buf)) {
46 ctx->desc_buf = NULL;
47 mfc_err("Allocating DESC buffer failed\n");
48 return -ENOMEM;
49 }
50 ctx->desc_phys = s5p_mfc_mem_cookie(
51 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->desc_buf);
52 BUG_ON(ctx->desc_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
53 desc_virt = vb2_dma_contig_memops.vaddr(ctx->desc_buf);
54 if (desc_virt == NULL) {
55 vb2_dma_contig_memops.put(ctx->desc_buf);
56 ctx->desc_phys = 0;
57 ctx->desc_buf = NULL;
58 mfc_err("Remapping DESC buffer failed\n");
59 return -ENOMEM;
60 }
61 memset(desc_virt, 0, DESC_BUF_SIZE);
62 wmb();
63 return 0;
64}
65
66/* Release temporary buffers for decoding */
67void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
68{
69 if (ctx->desc_phys) {
70 vb2_dma_contig_memops.put(ctx->desc_buf);
71 ctx->desc_phys = 0;
72 ctx->desc_buf = NULL;
73 }
74}
75
76/* Allocate codec buffers */
77int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
78{
79 struct s5p_mfc_dev *dev = ctx->dev;
80 unsigned int enc_ref_y_size = 0;
81 unsigned int enc_ref_c_size = 0;
82 unsigned int guard_width, guard_height;
83
84 if (ctx->type == MFCINST_DECODER) {
85 mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",
86 ctx->luma_size, ctx->chroma_size, ctx->mv_size);
87 mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);
88 } else if (ctx->type == MFCINST_ENCODER) {
89 enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
90 * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
91 enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);
92
93 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) {
94 enc_ref_c_size = ALIGN(ctx->img_width,
95 S5P_FIMV_NV12MT_HALIGN)
96 * ALIGN(ctx->img_height >> 1,
97 S5P_FIMV_NV12MT_VALIGN);
98 enc_ref_c_size = ALIGN(enc_ref_c_size,
99 S5P_FIMV_NV12MT_SALIGN);
100 } else {
101 guard_width = ALIGN(ctx->img_width + 16,
102 S5P_FIMV_NV12MT_HALIGN);
103 guard_height = ALIGN((ctx->img_height >> 1) + 4,
104 S5P_FIMV_NV12MT_VALIGN);
105 enc_ref_c_size = ALIGN(guard_width * guard_height,
106 S5P_FIMV_NV12MT_SALIGN);
107 }
108 mfc_debug(2, "recon luma size: %d chroma size: %d\n",
109 enc_ref_y_size, enc_ref_c_size);
110 } else { 26 } else {
111 return -EINVAL; 27 s5p_mfc_ops = s5p_mfc_init_hw_ops_v5();
112 } 28 dev->warn_start = S5P_FIMV_ERR_WARNINGS_START;
113 /* Codecs have different memory requirements */
114 switch (ctx->codec_mode) {
115 case S5P_FIMV_CODEC_H264_DEC:
116 ctx->bank1_size =
117 ALIGN(S5P_FIMV_DEC_NB_IP_SIZE +
118 S5P_FIMV_DEC_VERT_NB_MV_SIZE,
119 S5P_FIMV_DEC_BUF_ALIGN);
120 ctx->bank2_size = ctx->total_dpb_count * ctx->mv_size;
121 break;
122 case S5P_FIMV_CODEC_MPEG4_DEC:
123 ctx->bank1_size =
124 ALIGN(S5P_FIMV_DEC_NB_DCAC_SIZE +
125 S5P_FIMV_DEC_UPNB_MV_SIZE +
126 S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
127 S5P_FIMV_DEC_STX_PARSER_SIZE +
128 S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE,
129 S5P_FIMV_DEC_BUF_ALIGN);
130 ctx->bank2_size = 0;
131 break;
132 case S5P_FIMV_CODEC_VC1RCV_DEC:
133 case S5P_FIMV_CODEC_VC1_DEC:
134 ctx->bank1_size =
135 ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +
136 S5P_FIMV_DEC_UPNB_MV_SIZE +
137 S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
138 S5P_FIMV_DEC_NB_DCAC_SIZE +
139 3 * S5P_FIMV_DEC_VC1_BITPLANE_SIZE,
140 S5P_FIMV_DEC_BUF_ALIGN);
141 ctx->bank2_size = 0;
142 break;
143 case S5P_FIMV_CODEC_MPEG2_DEC:
144 ctx->bank1_size = 0;
145 ctx->bank2_size = 0;
146 break;
147 case S5P_FIMV_CODEC_H263_DEC:
148 ctx->bank1_size =
149 ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +
150 S5P_FIMV_DEC_UPNB_MV_SIZE +
151 S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
152 S5P_FIMV_DEC_NB_DCAC_SIZE,
153 S5P_FIMV_DEC_BUF_ALIGN);
154 ctx->bank2_size = 0;
155 break;
156 case S5P_FIMV_CODEC_H264_ENC:
157 ctx->bank1_size = (enc_ref_y_size * 2) +
158 S5P_FIMV_ENC_UPMV_SIZE +
159 S5P_FIMV_ENC_COLFLG_SIZE +
160 S5P_FIMV_ENC_INTRAMD_SIZE +
161 S5P_FIMV_ENC_NBORINFO_SIZE;
162 ctx->bank2_size = (enc_ref_y_size * 2) +
163 (enc_ref_c_size * 4) +
164 S5P_FIMV_ENC_INTRAPRED_SIZE;
165 break;
166 case S5P_FIMV_CODEC_MPEG4_ENC:
167 ctx->bank1_size = (enc_ref_y_size * 2) +
168 S5P_FIMV_ENC_UPMV_SIZE +
169 S5P_FIMV_ENC_COLFLG_SIZE +
170 S5P_FIMV_ENC_ACDCCOEF_SIZE;
171 ctx->bank2_size = (enc_ref_y_size * 2) +
172 (enc_ref_c_size * 4);
173 break;
174 case S5P_FIMV_CODEC_H263_ENC:
175 ctx->bank1_size = (enc_ref_y_size * 2) +
176 S5P_FIMV_ENC_UPMV_SIZE +
177 S5P_FIMV_ENC_ACDCCOEF_SIZE;
178 ctx->bank2_size = (enc_ref_y_size * 2) +
179 (enc_ref_c_size * 4);
180 break;
181 default:
182 break;
183 }
184 /* Allocate only if memory from bank 1 is necessary */
185 if (ctx->bank1_size > 0) {
186 ctx->bank1_buf = vb2_dma_contig_memops.alloc(
187 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_size);
188 if (IS_ERR(ctx->bank1_buf)) {
189 ctx->bank1_buf = NULL;
190 printk(KERN_ERR
191 "Buf alloc for decoding failed (port A)\n");
192 return -ENOMEM;
193 }
194 ctx->bank1_phys = s5p_mfc_mem_cookie(
195 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_buf);
196 BUG_ON(ctx->bank1_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
197 }
198 /* Allocate only if memory from bank 2 is necessary */
199 if (ctx->bank2_size > 0) {
200 ctx->bank2_buf = vb2_dma_contig_memops.alloc(
201 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], ctx->bank2_size);
202 if (IS_ERR(ctx->bank2_buf)) {
203 ctx->bank2_buf = NULL;
204 mfc_err("Buf alloc for decoding failed (port B)\n");
205 return -ENOMEM;
206 }
207 ctx->bank2_phys = s5p_mfc_mem_cookie(
208 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], ctx->bank2_buf);
209 BUG_ON(ctx->bank2_phys & ((1 << MFC_BANK2_ALIGN_ORDER) - 1));
210 }
211 return 0;
212}
213
214/* Release buffers allocated for codec */
215void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx)
216{
217 if (ctx->bank1_buf) {
218 vb2_dma_contig_memops.put(ctx->bank1_buf);
219 ctx->bank1_buf = NULL;
220 ctx->bank1_phys = 0;
221 ctx->bank1_size = 0;
222 }
223 if (ctx->bank2_buf) {
224 vb2_dma_contig_memops.put(ctx->bank2_buf);
225 ctx->bank2_buf = NULL;
226 ctx->bank2_phys = 0;
227 ctx->bank2_size = 0;
228 } 29 }
30 dev->mfc_ops = s5p_mfc_ops;
229} 31}
230
231/* Allocate memory for instance data buffer */
232int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx)
233{
234 void *context_virt;
235 struct s5p_mfc_dev *dev = ctx->dev;
236
237 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC ||
238 ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
239 ctx->ctx_size = MFC_H264_CTX_BUF_SIZE;
240 else
241 ctx->ctx_size = MFC_CTX_BUF_SIZE;
242 ctx->ctx_buf = vb2_dma_contig_memops.alloc(
243 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_size);
244 if (IS_ERR(ctx->ctx_buf)) {
245 mfc_err("Allocating context buffer failed\n");
246 ctx->ctx_phys = 0;
247 ctx->ctx_buf = NULL;
248 return -ENOMEM;
249 }
250 ctx->ctx_phys = s5p_mfc_mem_cookie(
251 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_buf);
252 BUG_ON(ctx->ctx_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
253 ctx->ctx_ofs = OFFSETA(ctx->ctx_phys);
254 context_virt = vb2_dma_contig_memops.vaddr(ctx->ctx_buf);
255 if (context_virt == NULL) {
256 mfc_err("Remapping instance buffer failed\n");
257 vb2_dma_contig_memops.put(ctx->ctx_buf);
258 ctx->ctx_phys = 0;
259 ctx->ctx_buf = NULL;
260 return -ENOMEM;
261 }
262 /* Zero content of the allocated memory */
263 memset(context_virt, 0, ctx->ctx_size);
264 wmb();
265 if (s5p_mfc_init_shm(ctx) < 0) {
266 vb2_dma_contig_memops.put(ctx->ctx_buf);
267 ctx->ctx_phys = 0;
268 ctx->ctx_buf = NULL;
269 return -ENOMEM;
270 }
271 return 0;
272}
273
274/* Release instance buffer */
275void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx)
276{
277 if (ctx->ctx_buf) {
278 vb2_dma_contig_memops.put(ctx->ctx_buf);
279 ctx->ctx_phys = 0;
280 ctx->ctx_buf = NULL;
281 }
282 if (ctx->shm_alloc) {
283 vb2_dma_contig_memops.put(ctx->shm_alloc);
284 ctx->shm_alloc = NULL;
285 ctx->shm = NULL;
286 }
287}
288
289/* Set registers for decoding temporary buffers */
290void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
291{
292 struct s5p_mfc_dev *dev = ctx->dev;
293
294 mfc_write(dev, OFFSETA(ctx->desc_phys), S5P_FIMV_SI_CH0_DESC_ADR);
295 mfc_write(dev, DESC_BUF_SIZE, S5P_FIMV_SI_CH0_DESC_SIZE);
296}
297
298/* Set registers for shared buffer */
299static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx)
300{
301 struct s5p_mfc_dev *dev = ctx->dev;
302 mfc_write(dev, ctx->shm_ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR);
303}
304
305/* Set registers for decoding stream buffer */
306int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
307 unsigned int start_num_byte, unsigned int buf_size)
308{
309 struct s5p_mfc_dev *dev = ctx->dev;
310
311 mfc_write(dev, OFFSETA(buf_addr), S5P_FIMV_SI_CH0_SB_ST_ADR);
312 mfc_write(dev, ctx->dec_src_buf_size, S5P_FIMV_SI_CH0_CPB_SIZE);
313 mfc_write(dev, buf_size, S5P_FIMV_SI_CH0_SB_FRM_SIZE);
314 s5p_mfc_write_shm(ctx, start_num_byte, START_BYTE_NUM);
315 return 0;
316}
317
318/* Set decoding frame buffer */
319int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
320{
321 unsigned int frame_size, i;
322 unsigned int frame_size_ch, frame_size_mv;
323 struct s5p_mfc_dev *dev = ctx->dev;
324 unsigned int dpb;
325 size_t buf_addr1, buf_addr2;
326 int buf_size1, buf_size2;
327
328 buf_addr1 = ctx->bank1_phys;
329 buf_size1 = ctx->bank1_size;
330 buf_addr2 = ctx->bank2_phys;
331 buf_size2 = ctx->bank2_size;
332 dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) &
333 ~S5P_FIMV_DPB_COUNT_MASK;
334 mfc_write(dev, ctx->total_dpb_count | dpb,
335 S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
336 s5p_mfc_set_shared_buffer(ctx);
337 switch (ctx->codec_mode) {
338 case S5P_FIMV_CODEC_H264_DEC:
339 mfc_write(dev, OFFSETA(buf_addr1),
340 S5P_FIMV_H264_VERT_NB_MV_ADR);
341 buf_addr1 += S5P_FIMV_DEC_VERT_NB_MV_SIZE;
342 buf_size1 -= S5P_FIMV_DEC_VERT_NB_MV_SIZE;
343 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H264_NB_IP_ADR);
344 buf_addr1 += S5P_FIMV_DEC_NB_IP_SIZE;
345 buf_size1 -= S5P_FIMV_DEC_NB_IP_SIZE;
346 break;
347 case S5P_FIMV_CODEC_MPEG4_DEC:
348 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_NB_DCAC_ADR);
349 buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
350 buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
351 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_UP_NB_MV_ADR);
352 buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
353 buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
354 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_SA_MV_ADR);
355 buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
356 buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
357 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_SP_ADR);
358 buf_addr1 += S5P_FIMV_DEC_STX_PARSER_SIZE;
359 buf_size1 -= S5P_FIMV_DEC_STX_PARSER_SIZE;
360 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_OT_LINE_ADR);
361 buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
362 buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
363 break;
364 case S5P_FIMV_CODEC_H263_DEC:
365 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_OT_LINE_ADR);
366 buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
367 buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
368 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_UP_NB_MV_ADR);
369 buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
370 buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
371 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_SA_MV_ADR);
372 buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
373 buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
374 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_NB_DCAC_ADR);
375 buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
376 buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
377 break;
378 case S5P_FIMV_CODEC_VC1_DEC:
379 case S5P_FIMV_CODEC_VC1RCV_DEC:
380 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_NB_DCAC_ADR);
381 buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
382 buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
383 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_OT_LINE_ADR);
384 buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
385 buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
386 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_UP_NB_MV_ADR);
387 buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
388 buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
389 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_SA_MV_ADR);
390 buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
391 buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
392 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE3_ADR);
393 buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
394 buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
395 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE2_ADR);
396 buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
397 buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
398 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE1_ADR);
399 buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
400 buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
401 break;
402 case S5P_FIMV_CODEC_MPEG2_DEC:
403 break;
404 default:
405 mfc_err("Unknown codec for decoding (%x)\n",
406 ctx->codec_mode);
407 return -EINVAL;
408 break;
409 }
410 frame_size = ctx->luma_size;
411 frame_size_ch = ctx->chroma_size;
412 frame_size_mv = ctx->mv_size;
413 mfc_debug(2, "Frm size: %d ch: %d mv: %d\n", frame_size, frame_size_ch,
414 frame_size_mv);
415 for (i = 0; i < ctx->total_dpb_count; i++) {
416 /* Bank2 */
417 mfc_debug(2, "Luma %d: %x\n", i,
418 ctx->dst_bufs[i].cookie.raw.luma);
419 mfc_write(dev, OFFSETB(ctx->dst_bufs[i].cookie.raw.luma),
420 S5P_FIMV_DEC_LUMA_ADR + i * 4);
421 mfc_debug(2, "\tChroma %d: %x\n", i,
422 ctx->dst_bufs[i].cookie.raw.chroma);
423 mfc_write(dev, OFFSETA(ctx->dst_bufs[i].cookie.raw.chroma),
424 S5P_FIMV_DEC_CHROMA_ADR + i * 4);
425 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
426 mfc_debug(2, "\tBuf2: %x, size: %d\n",
427 buf_addr2, buf_size2);
428 mfc_write(dev, OFFSETB(buf_addr2),
429 S5P_FIMV_H264_MV_ADR + i * 4);
430 buf_addr2 += frame_size_mv;
431 buf_size2 -= frame_size_mv;
432 }
433 }
434 mfc_debug(2, "Buf1: %u, buf_size1: %d\n", buf_addr1, buf_size1);
435 mfc_debug(2, "Buf 1/2 size after: %d/%d (frames %d)\n",
436 buf_size1, buf_size2, ctx->total_dpb_count);
437 if (buf_size1 < 0 || buf_size2 < 0) {
438 mfc_debug(2, "Not enough memory has been allocated\n");
439 return -ENOMEM;
440 }
441 s5p_mfc_write_shm(ctx, frame_size, ALLOC_LUMA_DPB_SIZE);
442 s5p_mfc_write_shm(ctx, frame_size_ch, ALLOC_CHROMA_DPB_SIZE);
443 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC)
444 s5p_mfc_write_shm(ctx, frame_size_mv, ALLOC_MV_SIZE);
445 mfc_write(dev, ((S5P_FIMV_CH_INIT_BUFS & S5P_FIMV_CH_MASK)
446 << S5P_FIMV_CH_SHIFT) | (ctx->inst_no),
447 S5P_FIMV_SI_CH0_INST_ID);
448 return 0;
449}
450
451/* Set registers for encoding stream buffer */
452int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
453 unsigned long addr, unsigned int size)
454{
455 struct s5p_mfc_dev *dev = ctx->dev;
456
457 mfc_write(dev, OFFSETA(addr), S5P_FIMV_ENC_SI_CH0_SB_ADR);
458 mfc_write(dev, size, S5P_FIMV_ENC_SI_CH0_SB_SIZE);
459 return 0;
460}
461
462void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
463 unsigned long y_addr, unsigned long c_addr)
464{
465 struct s5p_mfc_dev *dev = ctx->dev;
466
467 mfc_write(dev, OFFSETB(y_addr), S5P_FIMV_ENC_SI_CH0_CUR_Y_ADR);
468 mfc_write(dev, OFFSETB(c_addr), S5P_FIMV_ENC_SI_CH0_CUR_C_ADR);
469}
470
471void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
472 unsigned long *y_addr, unsigned long *c_addr)
473{
474 struct s5p_mfc_dev *dev = ctx->dev;
475
476 *y_addr = dev->bank2 + (mfc_read(dev, S5P_FIMV_ENCODED_Y_ADDR)
477 << MFC_OFFSET_SHIFT);
478 *c_addr = dev->bank2 + (mfc_read(dev, S5P_FIMV_ENCODED_C_ADDR)
479 << MFC_OFFSET_SHIFT);
480}
481
482/* Set encoding ref & codec buffer */
483int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx)
484{
485 struct s5p_mfc_dev *dev = ctx->dev;
486 size_t buf_addr1, buf_addr2;
487 size_t buf_size1, buf_size2;
488 unsigned int enc_ref_y_size, enc_ref_c_size;
489 unsigned int guard_width, guard_height;
490 int i;
491
492 buf_addr1 = ctx->bank1_phys;
493 buf_size1 = ctx->bank1_size;
494 buf_addr2 = ctx->bank2_phys;
495 buf_size2 = ctx->bank2_size;
496 enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
497 * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
498 enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);
499 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) {
500 enc_ref_c_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
501 * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN);
502 enc_ref_c_size = ALIGN(enc_ref_c_size, S5P_FIMV_NV12MT_SALIGN);
503 } else {
504 guard_width = ALIGN(ctx->img_width + 16,
505 S5P_FIMV_NV12MT_HALIGN);
506 guard_height = ALIGN((ctx->img_height >> 1) + 4,
507 S5P_FIMV_NV12MT_VALIGN);
508 enc_ref_c_size = ALIGN(guard_width * guard_height,
509 S5P_FIMV_NV12MT_SALIGN);
510 }
511 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n", buf_size1, buf_size2);
512 switch (ctx->codec_mode) {
513 case S5P_FIMV_CODEC_H264_ENC:
514 for (i = 0; i < 2; i++) {
515 mfc_write(dev, OFFSETA(buf_addr1),
516 S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
517 buf_addr1 += enc_ref_y_size;
518 buf_size1 -= enc_ref_y_size;
519
520 mfc_write(dev, OFFSETB(buf_addr2),
521 S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
522 buf_addr2 += enc_ref_y_size;
523 buf_size2 -= enc_ref_y_size;
524 }
525 for (i = 0; i < 4; i++) {
526 mfc_write(dev, OFFSETB(buf_addr2),
527 S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
528 buf_addr2 += enc_ref_c_size;
529 buf_size2 -= enc_ref_c_size;
530 }
531 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H264_UP_MV_ADR);
532 buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
533 buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
534 mfc_write(dev, OFFSETA(buf_addr1),
535 S5P_FIMV_H264_COZERO_FLAG_ADR);
536 buf_addr1 += S5P_FIMV_ENC_COLFLG_SIZE;
537 buf_size1 -= S5P_FIMV_ENC_COLFLG_SIZE;
538 mfc_write(dev, OFFSETA(buf_addr1),
539 S5P_FIMV_H264_UP_INTRA_MD_ADR);
540 buf_addr1 += S5P_FIMV_ENC_INTRAMD_SIZE;
541 buf_size1 -= S5P_FIMV_ENC_INTRAMD_SIZE;
542 mfc_write(dev, OFFSETB(buf_addr2),
543 S5P_FIMV_H264_UP_INTRA_PRED_ADR);
544 buf_addr2 += S5P_FIMV_ENC_INTRAPRED_SIZE;
545 buf_size2 -= S5P_FIMV_ENC_INTRAPRED_SIZE;
546 mfc_write(dev, OFFSETA(buf_addr1),
547 S5P_FIMV_H264_NBOR_INFO_ADR);
548 buf_addr1 += S5P_FIMV_ENC_NBORINFO_SIZE;
549 buf_size1 -= S5P_FIMV_ENC_NBORINFO_SIZE;
550 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
551 buf_size1, buf_size2);
552 break;
553 case S5P_FIMV_CODEC_MPEG4_ENC:
554 for (i = 0; i < 2; i++) {
555 mfc_write(dev, OFFSETA(buf_addr1),
556 S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
557 buf_addr1 += enc_ref_y_size;
558 buf_size1 -= enc_ref_y_size;
559 mfc_write(dev, OFFSETB(buf_addr2),
560 S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
561 buf_addr2 += enc_ref_y_size;
562 buf_size2 -= enc_ref_y_size;
563 }
564 for (i = 0; i < 4; i++) {
565 mfc_write(dev, OFFSETB(buf_addr2),
566 S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
567 buf_addr2 += enc_ref_c_size;
568 buf_size2 -= enc_ref_c_size;
569 }
570 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_UP_MV_ADR);
571 buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
572 buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
573 mfc_write(dev, OFFSETA(buf_addr1),
574 S5P_FIMV_MPEG4_COZERO_FLAG_ADR);
575 buf_addr1 += S5P_FIMV_ENC_COLFLG_SIZE;
576 buf_size1 -= S5P_FIMV_ENC_COLFLG_SIZE;
577 mfc_write(dev, OFFSETA(buf_addr1),
578 S5P_FIMV_MPEG4_ACDC_COEF_ADR);
579 buf_addr1 += S5P_FIMV_ENC_ACDCCOEF_SIZE;
580 buf_size1 -= S5P_FIMV_ENC_ACDCCOEF_SIZE;
581 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
582 buf_size1, buf_size2);
583 break;
584 case S5P_FIMV_CODEC_H263_ENC:
585 for (i = 0; i < 2; i++) {
586 mfc_write(dev, OFFSETA(buf_addr1),
587 S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
588 buf_addr1 += enc_ref_y_size;
589 buf_size1 -= enc_ref_y_size;
590 mfc_write(dev, OFFSETB(buf_addr2),
591 S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
592 buf_addr2 += enc_ref_y_size;
593 buf_size2 -= enc_ref_y_size;
594 }
595 for (i = 0; i < 4; i++) {
596 mfc_write(dev, OFFSETB(buf_addr2),
597 S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
598 buf_addr2 += enc_ref_c_size;
599 buf_size2 -= enc_ref_c_size;
600 }
601 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_UP_MV_ADR);
602 buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
603 buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
604 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_ACDC_COEF_ADR);
605 buf_addr1 += S5P_FIMV_ENC_ACDCCOEF_SIZE;
606 buf_size1 -= S5P_FIMV_ENC_ACDCCOEF_SIZE;
607 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
608 buf_size1, buf_size2);
609 break;
610 default:
611 mfc_err("Unknown codec set for encoding: %d\n",
612 ctx->codec_mode);
613 return -EINVAL;
614 }
615 return 0;
616}
617
618static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
619{
620 struct s5p_mfc_dev *dev = ctx->dev;
621 struct s5p_mfc_enc_params *p = &ctx->enc_params;
622 unsigned int reg;
623 unsigned int shm;
624
625 /* width */
626 mfc_write(dev, ctx->img_width, S5P_FIMV_ENC_HSIZE_PX);
627 /* height */
628 mfc_write(dev, ctx->img_height, S5P_FIMV_ENC_VSIZE_PX);
629 /* pictype : enable, IDR period */
630 reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
631 reg |= (1 << 18);
632 reg &= ~(0xFFFF);
633 reg |= p->gop_size;
634 mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
635 mfc_write(dev, 0, S5P_FIMV_ENC_B_RECON_WRITE_ON);
636 /* multi-slice control */
637 /* multi-slice MB number or bit size */
638 mfc_write(dev, p->slice_mode, S5P_FIMV_ENC_MSLICE_CTRL);
639 if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
640 mfc_write(dev, p->slice_mb, S5P_FIMV_ENC_MSLICE_MB);
641 } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
642 mfc_write(dev, p->slice_bit, S5P_FIMV_ENC_MSLICE_BIT);
643 } else {
644 mfc_write(dev, 0, S5P_FIMV_ENC_MSLICE_MB);
645 mfc_write(dev, 0, S5P_FIMV_ENC_MSLICE_BIT);
646 }
647 /* cyclic intra refresh */
648 mfc_write(dev, p->intra_refresh_mb, S5P_FIMV_ENC_CIR_CTRL);
649 /* memory structure cur. frame */
650 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M)
651 mfc_write(dev, 0, S5P_FIMV_ENC_MAP_FOR_CUR);
652 else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT)
653 mfc_write(dev, 3, S5P_FIMV_ENC_MAP_FOR_CUR);
654 /* padding control & value */
655 reg = mfc_read(dev, S5P_FIMV_ENC_PADDING_CTRL);
656 if (p->pad) {
657 /** enable */
658 reg |= (1 << 31);
659 /** cr value */
660 reg &= ~(0xFF << 16);
661 reg |= (p->pad_cr << 16);
662 /** cb value */
663 reg &= ~(0xFF << 8);
664 reg |= (p->pad_cb << 8);
665 /** y value */
666 reg &= ~(0xFF);
667 reg |= (p->pad_luma);
668 } else {
669 /** disable & all value clear */
670 reg = 0;
671 }
672 mfc_write(dev, reg, S5P_FIMV_ENC_PADDING_CTRL);
673 /* rate control config. */
674 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
675 /** frame-level rate control */
676 reg &= ~(0x1 << 9);
677 reg |= (p->rc_frame << 9);
678 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
679 /* bit rate */
680 if (p->rc_frame)
681 mfc_write(dev, p->rc_bitrate,
682 S5P_FIMV_ENC_RC_BIT_RATE);
683 else
684 mfc_write(dev, 0, S5P_FIMV_ENC_RC_BIT_RATE);
685 /* reaction coefficient */
686 if (p->rc_frame)
687 mfc_write(dev, p->rc_reaction_coeff, S5P_FIMV_ENC_RC_RPARA);
688 shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
689 /* seq header ctrl */
690 shm &= ~(0x1 << 3);
691 shm |= (p->seq_hdr_mode << 3);
692 /* frame skip mode */
693 shm &= ~(0x3 << 1);
694 shm |= (p->frame_skip_mode << 1);
695 s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
696 /* fixed target bit */
697 s5p_mfc_write_shm(ctx, p->fixed_target_bit, RC_CONTROL_CONFIG);
698 return 0;
699}
700
701static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
702{
703 struct s5p_mfc_dev *dev = ctx->dev;
704 struct s5p_mfc_enc_params *p = &ctx->enc_params;
705 struct s5p_mfc_h264_enc_params *p_264 = &p->codec.h264;
706 unsigned int reg;
707 unsigned int shm;
708
709 s5p_mfc_set_enc_params(ctx);
710 /* pictype : number of B */
711 reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
712 /* num_b_frame - 0 ~ 2 */
713 reg &= ~(0x3 << 16);
714 reg |= (p->num_b_frame << 16);
715 mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
716 /* profile & level */
717 reg = mfc_read(dev, S5P_FIMV_ENC_PROFILE);
718 /* level */
719 reg &= ~(0xFF << 8);
720 reg |= (p_264->level << 8);
721 /* profile - 0 ~ 2 */
722 reg &= ~(0x3F);
723 reg |= p_264->profile;
724 mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);
725 /* interlace */
726 mfc_write(dev, p->interlace, S5P_FIMV_ENC_PIC_STRUCT);
727 /* height */
728 if (p->interlace)
729 mfc_write(dev, ctx->img_height >> 1, S5P_FIMV_ENC_VSIZE_PX);
730 /* loopfilter ctrl */
731 mfc_write(dev, p_264->loop_filter_mode, S5P_FIMV_ENC_LF_CTRL);
732 /* loopfilter alpha offset */
733 if (p_264->loop_filter_alpha < 0) {
734 reg = 0x10;
735 reg |= (0xFF - p_264->loop_filter_alpha) + 1;
736 } else {
737 reg = 0x00;
738 reg |= (p_264->loop_filter_alpha & 0xF);
739 }
740 mfc_write(dev, reg, S5P_FIMV_ENC_ALPHA_OFF);
741 /* loopfilter beta offset */
742 if (p_264->loop_filter_beta < 0) {
743 reg = 0x10;
744 reg |= (0xFF - p_264->loop_filter_beta) + 1;
745 } else {
746 reg = 0x00;
747 reg |= (p_264->loop_filter_beta & 0xF);
748 }
749 mfc_write(dev, reg, S5P_FIMV_ENC_BETA_OFF);
750 /* entropy coding mode */
751 if (p_264->entropy_mode == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
752 mfc_write(dev, 1, S5P_FIMV_ENC_H264_ENTROPY_MODE);
753 else
754 mfc_write(dev, 0, S5P_FIMV_ENC_H264_ENTROPY_MODE);
755 /* number of ref. picture */
756 reg = mfc_read(dev, S5P_FIMV_ENC_H264_NUM_OF_REF);
757 /* num of ref. pictures of P */
758 reg &= ~(0x3 << 5);
759 reg |= (p_264->num_ref_pic_4p << 5);
760 /* max number of ref. pictures */
761 reg &= ~(0x1F);
762 reg |= p_264->max_ref_pic;
763 mfc_write(dev, reg, S5P_FIMV_ENC_H264_NUM_OF_REF);
764 /* 8x8 transform enable */
765 mfc_write(dev, p_264->_8x8_transform, S5P_FIMV_ENC_H264_TRANS_FLAG);
766 /* rate control config. */
767 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
768 /* macroblock level rate control */
769 reg &= ~(0x1 << 8);
770 reg |= (p_264->rc_mb << 8);
771 /* frame QP */
772 reg &= ~(0x3F);
773 reg |= p_264->rc_frame_qp;
774 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
775 /* frame rate */
776 if (p->rc_frame && p->rc_framerate_denom)
777 mfc_write(dev, p->rc_framerate_num * 1000
778 / p->rc_framerate_denom, S5P_FIMV_ENC_RC_FRAME_RATE);
779 else
780 mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
781 /* max & min value of QP */
782 reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
783 /* max QP */
784 reg &= ~(0x3F << 8);
785 reg |= (p_264->rc_max_qp << 8);
786 /* min QP */
787 reg &= ~(0x3F);
788 reg |= p_264->rc_min_qp;
789 mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
790 /* macroblock adaptive scaling features */
791 if (p_264->rc_mb) {
792 reg = mfc_read(dev, S5P_FIMV_ENC_RC_MB_CTRL);
793 /* dark region */
794 reg &= ~(0x1 << 3);
795 reg |= (p_264->rc_mb_dark << 3);
796 /* smooth region */
797 reg &= ~(0x1 << 2);
798 reg |= (p_264->rc_mb_smooth << 2);
799 /* static region */
800 reg &= ~(0x1 << 1);
801 reg |= (p_264->rc_mb_static << 1);
802 /* high activity region */
803 reg &= ~(0x1);
804 reg |= p_264->rc_mb_activity;
805 mfc_write(dev, reg, S5P_FIMV_ENC_RC_MB_CTRL);
806 }
807 if (!p->rc_frame &&
808 !p_264->rc_mb) {
809 shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
810 shm &= ~(0xFFF);
811 shm |= ((p_264->rc_b_frame_qp & 0x3F) << 6);
812 shm |= (p_264->rc_p_frame_qp & 0x3F);
813 s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
814 }
815 /* extended encoder ctrl */
816 shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
817 /* AR VUI control */
818 shm &= ~(0x1 << 15);
819 shm |= (p_264->vui_sar << 1);
820 s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
821 if (p_264->vui_sar) {
822 /* aspect ration IDC */
823 shm = s5p_mfc_read_shm(ctx, SAMPLE_ASPECT_RATIO_IDC);
824 shm &= ~(0xFF);
825 shm |= p_264->vui_sar_idc;
826 s5p_mfc_write_shm(ctx, shm, SAMPLE_ASPECT_RATIO_IDC);
827 if (p_264->vui_sar_idc == 0xFF) {
828 /* sample AR info */
829 shm = s5p_mfc_read_shm(ctx, EXTENDED_SAR);
830 shm &= ~(0xFFFFFFFF);
831 shm |= p_264->vui_ext_sar_width << 16;
832 shm |= p_264->vui_ext_sar_height;
833 s5p_mfc_write_shm(ctx, shm, EXTENDED_SAR);
834 }
835 }
836 /* intra picture period for H.264 */
837 shm = s5p_mfc_read_shm(ctx, H264_I_PERIOD);
838 /* control */
839 shm &= ~(0x1 << 16);
840 shm |= (p_264->open_gop << 16);
841 /* value */
842 if (p_264->open_gop) {
843 shm &= ~(0xFFFF);
844 shm |= p_264->open_gop_size;
845 }
846 s5p_mfc_write_shm(ctx, shm, H264_I_PERIOD);
847 /* extended encoder ctrl */
848 shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
849 /* vbv buffer size */
850 if (p->frame_skip_mode ==
851 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
852 shm &= ~(0xFFFF << 16);
853 shm |= (p_264->cpb_size << 16);
854 }
855 s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
856 return 0;
857}
858
859static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
860{
861 struct s5p_mfc_dev *dev = ctx->dev;
862 struct s5p_mfc_enc_params *p = &ctx->enc_params;
863 struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;
864 unsigned int reg;
865 unsigned int shm;
866 unsigned int framerate;
867
868 s5p_mfc_set_enc_params(ctx);
869 /* pictype : number of B */
870 reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
871 /* num_b_frame - 0 ~ 2 */
872 reg &= ~(0x3 << 16);
873 reg |= (p->num_b_frame << 16);
874 mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
875 /* profile & level */
876 reg = mfc_read(dev, S5P_FIMV_ENC_PROFILE);
877 /* level */
878 reg &= ~(0xFF << 8);
879 reg |= (p_mpeg4->level << 8);
880 /* profile - 0 ~ 2 */
881 reg &= ~(0x3F);
882 reg |= p_mpeg4->profile;
883 mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);
884 /* quarter_pixel */
885 mfc_write(dev, p_mpeg4->quarter_pixel, S5P_FIMV_ENC_MPEG4_QUART_PXL);
886 /* qp */
887 if (!p->rc_frame) {
888 shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
889 shm &= ~(0xFFF);
890 shm |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 6);
891 shm |= (p_mpeg4->rc_p_frame_qp & 0x3F);
892 s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
893 }
894 /* frame rate */
895 if (p->rc_frame) {
896 if (p->rc_framerate_denom > 0) {
897 framerate = p->rc_framerate_num * 1000 /
898 p->rc_framerate_denom;
899 mfc_write(dev, framerate,
900 S5P_FIMV_ENC_RC_FRAME_RATE);
901 shm = s5p_mfc_read_shm(ctx, RC_VOP_TIMING);
902 shm &= ~(0xFFFFFFFF);
903 shm |= (1 << 31);
904 shm |= ((p->rc_framerate_num & 0x7FFF) << 16);
905 shm |= (p->rc_framerate_denom & 0xFFFF);
906 s5p_mfc_write_shm(ctx, shm, RC_VOP_TIMING);
907 }
908 } else {
909 mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
910 }
911 /* rate control config. */
912 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
913 /* frame QP */
914 reg &= ~(0x3F);
915 reg |= p_mpeg4->rc_frame_qp;
916 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
917 /* max & min value of QP */
918 reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
919 /* max QP */
920 reg &= ~(0x3F << 8);
921 reg |= (p_mpeg4->rc_max_qp << 8);
922 /* min QP */
923 reg &= ~(0x3F);
924 reg |= p_mpeg4->rc_min_qp;
925 mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
926 /* extended encoder ctrl */
927 shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
928 /* vbv buffer size */
929 if (p->frame_skip_mode ==
930 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
931 shm &= ~(0xFFFF << 16);
932 shm |= (p->vbv_size << 16);
933 }
934 s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
935 return 0;
936}
937
938static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
939{
940 struct s5p_mfc_dev *dev = ctx->dev;
941 struct s5p_mfc_enc_params *p = &ctx->enc_params;
942 struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;
943 unsigned int reg;
944 unsigned int shm;
945
946 s5p_mfc_set_enc_params(ctx);
947 /* qp */
948 if (!p->rc_frame) {
949 shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
950 shm &= ~(0xFFF);
951 shm |= (p_h263->rc_p_frame_qp & 0x3F);
952 s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
953 }
954 /* frame rate */
955 if (p->rc_frame && p->rc_framerate_denom)
956 mfc_write(dev, p->rc_framerate_num * 1000
957 / p->rc_framerate_denom, S5P_FIMV_ENC_RC_FRAME_RATE);
958 else
959 mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
960 /* rate control config. */
961 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
962 /* frame QP */
963 reg &= ~(0x3F);
964 reg |= p_h263->rc_frame_qp;
965 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
966 /* max & min value of QP */
967 reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
968 /* max QP */
969 reg &= ~(0x3F << 8);
970 reg |= (p_h263->rc_max_qp << 8);
971 /* min QP */
972 reg &= ~(0x3F);
973 reg |= p_h263->rc_min_qp;
974 mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
975 /* extended encoder ctrl */
976 shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
977 /* vbv buffer size */
978 if (p->frame_skip_mode ==
979 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
980 shm &= ~(0xFFFF << 16);
981 shm |= (p->vbv_size << 16);
982 }
983 s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
984 return 0;
985}
986
987/* Initialize decoding */
988int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx)
989{
990 struct s5p_mfc_dev *dev = ctx->dev;
991
992 s5p_mfc_set_shared_buffer(ctx);
993 /* Setup loop filter, for decoding this is only valid for MPEG4 */
994 if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_DEC)
995 mfc_write(dev, ctx->loop_filter_mpeg4, S5P_FIMV_ENC_LF_CTRL);
996 else
997 mfc_write(dev, 0, S5P_FIMV_ENC_LF_CTRL);
998 mfc_write(dev, ((ctx->slice_interface & S5P_FIMV_SLICE_INT_MASK) <<
999 S5P_FIMV_SLICE_INT_SHIFT) | (ctx->display_delay_enable <<
1000 S5P_FIMV_DDELAY_ENA_SHIFT) | ((ctx->display_delay &
1001 S5P_FIMV_DDELAY_VAL_MASK) << S5P_FIMV_DDELAY_VAL_SHIFT),
1002 S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
1003 mfc_write(dev,
1004 ((S5P_FIMV_CH_SEQ_HEADER & S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT)
1005 | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1006 return 0;
1007}
1008
1009static void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush)
1010{
1011 struct s5p_mfc_dev *dev = ctx->dev;
1012 unsigned int dpb;
1013
1014 if (flush)
1015 dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) | (
1016 S5P_FIMV_DPB_FLUSH_MASK << S5P_FIMV_DPB_FLUSH_SHIFT);
1017 else
1018 dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) &
1019 ~(S5P_FIMV_DPB_FLUSH_MASK << S5P_FIMV_DPB_FLUSH_SHIFT);
1020 mfc_write(dev, dpb, S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
1021}
1022
1023/* Decode a single frame */
1024int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx,
1025 enum s5p_mfc_decode_arg last_frame)
1026{
1027 struct s5p_mfc_dev *dev = ctx->dev;
1028
1029 mfc_write(dev, ctx->dec_dst_flag, S5P_FIMV_SI_CH0_RELEASE_BUF);
1030 s5p_mfc_set_shared_buffer(ctx);
1031 s5p_mfc_set_flush(ctx, ctx->dpb_flush_flag);
1032 /* Issue different commands to instance basing on whether it
1033 * is the last frame or not. */
1034 switch (last_frame) {
1035 case MFC_DEC_FRAME:
1036 mfc_write(dev, ((S5P_FIMV_CH_FRAME_START & S5P_FIMV_CH_MASK) <<
1037 S5P_FIMV_CH_SHIFT) | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1038 break;
1039 case MFC_DEC_LAST_FRAME:
1040 mfc_write(dev, ((S5P_FIMV_CH_LAST_FRAME & S5P_FIMV_CH_MASK) <<
1041 S5P_FIMV_CH_SHIFT) | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1042 break;
1043 case MFC_DEC_RES_CHANGE:
1044 mfc_write(dev, ((S5P_FIMV_CH_FRAME_START_REALLOC &
1045 S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT) | (ctx->inst_no),
1046 S5P_FIMV_SI_CH0_INST_ID);
1047 break;
1048 }
1049 mfc_debug(2, "Decoding a usual frame\n");
1050 return 0;
1051}
1052
1053int s5p_mfc_init_encode(struct s5p_mfc_ctx *ctx)
1054{
1055 struct s5p_mfc_dev *dev = ctx->dev;
1056
1057 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
1058 s5p_mfc_set_enc_params_h264(ctx);
1059 else if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_ENC)
1060 s5p_mfc_set_enc_params_mpeg4(ctx);
1061 else if (ctx->codec_mode == S5P_FIMV_CODEC_H263_ENC)
1062 s5p_mfc_set_enc_params_h263(ctx);
1063 else {
1064 mfc_err("Unknown codec for encoding (%x)\n",
1065 ctx->codec_mode);
1066 return -EINVAL;
1067 }
1068 s5p_mfc_set_shared_buffer(ctx);
1069 mfc_write(dev, ((S5P_FIMV_CH_SEQ_HEADER << 16) & 0x70000) |
1070 (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1071 return 0;
1072}
1073
1074/* Encode a single frame */
1075int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx)
1076{
1077 struct s5p_mfc_dev *dev = ctx->dev;
1078 int cmd;
1079 /* memory structure cur. frame */
1080 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M)
1081 mfc_write(dev, 0, S5P_FIMV_ENC_MAP_FOR_CUR);
1082 else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT)
1083 mfc_write(dev, 3, S5P_FIMV_ENC_MAP_FOR_CUR);
1084 s5p_mfc_set_shared_buffer(ctx);
1085
1086 if (ctx->state == MFCINST_FINISHING)
1087 cmd = S5P_FIMV_CH_LAST_FRAME;
1088 else
1089 cmd = S5P_FIMV_CH_FRAME_START;
1090 mfc_write(dev, ((cmd & S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT)
1091 | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1092
1093 return 0;
1094}
1095
1096static int s5p_mfc_get_new_ctx(struct s5p_mfc_dev *dev)
1097{
1098 unsigned long flags;
1099 int new_ctx;
1100 int cnt;
1101
1102 spin_lock_irqsave(&dev->condlock, flags);
1103 new_ctx = (dev->curr_ctx + 1) % MFC_NUM_CONTEXTS;
1104 cnt = 0;
1105 while (!test_bit(new_ctx, &dev->ctx_work_bits)) {
1106 new_ctx = (new_ctx + 1) % MFC_NUM_CONTEXTS;
1107 if (++cnt > MFC_NUM_CONTEXTS) {
1108 /* No contexts to run */
1109 spin_unlock_irqrestore(&dev->condlock, flags);
1110 return -EAGAIN;
1111 }
1112 }
1113 spin_unlock_irqrestore(&dev->condlock, flags);
1114 return new_ctx;
1115}
1116
1117static void s5p_mfc_run_res_change(struct s5p_mfc_ctx *ctx)
1118{
1119 struct s5p_mfc_dev *dev = ctx->dev;
1120
1121 s5p_mfc_set_dec_stream_buffer(ctx, 0, 0, 0);
1122 dev->curr_ctx = ctx->num;
1123 s5p_mfc_clean_ctx_int_flags(ctx);
1124 s5p_mfc_decode_one_frame(ctx, MFC_DEC_RES_CHANGE);
1125}
1126
1127static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame)
1128{
1129 struct s5p_mfc_dev *dev = ctx->dev;
1130 struct s5p_mfc_buf *temp_vb;
1131 unsigned long flags;
1132 unsigned int index;
1133
1134 spin_lock_irqsave(&dev->irqlock, flags);
1135 /* Frames are being decoded */
1136 if (list_empty(&ctx->src_queue)) {
1137 mfc_debug(2, "No src buffers\n");
1138 spin_unlock_irqrestore(&dev->irqlock, flags);
1139 return -EAGAIN;
1140 }
1141 /* Get the next source buffer */
1142 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1143 temp_vb->flags |= MFC_BUF_FLAG_USED;
1144 s5p_mfc_set_dec_stream_buffer(ctx,
1145 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), ctx->consumed_stream,
1146 temp_vb->b->v4l2_planes[0].bytesused);
1147 spin_unlock_irqrestore(&dev->irqlock, flags);
1148 index = temp_vb->b->v4l2_buf.index;
1149 dev->curr_ctx = ctx->num;
1150 s5p_mfc_clean_ctx_int_flags(ctx);
1151 if (temp_vb->b->v4l2_planes[0].bytesused == 0) {
1152 last_frame = MFC_DEC_LAST_FRAME;
1153 mfc_debug(2, "Setting ctx->state to FINISHING\n");
1154 ctx->state = MFCINST_FINISHING;
1155 }
1156 s5p_mfc_decode_one_frame(ctx, last_frame);
1157 return 0;
1158}
1159
1160static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
1161{
1162 struct s5p_mfc_dev *dev = ctx->dev;
1163 unsigned long flags;
1164 struct s5p_mfc_buf *dst_mb;
1165 struct s5p_mfc_buf *src_mb;
1166 unsigned long src_y_addr, src_c_addr, dst_addr;
1167 unsigned int dst_size;
1168
1169 spin_lock_irqsave(&dev->irqlock, flags);
1170 if (list_empty(&ctx->src_queue) && ctx->state != MFCINST_FINISHING) {
1171 mfc_debug(2, "no src buffers\n");
1172 spin_unlock_irqrestore(&dev->irqlock, flags);
1173 return -EAGAIN;
1174 }
1175 if (list_empty(&ctx->dst_queue)) {
1176 mfc_debug(2, "no dst buffers\n");
1177 spin_unlock_irqrestore(&dev->irqlock, flags);
1178 return -EAGAIN;
1179 }
1180 if (list_empty(&ctx->src_queue)) {
1181 /* send null frame */
1182 s5p_mfc_set_enc_frame_buffer(ctx, dev->bank2, dev->bank2);
1183 src_mb = NULL;
1184 } else {
1185 src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
1186 list);
1187 src_mb->flags |= MFC_BUF_FLAG_USED;
1188 if (src_mb->b->v4l2_planes[0].bytesused == 0) {
1189 /* send null frame */
1190 s5p_mfc_set_enc_frame_buffer(ctx, dev->bank2,
1191 dev->bank2);
1192 ctx->state = MFCINST_FINISHING;
1193 } else {
1194 src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b,
1195 0);
1196 src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b,
1197 1);
1198 s5p_mfc_set_enc_frame_buffer(ctx, src_y_addr,
1199 src_c_addr);
1200 if (src_mb->flags & MFC_BUF_FLAG_EOS)
1201 ctx->state = MFCINST_FINISHING;
1202 }
1203 }
1204 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
1205 dst_mb->flags |= MFC_BUF_FLAG_USED;
1206 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
1207 dst_size = vb2_plane_size(dst_mb->b, 0);
1208 s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
1209 spin_unlock_irqrestore(&dev->irqlock, flags);
1210 dev->curr_ctx = ctx->num;
1211 s5p_mfc_clean_ctx_int_flags(ctx);
1212 mfc_debug(2, "encoding buffer with index=%d state=%d",
1213 src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state);
1214 s5p_mfc_encode_one_frame(ctx);
1215 return 0;
1216}
1217
1218static void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
1219{
1220 struct s5p_mfc_dev *dev = ctx->dev;
1221 unsigned long flags;
1222 struct s5p_mfc_buf *temp_vb;
1223
1224 /* Initializing decoding - parsing header */
1225 spin_lock_irqsave(&dev->irqlock, flags);
1226 mfc_debug(2, "Preparing to init decoding\n");
1227 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1228 s5p_mfc_set_dec_desc_buffer(ctx);
1229 mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
1230 s5p_mfc_set_dec_stream_buffer(ctx,
1231 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
1232 0, temp_vb->b->v4l2_planes[0].bytesused);
1233 spin_unlock_irqrestore(&dev->irqlock, flags);
1234 dev->curr_ctx = ctx->num;
1235 s5p_mfc_clean_ctx_int_flags(ctx);
1236 s5p_mfc_init_decode(ctx);
1237}
1238
1239static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
1240{
1241 struct s5p_mfc_dev *dev = ctx->dev;
1242 unsigned long flags;
1243 struct s5p_mfc_buf *dst_mb;
1244 unsigned long dst_addr;
1245 unsigned int dst_size;
1246
1247 s5p_mfc_set_enc_ref_buffer(ctx);
1248 spin_lock_irqsave(&dev->irqlock, flags);
1249 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
1250 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
1251 dst_size = vb2_plane_size(dst_mb->b, 0);
1252 s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
1253 spin_unlock_irqrestore(&dev->irqlock, flags);
1254 dev->curr_ctx = ctx->num;
1255 s5p_mfc_clean_ctx_int_flags(ctx);
1256 s5p_mfc_init_encode(ctx);
1257}
1258
1259static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
1260{
1261 struct s5p_mfc_dev *dev = ctx->dev;
1262 unsigned long flags;
1263 struct s5p_mfc_buf *temp_vb;
1264 int ret;
1265
1266 /*
1267 * Header was parsed now starting processing
1268 * First set the output frame buffers
1269 */
1270 if (ctx->capture_state != QUEUE_BUFS_MMAPED) {
1271 mfc_err("It seems that not all destionation buffers were "
1272 "mmaped\nMFC requires that all destination are mmaped "
1273 "before starting processing\n");
1274 return -EAGAIN;
1275 }
1276 spin_lock_irqsave(&dev->irqlock, flags);
1277 if (list_empty(&ctx->src_queue)) {
1278 mfc_err("Header has been deallocated in the middle of"
1279 " initialization\n");
1280 spin_unlock_irqrestore(&dev->irqlock, flags);
1281 return -EIO;
1282 }
1283 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1284 mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
1285 s5p_mfc_set_dec_stream_buffer(ctx,
1286 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
1287 0, temp_vb->b->v4l2_planes[0].bytesused);
1288 spin_unlock_irqrestore(&dev->irqlock, flags);
1289 dev->curr_ctx = ctx->num;
1290 s5p_mfc_clean_ctx_int_flags(ctx);
1291 ret = s5p_mfc_set_dec_frame_buffer(ctx);
1292 if (ret) {
1293 mfc_err("Failed to alloc frame mem\n");
1294 ctx->state = MFCINST_ERROR;
1295 }
1296 return ret;
1297}
1298
1299/* Try running an operation on hardware */
1300void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
1301{
1302 struct s5p_mfc_ctx *ctx;
1303 int new_ctx;
1304 unsigned int ret = 0;
1305
1306 if (test_bit(0, &dev->enter_suspend)) {
1307 mfc_debug(1, "Entering suspend so do not schedule any jobs\n");
1308 return;
1309 }
1310 /* Check whether hardware is not running */
1311 if (test_and_set_bit(0, &dev->hw_lock) != 0) {
1312 /* This is perfectly ok, the scheduled ctx should wait */
1313 mfc_debug(1, "Couldn't lock HW\n");
1314 return;
1315 }
1316 /* Choose the context to run */
1317 new_ctx = s5p_mfc_get_new_ctx(dev);
1318 if (new_ctx < 0) {
1319 /* No contexts to run */
1320 if (test_and_clear_bit(0, &dev->hw_lock) == 0) {
1321 mfc_err("Failed to unlock hardware\n");
1322 return;
1323 }
1324 mfc_debug(1, "No ctx is scheduled to be run\n");
1325 return;
1326 }
1327 ctx = dev->ctx[new_ctx];
1328 /* Got context to run in ctx */
1329 /*
1330 * Last frame has already been sent to MFC.
1331 * Now obtaining frames from MFC buffer
1332 */
1333 s5p_mfc_clock_on();
1334 if (ctx->type == MFCINST_DECODER) {
1335 s5p_mfc_set_dec_desc_buffer(ctx);
1336 switch (ctx->state) {
1337 case MFCINST_FINISHING:
1338 s5p_mfc_run_dec_frame(ctx, MFC_DEC_LAST_FRAME);
1339 break;
1340 case MFCINST_RUNNING:
1341 ret = s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME);
1342 break;
1343 case MFCINST_INIT:
1344 s5p_mfc_clean_ctx_int_flags(ctx);
1345 ret = s5p_mfc_open_inst_cmd(ctx);
1346 break;
1347 case MFCINST_RETURN_INST:
1348 s5p_mfc_clean_ctx_int_flags(ctx);
1349 ret = s5p_mfc_close_inst_cmd(ctx);
1350 break;
1351 case MFCINST_GOT_INST:
1352 s5p_mfc_run_init_dec(ctx);
1353 break;
1354 case MFCINST_HEAD_PARSED:
1355 ret = s5p_mfc_run_init_dec_buffers(ctx);
1356 mfc_debug(1, "head parsed\n");
1357 break;
1358 case MFCINST_RES_CHANGE_INIT:
1359 s5p_mfc_run_res_change(ctx);
1360 break;
1361 case MFCINST_RES_CHANGE_FLUSH:
1362 s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME);
1363 break;
1364 case MFCINST_RES_CHANGE_END:
1365 mfc_debug(2, "Finished remaining frames after resolution change\n");
1366 ctx->capture_state = QUEUE_FREE;
1367 mfc_debug(2, "Will re-init the codec\n");
1368 s5p_mfc_run_init_dec(ctx);
1369 break;
1370 default:
1371 ret = -EAGAIN;
1372 }
1373 } else if (ctx->type == MFCINST_ENCODER) {
1374 switch (ctx->state) {
1375 case MFCINST_FINISHING:
1376 case MFCINST_RUNNING:
1377 ret = s5p_mfc_run_enc_frame(ctx);
1378 break;
1379 case MFCINST_INIT:
1380 s5p_mfc_clean_ctx_int_flags(ctx);
1381 ret = s5p_mfc_open_inst_cmd(ctx);
1382 break;
1383 case MFCINST_RETURN_INST:
1384 s5p_mfc_clean_ctx_int_flags(ctx);
1385 ret = s5p_mfc_close_inst_cmd(ctx);
1386 break;
1387 case MFCINST_GOT_INST:
1388 s5p_mfc_run_init_enc(ctx);
1389 break;
1390 default:
1391 ret = -EAGAIN;
1392 }
1393 } else {
1394 mfc_err("Invalid context type: %d\n", ctx->type);
1395 ret = -EAGAIN;
1396 }
1397
1398 if (ret) {
1399 /* Free hardware lock */
1400 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
1401 mfc_err("Failed to unlock hardware\n");
1402
1403 /* This is in deed imporant, as no operation has been
1404 * scheduled, reduce the clock count as no one will
1405 * ever do this, because no interrupt related to this try_run
1406 * will ever come from hardware. */
1407 s5p_mfc_clock_off();
1408 }
1409}
1410
1411
1412void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq)
1413{
1414 struct s5p_mfc_buf *b;
1415 int i;
1416
1417 while (!list_empty(lh)) {
1418 b = list_entry(lh->next, struct s5p_mfc_buf, list);
1419 for (i = 0; i < b->b->num_planes; i++)
1420 vb2_set_plane_payload(b->b, i, 0);
1421 vb2_buffer_done(b->b, VB2_BUF_STATE_ERROR);
1422 list_del(&b->list);
1423 }
1424}
1425
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h
index 2ad3def052f8..420abecafec0 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h
@@ -1,10 +1,10 @@
1/* 1/*
2 * drivers/media/platform/samsung/mfc5/s5p_mfc_opr.h 2 * drivers/media/platform/s5p-mfc/s5p_mfc_opr.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.
6 * 6 *
7 * Kamil Debski, Copyright (C) 2011 Samsung Electronics 7 * Kamil Debski, Copyright (C) 2012 Samsung Electronics Co., Ltd.
8 * http://www.samsung.com/ 8 * http://www.samsung.com/
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
@@ -17,77 +17,68 @@
17 17
18#include "s5p_mfc_common.h" 18#include "s5p_mfc_common.h"
19 19
20int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx); 20struct s5p_mfc_hw_ops {
21int s5p_mfc_init_encode(struct s5p_mfc_ctx *mfc_ctx); 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};
22 81
23/* Decoding functions */ 82void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev);
24int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx);
25int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
26 unsigned int start_num_byte,
27 unsigned int buf_size);
28
29/* Encoding functions */
30void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
31 unsigned long y_addr, unsigned long c_addr);
32int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
33 unsigned long addr, unsigned int size);
34void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
35 unsigned long *y_addr, unsigned long *c_addr);
36int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *mfc_ctx);
37
38int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx,
39 enum s5p_mfc_decode_arg last_frame);
40int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *mfc_ctx);
41
42/* Memory allocation */
43int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx);
44void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx);
45void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx);
46
47int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx);
48void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx);
49
50int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx);
51void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx);
52
53void s5p_mfc_try_run(struct s5p_mfc_dev *dev);
54void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
55
56#define s5p_mfc_get_dspl_y_adr() (readl(dev->regs_base + \
57 S5P_FIMV_SI_DISPLAY_Y_ADR) << \
58 MFC_OFFSET_SHIFT)
59#define s5p_mfc_get_dec_y_adr() (readl(dev->regs_base + \
60 S5P_FIMV_SI_DECODE_Y_ADR) << \
61 MFC_OFFSET_SHIFT)
62#define s5p_mfc_get_dspl_status() readl(dev->regs_base + \
63 S5P_FIMV_SI_DISPLAY_STATUS)
64#define s5p_mfc_get_dec_status() readl(dev->regs_base + \
65 S5P_FIMV_SI_DECODE_STATUS)
66#define s5p_mfc_get_frame_type() (readl(dev->regs_base + \
67 S5P_FIMV_DECODE_FRAME_TYPE) \
68 & S5P_FIMV_DECODE_FRAME_MASK)
69#define s5p_mfc_get_consumed_stream() readl(dev->regs_base + \
70 S5P_FIMV_SI_CONSUMED_BYTES)
71#define s5p_mfc_get_int_reason() (readl(dev->regs_base + \
72 S5P_FIMV_RISC2HOST_CMD) & \
73 S5P_FIMV_RISC2HOST_CMD_MASK)
74#define s5p_mfc_get_int_err() readl(dev->regs_base + \
75 S5P_FIMV_RISC2HOST_ARG2)
76#define s5p_mfc_err_dec(x) (((x) & S5P_FIMV_ERR_DEC_MASK) >> \
77 S5P_FIMV_ERR_DEC_SHIFT)
78#define s5p_mfc_err_dspl(x) (((x) & S5P_FIMV_ERR_DSPL_MASK) >> \
79 S5P_FIMV_ERR_DSPL_SHIFT)
80#define s5p_mfc_get_img_width() readl(dev->regs_base + \
81 S5P_FIMV_SI_HRESOL)
82#define s5p_mfc_get_img_height() readl(dev->regs_base + \
83 S5P_FIMV_SI_VRESOL)
84#define s5p_mfc_get_dpb_count() readl(dev->regs_base + \
85 S5P_FIMV_SI_BUF_NUMBER)
86#define s5p_mfc_get_inst_no() readl(dev->regs_base + \
87 S5P_FIMV_RISC2HOST_ARG1)
88#define s5p_mfc_get_enc_strm_size() readl(dev->regs_base + \
89 S5P_FIMV_ENC_SI_STRM_SIZE)
90#define s5p_mfc_get_enc_slice_type() readl(dev->regs_base + \
91 S5P_FIMV_ENC_SI_SLICE_TYPE)
92 83
93#endif /* S5P_MFC_OPR_H_ */ 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
new file mode 100644
index 000000000000..bf7d010a4107
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
@@ -0,0 +1,1794 @@
1/*
2 * drivers/media/platform/samsung/mfc5/s5p_mfc_opr_v5.c
3 *
4 * Samsung MFC (Multi Function Codec - FIMV) driver
5 * This file contains hw related functions.
6 *
7 * Kamil Debski, Copyright (c) 2011 Samsung Electronics
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_common.h"
16#include "s5p_mfc_cmd.h"
17#include "s5p_mfc_ctrl.h"
18#include "s5p_mfc_debug.h"
19#include "s5p_mfc_intr.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>
24#include <linux/delay.h>
25#include <linux/dma-mapping.h>
26#include <linux/err.h>
27#include <linux/firmware.h>
28#include <linux/io.h>
29#include <linux/jiffies.h>
30#include <linux/mm.h>
31#include <linux/sched.h>
32
33#define OFFSETA(x) (((x) - dev->bank1) >> MFC_OFFSET_SHIFT)
34#define OFFSETB(x) (((x) - dev->bank2) >> MFC_OFFSET_SHIFT)
35
36/* Allocate temporary buffers for decoding */
37int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx)
38{
39 struct s5p_mfc_dev *dev = ctx->dev;
40 struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
41
42 ctx->dsc.alloc = vb2_dma_contig_memops.alloc(
43 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX],
44 buf_size->dsc);
45 if (IS_ERR_VALUE((int)ctx->dsc.alloc)) {
46 ctx->dsc.alloc = NULL;
47 mfc_err("Allocating DESC buffer failed\n");
48 return -ENOMEM;
49 }
50 ctx->dsc.dma = s5p_mfc_mem_cookie(
51 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->dsc.alloc);
52 BUG_ON(ctx->dsc.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
53 ctx->dsc.virt = vb2_dma_contig_memops.vaddr(ctx->dsc.alloc);
54 if (ctx->dsc.virt == NULL) {
55 vb2_dma_contig_memops.put(ctx->dsc.alloc);
56 ctx->dsc.dma = 0;
57 ctx->dsc.alloc = NULL;
58 mfc_err("Remapping DESC buffer failed\n");
59 return -ENOMEM;
60 }
61 memset(ctx->dsc.virt, 0, buf_size->dsc);
62 wmb();
63 return 0;
64}
65
66/* Release temporary buffers for decoding */
67void s5p_mfc_release_dec_desc_buffer_v5(struct s5p_mfc_ctx *ctx)
68{
69 if (ctx->dsc.dma) {
70 vb2_dma_contig_memops.put(ctx->dsc.alloc);
71 ctx->dsc.alloc = NULL;
72 ctx->dsc.dma = 0;
73 }
74}
75
76/* Allocate codec buffers */
77int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx)
78{
79 struct s5p_mfc_dev *dev = ctx->dev;
80 unsigned int enc_ref_y_size = 0;
81 unsigned int enc_ref_c_size = 0;
82 unsigned int guard_width, guard_height;
83
84 if (ctx->type == MFCINST_DECODER) {
85 mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",
86 ctx->luma_size, ctx->chroma_size, ctx->mv_size);
87 mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);
88 } else if (ctx->type == MFCINST_ENCODER) {
89 enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
90 * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
91 enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);
92
93 if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) {
94 enc_ref_c_size = ALIGN(ctx->img_width,
95 S5P_FIMV_NV12MT_HALIGN)
96 * ALIGN(ctx->img_height >> 1,
97 S5P_FIMV_NV12MT_VALIGN);
98 enc_ref_c_size = ALIGN(enc_ref_c_size,
99 S5P_FIMV_NV12MT_SALIGN);
100 } else {
101 guard_width = ALIGN(ctx->img_width + 16,
102 S5P_FIMV_NV12MT_HALIGN);
103 guard_height = ALIGN((ctx->img_height >> 1) + 4,
104 S5P_FIMV_NV12MT_VALIGN);
105 enc_ref_c_size = ALIGN(guard_width * guard_height,
106 S5P_FIMV_NV12MT_SALIGN);
107 }
108 mfc_debug(2, "recon luma size: %d chroma size: %d\n",
109 enc_ref_y_size, enc_ref_c_size);
110 } else {
111 return -EINVAL;
112 }
113 /* Codecs have different memory requirements */
114 switch (ctx->codec_mode) {
115 case S5P_MFC_CODEC_H264_DEC:
116 ctx->bank1_size =
117 ALIGN(S5P_FIMV_DEC_NB_IP_SIZE +
118 S5P_FIMV_DEC_VERT_NB_MV_SIZE,
119 S5P_FIMV_DEC_BUF_ALIGN);
120 ctx->bank2_size = ctx->total_dpb_count * ctx->mv_size;
121 break;
122 case S5P_MFC_CODEC_MPEG4_DEC:
123 ctx->bank1_size =
124 ALIGN(S5P_FIMV_DEC_NB_DCAC_SIZE +
125 S5P_FIMV_DEC_UPNB_MV_SIZE +
126 S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
127 S5P_FIMV_DEC_STX_PARSER_SIZE +
128 S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE,
129 S5P_FIMV_DEC_BUF_ALIGN);
130 ctx->bank2_size = 0;
131 break;
132 case S5P_MFC_CODEC_VC1RCV_DEC:
133 case S5P_MFC_CODEC_VC1_DEC:
134 ctx->bank1_size =
135 ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +
136 S5P_FIMV_DEC_UPNB_MV_SIZE +
137 S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
138 S5P_FIMV_DEC_NB_DCAC_SIZE +
139 3 * S5P_FIMV_DEC_VC1_BITPLANE_SIZE,
140 S5P_FIMV_DEC_BUF_ALIGN);
141 ctx->bank2_size = 0;
142 break;
143 case S5P_MFC_CODEC_MPEG2_DEC:
144 ctx->bank1_size = 0;
145 ctx->bank2_size = 0;
146 break;
147 case S5P_MFC_CODEC_H263_DEC:
148 ctx->bank1_size =
149 ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +
150 S5P_FIMV_DEC_UPNB_MV_SIZE +
151 S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
152 S5P_FIMV_DEC_NB_DCAC_SIZE,
153 S5P_FIMV_DEC_BUF_ALIGN);
154 ctx->bank2_size = 0;
155 break;
156 case S5P_MFC_CODEC_H264_ENC:
157 ctx->bank1_size = (enc_ref_y_size * 2) +
158 S5P_FIMV_ENC_UPMV_SIZE +
159 S5P_FIMV_ENC_COLFLG_SIZE +
160 S5P_FIMV_ENC_INTRAMD_SIZE +
161 S5P_FIMV_ENC_NBORINFO_SIZE;
162 ctx->bank2_size = (enc_ref_y_size * 2) +
163 (enc_ref_c_size * 4) +
164 S5P_FIMV_ENC_INTRAPRED_SIZE;
165 break;
166 case S5P_MFC_CODEC_MPEG4_ENC:
167 ctx->bank1_size = (enc_ref_y_size * 2) +
168 S5P_FIMV_ENC_UPMV_SIZE +
169 S5P_FIMV_ENC_COLFLG_SIZE +
170 S5P_FIMV_ENC_ACDCCOEF_SIZE;
171 ctx->bank2_size = (enc_ref_y_size * 2) +
172 (enc_ref_c_size * 4);
173 break;
174 case S5P_MFC_CODEC_H263_ENC:
175 ctx->bank1_size = (enc_ref_y_size * 2) +
176 S5P_FIMV_ENC_UPMV_SIZE +
177 S5P_FIMV_ENC_ACDCCOEF_SIZE;
178 ctx->bank2_size = (enc_ref_y_size * 2) +
179 (enc_ref_c_size * 4);
180 break;
181 default:
182 break;
183 }
184 /* Allocate only if memory from bank 1 is necessary */
185 if (ctx->bank1_size > 0) {
186 ctx->bank1_buf = vb2_dma_contig_memops.alloc(
187 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_size);
188 if (IS_ERR(ctx->bank1_buf)) {
189 ctx->bank1_buf = NULL;
190 printk(KERN_ERR
191 "Buf alloc for decoding failed (port A)\n");
192 return -ENOMEM;
193 }
194 ctx->bank1_phys = s5p_mfc_mem_cookie(
195 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_buf);
196 BUG_ON(ctx->bank1_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
197 }
198 /* Allocate only if memory from bank 2 is necessary */
199 if (ctx->bank2_size > 0) {
200 ctx->bank2_buf = vb2_dma_contig_memops.alloc(
201 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], ctx->bank2_size);
202 if (IS_ERR(ctx->bank2_buf)) {
203 ctx->bank2_buf = NULL;
204 mfc_err("Buf alloc for decoding failed (port B)\n");
205 return -ENOMEM;
206 }
207 ctx->bank2_phys = s5p_mfc_mem_cookie(
208 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], ctx->bank2_buf);
209 BUG_ON(ctx->bank2_phys & ((1 << MFC_BANK2_ALIGN_ORDER) - 1));
210 }
211 return 0;
212}
213
214/* Release buffers allocated for codec */
215void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx *ctx)
216{
217 if (ctx->bank1_buf) {
218 vb2_dma_contig_memops.put(ctx->bank1_buf);
219 ctx->bank1_buf = NULL;
220 ctx->bank1_phys = 0;
221 ctx->bank1_size = 0;
222 }
223 if (ctx->bank2_buf) {
224 vb2_dma_contig_memops.put(ctx->bank2_buf);
225 ctx->bank2_buf = NULL;
226 ctx->bank2_phys = 0;
227 ctx->bank2_size = 0;
228 }
229}
230
231/* Allocate memory for instance data buffer */
232int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx)
233{
234 struct s5p_mfc_dev *dev = ctx->dev;
235 struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
236
237 if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
238 ctx->codec_mode == S5P_MFC_CODEC_H264_ENC)
239 ctx->ctx.size = buf_size->h264_ctx;
240 else
241 ctx->ctx.size = buf_size->non_h264_ctx;
242 ctx->ctx.alloc = vb2_dma_contig_memops.alloc(
243 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.size);
244 if (IS_ERR(ctx->ctx.alloc)) {
245 mfc_err("Allocating context buffer failed\n");
246 ctx->ctx.alloc = NULL;
247 return -ENOMEM;
248 }
249 ctx->ctx.dma = s5p_mfc_mem_cookie(
250 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.alloc);
251 BUG_ON(ctx->ctx.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
252 ctx->ctx.ofs = OFFSETA(ctx->ctx.dma);
253 ctx->ctx.virt = vb2_dma_contig_memops.vaddr(ctx->ctx.alloc);
254 if (!ctx->ctx.virt) {
255 mfc_err("Remapping instance buffer failed\n");
256 vb2_dma_contig_memops.put(ctx->ctx.alloc);
257 ctx->ctx.alloc = NULL;
258 ctx->ctx.ofs = 0;
259 ctx->ctx.dma = 0;
260 return -ENOMEM;
261 }
262 /* Zero content of the allocated memory */
263 memset(ctx->ctx.virt, 0, ctx->ctx.size);
264 wmb();
265
266 /* Initialize shared memory */
267 ctx->shm.alloc = vb2_dma_contig_memops.alloc(
268 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], buf_size->shm);
269 if (IS_ERR(ctx->shm.alloc)) {
270 mfc_err("failed to allocate shared memory\n");
271 return PTR_ERR(ctx->shm.alloc);
272 }
273 /* shared memory offset only keeps the offset from base (port a) */
274 ctx->shm.ofs = s5p_mfc_mem_cookie(
275 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->shm.alloc)
276 - dev->bank1;
277 BUG_ON(ctx->shm.ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
278
279 ctx->shm.virt = vb2_dma_contig_memops.vaddr(ctx->shm.alloc);
280 if (!ctx->shm.virt) {
281 vb2_dma_contig_memops.put(ctx->shm.alloc);
282 ctx->shm.alloc = NULL;
283 ctx->shm.ofs = 0;
284 mfc_err("failed to virt addr of shared memory\n");
285 return -ENOMEM;
286 }
287 memset((void *)ctx->shm.virt, 0, buf_size->shm);
288 wmb();
289 return 0;
290}
291
292/* Release instance buffer */
293void s5p_mfc_release_instance_buffer_v5(struct s5p_mfc_ctx *ctx)
294{
295 if (ctx->ctx.alloc) {
296 vb2_dma_contig_memops.put(ctx->ctx.alloc);
297 ctx->ctx.alloc = NULL;
298 ctx->ctx.ofs = 0;
299 ctx->ctx.virt = NULL;
300 ctx->ctx.dma = 0;
301 }
302 if (ctx->shm.alloc) {
303 vb2_dma_contig_memops.put(ctx->shm.alloc);
304 ctx->shm.alloc = NULL;
305 ctx->shm.ofs = 0;
306 ctx->shm.virt = NULL;
307 }
308}
309
310int s5p_mfc_alloc_dev_context_buffer_v5(struct s5p_mfc_dev *dev)
311{
312 /* NOP */
313
314 return 0;
315}
316
317void s5p_mfc_release_dev_context_buffer_v5(struct s5p_mfc_dev *dev)
318{
319 /* NOP */
320}
321
322static void s5p_mfc_write_info_v5(struct s5p_mfc_ctx *ctx, unsigned int data,
323 unsigned int ofs)
324{
325 writel(data, (ctx->shm.virt + ofs));
326 wmb();
327}
328
329static unsigned int s5p_mfc_read_info_v5(struct s5p_mfc_ctx *ctx,
330 unsigned int ofs)
331{
332 rmb();
333 return readl(ctx->shm.virt + ofs);
334}
335
336void s5p_mfc_dec_calc_dpb_size_v5(struct s5p_mfc_ctx *ctx)
337{
338 unsigned int guard_width, guard_height;
339
340 ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN);
341 ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
342 mfc_debug(2,
343 "SEQ Done: Movie dimensions %dx%d, buffer dimensions: %dx%d\n",
344 ctx->img_width, ctx->img_height, ctx->buf_width,
345 ctx->buf_height);
346
347 if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC) {
348 ctx->luma_size = ALIGN(ctx->buf_width * ctx->buf_height,
349 S5P_FIMV_DEC_BUF_ALIGN);
350 ctx->chroma_size = ALIGN(ctx->buf_width *
351 ALIGN((ctx->img_height >> 1),
352 S5P_FIMV_NV12MT_VALIGN),
353 S5P_FIMV_DEC_BUF_ALIGN);
354 ctx->mv_size = ALIGN(ctx->buf_width *
355 ALIGN((ctx->buf_height >> 2),
356 S5P_FIMV_NV12MT_VALIGN),
357 S5P_FIMV_DEC_BUF_ALIGN);
358 } else {
359 guard_width =
360 ALIGN(ctx->img_width + 24, S5P_FIMV_NV12MT_HALIGN);
361 guard_height =
362 ALIGN(ctx->img_height + 16, S5P_FIMV_NV12MT_VALIGN);
363 ctx->luma_size = ALIGN(guard_width * guard_height,
364 S5P_FIMV_DEC_BUF_ALIGN);
365
366 guard_width =
367 ALIGN(ctx->img_width + 16, S5P_FIMV_NV12MT_HALIGN);
368 guard_height =
369 ALIGN((ctx->img_height >> 1) + 4,
370 S5P_FIMV_NV12MT_VALIGN);
371 ctx->chroma_size = ALIGN(guard_width * guard_height,
372 S5P_FIMV_DEC_BUF_ALIGN);
373
374 ctx->mv_size = 0;
375 }
376}
377
378void s5p_mfc_enc_calc_src_size_v5(struct s5p_mfc_ctx *ctx)
379{
380 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) {
381 ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN);
382
383 ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN)
384 * ALIGN(ctx->img_height, S5P_FIMV_NV12M_LVALIGN);
385 ctx->chroma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN)
386 * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12M_CVALIGN);
387
388 ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12M_SALIGN);
389 ctx->chroma_size =
390 ALIGN(ctx->chroma_size, S5P_FIMV_NV12M_SALIGN);
391 } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) {
392 ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN);
393
394 ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
395 * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
396 ctx->chroma_size =
397 ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
398 * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN);
399
400 ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12MT_SALIGN);
401 ctx->chroma_size =
402 ALIGN(ctx->chroma_size, S5P_FIMV_NV12MT_SALIGN);
403 }
404}
405
406/* Set registers for decoding temporary buffers */
407static void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
408{
409 struct s5p_mfc_dev *dev = ctx->dev;
410 struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
411
412 mfc_write(dev, OFFSETA(ctx->dsc.dma), S5P_FIMV_SI_CH0_DESC_ADR);
413 mfc_write(dev, buf_size->dsc, S5P_FIMV_SI_CH0_DESC_SIZE);
414}
415
416/* Set registers for shared buffer */
417static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx)
418{
419 struct s5p_mfc_dev *dev = ctx->dev;
420 mfc_write(dev, ctx->shm.ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR);
421}
422
423/* Set registers for decoding stream buffer */
424int s5p_mfc_set_dec_stream_buffer_v5(struct s5p_mfc_ctx *ctx, int buf_addr,
425 unsigned int start_num_byte, unsigned int buf_size)
426{
427 struct s5p_mfc_dev *dev = ctx->dev;
428
429 mfc_write(dev, OFFSETA(buf_addr), S5P_FIMV_SI_CH0_SB_ST_ADR);
430 mfc_write(dev, ctx->dec_src_buf_size, S5P_FIMV_SI_CH0_CPB_SIZE);
431 mfc_write(dev, buf_size, S5P_FIMV_SI_CH0_SB_FRM_SIZE);
432 s5p_mfc_write_info_v5(ctx, start_num_byte, START_BYTE_NUM);
433 return 0;
434}
435
436/* Set decoding frame buffer */
437int s5p_mfc_set_dec_frame_buffer_v5(struct s5p_mfc_ctx *ctx)
438{
439 unsigned int frame_size, i;
440 unsigned int frame_size_ch, frame_size_mv;
441 struct s5p_mfc_dev *dev = ctx->dev;
442 unsigned int dpb;
443 size_t buf_addr1, buf_addr2;
444 int buf_size1, buf_size2;
445
446 buf_addr1 = ctx->bank1_phys;
447 buf_size1 = ctx->bank1_size;
448 buf_addr2 = ctx->bank2_phys;
449 buf_size2 = ctx->bank2_size;
450 dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) &
451 ~S5P_FIMV_DPB_COUNT_MASK;
452 mfc_write(dev, ctx->total_dpb_count | dpb,
453 S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
454 s5p_mfc_set_shared_buffer(ctx);
455 switch (ctx->codec_mode) {
456 case S5P_MFC_CODEC_H264_DEC:
457 mfc_write(dev, OFFSETA(buf_addr1),
458 S5P_FIMV_H264_VERT_NB_MV_ADR);
459 buf_addr1 += S5P_FIMV_DEC_VERT_NB_MV_SIZE;
460 buf_size1 -= S5P_FIMV_DEC_VERT_NB_MV_SIZE;
461 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H264_NB_IP_ADR);
462 buf_addr1 += S5P_FIMV_DEC_NB_IP_SIZE;
463 buf_size1 -= S5P_FIMV_DEC_NB_IP_SIZE;
464 break;
465 case S5P_MFC_CODEC_MPEG4_DEC:
466 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_NB_DCAC_ADR);
467 buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
468 buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
469 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_UP_NB_MV_ADR);
470 buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
471 buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
472 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_SA_MV_ADR);
473 buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
474 buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
475 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_SP_ADR);
476 buf_addr1 += S5P_FIMV_DEC_STX_PARSER_SIZE;
477 buf_size1 -= S5P_FIMV_DEC_STX_PARSER_SIZE;
478 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_OT_LINE_ADR);
479 buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
480 buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
481 break;
482 case S5P_MFC_CODEC_H263_DEC:
483 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_OT_LINE_ADR);
484 buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
485 buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
486 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_UP_NB_MV_ADR);
487 buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
488 buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
489 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_SA_MV_ADR);
490 buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
491 buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
492 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_NB_DCAC_ADR);
493 buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
494 buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
495 break;
496 case S5P_MFC_CODEC_VC1_DEC:
497 case S5P_MFC_CODEC_VC1RCV_DEC:
498 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_NB_DCAC_ADR);
499 buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
500 buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
501 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_OT_LINE_ADR);
502 buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
503 buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
504 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_UP_NB_MV_ADR);
505 buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
506 buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
507 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_SA_MV_ADR);
508 buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
509 buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
510 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE3_ADR);
511 buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
512 buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
513 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE2_ADR);
514 buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
515 buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
516 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE1_ADR);
517 buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
518 buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
519 break;
520 case S5P_MFC_CODEC_MPEG2_DEC:
521 break;
522 default:
523 mfc_err("Unknown codec for decoding (%x)\n",
524 ctx->codec_mode);
525 return -EINVAL;
526 break;
527 }
528 frame_size = ctx->luma_size;
529 frame_size_ch = ctx->chroma_size;
530 frame_size_mv = ctx->mv_size;
531 mfc_debug(2, "Frm size: %d ch: %d mv: %d\n", frame_size, frame_size_ch,
532 frame_size_mv);
533 for (i = 0; i < ctx->total_dpb_count; i++) {
534 /* Bank2 */
535 mfc_debug(2, "Luma %d: %x\n", i,
536 ctx->dst_bufs[i].cookie.raw.luma);
537 mfc_write(dev, OFFSETB(ctx->dst_bufs[i].cookie.raw.luma),
538 S5P_FIMV_DEC_LUMA_ADR + i * 4);
539 mfc_debug(2, "\tChroma %d: %x\n", i,
540 ctx->dst_bufs[i].cookie.raw.chroma);
541 mfc_write(dev, OFFSETA(ctx->dst_bufs[i].cookie.raw.chroma),
542 S5P_FIMV_DEC_CHROMA_ADR + i * 4);
543 if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC) {
544 mfc_debug(2, "\tBuf2: %x, size: %d\n",
545 buf_addr2, buf_size2);
546 mfc_write(dev, OFFSETB(buf_addr2),
547 S5P_FIMV_H264_MV_ADR + i * 4);
548 buf_addr2 += frame_size_mv;
549 buf_size2 -= frame_size_mv;
550 }
551 }
552 mfc_debug(2, "Buf1: %u, buf_size1: %d\n", buf_addr1, buf_size1);
553 mfc_debug(2, "Buf 1/2 size after: %d/%d (frames %d)\n",
554 buf_size1, buf_size2, ctx->total_dpb_count);
555 if (buf_size1 < 0 || buf_size2 < 0) {
556 mfc_debug(2, "Not enough memory has been allocated\n");
557 return -ENOMEM;
558 }
559 s5p_mfc_write_info_v5(ctx, frame_size, ALLOC_LUMA_DPB_SIZE);
560 s5p_mfc_write_info_v5(ctx, frame_size_ch, ALLOC_CHROMA_DPB_SIZE);
561 if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC)
562 s5p_mfc_write_info_v5(ctx, frame_size_mv, ALLOC_MV_SIZE);
563 mfc_write(dev, ((S5P_FIMV_CH_INIT_BUFS & S5P_FIMV_CH_MASK)
564 << S5P_FIMV_CH_SHIFT) | (ctx->inst_no),
565 S5P_FIMV_SI_CH0_INST_ID);
566 return 0;
567}
568
569/* Set registers for encoding stream buffer */
570int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx,
571 unsigned long addr, unsigned int size)
572{
573 struct s5p_mfc_dev *dev = ctx->dev;
574
575 mfc_write(dev, OFFSETA(addr), S5P_FIMV_ENC_SI_CH0_SB_ADR);
576 mfc_write(dev, size, S5P_FIMV_ENC_SI_CH0_SB_SIZE);
577 return 0;
578}
579
580void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
581 unsigned long y_addr, unsigned long c_addr)
582{
583 struct s5p_mfc_dev *dev = ctx->dev;
584
585 mfc_write(dev, OFFSETB(y_addr), S5P_FIMV_ENC_SI_CH0_CUR_Y_ADR);
586 mfc_write(dev, OFFSETB(c_addr), S5P_FIMV_ENC_SI_CH0_CUR_C_ADR);
587}
588
589void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
590 unsigned long *y_addr, unsigned long *c_addr)
591{
592 struct s5p_mfc_dev *dev = ctx->dev;
593
594 *y_addr = dev->bank2 + (mfc_read(dev, S5P_FIMV_ENCODED_Y_ADDR)
595 << MFC_OFFSET_SHIFT);
596 *c_addr = dev->bank2 + (mfc_read(dev, S5P_FIMV_ENCODED_C_ADDR)
597 << MFC_OFFSET_SHIFT);
598}
599
600/* Set encoding ref & codec buffer */
601int s5p_mfc_set_enc_ref_buffer_v5(struct s5p_mfc_ctx *ctx)
602{
603 struct s5p_mfc_dev *dev = ctx->dev;
604 size_t buf_addr1, buf_addr2;
605 size_t buf_size1, buf_size2;
606 unsigned int enc_ref_y_size, enc_ref_c_size;
607 unsigned int guard_width, guard_height;
608 int i;
609
610 buf_addr1 = ctx->bank1_phys;
611 buf_size1 = ctx->bank1_size;
612 buf_addr2 = ctx->bank2_phys;
613 buf_size2 = ctx->bank2_size;
614 enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
615 * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
616 enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);
617 if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) {
618 enc_ref_c_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
619 * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN);
620 enc_ref_c_size = ALIGN(enc_ref_c_size, S5P_FIMV_NV12MT_SALIGN);
621 } else {
622 guard_width = ALIGN(ctx->img_width + 16,
623 S5P_FIMV_NV12MT_HALIGN);
624 guard_height = ALIGN((ctx->img_height >> 1) + 4,
625 S5P_FIMV_NV12MT_VALIGN);
626 enc_ref_c_size = ALIGN(guard_width * guard_height,
627 S5P_FIMV_NV12MT_SALIGN);
628 }
629 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n", buf_size1, buf_size2);
630 switch (ctx->codec_mode) {
631 case S5P_MFC_CODEC_H264_ENC:
632 for (i = 0; i < 2; i++) {
633 mfc_write(dev, OFFSETA(buf_addr1),
634 S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
635 buf_addr1 += enc_ref_y_size;
636 buf_size1 -= enc_ref_y_size;
637
638 mfc_write(dev, OFFSETB(buf_addr2),
639 S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
640 buf_addr2 += enc_ref_y_size;
641 buf_size2 -= enc_ref_y_size;
642 }
643 for (i = 0; i < 4; i++) {
644 mfc_write(dev, OFFSETB(buf_addr2),
645 S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
646 buf_addr2 += enc_ref_c_size;
647 buf_size2 -= enc_ref_c_size;
648 }
649 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H264_UP_MV_ADR);
650 buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
651 buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
652 mfc_write(dev, OFFSETA(buf_addr1),
653 S5P_FIMV_H264_COZERO_FLAG_ADR);
654 buf_addr1 += S5P_FIMV_ENC_COLFLG_SIZE;
655 buf_size1 -= S5P_FIMV_ENC_COLFLG_SIZE;
656 mfc_write(dev, OFFSETA(buf_addr1),
657 S5P_FIMV_H264_UP_INTRA_MD_ADR);
658 buf_addr1 += S5P_FIMV_ENC_INTRAMD_SIZE;
659 buf_size1 -= S5P_FIMV_ENC_INTRAMD_SIZE;
660 mfc_write(dev, OFFSETB(buf_addr2),
661 S5P_FIMV_H264_UP_INTRA_PRED_ADR);
662 buf_addr2 += S5P_FIMV_ENC_INTRAPRED_SIZE;
663 buf_size2 -= S5P_FIMV_ENC_INTRAPRED_SIZE;
664 mfc_write(dev, OFFSETA(buf_addr1),
665 S5P_FIMV_H264_NBOR_INFO_ADR);
666 buf_addr1 += S5P_FIMV_ENC_NBORINFO_SIZE;
667 buf_size1 -= S5P_FIMV_ENC_NBORINFO_SIZE;
668 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
669 buf_size1, buf_size2);
670 break;
671 case S5P_MFC_CODEC_MPEG4_ENC:
672 for (i = 0; i < 2; i++) {
673 mfc_write(dev, OFFSETA(buf_addr1),
674 S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
675 buf_addr1 += enc_ref_y_size;
676 buf_size1 -= enc_ref_y_size;
677 mfc_write(dev, OFFSETB(buf_addr2),
678 S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
679 buf_addr2 += enc_ref_y_size;
680 buf_size2 -= enc_ref_y_size;
681 }
682 for (i = 0; i < 4; i++) {
683 mfc_write(dev, OFFSETB(buf_addr2),
684 S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
685 buf_addr2 += enc_ref_c_size;
686 buf_size2 -= enc_ref_c_size;
687 }
688 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_UP_MV_ADR);
689 buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
690 buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
691 mfc_write(dev, OFFSETA(buf_addr1),
692 S5P_FIMV_MPEG4_COZERO_FLAG_ADR);
693 buf_addr1 += S5P_FIMV_ENC_COLFLG_SIZE;
694 buf_size1 -= S5P_FIMV_ENC_COLFLG_SIZE;
695 mfc_write(dev, OFFSETA(buf_addr1),
696 S5P_FIMV_MPEG4_ACDC_COEF_ADR);
697 buf_addr1 += S5P_FIMV_ENC_ACDCCOEF_SIZE;
698 buf_size1 -= S5P_FIMV_ENC_ACDCCOEF_SIZE;
699 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
700 buf_size1, buf_size2);
701 break;
702 case S5P_MFC_CODEC_H263_ENC:
703 for (i = 0; i < 2; i++) {
704 mfc_write(dev, OFFSETA(buf_addr1),
705 S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
706 buf_addr1 += enc_ref_y_size;
707 buf_size1 -= enc_ref_y_size;
708 mfc_write(dev, OFFSETB(buf_addr2),
709 S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
710 buf_addr2 += enc_ref_y_size;
711 buf_size2 -= enc_ref_y_size;
712 }
713 for (i = 0; i < 4; i++) {
714 mfc_write(dev, OFFSETB(buf_addr2),
715 S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
716 buf_addr2 += enc_ref_c_size;
717 buf_size2 -= enc_ref_c_size;
718 }
719 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_UP_MV_ADR);
720 buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
721 buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
722 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_ACDC_COEF_ADR);
723 buf_addr1 += S5P_FIMV_ENC_ACDCCOEF_SIZE;
724 buf_size1 -= S5P_FIMV_ENC_ACDCCOEF_SIZE;
725 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
726 buf_size1, buf_size2);
727 break;
728 default:
729 mfc_err("Unknown codec set for encoding: %d\n",
730 ctx->codec_mode);
731 return -EINVAL;
732 }
733 return 0;
734}
735
736static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
737{
738 struct s5p_mfc_dev *dev = ctx->dev;
739 struct s5p_mfc_enc_params *p = &ctx->enc_params;
740 unsigned int reg;
741 unsigned int shm;
742
743 /* width */
744 mfc_write(dev, ctx->img_width, S5P_FIMV_ENC_HSIZE_PX);
745 /* height */
746 mfc_write(dev, ctx->img_height, S5P_FIMV_ENC_VSIZE_PX);
747 /* pictype : enable, IDR period */
748 reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
749 reg |= (1 << 18);
750 reg &= ~(0xFFFF);
751 reg |= p->gop_size;
752 mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
753 mfc_write(dev, 0, S5P_FIMV_ENC_B_RECON_WRITE_ON);
754 /* multi-slice control */
755 /* multi-slice MB number or bit size */
756 mfc_write(dev, p->slice_mode, S5P_FIMV_ENC_MSLICE_CTRL);
757 if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
758 mfc_write(dev, p->slice_mb, S5P_FIMV_ENC_MSLICE_MB);
759 } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
760 mfc_write(dev, p->slice_bit, S5P_FIMV_ENC_MSLICE_BIT);
761 } else {
762 mfc_write(dev, 0, S5P_FIMV_ENC_MSLICE_MB);
763 mfc_write(dev, 0, S5P_FIMV_ENC_MSLICE_BIT);
764 }
765 /* cyclic intra refresh */
766 mfc_write(dev, p->intra_refresh_mb, S5P_FIMV_ENC_CIR_CTRL);
767 /* memory structure cur. frame */
768 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M)
769 mfc_write(dev, 0, S5P_FIMV_ENC_MAP_FOR_CUR);
770 else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT)
771 mfc_write(dev, 3, S5P_FIMV_ENC_MAP_FOR_CUR);
772 /* padding control & value */
773 reg = mfc_read(dev, S5P_FIMV_ENC_PADDING_CTRL);
774 if (p->pad) {
775 /** enable */
776 reg |= (1 << 31);
777 /** cr value */
778 reg &= ~(0xFF << 16);
779 reg |= (p->pad_cr << 16);
780 /** cb value */
781 reg &= ~(0xFF << 8);
782 reg |= (p->pad_cb << 8);
783 /** y value */
784 reg &= ~(0xFF);
785 reg |= (p->pad_luma);
786 } else {
787 /** disable & all value clear */
788 reg = 0;
789 }
790 mfc_write(dev, reg, S5P_FIMV_ENC_PADDING_CTRL);
791 /* rate control config. */
792 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
793 /** frame-level rate control */
794 reg &= ~(0x1 << 9);
795 reg |= (p->rc_frame << 9);
796 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
797 /* bit rate */
798 if (p->rc_frame)
799 mfc_write(dev, p->rc_bitrate,
800 S5P_FIMV_ENC_RC_BIT_RATE);
801 else
802 mfc_write(dev, 0, S5P_FIMV_ENC_RC_BIT_RATE);
803 /* reaction coefficient */
804 if (p->rc_frame)
805 mfc_write(dev, p->rc_reaction_coeff, S5P_FIMV_ENC_RC_RPARA);
806 shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);
807 /* seq header ctrl */
808 shm &= ~(0x1 << 3);
809 shm |= (p->seq_hdr_mode << 3);
810 /* frame skip mode */
811 shm &= ~(0x3 << 1);
812 shm |= (p->frame_skip_mode << 1);
813 s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);
814 /* fixed target bit */
815 s5p_mfc_write_info_v5(ctx, p->fixed_target_bit, RC_CONTROL_CONFIG);
816 return 0;
817}
818
819static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
820{
821 struct s5p_mfc_dev *dev = ctx->dev;
822 struct s5p_mfc_enc_params *p = &ctx->enc_params;
823 struct s5p_mfc_h264_enc_params *p_264 = &p->codec.h264;
824 unsigned int reg;
825 unsigned int shm;
826
827 s5p_mfc_set_enc_params(ctx);
828 /* pictype : number of B */
829 reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
830 /* num_b_frame - 0 ~ 2 */
831 reg &= ~(0x3 << 16);
832 reg |= (p->num_b_frame << 16);
833 mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
834 /* profile & level */
835 reg = mfc_read(dev, S5P_FIMV_ENC_PROFILE);
836 /* level */
837 reg &= ~(0xFF << 8);
838 reg |= (p_264->level << 8);
839 /* profile - 0 ~ 2 */
840 reg &= ~(0x3F);
841 reg |= p_264->profile;
842 mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);
843 /* interlace */
844 mfc_write(dev, p_264->interlace, S5P_FIMV_ENC_PIC_STRUCT);
845 /* height */
846 if (p_264->interlace)
847 mfc_write(dev, ctx->img_height >> 1, S5P_FIMV_ENC_VSIZE_PX);
848 /* loopfilter ctrl */
849 mfc_write(dev, p_264->loop_filter_mode, S5P_FIMV_ENC_LF_CTRL);
850 /* loopfilter alpha offset */
851 if (p_264->loop_filter_alpha < 0) {
852 reg = 0x10;
853 reg |= (0xFF - p_264->loop_filter_alpha) + 1;
854 } else {
855 reg = 0x00;
856 reg |= (p_264->loop_filter_alpha & 0xF);
857 }
858 mfc_write(dev, reg, S5P_FIMV_ENC_ALPHA_OFF);
859 /* loopfilter beta offset */
860 if (p_264->loop_filter_beta < 0) {
861 reg = 0x10;
862 reg |= (0xFF - p_264->loop_filter_beta) + 1;
863 } else {
864 reg = 0x00;
865 reg |= (p_264->loop_filter_beta & 0xF);
866 }
867 mfc_write(dev, reg, S5P_FIMV_ENC_BETA_OFF);
868 /* entropy coding mode */
869 if (p_264->entropy_mode == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
870 mfc_write(dev, 1, S5P_FIMV_ENC_H264_ENTROPY_MODE);
871 else
872 mfc_write(dev, 0, S5P_FIMV_ENC_H264_ENTROPY_MODE);
873 /* number of ref. picture */
874 reg = mfc_read(dev, S5P_FIMV_ENC_H264_NUM_OF_REF);
875 /* num of ref. pictures of P */
876 reg &= ~(0x3 << 5);
877 reg |= (p_264->num_ref_pic_4p << 5);
878 /* max number of ref. pictures */
879 reg &= ~(0x1F);
880 reg |= p_264->max_ref_pic;
881 mfc_write(dev, reg, S5P_FIMV_ENC_H264_NUM_OF_REF);
882 /* 8x8 transform enable */
883 mfc_write(dev, p_264->_8x8_transform, S5P_FIMV_ENC_H264_TRANS_FLAG);
884 /* rate control config. */
885 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
886 /* macroblock level rate control */
887 reg &= ~(0x1 << 8);
888 reg |= (p->rc_mb << 8);
889 /* frame QP */
890 reg &= ~(0x3F);
891 reg |= p_264->rc_frame_qp;
892 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
893 /* frame rate */
894 if (p->rc_frame && p->rc_framerate_denom)
895 mfc_write(dev, p->rc_framerate_num * 1000
896 / p->rc_framerate_denom, S5P_FIMV_ENC_RC_FRAME_RATE);
897 else
898 mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
899 /* max & min value of QP */
900 reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
901 /* max QP */
902 reg &= ~(0x3F << 8);
903 reg |= (p_264->rc_max_qp << 8);
904 /* min QP */
905 reg &= ~(0x3F);
906 reg |= p_264->rc_min_qp;
907 mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
908 /* macroblock adaptive scaling features */
909 if (p->rc_mb) {
910 reg = mfc_read(dev, S5P_FIMV_ENC_RC_MB_CTRL);
911 /* dark region */
912 reg &= ~(0x1 << 3);
913 reg |= (p_264->rc_mb_dark << 3);
914 /* smooth region */
915 reg &= ~(0x1 << 2);
916 reg |= (p_264->rc_mb_smooth << 2);
917 /* static region */
918 reg &= ~(0x1 << 1);
919 reg |= (p_264->rc_mb_static << 1);
920 /* high activity region */
921 reg &= ~(0x1);
922 reg |= p_264->rc_mb_activity;
923 mfc_write(dev, reg, S5P_FIMV_ENC_RC_MB_CTRL);
924 }
925 if (!p->rc_frame && !p->rc_mb) {
926 shm = s5p_mfc_read_info_v5(ctx, P_B_FRAME_QP);
927 shm &= ~(0xFFF);
928 shm |= ((p_264->rc_b_frame_qp & 0x3F) << 6);
929 shm |= (p_264->rc_p_frame_qp & 0x3F);
930 s5p_mfc_write_info_v5(ctx, shm, P_B_FRAME_QP);
931 }
932 /* extended encoder ctrl */
933 shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);
934 /* AR VUI control */
935 shm &= ~(0x1 << 15);
936 shm |= (p_264->vui_sar << 1);
937 s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);
938 if (p_264->vui_sar) {
939 /* aspect ration IDC */
940 shm = s5p_mfc_read_info_v5(ctx, SAMPLE_ASPECT_RATIO_IDC);
941 shm &= ~(0xFF);
942 shm |= p_264->vui_sar_idc;
943 s5p_mfc_write_info_v5(ctx, shm, SAMPLE_ASPECT_RATIO_IDC);
944 if (p_264->vui_sar_idc == 0xFF) {
945 /* sample AR info */
946 shm = s5p_mfc_read_info_v5(ctx, EXTENDED_SAR);
947 shm &= ~(0xFFFFFFFF);
948 shm |= p_264->vui_ext_sar_width << 16;
949 shm |= p_264->vui_ext_sar_height;
950 s5p_mfc_write_info_v5(ctx, shm, EXTENDED_SAR);
951 }
952 }
953 /* intra picture period for H.264 */
954 shm = s5p_mfc_read_info_v5(ctx, H264_I_PERIOD);
955 /* control */
956 shm &= ~(0x1 << 16);
957 shm |= (p_264->open_gop << 16);
958 /* value */
959 if (p_264->open_gop) {
960 shm &= ~(0xFFFF);
961 shm |= p_264->open_gop_size;
962 }
963 s5p_mfc_write_info_v5(ctx, shm, H264_I_PERIOD);
964 /* extended encoder ctrl */
965 shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);
966 /* vbv buffer size */
967 if (p->frame_skip_mode ==
968 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
969 shm &= ~(0xFFFF << 16);
970 shm |= (p_264->cpb_size << 16);
971 }
972 s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);
973 return 0;
974}
975
976static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
977{
978 struct s5p_mfc_dev *dev = ctx->dev;
979 struct s5p_mfc_enc_params *p = &ctx->enc_params;
980 struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;
981 unsigned int reg;
982 unsigned int shm;
983 unsigned int framerate;
984
985 s5p_mfc_set_enc_params(ctx);
986 /* pictype : number of B */
987 reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
988 /* num_b_frame - 0 ~ 2 */
989 reg &= ~(0x3 << 16);
990 reg |= (p->num_b_frame << 16);
991 mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
992 /* profile & level */
993 reg = mfc_read(dev, S5P_FIMV_ENC_PROFILE);
994 /* level */
995 reg &= ~(0xFF << 8);
996 reg |= (p_mpeg4->level << 8);
997 /* profile - 0 ~ 2 */
998 reg &= ~(0x3F);
999 reg |= p_mpeg4->profile;
1000 mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);
1001 /* quarter_pixel */
1002 mfc_write(dev, p_mpeg4->quarter_pixel, S5P_FIMV_ENC_MPEG4_QUART_PXL);
1003 /* qp */
1004 if (!p->rc_frame) {
1005 shm = s5p_mfc_read_info_v5(ctx, P_B_FRAME_QP);
1006 shm &= ~(0xFFF);
1007 shm |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 6);
1008 shm |= (p_mpeg4->rc_p_frame_qp & 0x3F);
1009 s5p_mfc_write_info_v5(ctx, shm, P_B_FRAME_QP);
1010 }
1011 /* frame rate */
1012 if (p->rc_frame) {
1013 if (p->rc_framerate_denom > 0) {
1014 framerate = p->rc_framerate_num * 1000 /
1015 p->rc_framerate_denom;
1016 mfc_write(dev, framerate,
1017 S5P_FIMV_ENC_RC_FRAME_RATE);
1018 shm = s5p_mfc_read_info_v5(ctx, RC_VOP_TIMING);
1019 shm &= ~(0xFFFFFFFF);
1020 shm |= (1 << 31);
1021 shm |= ((p->rc_framerate_num & 0x7FFF) << 16);
1022 shm |= (p->rc_framerate_denom & 0xFFFF);
1023 s5p_mfc_write_info_v5(ctx, shm, RC_VOP_TIMING);
1024 }
1025 } else {
1026 mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
1027 }
1028 /* rate control config. */
1029 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
1030 /* frame QP */
1031 reg &= ~(0x3F);
1032 reg |= p_mpeg4->rc_frame_qp;
1033 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
1034 /* max & min value of QP */
1035 reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
1036 /* max QP */
1037 reg &= ~(0x3F << 8);
1038 reg |= (p_mpeg4->rc_max_qp << 8);
1039 /* min QP */
1040 reg &= ~(0x3F);
1041 reg |= p_mpeg4->rc_min_qp;
1042 mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
1043 /* extended encoder ctrl */
1044 shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);
1045 /* vbv buffer size */
1046 if (p->frame_skip_mode ==
1047 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
1048 shm &= ~(0xFFFF << 16);
1049 shm |= (p->vbv_size << 16);
1050 }
1051 s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);
1052 return 0;
1053}
1054
1055static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
1056{
1057 struct s5p_mfc_dev *dev = ctx->dev;
1058 struct s5p_mfc_enc_params *p = &ctx->enc_params;
1059 struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;
1060 unsigned int reg;
1061 unsigned int shm;
1062
1063 s5p_mfc_set_enc_params(ctx);
1064 /* qp */
1065 if (!p->rc_frame) {
1066 shm = s5p_mfc_read_info_v5(ctx, P_B_FRAME_QP);
1067 shm &= ~(0xFFF);
1068 shm |= (p_h263->rc_p_frame_qp & 0x3F);
1069 s5p_mfc_write_info_v5(ctx, shm, P_B_FRAME_QP);
1070 }
1071 /* frame rate */
1072 if (p->rc_frame && p->rc_framerate_denom)
1073 mfc_write(dev, p->rc_framerate_num * 1000
1074 / p->rc_framerate_denom, S5P_FIMV_ENC_RC_FRAME_RATE);
1075 else
1076 mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
1077 /* rate control config. */
1078 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
1079 /* frame QP */
1080 reg &= ~(0x3F);
1081 reg |= p_h263->rc_frame_qp;
1082 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
1083 /* max & min value of QP */
1084 reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
1085 /* max QP */
1086 reg &= ~(0x3F << 8);
1087 reg |= (p_h263->rc_max_qp << 8);
1088 /* min QP */
1089 reg &= ~(0x3F);
1090 reg |= p_h263->rc_min_qp;
1091 mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
1092 /* extended encoder ctrl */
1093 shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);
1094 /* vbv buffer size */
1095 if (p->frame_skip_mode ==
1096 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
1097 shm &= ~(0xFFFF << 16);
1098 shm |= (p->vbv_size << 16);
1099 }
1100 s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);
1101 return 0;
1102}
1103
1104/* Initialize decoding */
1105int s5p_mfc_init_decode_v5(struct s5p_mfc_ctx *ctx)
1106{
1107 struct s5p_mfc_dev *dev = ctx->dev;
1108
1109 s5p_mfc_set_shared_buffer(ctx);
1110 /* Setup loop filter, for decoding this is only valid for MPEG4 */
1111 if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_DEC)
1112 mfc_write(dev, ctx->loop_filter_mpeg4, S5P_FIMV_ENC_LF_CTRL);
1113 else
1114 mfc_write(dev, 0, S5P_FIMV_ENC_LF_CTRL);
1115 mfc_write(dev, ((ctx->slice_interface & S5P_FIMV_SLICE_INT_MASK) <<
1116 S5P_FIMV_SLICE_INT_SHIFT) | (ctx->display_delay_enable <<
1117 S5P_FIMV_DDELAY_ENA_SHIFT) | ((ctx->display_delay &
1118 S5P_FIMV_DDELAY_VAL_MASK) << S5P_FIMV_DDELAY_VAL_SHIFT),
1119 S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
1120 mfc_write(dev,
1121 ((S5P_FIMV_CH_SEQ_HEADER & S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT)
1122 | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1123 return 0;
1124}
1125
1126static void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush)
1127{
1128 struct s5p_mfc_dev *dev = ctx->dev;
1129 unsigned int dpb;
1130
1131 if (flush)
1132 dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) | (
1133 S5P_FIMV_DPB_FLUSH_MASK << S5P_FIMV_DPB_FLUSH_SHIFT);
1134 else
1135 dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) &
1136 ~(S5P_FIMV_DPB_FLUSH_MASK << S5P_FIMV_DPB_FLUSH_SHIFT);
1137 mfc_write(dev, dpb, S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
1138}
1139
1140/* Decode a single frame */
1141int s5p_mfc_decode_one_frame_v5(struct s5p_mfc_ctx *ctx,
1142 enum s5p_mfc_decode_arg last_frame)
1143{
1144 struct s5p_mfc_dev *dev = ctx->dev;
1145
1146 mfc_write(dev, ctx->dec_dst_flag, S5P_FIMV_SI_CH0_RELEASE_BUF);
1147 s5p_mfc_set_shared_buffer(ctx);
1148 s5p_mfc_set_flush(ctx, ctx->dpb_flush_flag);
1149 /* Issue different commands to instance basing on whether it
1150 * is the last frame or not. */
1151 switch (last_frame) {
1152 case MFC_DEC_FRAME:
1153 mfc_write(dev, ((S5P_FIMV_CH_FRAME_START & S5P_FIMV_CH_MASK) <<
1154 S5P_FIMV_CH_SHIFT) | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1155 break;
1156 case MFC_DEC_LAST_FRAME:
1157 mfc_write(dev, ((S5P_FIMV_CH_LAST_FRAME & S5P_FIMV_CH_MASK) <<
1158 S5P_FIMV_CH_SHIFT) | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1159 break;
1160 case MFC_DEC_RES_CHANGE:
1161 mfc_write(dev, ((S5P_FIMV_CH_FRAME_START_REALLOC &
1162 S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT) | (ctx->inst_no),
1163 S5P_FIMV_SI_CH0_INST_ID);
1164 break;
1165 }
1166 mfc_debug(2, "Decoding a usual frame\n");
1167 return 0;
1168}
1169
1170int s5p_mfc_init_encode_v5(struct s5p_mfc_ctx *ctx)
1171{
1172 struct s5p_mfc_dev *dev = ctx->dev;
1173
1174 if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC)
1175 s5p_mfc_set_enc_params_h264(ctx);
1176 else if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_ENC)
1177 s5p_mfc_set_enc_params_mpeg4(ctx);
1178 else if (ctx->codec_mode == S5P_MFC_CODEC_H263_ENC)
1179 s5p_mfc_set_enc_params_h263(ctx);
1180 else {
1181 mfc_err("Unknown codec for encoding (%x)\n",
1182 ctx->codec_mode);
1183 return -EINVAL;
1184 }
1185 s5p_mfc_set_shared_buffer(ctx);
1186 mfc_write(dev, ((S5P_FIMV_CH_SEQ_HEADER << 16) & 0x70000) |
1187 (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1188 return 0;
1189}
1190
1191/* Encode a single frame */
1192int s5p_mfc_encode_one_frame_v5(struct s5p_mfc_ctx *ctx)
1193{
1194 struct s5p_mfc_dev *dev = ctx->dev;
1195 int cmd;
1196 /* memory structure cur. frame */
1197 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M)
1198 mfc_write(dev, 0, S5P_FIMV_ENC_MAP_FOR_CUR);
1199 else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT)
1200 mfc_write(dev, 3, S5P_FIMV_ENC_MAP_FOR_CUR);
1201 s5p_mfc_set_shared_buffer(ctx);
1202
1203 if (ctx->state == MFCINST_FINISHING)
1204 cmd = S5P_FIMV_CH_LAST_FRAME;
1205 else
1206 cmd = S5P_FIMV_CH_FRAME_START;
1207 mfc_write(dev, ((cmd & S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT)
1208 | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1209
1210 return 0;
1211}
1212
1213static int s5p_mfc_get_new_ctx(struct s5p_mfc_dev *dev)
1214{
1215 unsigned long flags;
1216 int new_ctx;
1217 int cnt;
1218
1219 spin_lock_irqsave(&dev->condlock, flags);
1220 new_ctx = (dev->curr_ctx + 1) % MFC_NUM_CONTEXTS;
1221 cnt = 0;
1222 while (!test_bit(new_ctx, &dev->ctx_work_bits)) {
1223 new_ctx = (new_ctx + 1) % MFC_NUM_CONTEXTS;
1224 if (++cnt > MFC_NUM_CONTEXTS) {
1225 /* No contexts to run */
1226 spin_unlock_irqrestore(&dev->condlock, flags);
1227 return -EAGAIN;
1228 }
1229 }
1230 spin_unlock_irqrestore(&dev->condlock, flags);
1231 return new_ctx;
1232}
1233
1234static void s5p_mfc_run_res_change(struct s5p_mfc_ctx *ctx)
1235{
1236 struct s5p_mfc_dev *dev = ctx->dev;
1237
1238 s5p_mfc_set_dec_stream_buffer_v5(ctx, 0, 0, 0);
1239 dev->curr_ctx = ctx->num;
1240 s5p_mfc_clean_ctx_int_flags(ctx);
1241 s5p_mfc_decode_one_frame_v5(ctx, MFC_DEC_RES_CHANGE);
1242}
1243
1244static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame)
1245{
1246 struct s5p_mfc_dev *dev = ctx->dev;
1247 struct s5p_mfc_buf *temp_vb;
1248 unsigned long flags;
1249 unsigned int index;
1250
1251 spin_lock_irqsave(&dev->irqlock, flags);
1252 /* Frames are being decoded */
1253 if (list_empty(&ctx->src_queue)) {
1254 mfc_debug(2, "No src buffers\n");
1255 spin_unlock_irqrestore(&dev->irqlock, flags);
1256 return -EAGAIN;
1257 }
1258 /* Get the next source buffer */
1259 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1260 temp_vb->flags |= MFC_BUF_FLAG_USED;
1261 s5p_mfc_set_dec_stream_buffer_v5(ctx,
1262 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
1263 ctx->consumed_stream, temp_vb->b->v4l2_planes[0].bytesused);
1264 spin_unlock_irqrestore(&dev->irqlock, flags);
1265 index = temp_vb->b->v4l2_buf.index;
1266 dev->curr_ctx = ctx->num;
1267 s5p_mfc_clean_ctx_int_flags(ctx);
1268 if (temp_vb->b->v4l2_planes[0].bytesused == 0) {
1269 last_frame = MFC_DEC_LAST_FRAME;
1270 mfc_debug(2, "Setting ctx->state to FINISHING\n");
1271 ctx->state = MFCINST_FINISHING;
1272 }
1273 s5p_mfc_decode_one_frame_v5(ctx, last_frame);
1274 return 0;
1275}
1276
1277static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
1278{
1279 struct s5p_mfc_dev *dev = ctx->dev;
1280 unsigned long flags;
1281 struct s5p_mfc_buf *dst_mb;
1282 struct s5p_mfc_buf *src_mb;
1283 unsigned long src_y_addr, src_c_addr, dst_addr;
1284 unsigned int dst_size;
1285
1286 spin_lock_irqsave(&dev->irqlock, flags);
1287 if (list_empty(&ctx->src_queue) && ctx->state != MFCINST_FINISHING) {
1288 mfc_debug(2, "no src buffers\n");
1289 spin_unlock_irqrestore(&dev->irqlock, flags);
1290 return -EAGAIN;
1291 }
1292 if (list_empty(&ctx->dst_queue)) {
1293 mfc_debug(2, "no dst buffers\n");
1294 spin_unlock_irqrestore(&dev->irqlock, flags);
1295 return -EAGAIN;
1296 }
1297 if (list_empty(&ctx->src_queue)) {
1298 /* send null frame */
1299 s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->bank2, dev->bank2);
1300 src_mb = NULL;
1301 } else {
1302 src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
1303 list);
1304 src_mb->flags |= MFC_BUF_FLAG_USED;
1305 if (src_mb->b->v4l2_planes[0].bytesused == 0) {
1306 /* send null frame */
1307 s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->bank2,
1308 dev->bank2);
1309 ctx->state = MFCINST_FINISHING;
1310 } else {
1311 src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b,
1312 0);
1313 src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b,
1314 1);
1315 s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
1316 src_c_addr);
1317 if (src_mb->flags & MFC_BUF_FLAG_EOS)
1318 ctx->state = MFCINST_FINISHING;
1319 }
1320 }
1321 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
1322 dst_mb->flags |= MFC_BUF_FLAG_USED;
1323 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
1324 dst_size = vb2_plane_size(dst_mb->b, 0);
1325 s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size);
1326 spin_unlock_irqrestore(&dev->irqlock, flags);
1327 dev->curr_ctx = ctx->num;
1328 s5p_mfc_clean_ctx_int_flags(ctx);
1329 mfc_debug(2, "encoding buffer with index=%d state=%d",
1330 src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state);
1331 s5p_mfc_encode_one_frame_v5(ctx);
1332 return 0;
1333}
1334
1335static void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
1336{
1337 struct s5p_mfc_dev *dev = ctx->dev;
1338 unsigned long flags;
1339 struct s5p_mfc_buf *temp_vb;
1340
1341 /* Initializing decoding - parsing header */
1342 spin_lock_irqsave(&dev->irqlock, flags);
1343 mfc_debug(2, "Preparing to init decoding\n");
1344 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1345 s5p_mfc_set_dec_desc_buffer(ctx);
1346 mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
1347 s5p_mfc_set_dec_stream_buffer_v5(ctx,
1348 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
1349 0, temp_vb->b->v4l2_planes[0].bytesused);
1350 spin_unlock_irqrestore(&dev->irqlock, flags);
1351 dev->curr_ctx = ctx->num;
1352 s5p_mfc_clean_ctx_int_flags(ctx);
1353 s5p_mfc_init_decode_v5(ctx);
1354}
1355
1356static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
1357{
1358 struct s5p_mfc_dev *dev = ctx->dev;
1359 unsigned long flags;
1360 struct s5p_mfc_buf *dst_mb;
1361 unsigned long dst_addr;
1362 unsigned int dst_size;
1363
1364 s5p_mfc_set_enc_ref_buffer_v5(ctx);
1365 spin_lock_irqsave(&dev->irqlock, flags);
1366 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
1367 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
1368 dst_size = vb2_plane_size(dst_mb->b, 0);
1369 s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size);
1370 spin_unlock_irqrestore(&dev->irqlock, flags);
1371 dev->curr_ctx = ctx->num;
1372 s5p_mfc_clean_ctx_int_flags(ctx);
1373 s5p_mfc_init_encode_v5(ctx);
1374}
1375
1376static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
1377{
1378 struct s5p_mfc_dev *dev = ctx->dev;
1379 unsigned long flags;
1380 struct s5p_mfc_buf *temp_vb;
1381 int ret;
1382
1383 /*
1384 * Header was parsed now starting processing
1385 * First set the output frame buffers
1386 */
1387 if (ctx->capture_state != QUEUE_BUFS_MMAPED) {
1388 mfc_err("It seems that not all destionation buffers were "
1389 "mmaped\nMFC requires that all destination are mmaped "
1390 "before starting processing\n");
1391 return -EAGAIN;
1392 }
1393 spin_lock_irqsave(&dev->irqlock, flags);
1394 if (list_empty(&ctx->src_queue)) {
1395 mfc_err("Header has been deallocated in the middle of"
1396 " initialization\n");
1397 spin_unlock_irqrestore(&dev->irqlock, flags);
1398 return -EIO;
1399 }
1400 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1401 mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
1402 s5p_mfc_set_dec_stream_buffer_v5(ctx,
1403 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
1404 0, temp_vb->b->v4l2_planes[0].bytesused);
1405 spin_unlock_irqrestore(&dev->irqlock, flags);
1406 dev->curr_ctx = ctx->num;
1407 s5p_mfc_clean_ctx_int_flags(ctx);
1408 ret = s5p_mfc_set_dec_frame_buffer_v5(ctx);
1409 if (ret) {
1410 mfc_err("Failed to alloc frame mem\n");
1411 ctx->state = MFCINST_ERROR;
1412 }
1413 return ret;
1414}
1415
1416/* Try running an operation on hardware */
1417void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev)
1418{
1419 struct s5p_mfc_ctx *ctx;
1420 int new_ctx;
1421 unsigned int ret = 0;
1422
1423 if (test_bit(0, &dev->enter_suspend)) {
1424 mfc_debug(1, "Entering suspend so do not schedule any jobs\n");
1425 return;
1426 }
1427 /* Check whether hardware is not running */
1428 if (test_and_set_bit(0, &dev->hw_lock) != 0) {
1429 /* This is perfectly ok, the scheduled ctx should wait */
1430 mfc_debug(1, "Couldn't lock HW\n");
1431 return;
1432 }
1433 /* Choose the context to run */
1434 new_ctx = s5p_mfc_get_new_ctx(dev);
1435 if (new_ctx < 0) {
1436 /* No contexts to run */
1437 if (test_and_clear_bit(0, &dev->hw_lock) == 0) {
1438 mfc_err("Failed to unlock hardware\n");
1439 return;
1440 }
1441 mfc_debug(1, "No ctx is scheduled to be run\n");
1442 return;
1443 }
1444 ctx = dev->ctx[new_ctx];
1445 /* Got context to run in ctx */
1446 /*
1447 * Last frame has already been sent to MFC.
1448 * Now obtaining frames from MFC buffer
1449 */
1450 s5p_mfc_clock_on();
1451 if (ctx->type == MFCINST_DECODER) {
1452 s5p_mfc_set_dec_desc_buffer(ctx);
1453 switch (ctx->state) {
1454 case MFCINST_FINISHING:
1455 s5p_mfc_run_dec_frame(ctx, MFC_DEC_LAST_FRAME);
1456 break;
1457 case MFCINST_RUNNING:
1458 ret = s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME);
1459 break;
1460 case MFCINST_INIT:
1461 s5p_mfc_clean_ctx_int_flags(ctx);
1462 ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd,
1463 ctx);
1464 break;
1465 case MFCINST_RETURN_INST:
1466 s5p_mfc_clean_ctx_int_flags(ctx);
1467 ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd,
1468 ctx);
1469 break;
1470 case MFCINST_GOT_INST:
1471 s5p_mfc_run_init_dec(ctx);
1472 break;
1473 case MFCINST_HEAD_PARSED:
1474 ret = s5p_mfc_run_init_dec_buffers(ctx);
1475 mfc_debug(1, "head parsed\n");
1476 break;
1477 case MFCINST_RES_CHANGE_INIT:
1478 s5p_mfc_run_res_change(ctx);
1479 break;
1480 case MFCINST_RES_CHANGE_FLUSH:
1481 s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME);
1482 break;
1483 case MFCINST_RES_CHANGE_END:
1484 mfc_debug(2, "Finished remaining frames after resolution change\n");
1485 ctx->capture_state = QUEUE_FREE;
1486 mfc_debug(2, "Will re-init the codec\n");
1487 s5p_mfc_run_init_dec(ctx);
1488 break;
1489 default:
1490 ret = -EAGAIN;
1491 }
1492 } else if (ctx->type == MFCINST_ENCODER) {
1493 switch (ctx->state) {
1494 case MFCINST_FINISHING:
1495 case MFCINST_RUNNING:
1496 ret = s5p_mfc_run_enc_frame(ctx);
1497 break;
1498 case MFCINST_INIT:
1499 s5p_mfc_clean_ctx_int_flags(ctx);
1500 ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd,
1501 ctx);
1502 break;
1503 case MFCINST_RETURN_INST:
1504 s5p_mfc_clean_ctx_int_flags(ctx);
1505 ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd,
1506 ctx);
1507 break;
1508 case MFCINST_GOT_INST:
1509 s5p_mfc_run_init_enc(ctx);
1510 break;
1511 default:
1512 ret = -EAGAIN;
1513 }
1514 } else {
1515 mfc_err("Invalid context type: %d\n", ctx->type);
1516 ret = -EAGAIN;
1517 }
1518
1519 if (ret) {
1520 /* Free hardware lock */
1521 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
1522 mfc_err("Failed to unlock hardware\n");
1523
1524 /* This is in deed imporant, as no operation has been
1525 * scheduled, reduce the clock count as no one will
1526 * ever do this, because no interrupt related to this try_run
1527 * will ever come from hardware. */
1528 s5p_mfc_clock_off();
1529 }
1530}
1531
1532
1533void s5p_mfc_cleanup_queue_v5(struct list_head *lh, struct vb2_queue *vq)
1534{
1535 struct s5p_mfc_buf *b;
1536 int i;
1537
1538 while (!list_empty(lh)) {
1539 b = list_entry(lh->next, struct s5p_mfc_buf, list);
1540 for (i = 0; i < b->b->num_planes; i++)
1541 vb2_set_plane_payload(b->b, i, 0);
1542 vb2_buffer_done(b->b, VB2_BUF_STATE_ERROR);
1543 list_del(&b->list);
1544 }
1545}
1546
1547void s5p_mfc_clear_int_flags_v5(struct s5p_mfc_dev *dev)
1548{
1549 mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT);
1550 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
1551 mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID);
1552}
1553
1554int s5p_mfc_get_dspl_y_adr_v5(struct s5p_mfc_dev *dev)
1555{
1556 return mfc_read(dev, S5P_FIMV_SI_DISPLAY_Y_ADR) << MFC_OFFSET_SHIFT;
1557}
1558
1559int s5p_mfc_get_dec_y_adr_v5(struct s5p_mfc_dev *dev)
1560{
1561 return mfc_read(dev, S5P_FIMV_SI_DECODE_Y_ADR) << MFC_OFFSET_SHIFT;
1562}
1563
1564int s5p_mfc_get_dspl_status_v5(struct s5p_mfc_dev *dev)
1565{
1566 return mfc_read(dev, S5P_FIMV_SI_DISPLAY_STATUS);
1567}
1568
1569int s5p_mfc_get_dec_status_v5(struct s5p_mfc_dev *dev)
1570{
1571 return mfc_read(dev, S5P_FIMV_SI_DECODE_STATUS);
1572}
1573
1574int s5p_mfc_get_dec_frame_type_v5(struct s5p_mfc_dev *dev)
1575{
1576 return mfc_read(dev, S5P_FIMV_DECODE_FRAME_TYPE) &
1577 S5P_FIMV_DECODE_FRAME_MASK;
1578}
1579
1580int s5p_mfc_get_disp_frame_type_v5(struct s5p_mfc_ctx *ctx)
1581{
1582 return (s5p_mfc_read_info_v5(ctx, DISP_PIC_FRAME_TYPE) >>
1583 S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT) &
1584 S5P_FIMV_DECODE_FRAME_MASK;
1585}
1586
1587int s5p_mfc_get_consumed_stream_v5(struct s5p_mfc_dev *dev)
1588{
1589 return mfc_read(dev, S5P_FIMV_SI_CONSUMED_BYTES);
1590}
1591
1592int s5p_mfc_get_int_reason_v5(struct s5p_mfc_dev *dev)
1593{
1594 int reason;
1595 reason = mfc_read(dev, S5P_FIMV_RISC2HOST_CMD) &
1596 S5P_FIMV_RISC2HOST_CMD_MASK;
1597 switch (reason) {
1598 case S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET:
1599 reason = S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET;
1600 break;
1601 case S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET:
1602 reason = S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET;
1603 break;
1604 case S5P_FIMV_R2H_CMD_SEQ_DONE_RET:
1605 reason = S5P_MFC_R2H_CMD_SEQ_DONE_RET;
1606 break;
1607 case S5P_FIMV_R2H_CMD_FRAME_DONE_RET:
1608 reason = S5P_MFC_R2H_CMD_FRAME_DONE_RET;
1609 break;
1610 case S5P_FIMV_R2H_CMD_SLICE_DONE_RET:
1611 reason = S5P_MFC_R2H_CMD_SLICE_DONE_RET;
1612 break;
1613 case S5P_FIMV_R2H_CMD_SYS_INIT_RET:
1614 reason = S5P_MFC_R2H_CMD_SYS_INIT_RET;
1615 break;
1616 case S5P_FIMV_R2H_CMD_FW_STATUS_RET:
1617 reason = S5P_MFC_R2H_CMD_FW_STATUS_RET;
1618 break;
1619 case S5P_FIMV_R2H_CMD_SLEEP_RET:
1620 reason = S5P_MFC_R2H_CMD_SLEEP_RET;
1621 break;
1622 case S5P_FIMV_R2H_CMD_WAKEUP_RET:
1623 reason = S5P_MFC_R2H_CMD_WAKEUP_RET;
1624 break;
1625 case S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET:
1626 reason = S5P_MFC_R2H_CMD_INIT_BUFFERS_RET;
1627 break;
1628 case S5P_FIMV_R2H_CMD_ENC_COMPLETE_RET:
1629 reason = S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET;
1630 break;
1631 case S5P_FIMV_R2H_CMD_ERR_RET:
1632 reason = S5P_MFC_R2H_CMD_ERR_RET;
1633 break;
1634 default:
1635 reason = S5P_MFC_R2H_CMD_EMPTY;
1636 };
1637 return reason;
1638}
1639
1640int s5p_mfc_get_int_err_v5(struct s5p_mfc_dev *dev)
1641{
1642 return mfc_read(dev, S5P_FIMV_RISC2HOST_ARG2);
1643}
1644
1645int s5p_mfc_err_dec_v5(unsigned int err)
1646{
1647 return (err & S5P_FIMV_ERR_DEC_MASK) >> S5P_FIMV_ERR_DEC_SHIFT;
1648}
1649
1650int s5p_mfc_err_dspl_v5(unsigned int err)
1651{
1652 return (err & S5P_FIMV_ERR_DSPL_MASK) >> S5P_FIMV_ERR_DSPL_SHIFT;
1653}
1654
1655int s5p_mfc_get_img_width_v5(struct s5p_mfc_dev *dev)
1656{
1657 return mfc_read(dev, S5P_FIMV_SI_HRESOL);
1658}
1659
1660int s5p_mfc_get_img_height_v5(struct s5p_mfc_dev *dev)
1661{
1662 return mfc_read(dev, S5P_FIMV_SI_VRESOL);
1663}
1664
1665int s5p_mfc_get_dpb_count_v5(struct s5p_mfc_dev *dev)
1666{
1667 return mfc_read(dev, S5P_FIMV_SI_BUF_NUMBER);
1668}
1669
1670int s5p_mfc_get_mv_count_v5(struct s5p_mfc_dev *dev)
1671{
1672 /* NOP */
1673 return -1;
1674}
1675
1676int s5p_mfc_get_inst_no_v5(struct s5p_mfc_dev *dev)
1677{
1678 return mfc_read(dev, S5P_FIMV_RISC2HOST_ARG1);
1679}
1680
1681int s5p_mfc_get_enc_strm_size_v5(struct s5p_mfc_dev *dev)
1682{
1683 return mfc_read(dev, S5P_FIMV_ENC_SI_STRM_SIZE);
1684}
1685
1686int s5p_mfc_get_enc_slice_type_v5(struct s5p_mfc_dev *dev)
1687{
1688 return mfc_read(dev, S5P_FIMV_ENC_SI_SLICE_TYPE);
1689}
1690
1691int s5p_mfc_get_enc_dpb_count_v5(struct s5p_mfc_dev *dev)
1692{
1693 return -1;
1694}
1695
1696int s5p_mfc_get_enc_pic_count_v5(struct s5p_mfc_dev *dev)
1697{
1698 return mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT);
1699}
1700
1701int s5p_mfc_get_sei_avail_status_v5(struct s5p_mfc_ctx *ctx)
1702{
1703 return s5p_mfc_read_info_v5(ctx, FRAME_PACK_SEI_AVAIL);
1704}
1705
1706int s5p_mfc_get_mvc_num_views_v5(struct s5p_mfc_dev *dev)
1707{
1708 return -1;
1709}
1710
1711int s5p_mfc_get_mvc_view_id_v5(struct s5p_mfc_dev *dev)
1712{
1713 return -1;
1714}
1715
1716unsigned int s5p_mfc_get_pic_type_top_v5(struct s5p_mfc_ctx *ctx)
1717{
1718 return s5p_mfc_read_info_v5(ctx, PIC_TIME_TOP);
1719}
1720
1721unsigned int s5p_mfc_get_pic_type_bot_v5(struct s5p_mfc_ctx *ctx)
1722{
1723 return s5p_mfc_read_info_v5(ctx, PIC_TIME_BOT);
1724}
1725
1726unsigned int s5p_mfc_get_crop_info_h_v5(struct s5p_mfc_ctx *ctx)
1727{
1728 return s5p_mfc_read_info_v5(ctx, CROP_INFO_H);
1729}
1730
1731unsigned int s5p_mfc_get_crop_info_v_v5(struct s5p_mfc_ctx *ctx)
1732{
1733 return s5p_mfc_read_info_v5(ctx, CROP_INFO_V);
1734}
1735
1736/* Initialize opr function pointers for MFC v5 */
1737static struct s5p_mfc_hw_ops s5p_mfc_ops_v5 = {
1738 .alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v5,
1739 .release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v5,
1740 .alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v5,
1741 .release_codec_buffers = s5p_mfc_release_codec_buffers_v5,
1742 .alloc_instance_buffer = s5p_mfc_alloc_instance_buffer_v5,
1743 .release_instance_buffer = s5p_mfc_release_instance_buffer_v5,
1744 .alloc_dev_context_buffer = s5p_mfc_alloc_dev_context_buffer_v5,
1745 .release_dev_context_buffer = s5p_mfc_release_dev_context_buffer_v5,
1746 .dec_calc_dpb_size = s5p_mfc_dec_calc_dpb_size_v5,
1747 .enc_calc_src_size = s5p_mfc_enc_calc_src_size_v5,
1748 .set_dec_stream_buffer = s5p_mfc_set_dec_stream_buffer_v5,
1749 .set_dec_frame_buffer = s5p_mfc_set_dec_frame_buffer_v5,
1750 .set_enc_stream_buffer = s5p_mfc_set_enc_stream_buffer_v5,
1751 .set_enc_frame_buffer = s5p_mfc_set_enc_frame_buffer_v5,
1752 .get_enc_frame_buffer = s5p_mfc_get_enc_frame_buffer_v5,
1753 .set_enc_ref_buffer = s5p_mfc_set_enc_ref_buffer_v5,
1754 .init_decode = s5p_mfc_init_decode_v5,
1755 .init_encode = s5p_mfc_init_encode_v5,
1756 .encode_one_frame = s5p_mfc_encode_one_frame_v5,
1757 .try_run = s5p_mfc_try_run_v5,
1758 .cleanup_queue = s5p_mfc_cleanup_queue_v5,
1759 .clear_int_flags = s5p_mfc_clear_int_flags_v5,
1760 .write_info = s5p_mfc_write_info_v5,
1761 .read_info = s5p_mfc_read_info_v5,
1762 .get_dspl_y_adr = s5p_mfc_get_dspl_y_adr_v5,
1763 .get_dec_y_adr = s5p_mfc_get_dec_y_adr_v5,
1764 .get_dspl_status = s5p_mfc_get_dspl_status_v5,
1765 .get_dec_status = s5p_mfc_get_dec_status_v5,
1766 .get_dec_frame_type = s5p_mfc_get_dec_frame_type_v5,
1767 .get_disp_frame_type = s5p_mfc_get_disp_frame_type_v5,
1768 .get_consumed_stream = s5p_mfc_get_consumed_stream_v5,
1769 .get_int_reason = s5p_mfc_get_int_reason_v5,
1770 .get_int_err = s5p_mfc_get_int_err_v5,
1771 .err_dec = s5p_mfc_err_dec_v5,
1772 .err_dspl = s5p_mfc_err_dspl_v5,
1773 .get_img_width = s5p_mfc_get_img_width_v5,
1774 .get_img_height = s5p_mfc_get_img_height_v5,
1775 .get_dpb_count = s5p_mfc_get_dpb_count_v5,
1776 .get_mv_count = s5p_mfc_get_mv_count_v5,
1777 .get_inst_no = s5p_mfc_get_inst_no_v5,
1778 .get_enc_strm_size = s5p_mfc_get_enc_strm_size_v5,
1779 .get_enc_slice_type = s5p_mfc_get_enc_slice_type_v5,
1780 .get_enc_dpb_count = s5p_mfc_get_enc_dpb_count_v5,
1781 .get_enc_pic_count = s5p_mfc_get_enc_pic_count_v5,
1782 .get_sei_avail_status = s5p_mfc_get_sei_avail_status_v5,
1783 .get_mvc_num_views = s5p_mfc_get_mvc_num_views_v5,
1784 .get_mvc_view_id = s5p_mfc_get_mvc_view_id_v5,
1785 .get_pic_type_top = s5p_mfc_get_pic_type_top_v5,
1786 .get_pic_type_bot = s5p_mfc_get_pic_type_bot_v5,
1787 .get_crop_info_h = s5p_mfc_get_crop_info_h_v5,
1788 .get_crop_info_v = s5p_mfc_get_crop_info_v_v5,
1789};
1790
1791struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void)
1792{
1793 return &s5p_mfc_ops_v5;
1794}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_shm.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h
index 416ebd7ba35a..ffee39a127d5 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_shm.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h
@@ -1,17 +1,22 @@
1/* 1/*
2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_shm.h 2 * drivers/media/platform/samsung/mfc5/s5p_mfc_opr_v5.h
3 * 3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 4 * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
5 * http://www.samsung.com/ 5 * Contains declarations of hw related functions.
6 *
7 * Kamil Debski, Copyright (C) 2011 Samsung Electronics
8 * http://www.samsung.com/
6 * 9 *
7 * This program is free software; you can redistribute it and/or modify 10 * 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 11 * it under the terms of the GNU General Public License version 2 as
9 * the Free Software Foundation; either version 2 of the License, or 12 * published by the Free Software Foundation.
10 * (at your option) any later version.
11 */ 13 */
12 14
13#ifndef S5P_MFC_SHM_H_ 15#ifndef S5P_MFC_OPR_V5_H_
14#define S5P_MFC_SHM_H_ 16#define S5P_MFC_OPR_V5_H_
17
18#include "s5p_mfc_common.h"
19#include "s5p_mfc_opr.h"
15 20
16enum MFC_SHM_OFS { 21enum MFC_SHM_OFS {
17 EXTENEDED_DECODE_STATUS = 0x00, /* D */ 22 EXTENEDED_DECODE_STATUS = 0x00, /* D */
@@ -71,20 +76,10 @@ enum MFC_SHM_OFS {
71 DBG_HISTORY_INPUT1 = 0xD4, /* C */ 76 DBG_HISTORY_INPUT1 = 0xD4, /* C */
72 DBG_HISTORY_OUTPUT = 0xD8, /* C */ 77 DBG_HISTORY_OUTPUT = 0xD8, /* C */
73 HIERARCHICAL_P_QP = 0xE0, /* E, H.264 */ 78 HIERARCHICAL_P_QP = 0xE0, /* E, H.264 */
79 FRAME_PACK_SEI_ENABLE = 0x168, /* C */
80 FRAME_PACK_SEI_AVAIL = 0x16c, /* D */
81 FRAME_PACK_SEI_INFO = 0x17c, /* E */
74}; 82};
75 83
76int s5p_mfc_init_shm(struct s5p_mfc_ctx *ctx); 84struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void);
77 85#endif /* S5P_MFC_OPR_H_ */
78#define s5p_mfc_write_shm(ctx, x, ofs) \
79 do { \
80 writel(x, (ctx->shm + ofs)); \
81 wmb(); \
82 } while (0)
83
84static inline u32 s5p_mfc_read_shm(struct s5p_mfc_ctx *ctx, unsigned int ofs)
85{
86 rmb();
87 return readl(ctx->shm + ofs);
88}
89
90#endif /* S5P_MFC_SHM_H_ */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
new file mode 100644
index 000000000000..50b5bee3c44e
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -0,0 +1,1956 @@
1/*
2 * drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
3 *
4 * Samsung MFC (Multi Function Codec - FIMV) driver
5 * This file contains hw related functions.
6 *
7 * 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#undef DEBUG
16
17#include <linux/delay.h>
18#include <linux/mm.h>
19#include <linux/io.h>
20#include <linux/jiffies.h>
21#include <linux/firmware.h>
22#include <linux/err.h>
23#include <linux/sched.h>
24#include <linux/dma-mapping.h>
25
26#include <asm/cacheflush.h>
27
28#include "s5p_mfc_common.h"
29#include "s5p_mfc_cmd.h"
30#include "s5p_mfc_intr.h"
31#include "s5p_mfc_pm.h"
32#include "s5p_mfc_debug.h"
33#include "s5p_mfc_opr.h"
34#include "s5p_mfc_opr_v6.h"
35
36/* #define S5P_MFC_DEBUG_REGWRITE */
37#ifdef S5P_MFC_DEBUG_REGWRITE
38#undef writel
39#define writel(v, r) \
40 do { \
41 pr_err("MFCWRITE(%p): %08x\n", r, (unsigned int)v); \
42 __raw_writel(v, r); \
43 } while (0)
44#endif /* S5P_MFC_DEBUG_REGWRITE */
45
46#define READL(offset) readl(dev->regs_base + (offset))
47#define WRITEL(data, offset) writel((data), dev->regs_base + (offset))
48#define OFFSETA(x) (((x) - dev->port_a) >> S5P_FIMV_MEM_OFFSET)
49#define OFFSETB(x) (((x) - dev->port_b) >> S5P_FIMV_MEM_OFFSET)
50
51/* Allocate temporary buffers for decoding */
52int s5p_mfc_alloc_dec_temp_buffers_v6(struct s5p_mfc_ctx *ctx)
53{
54 /* NOP */
55
56 return 0;
57}
58
59/* Release temproary buffers for decoding */
60void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx)
61{
62 /* NOP */
63}
64
65int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev)
66{
67 /* NOP */
68 return -1;
69}
70
71/* Allocate codec buffers */
72int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
73{
74 struct s5p_mfc_dev *dev = ctx->dev;
75 unsigned int mb_width, mb_height;
76
77 mb_width = MB_WIDTH(ctx->img_width);
78 mb_height = MB_HEIGHT(ctx->img_height);
79
80 if (ctx->type == MFCINST_DECODER) {
81 mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",
82 ctx->luma_size, ctx->chroma_size, ctx->mv_size);
83 mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);
84 } else if (ctx->type == MFCINST_ENCODER) {
85 ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 *
86 ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
87 S5P_FIMV_TMV_BUFFER_ALIGN_V6);
88 ctx->luma_dpb_size = ALIGN((mb_width * mb_height) *
89 S5P_FIMV_LUMA_MB_TO_PIXEL_V6,
90 S5P_FIMV_LUMA_DPB_BUFFER_ALIGN_V6);
91 ctx->chroma_dpb_size = ALIGN((mb_width * mb_height) *
92 S5P_FIMV_CHROMA_MB_TO_PIXEL_V6,
93 S5P_FIMV_CHROMA_DPB_BUFFER_ALIGN_V6);
94 ctx->me_buffer_size = ALIGN(S5P_FIMV_ME_BUFFER_SIZE_V6(
95 ctx->img_width, ctx->img_height,
96 mb_width, mb_height),
97 S5P_FIMV_ME_BUFFER_ALIGN_V6);
98
99 mfc_debug(2, "recon luma size: %d chroma size: %d\n",
100 ctx->luma_dpb_size, ctx->chroma_dpb_size);
101 } else {
102 return -EINVAL;
103 }
104
105 /* Codecs have different memory requirements */
106 switch (ctx->codec_mode) {
107 case S5P_MFC_CODEC_H264_DEC:
108 case S5P_MFC_CODEC_H264_MVC_DEC:
109 ctx->scratch_buf_size =
110 S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V6(
111 mb_width,
112 mb_height);
113 ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
114 S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
115 ctx->bank1_size =
116 ctx->scratch_buf_size +
117 (ctx->mv_count * ctx->mv_size);
118 break;
119 case S5P_MFC_CODEC_MPEG4_DEC:
120 ctx->scratch_buf_size =
121 S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V6(
122 mb_width,
123 mb_height);
124 ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
125 S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
126 ctx->bank1_size = ctx->scratch_buf_size;
127 break;
128 case S5P_MFC_CODEC_VC1RCV_DEC:
129 case S5P_MFC_CODEC_VC1_DEC:
130 ctx->scratch_buf_size =
131 S5P_FIMV_SCRATCH_BUF_SIZE_VC1_DEC_V6(
132 mb_width,
133 mb_height);
134 ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
135 S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
136 ctx->bank1_size = ctx->scratch_buf_size;
137 break;
138 case S5P_MFC_CODEC_MPEG2_DEC:
139 ctx->bank1_size = 0;
140 ctx->bank2_size = 0;
141 break;
142 case S5P_MFC_CODEC_H263_DEC:
143 ctx->scratch_buf_size =
144 S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6(
145 mb_width,
146 mb_height);
147 ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
148 S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
149 ctx->bank1_size = ctx->scratch_buf_size;
150 break;
151 case S5P_MFC_CODEC_VP8_DEC:
152 ctx->scratch_buf_size =
153 S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V6(
154 mb_width,
155 mb_height);
156 ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
157 S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
158 ctx->bank1_size = ctx->scratch_buf_size;
159 break;
160 case S5P_MFC_CODEC_H264_ENC:
161 ctx->scratch_buf_size =
162 S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V6(
163 mb_width,
164 mb_height);
165 ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
166 S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
167 ctx->bank1_size =
168 ctx->scratch_buf_size + ctx->tmv_buffer_size +
169 (ctx->dpb_count * (ctx->luma_dpb_size +
170 ctx->chroma_dpb_size + ctx->me_buffer_size));
171 ctx->bank2_size = 0;
172 break;
173 case S5P_MFC_CODEC_MPEG4_ENC:
174 case S5P_MFC_CODEC_H263_ENC:
175 ctx->scratch_buf_size =
176 S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_ENC_V6(
177 mb_width,
178 mb_height);
179 ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
180 S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
181 ctx->bank1_size =
182 ctx->scratch_buf_size + ctx->tmv_buffer_size +
183 (ctx->dpb_count * (ctx->luma_dpb_size +
184 ctx->chroma_dpb_size + ctx->me_buffer_size));
185 ctx->bank2_size = 0;
186 break;
187 default:
188 break;
189 }
190
191 /* Allocate only if memory from bank 1 is necessary */
192 if (ctx->bank1_size > 0) {
193 ctx->bank1_buf = vb2_dma_contig_memops.alloc(
194 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_size);
195 if (IS_ERR(ctx->bank1_buf)) {
196 ctx->bank1_buf = 0;
197 pr_err("Buf alloc for decoding failed (port A)\n");
198 return -ENOMEM;
199 }
200 ctx->bank1_phys = s5p_mfc_mem_cookie(
201 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_buf);
202 BUG_ON(ctx->bank1_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
203 }
204
205 return 0;
206}
207
208/* Release buffers allocated for codec */
209void s5p_mfc_release_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
210{
211 if (ctx->bank1_buf) {
212 vb2_dma_contig_memops.put(ctx->bank1_buf);
213 ctx->bank1_buf = 0;
214 ctx->bank1_phys = 0;
215 ctx->bank1_size = 0;
216 }
217}
218
219/* Allocate memory for instance data buffer */
220int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx)
221{
222 struct s5p_mfc_dev *dev = ctx->dev;
223 struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
224
225 mfc_debug_enter();
226
227 switch (ctx->codec_mode) {
228 case S5P_MFC_CODEC_H264_DEC:
229 case S5P_MFC_CODEC_H264_MVC_DEC:
230 ctx->ctx.size = buf_size->h264_dec_ctx;
231 break;
232 case S5P_MFC_CODEC_MPEG4_DEC:
233 case S5P_MFC_CODEC_H263_DEC:
234 case S5P_MFC_CODEC_VC1RCV_DEC:
235 case S5P_MFC_CODEC_VC1_DEC:
236 case S5P_MFC_CODEC_MPEG2_DEC:
237 case S5P_MFC_CODEC_VP8_DEC:
238 ctx->ctx.size = buf_size->other_dec_ctx;
239 break;
240 case S5P_MFC_CODEC_H264_ENC:
241 ctx->ctx.size = buf_size->h264_enc_ctx;
242 break;
243 case S5P_MFC_CODEC_MPEG4_ENC:
244 case S5P_MFC_CODEC_H263_ENC:
245 ctx->ctx.size = buf_size->other_enc_ctx;
246 break;
247 default:
248 ctx->ctx.size = 0;
249 mfc_err("Codec type(%d) should be checked!\n", ctx->codec_mode);
250 break;
251 }
252
253 ctx->ctx.alloc = vb2_dma_contig_memops.alloc(
254 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.size);
255 if (IS_ERR(ctx->ctx.alloc)) {
256 mfc_err("Allocating context buffer failed.\n");
257 return PTR_ERR(ctx->ctx.alloc);
258 }
259
260 ctx->ctx.dma = s5p_mfc_mem_cookie(
261 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.alloc);
262
263 ctx->ctx.virt = vb2_dma_contig_memops.vaddr(ctx->ctx.alloc);
264 if (!ctx->ctx.virt) {
265 vb2_dma_contig_memops.put(ctx->ctx.alloc);
266 ctx->ctx.alloc = NULL;
267 ctx->ctx.dma = 0;
268 ctx->ctx.virt = NULL;
269
270 mfc_err("Remapping context buffer failed.\n");
271 return -ENOMEM;
272 }
273
274 memset(ctx->ctx.virt, 0, ctx->ctx.size);
275 wmb();
276
277 mfc_debug_leave();
278
279 return 0;
280}
281
282/* Release instance buffer */
283void s5p_mfc_release_instance_buffer_v6(struct s5p_mfc_ctx *ctx)
284{
285 mfc_debug_enter();
286
287 if (ctx->ctx.alloc) {
288 vb2_dma_contig_memops.put(ctx->ctx.alloc);
289 ctx->ctx.alloc = NULL;
290 ctx->ctx.dma = 0;
291 ctx->ctx.virt = NULL;
292 }
293
294 mfc_debug_leave();
295}
296
297/* Allocate context buffers for SYS_INIT */
298int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev)
299{
300 struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
301
302 mfc_debug_enter();
303
304 dev->ctx_buf.alloc = vb2_dma_contig_memops.alloc(
305 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], buf_size->dev_ctx);
306 if (IS_ERR(dev->ctx_buf.alloc)) {
307 mfc_err("Allocating DESC buffer failed.\n");
308 return PTR_ERR(dev->ctx_buf.alloc);
309 }
310
311 dev->ctx_buf.dma = s5p_mfc_mem_cookie(
312 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX],
313 dev->ctx_buf.alloc);
314
315 dev->ctx_buf.virt = vb2_dma_contig_memops.vaddr(dev->ctx_buf.alloc);
316 if (!dev->ctx_buf.virt) {
317 vb2_dma_contig_memops.put(dev->ctx_buf.alloc);
318 dev->ctx_buf.alloc = NULL;
319 dev->ctx_buf.dma = 0;
320
321 mfc_err("Remapping DESC buffer failed.\n");
322 return -ENOMEM;
323 }
324
325 memset(dev->ctx_buf.virt, 0, buf_size->dev_ctx);
326 wmb();
327
328 mfc_debug_leave();
329
330 return 0;
331}
332
333/* Release context buffers for SYS_INIT */
334void s5p_mfc_release_dev_context_buffer_v6(struct s5p_mfc_dev *dev)
335{
336 if (dev->ctx_buf.alloc) {
337 vb2_dma_contig_memops.put(dev->ctx_buf.alloc);
338 dev->ctx_buf.alloc = NULL;
339 dev->ctx_buf.dma = 0;
340 dev->ctx_buf.virt = NULL;
341 }
342}
343
344static int calc_plane(int width, int height)
345{
346 int mbX, mbY;
347
348 mbX = DIV_ROUND_UP(width, S5P_FIMV_NUM_PIXELS_IN_MB_ROW_V6);
349 mbY = DIV_ROUND_UP(height, S5P_FIMV_NUM_PIXELS_IN_MB_COL_V6);
350
351 if (width * height < S5P_FIMV_MAX_FRAME_SIZE_V6)
352 mbY = (mbY + 1) / 2 * 2;
353
354 return (mbX * S5P_FIMV_NUM_PIXELS_IN_MB_COL_V6) *
355 (mbY * S5P_FIMV_NUM_PIXELS_IN_MB_ROW_V6);
356}
357
358void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
359{
360 ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6);
361 ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6);
362 mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
363 "buffer dimensions: %dx%d\n", ctx->img_width,
364 ctx->img_height, ctx->buf_width, ctx->buf_height);
365
366 ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
367 ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1));
368 if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
369 ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) {
370 ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width,
371 ctx->img_height);
372 ctx->mv_size = ALIGN(ctx->mv_size, 16);
373 } else {
374 ctx->mv_size = 0;
375 }
376}
377
378void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
379{
380 unsigned int mb_width, mb_height;
381
382 mb_width = MB_WIDTH(ctx->img_width);
383 mb_height = MB_HEIGHT(ctx->img_height);
384
385 ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN_V6);
386 ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
387 ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
388}
389
390/* Set registers for decoding stream buffer */
391int s5p_mfc_set_dec_stream_buffer_v6(struct s5p_mfc_ctx *ctx, int buf_addr,
392 unsigned int start_num_byte, unsigned int strm_size)
393{
394 struct s5p_mfc_dev *dev = ctx->dev;
395 struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;
396
397 mfc_debug_enter();
398 mfc_debug(2, "inst_no: %d, buf_addr: 0x%08x,\n"
399 "buf_size: 0x%08x (%d)\n",
400 ctx->inst_no, buf_addr, strm_size, strm_size);
401 WRITEL(strm_size, S5P_FIMV_D_STREAM_DATA_SIZE_V6);
402 WRITEL(buf_addr, S5P_FIMV_D_CPB_BUFFER_ADDR_V6);
403 WRITEL(buf_size->cpb, S5P_FIMV_D_CPB_BUFFER_SIZE_V6);
404 WRITEL(start_num_byte, S5P_FIMV_D_CPB_BUFFER_OFFSET_V6);
405
406 mfc_debug_leave();
407 return 0;
408}
409
410/* Set decoding frame buffer */
411int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
412{
413 unsigned int frame_size, i;
414 unsigned int frame_size_ch, frame_size_mv;
415 struct s5p_mfc_dev *dev = ctx->dev;
416 size_t buf_addr1;
417 int buf_size1;
418 int align_gap;
419
420 buf_addr1 = ctx->bank1_phys;
421 buf_size1 = ctx->bank1_size;
422
423 mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1);
424 mfc_debug(2, "Total DPB COUNT: %d\n", ctx->total_dpb_count);
425 mfc_debug(2, "Setting display delay to %d\n", ctx->display_delay);
426
427 WRITEL(ctx->total_dpb_count, S5P_FIMV_D_NUM_DPB_V6);
428 WRITEL(ctx->luma_size, S5P_FIMV_D_LUMA_DPB_SIZE_V6);
429 WRITEL(ctx->chroma_size, S5P_FIMV_D_CHROMA_DPB_SIZE_V6);
430
431 WRITEL(buf_addr1, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V6);
432 WRITEL(ctx->scratch_buf_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V6);
433 buf_addr1 += ctx->scratch_buf_size;
434 buf_size1 -= ctx->scratch_buf_size;
435
436 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC ||
437 ctx->codec_mode == S5P_FIMV_CODEC_H264_MVC_DEC){
438 WRITEL(ctx->mv_size, S5P_FIMV_D_MV_BUFFER_SIZE_V6);
439 WRITEL(ctx->mv_count, S5P_FIMV_D_NUM_MV_V6);
440 }
441
442 frame_size = ctx->luma_size;
443 frame_size_ch = ctx->chroma_size;
444 frame_size_mv = ctx->mv_size;
445 mfc_debug(2, "Frame size: %d ch: %d mv: %d\n",
446 frame_size, frame_size_ch, frame_size_mv);
447
448 for (i = 0; i < ctx->total_dpb_count; i++) {
449 /* Bank2 */
450 mfc_debug(2, "Luma %d: %x\n", i,
451 ctx->dst_bufs[i].cookie.raw.luma);
452 WRITEL(ctx->dst_bufs[i].cookie.raw.luma,
453 S5P_FIMV_D_LUMA_DPB_V6 + i * 4);
454 mfc_debug(2, "\tChroma %d: %x\n", i,
455 ctx->dst_bufs[i].cookie.raw.chroma);
456 WRITEL(ctx->dst_bufs[i].cookie.raw.chroma,
457 S5P_FIMV_D_CHROMA_DPB_V6 + i * 4);
458 }
459 if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
460 ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) {
461 for (i = 0; i < ctx->mv_count; i++) {
462 /* To test alignment */
463 align_gap = buf_addr1;
464 buf_addr1 = ALIGN(buf_addr1, 16);
465 align_gap = buf_addr1 - align_gap;
466 buf_size1 -= align_gap;
467
468 mfc_debug(2, "\tBuf1: %x, size: %d\n",
469 buf_addr1, buf_size1);
470 WRITEL(buf_addr1, S5P_FIMV_D_MV_BUFFER_V6 + i * 4);
471 buf_addr1 += frame_size_mv;
472 buf_size1 -= frame_size_mv;
473 }
474 }
475
476 mfc_debug(2, "Buf1: %u, buf_size1: %d (frames %d)\n",
477 buf_addr1, buf_size1, ctx->total_dpb_count);
478 if (buf_size1 < 0) {
479 mfc_debug(2, "Not enough memory has been allocated.\n");
480 return -ENOMEM;
481 }
482
483 WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
484 s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
485 S5P_FIMV_CH_INIT_BUFS_V6, NULL);
486
487 mfc_debug(2, "After setting buffers.\n");
488 return 0;
489}
490
491/* Set registers for encoding stream buffer */
492int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
493 unsigned long addr, unsigned int size)
494{
495 struct s5p_mfc_dev *dev = ctx->dev;
496
497 WRITEL(addr, S5P_FIMV_E_STREAM_BUFFER_ADDR_V6); /* 16B align */
498 WRITEL(size, S5P_FIMV_E_STREAM_BUFFER_SIZE_V6);
499
500 mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d",
501 addr, size);
502
503 return 0;
504}
505
506void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
507 unsigned long y_addr, unsigned long c_addr)
508{
509 struct s5p_mfc_dev *dev = ctx->dev;
510
511 WRITEL(y_addr, S5P_FIMV_E_SOURCE_LUMA_ADDR_V6); /* 256B align */
512 WRITEL(c_addr, S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6);
513
514 mfc_debug(2, "enc src y buf addr: 0x%08lx", y_addr);
515 mfc_debug(2, "enc src c buf addr: 0x%08lx", c_addr);
516}
517
518void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
519 unsigned long *y_addr, unsigned long *c_addr)
520{
521 struct s5p_mfc_dev *dev = ctx->dev;
522 unsigned long enc_recon_y_addr, enc_recon_c_addr;
523
524 *y_addr = READL(S5P_FIMV_E_ENCODED_SOURCE_LUMA_ADDR_V6);
525 *c_addr = READL(S5P_FIMV_E_ENCODED_SOURCE_CHROMA_ADDR_V6);
526
527 enc_recon_y_addr = READL(S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6);
528 enc_recon_c_addr = READL(S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6);
529
530 mfc_debug(2, "recon y addr: 0x%08lx", enc_recon_y_addr);
531 mfc_debug(2, "recon c addr: 0x%08lx", enc_recon_c_addr);
532}
533
534/* Set encoding ref & codec buffer */
535int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx)
536{
537 struct s5p_mfc_dev *dev = ctx->dev;
538 size_t buf_addr1, buf_size1;
539 int i;
540
541 mfc_debug_enter();
542
543 buf_addr1 = ctx->bank1_phys;
544 buf_size1 = ctx->bank1_size;
545
546 mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1);
547
548 for (i = 0; i < ctx->dpb_count; i++) {
549 WRITEL(buf_addr1, S5P_FIMV_E_LUMA_DPB_V6 + (4 * i));
550 buf_addr1 += ctx->luma_dpb_size;
551 WRITEL(buf_addr1, S5P_FIMV_E_CHROMA_DPB_V6 + (4 * i));
552 buf_addr1 += ctx->chroma_dpb_size;
553 WRITEL(buf_addr1, S5P_FIMV_E_ME_BUFFER_V6 + (4 * i));
554 buf_addr1 += ctx->me_buffer_size;
555 buf_size1 -= (ctx->luma_dpb_size + ctx->chroma_dpb_size +
556 ctx->me_buffer_size);
557 }
558
559 WRITEL(buf_addr1, S5P_FIMV_E_SCRATCH_BUFFER_ADDR_V6);
560 WRITEL(ctx->scratch_buf_size, S5P_FIMV_E_SCRATCH_BUFFER_SIZE_V6);
561 buf_addr1 += ctx->scratch_buf_size;
562 buf_size1 -= ctx->scratch_buf_size;
563
564 WRITEL(buf_addr1, S5P_FIMV_E_TMV_BUFFER0_V6);
565 buf_addr1 += ctx->tmv_buffer_size >> 1;
566 WRITEL(buf_addr1, S5P_FIMV_E_TMV_BUFFER1_V6);
567 buf_addr1 += ctx->tmv_buffer_size >> 1;
568 buf_size1 -= ctx->tmv_buffer_size;
569
570 mfc_debug(2, "Buf1: %u, buf_size1: %d (ref frames %d)\n",
571 buf_addr1, buf_size1, ctx->dpb_count);
572 if (buf_size1 < 0) {
573 mfc_debug(2, "Not enough memory has been allocated.\n");
574 return -ENOMEM;
575 }
576
577 WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
578 s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
579 S5P_FIMV_CH_INIT_BUFS_V6, NULL);
580
581 mfc_debug_leave();
582
583 return 0;
584}
585
586static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx)
587{
588 struct s5p_mfc_dev *dev = ctx->dev;
589
590 /* multi-slice control */
591 /* multi-slice MB number or bit size */
592 WRITEL(ctx->slice_mode, S5P_FIMV_E_MSLICE_MODE_V6);
593 if (ctx->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
594 WRITEL(ctx->slice_size.mb, S5P_FIMV_E_MSLICE_SIZE_MB_V6);
595 } else if (ctx->slice_mode ==
596 V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
597 WRITEL(ctx->slice_size.bits, S5P_FIMV_E_MSLICE_SIZE_BITS_V6);
598 } else {
599 WRITEL(0x0, S5P_FIMV_E_MSLICE_SIZE_MB_V6);
600 WRITEL(0x0, S5P_FIMV_E_MSLICE_SIZE_BITS_V6);
601 }
602
603 return 0;
604}
605
606static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
607{
608 struct s5p_mfc_dev *dev = ctx->dev;
609 struct s5p_mfc_enc_params *p = &ctx->enc_params;
610 unsigned int reg = 0;
611
612 mfc_debug_enter();
613
614 /* width */
615 WRITEL(ctx->img_width, S5P_FIMV_E_FRAME_WIDTH_V6); /* 16 align */
616 /* height */
617 WRITEL(ctx->img_height, S5P_FIMV_E_FRAME_HEIGHT_V6); /* 16 align */
618
619 /* cropped width */
620 WRITEL(ctx->img_width, S5P_FIMV_E_CROPPED_FRAME_WIDTH_V6);
621 /* cropped height */
622 WRITEL(ctx->img_height, S5P_FIMV_E_CROPPED_FRAME_HEIGHT_V6);
623 /* cropped offset */
624 WRITEL(0x0, S5P_FIMV_E_FRAME_CROP_OFFSET_V6);
625
626 /* pictype : IDR period */
627 reg = 0;
628 reg |= p->gop_size & 0xFFFF;
629 WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6);
630
631 /* multi-slice control */
632 /* multi-slice MB number or bit size */
633 ctx->slice_mode = p->slice_mode;
634 reg = 0;
635 if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
636 reg |= (0x1 << 3);
637 WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
638 ctx->slice_size.mb = p->slice_mb;
639 } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
640 reg |= (0x1 << 3);
641 WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
642 ctx->slice_size.bits = p->slice_bit;
643 } else {
644 reg &= ~(0x1 << 3);
645 WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
646 }
647
648 s5p_mfc_set_slice_mode(ctx);
649
650 /* cyclic intra refresh */
651 WRITEL(p->intra_refresh_mb, S5P_FIMV_E_IR_SIZE_V6);
652 reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
653 if (p->intra_refresh_mb == 0)
654 reg &= ~(0x1 << 4);
655 else
656 reg |= (0x1 << 4);
657 WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
658
659 /* 'NON_REFERENCE_STORE_ENABLE' for debugging */
660 reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
661 reg &= ~(0x1 << 9);
662 WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
663
664 /* memory structure cur. frame */
665 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) {
666 /* 0: Linear, 1: 2D tiled*/
667 reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
668 reg &= ~(0x1 << 7);
669 WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
670 /* 0: NV12(CbCr), 1: NV21(CrCb) */
671 WRITEL(0x0, S5P_FIMV_PIXEL_FORMAT_V6);
672 } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV21M) {
673 /* 0: Linear, 1: 2D tiled*/
674 reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
675 reg &= ~(0x1 << 7);
676 WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
677 /* 0: NV12(CbCr), 1: NV21(CrCb) */
678 WRITEL(0x1, S5P_FIMV_PIXEL_FORMAT_V6);
679 } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) {
680 /* 0: Linear, 1: 2D tiled*/
681 reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
682 reg |= (0x1 << 7);
683 WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
684 /* 0: NV12(CbCr), 1: NV21(CrCb) */
685 WRITEL(0x0, S5P_FIMV_PIXEL_FORMAT_V6);
686 }
687
688 /* memory structure recon. frame */
689 /* 0: Linear, 1: 2D tiled */
690 reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
691 reg |= (0x1 << 8);
692 WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
693
694 /* padding control & value */
695 WRITEL(0x0, S5P_FIMV_E_PADDING_CTRL_V6);
696 if (p->pad) {
697 reg = 0;
698 /** enable */
699 reg |= (1 << 31);
700 /** cr value */
701 reg |= ((p->pad_cr & 0xFF) << 16);
702 /** cb value */
703 reg |= ((p->pad_cb & 0xFF) << 8);
704 /** y value */
705 reg |= p->pad_luma & 0xFF;
706 WRITEL(reg, S5P_FIMV_E_PADDING_CTRL_V6);
707 }
708
709 /* rate control config. */
710 reg = 0;
711 /* frame-level rate control */
712 reg |= ((p->rc_frame & 0x1) << 9);
713 WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
714
715 /* bit rate */
716 if (p->rc_frame)
717 WRITEL(p->rc_bitrate,
718 S5P_FIMV_E_RC_BIT_RATE_V6);
719 else
720 WRITEL(1, S5P_FIMV_E_RC_BIT_RATE_V6);
721
722 /* reaction coefficient */
723 if (p->rc_frame) {
724 if (p->rc_reaction_coeff < TIGHT_CBR_MAX) /* tight CBR */
725 WRITEL(1, S5P_FIMV_E_RC_RPARAM_V6);
726 else /* loose CBR */
727 WRITEL(2, S5P_FIMV_E_RC_RPARAM_V6);
728 }
729
730 /* seq header ctrl */
731 reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
732 reg &= ~(0x1 << 2);
733 reg |= ((p->seq_hdr_mode & 0x1) << 2);
734
735 /* frame skip mode */
736 reg &= ~(0x3);
737 reg |= (p->frame_skip_mode & 0x3);
738 WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
739
740 /* 'DROP_CONTROL_ENABLE', disable */
741 reg = READL(S5P_FIMV_E_RC_CONFIG_V6);
742 reg &= ~(0x1 << 10);
743 WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
744
745 /* setting for MV range [16, 256] */
746 reg = 0;
747 reg &= ~(0x3FFF);
748 reg = 256;
749 WRITEL(reg, S5P_FIMV_E_MV_HOR_RANGE_V6);
750
751 reg = 0;
752 reg &= ~(0x3FFF);
753 reg = 256;
754 WRITEL(reg, S5P_FIMV_E_MV_VER_RANGE_V6);
755
756 WRITEL(0x0, S5P_FIMV_E_FRAME_INSERTION_V6);
757 WRITEL(0x0, S5P_FIMV_E_ROI_BUFFER_ADDR_V6);
758 WRITEL(0x0, S5P_FIMV_E_PARAM_CHANGE_V6);
759 WRITEL(0x0, S5P_FIMV_E_RC_ROI_CTRL_V6);
760 WRITEL(0x0, S5P_FIMV_E_PICTURE_TAG_V6);
761
762 WRITEL(0x0, S5P_FIMV_E_BIT_COUNT_ENABLE_V6);
763 WRITEL(0x0, S5P_FIMV_E_MAX_BIT_COUNT_V6);
764 WRITEL(0x0, S5P_FIMV_E_MIN_BIT_COUNT_V6);
765
766 WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_ADDR_V6);
767 WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_SIZE_V6);
768
769 mfc_debug_leave();
770
771 return 0;
772}
773
774static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
775{
776 struct s5p_mfc_dev *dev = ctx->dev;
777 struct s5p_mfc_enc_params *p = &ctx->enc_params;
778 struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264;
779 unsigned int reg = 0;
780 int i;
781
782 mfc_debug_enter();
783
784 s5p_mfc_set_enc_params(ctx);
785
786 /* pictype : number of B */
787 reg = READL(S5P_FIMV_E_GOP_CONFIG_V6);
788 reg &= ~(0x3 << 16);
789 reg |= ((p->num_b_frame & 0x3) << 16);
790 WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6);
791
792 /* profile & level */
793 reg = 0;
794 /** level */
795 reg |= ((p_h264->level & 0xFF) << 8);
796 /** profile - 0 ~ 3 */
797 reg |= p_h264->profile & 0x3F;
798 WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6);
799
800 /* rate control config. */
801 reg = READL(S5P_FIMV_E_RC_CONFIG_V6);
802 /** macroblock level rate control */
803 reg &= ~(0x1 << 8);
804 reg |= ((p->rc_mb & 0x1) << 8);
805 WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
806 /** frame QP */
807 reg &= ~(0x3F);
808 reg |= p_h264->rc_frame_qp & 0x3F;
809 WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
810
811 /* max & min value of QP */
812 reg = 0;
813 /** max QP */
814 reg |= ((p_h264->rc_max_qp & 0x3F) << 8);
815 /** min QP */
816 reg |= p_h264->rc_min_qp & 0x3F;
817 WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_V6);
818
819 /* other QPs */
820 WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
821 if (!p->rc_frame && !p->rc_mb) {
822 reg = 0;
823 reg |= ((p_h264->rc_b_frame_qp & 0x3F) << 16);
824 reg |= ((p_h264->rc_p_frame_qp & 0x3F) << 8);
825 reg |= p_h264->rc_frame_qp & 0x3F;
826 WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
827 }
828
829 /* frame rate */
830 if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) {
831 reg = 0;
832 reg |= ((p->rc_framerate_num & 0xFFFF) << 16);
833 reg |= p->rc_framerate_denom & 0xFFFF;
834 WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6);
835 }
836
837 /* vbv buffer size */
838 if (p->frame_skip_mode ==
839 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
840 WRITEL(p_h264->cpb_size & 0xFFFF,
841 S5P_FIMV_E_VBV_BUFFER_SIZE_V6);
842
843 if (p->rc_frame)
844 WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6);
845 }
846
847 /* interlace */
848 reg = 0;
849 reg |= ((p_h264->interlace & 0x1) << 3);
850 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
851
852 /* height */
853 if (p_h264->interlace) {
854 WRITEL(ctx->img_height >> 1,
855 S5P_FIMV_E_FRAME_HEIGHT_V6); /* 32 align */
856 /* cropped height */
857 WRITEL(ctx->img_height >> 1,
858 S5P_FIMV_E_CROPPED_FRAME_HEIGHT_V6);
859 }
860
861 /* loop filter ctrl */
862 reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
863 reg &= ~(0x3 << 1);
864 reg |= ((p_h264->loop_filter_mode & 0x3) << 1);
865 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
866
867 /* loopfilter alpha offset */
868 if (p_h264->loop_filter_alpha < 0) {
869 reg = 0x10;
870 reg |= (0xFF - p_h264->loop_filter_alpha) + 1;
871 } else {
872 reg = 0x00;
873 reg |= (p_h264->loop_filter_alpha & 0xF);
874 }
875 WRITEL(reg, S5P_FIMV_E_H264_LF_ALPHA_OFFSET_V6);
876
877 /* loopfilter beta offset */
878 if (p_h264->loop_filter_beta < 0) {
879 reg = 0x10;
880 reg |= (0xFF - p_h264->loop_filter_beta) + 1;
881 } else {
882 reg = 0x00;
883 reg |= (p_h264->loop_filter_beta & 0xF);
884 }
885 WRITEL(reg, S5P_FIMV_E_H264_LF_BETA_OFFSET_V6);
886
887 /* entropy coding mode */
888 reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
889 reg &= ~(0x1);
890 reg |= p_h264->entropy_mode & 0x1;
891 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
892
893 /* number of ref. picture */
894 reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
895 reg &= ~(0x1 << 7);
896 reg |= (((p_h264->num_ref_pic_4p - 1) & 0x1) << 7);
897 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
898
899 /* 8x8 transform enable */
900 reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
901 reg &= ~(0x3 << 12);
902 reg |= ((p_h264->_8x8_transform & 0x3) << 12);
903 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
904
905 /* macroblock adaptive scaling features */
906 WRITEL(0x0, S5P_FIMV_E_MB_RC_CONFIG_V6);
907 if (p->rc_mb) {
908 reg = 0;
909 /** dark region */
910 reg |= ((p_h264->rc_mb_dark & 0x1) << 3);
911 /** smooth region */
912 reg |= ((p_h264->rc_mb_smooth & 0x1) << 2);
913 /** static region */
914 reg |= ((p_h264->rc_mb_static & 0x1) << 1);
915 /** high activity region */
916 reg |= p_h264->rc_mb_activity & 0x1;
917 WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG_V6);
918 }
919
920 /* aspect ratio VUI */
921 reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
922 reg &= ~(0x1 << 5);
923 reg |= ((p_h264->vui_sar & 0x1) << 5);
924 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
925
926 WRITEL(0x0, S5P_FIMV_E_ASPECT_RATIO_V6);
927 WRITEL(0x0, S5P_FIMV_E_EXTENDED_SAR_V6);
928 if (p_h264->vui_sar) {
929 /* aspect ration IDC */
930 reg = 0;
931 reg |= p_h264->vui_sar_idc & 0xFF;
932 WRITEL(reg, S5P_FIMV_E_ASPECT_RATIO_V6);
933 if (p_h264->vui_sar_idc == 0xFF) {
934 /* extended SAR */
935 reg = 0;
936 reg |= (p_h264->vui_ext_sar_width & 0xFFFF) << 16;
937 reg |= p_h264->vui_ext_sar_height & 0xFFFF;
938 WRITEL(reg, S5P_FIMV_E_EXTENDED_SAR_V6);
939 }
940 }
941
942 /* intra picture period for H.264 open GOP */
943 /* control */
944 reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
945 reg &= ~(0x1 << 4);
946 reg |= ((p_h264->open_gop & 0x1) << 4);
947 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
948 /* value */
949 WRITEL(0x0, S5P_FIMV_E_H264_I_PERIOD_V6);
950 if (p_h264->open_gop) {
951 reg = 0;
952 reg |= p_h264->open_gop_size & 0xFFFF;
953 WRITEL(reg, S5P_FIMV_E_H264_I_PERIOD_V6);
954 }
955
956 /* 'WEIGHTED_BI_PREDICTION' for B is disable */
957 reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
958 reg &= ~(0x3 << 9);
959 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
960
961 /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
962 reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
963 reg &= ~(0x1 << 14);
964 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
965
966 /* ASO */
967 reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
968 reg &= ~(0x1 << 6);
969 reg |= ((p_h264->aso & 0x1) << 6);
970 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
971
972 /* hier qp enable */
973 reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
974 reg &= ~(0x1 << 8);
975 reg |= ((p_h264->open_gop & 0x1) << 8);
976 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
977 reg = 0;
978 if (p_h264->hier_qp && p_h264->hier_qp_layer) {
979 reg |= (p_h264->hier_qp_type & 0x1) << 0x3;
980 reg |= p_h264->hier_qp_layer & 0x7;
981 WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER_V6);
982 /* QP value for each layer */
983 for (i = 0; i < (p_h264->hier_qp_layer & 0x7); i++)
984 WRITEL(p_h264->hier_qp_layer_qp[i],
985 S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0_V6 +
986 i * 4);
987 }
988 /* number of coding layer should be zero when hierarchical is disable */
989 WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER_V6);
990
991 /* frame packing SEI generation */
992 reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
993 reg &= ~(0x1 << 25);
994 reg |= ((p_h264->sei_frame_packing & 0x1) << 25);
995 WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
996 if (p_h264->sei_frame_packing) {
997 reg = 0;
998 /** current frame0 flag */
999 reg |= ((p_h264->sei_fp_curr_frame_0 & 0x1) << 2);
1000 /** arrangement type */
1001 reg |= p_h264->sei_fp_arrangement_type & 0x3;
1002 WRITEL(reg, S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO_V6);
1003 }
1004
1005 if (p_h264->fmo) {
1006 switch (p_h264->fmo_map_type) {
1007 case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES:
1008 if (p_h264->fmo_slice_grp > 4)
1009 p_h264->fmo_slice_grp = 4;
1010 for (i = 0; i < (p_h264->fmo_slice_grp & 0xF); i++)
1011 WRITEL(p_h264->fmo_run_len[i] - 1,
1012 S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_0_V6 +
1013 i * 4);
1014 break;
1015 case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES:
1016 if (p_h264->fmo_slice_grp > 4)
1017 p_h264->fmo_slice_grp = 4;
1018 break;
1019 case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN:
1020 case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN:
1021 if (p_h264->fmo_slice_grp > 2)
1022 p_h264->fmo_slice_grp = 2;
1023 WRITEL(p_h264->fmo_chg_dir & 0x1,
1024 S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_DIR_V6);
1025 /* the valid range is 0 ~ number of macroblocks -1 */
1026 WRITEL(p_h264->fmo_chg_rate,
1027 S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1_V6);
1028 break;
1029 default:
1030 mfc_err("Unsupported map type for FMO: %d\n",
1031 p_h264->fmo_map_type);
1032 p_h264->fmo_map_type = 0;
1033 p_h264->fmo_slice_grp = 1;
1034 break;
1035 }
1036
1037 WRITEL(p_h264->fmo_map_type,
1038 S5P_FIMV_E_H264_FMO_SLICE_GRP_MAP_TYPE_V6);
1039 WRITEL(p_h264->fmo_slice_grp - 1,
1040 S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1_V6);
1041 } else {
1042 WRITEL(0, S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1_V6);
1043 }
1044
1045 mfc_debug_leave();
1046
1047 return 0;
1048}
1049
1050static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
1051{
1052 struct s5p_mfc_dev *dev = ctx->dev;
1053 struct s5p_mfc_enc_params *p = &ctx->enc_params;
1054 struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;
1055 unsigned int reg = 0;
1056
1057 mfc_debug_enter();
1058
1059 s5p_mfc_set_enc_params(ctx);
1060
1061 /* pictype : number of B */
1062 reg = READL(S5P_FIMV_E_GOP_CONFIG_V6);
1063 reg &= ~(0x3 << 16);
1064 reg |= ((p->num_b_frame & 0x3) << 16);
1065 WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6);
1066
1067 /* profile & level */
1068 reg = 0;
1069 /** level */
1070 reg |= ((p_mpeg4->level & 0xFF) << 8);
1071 /** profile - 0 ~ 1 */
1072 reg |= p_mpeg4->profile & 0x3F;
1073 WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6);
1074
1075 /* rate control config. */
1076 reg = READL(S5P_FIMV_E_RC_CONFIG_V6);
1077 /** macroblock level rate control */
1078 reg &= ~(0x1 << 8);
1079 reg |= ((p->rc_mb & 0x1) << 8);
1080 WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
1081 /** frame QP */
1082 reg &= ~(0x3F);
1083 reg |= p_mpeg4->rc_frame_qp & 0x3F;
1084 WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
1085
1086 /* max & min value of QP */
1087 reg = 0;
1088 /** max QP */
1089 reg |= ((p_mpeg4->rc_max_qp & 0x3F) << 8);
1090 /** min QP */
1091 reg |= p_mpeg4->rc_min_qp & 0x3F;
1092 WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_V6);
1093
1094 /* other QPs */
1095 WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
1096 if (!p->rc_frame && !p->rc_mb) {
1097 reg = 0;
1098 reg |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 16);
1099 reg |= ((p_mpeg4->rc_p_frame_qp & 0x3F) << 8);
1100 reg |= p_mpeg4->rc_frame_qp & 0x3F;
1101 WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
1102 }
1103
1104 /* frame rate */
1105 if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) {
1106 reg = 0;
1107 reg |= ((p->rc_framerate_num & 0xFFFF) << 16);
1108 reg |= p->rc_framerate_denom & 0xFFFF;
1109 WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6);
1110 }
1111
1112 /* vbv buffer size */
1113 if (p->frame_skip_mode ==
1114 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
1115 WRITEL(p->vbv_size & 0xFFFF, S5P_FIMV_E_VBV_BUFFER_SIZE_V6);
1116
1117 if (p->rc_frame)
1118 WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6);
1119 }
1120
1121 /* Disable HEC */
1122 WRITEL(0x0, S5P_FIMV_E_MPEG4_OPTIONS_V6);
1123 WRITEL(0x0, S5P_FIMV_E_MPEG4_HEC_PERIOD_V6);
1124
1125 mfc_debug_leave();
1126
1127 return 0;
1128}
1129
1130static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
1131{
1132 struct s5p_mfc_dev *dev = ctx->dev;
1133 struct s5p_mfc_enc_params *p = &ctx->enc_params;
1134 struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;
1135 unsigned int reg = 0;
1136
1137 mfc_debug_enter();
1138
1139 s5p_mfc_set_enc_params(ctx);
1140
1141 /* profile & level */
1142 reg = 0;
1143 /** profile */
1144 reg |= (0x1 << 4);
1145 WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6);
1146
1147 /* rate control config. */
1148 reg = READL(S5P_FIMV_E_RC_CONFIG_V6);
1149 /** macroblock level rate control */
1150 reg &= ~(0x1 << 8);
1151 reg |= ((p->rc_mb & 0x1) << 8);
1152 WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
1153 /** frame QP */
1154 reg &= ~(0x3F);
1155 reg |= p_h263->rc_frame_qp & 0x3F;
1156 WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
1157
1158 /* max & min value of QP */
1159 reg = 0;
1160 /** max QP */
1161 reg |= ((p_h263->rc_max_qp & 0x3F) << 8);
1162 /** min QP */
1163 reg |= p_h263->rc_min_qp & 0x3F;
1164 WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_V6);
1165
1166 /* other QPs */
1167 WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
1168 if (!p->rc_frame && !p->rc_mb) {
1169 reg = 0;
1170 reg |= ((p_h263->rc_b_frame_qp & 0x3F) << 16);
1171 reg |= ((p_h263->rc_p_frame_qp & 0x3F) << 8);
1172 reg |= p_h263->rc_frame_qp & 0x3F;
1173 WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
1174 }
1175
1176 /* frame rate */
1177 if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) {
1178 reg = 0;
1179 reg |= ((p->rc_framerate_num & 0xFFFF) << 16);
1180 reg |= p->rc_framerate_denom & 0xFFFF;
1181 WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6);
1182 }
1183
1184 /* vbv buffer size */
1185 if (p->frame_skip_mode ==
1186 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
1187 WRITEL(p->vbv_size & 0xFFFF, S5P_FIMV_E_VBV_BUFFER_SIZE_V6);
1188
1189 if (p->rc_frame)
1190 WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6);
1191 }
1192
1193 mfc_debug_leave();
1194
1195 return 0;
1196}
1197
1198/* Initialize decoding */
1199int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx)
1200{
1201 struct s5p_mfc_dev *dev = ctx->dev;
1202 unsigned int reg = 0;
1203 int fmo_aso_ctrl = 0;
1204
1205 mfc_debug_enter();
1206 mfc_debug(2, "InstNo: %d/%d\n", ctx->inst_no,
1207 S5P_FIMV_CH_SEQ_HEADER_V6);
1208 mfc_debug(2, "BUFs: %08x %08x %08x\n",
1209 READL(S5P_FIMV_D_CPB_BUFFER_ADDR_V6),
1210 READL(S5P_FIMV_D_CPB_BUFFER_ADDR_V6),
1211 READL(S5P_FIMV_D_CPB_BUFFER_ADDR_V6));
1212
1213 /* FMO_ASO_CTRL - 0: Enable, 1: Disable */
1214 reg |= (fmo_aso_ctrl << S5P_FIMV_D_OPT_FMO_ASO_CTRL_MASK_V6);
1215
1216 /* When user sets desplay_delay to 0,
1217 * It works as "display_delay enable" and delay set to 0.
1218 * If user wants display_delay disable, It should be
1219 * set to negative value. */
1220 if (ctx->display_delay >= 0) {
1221 reg |= (0x1 << S5P_FIMV_D_OPT_DDELAY_EN_SHIFT_V6);
1222 WRITEL(ctx->display_delay, S5P_FIMV_D_DISPLAY_DELAY_V6);
1223 }
1224 /* Setup loop filter, for decoding this is only valid for MPEG4 */
1225 if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_DEC) {
1226 mfc_debug(2, "Set loop filter to: %d\n",
1227 ctx->loop_filter_mpeg4);
1228 reg |= (ctx->loop_filter_mpeg4 <<
1229 S5P_FIMV_D_OPT_LF_CTRL_SHIFT_V6);
1230 }
1231 if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)
1232 reg |= (0x1 << S5P_FIMV_D_OPT_TILE_MODE_SHIFT_V6);
1233
1234 WRITEL(reg, S5P_FIMV_D_DEC_OPTIONS_V6);
1235
1236 /* 0: NV12(CbCr), 1: NV21(CrCb) */
1237 if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
1238 WRITEL(0x1, S5P_FIMV_PIXEL_FORMAT_V6);
1239 else
1240 WRITEL(0x0, S5P_FIMV_PIXEL_FORMAT_V6);
1241
1242 /* sei parse */
1243 WRITEL(ctx->sei_fp_parse & 0x1, S5P_FIMV_D_SEI_ENABLE_V6);
1244
1245 WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
1246 s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
1247 S5P_FIMV_CH_SEQ_HEADER_V6, NULL);
1248
1249 mfc_debug_leave();
1250 return 0;
1251}
1252
1253static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush)
1254{
1255 struct s5p_mfc_dev *dev = ctx->dev;
1256 unsigned int dpb;
1257 if (flush)
1258 dpb = READL(S5P_FIMV_SI_CH0_DPB_CONF_CTRL) | (1 << 14);
1259 else
1260 dpb = READL(S5P_FIMV_SI_CH0_DPB_CONF_CTRL) & ~(1 << 14);
1261 WRITEL(dpb, S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
1262}
1263
1264/* Decode a single frame */
1265int s5p_mfc_decode_one_frame_v6(struct s5p_mfc_ctx *ctx,
1266 enum s5p_mfc_decode_arg last_frame)
1267{
1268 struct s5p_mfc_dev *dev = ctx->dev;
1269
1270 WRITEL(ctx->dec_dst_flag, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V6);
1271 WRITEL(ctx->slice_interface & 0x1, S5P_FIMV_D_SLICE_IF_ENABLE_V6);
1272
1273 WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
1274 /* Issue different commands to instance basing on whether it
1275 * is the last frame or not. */
1276 switch (last_frame) {
1277 case 0:
1278 s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
1279 S5P_FIMV_CH_FRAME_START_V6, NULL);
1280 break;
1281 case 1:
1282 s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
1283 S5P_FIMV_CH_LAST_FRAME_V6, NULL);
1284 break;
1285 default:
1286 mfc_err("Unsupported last frame arg.\n");
1287 return -EINVAL;
1288 }
1289
1290 mfc_debug(2, "Decoding a usual frame.\n");
1291 return 0;
1292}
1293
1294int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
1295{
1296 struct s5p_mfc_dev *dev = ctx->dev;
1297
1298 if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC)
1299 s5p_mfc_set_enc_params_h264(ctx);
1300 else if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_ENC)
1301 s5p_mfc_set_enc_params_mpeg4(ctx);
1302 else if (ctx->codec_mode == S5P_MFC_CODEC_H263_ENC)
1303 s5p_mfc_set_enc_params_h263(ctx);
1304 else {
1305 mfc_err("Unknown codec for encoding (%x).\n",
1306 ctx->codec_mode);
1307 return -EINVAL;
1308 }
1309
1310 WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
1311 s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
1312 S5P_FIMV_CH_SEQ_HEADER_V6, NULL);
1313
1314 return 0;
1315}
1316
1317int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx)
1318{
1319 struct s5p_mfc_dev *dev = ctx->dev;
1320 struct s5p_mfc_enc_params *p = &ctx->enc_params;
1321 struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264;
1322 int i;
1323
1324 if (p_h264->aso) {
1325 for (i = 0; i < 8; i++)
1326 WRITEL(p_h264->aso_slice_order[i],
1327 S5P_FIMV_E_H264_ASO_SLICE_ORDER_0_V6 + i * 4);
1328 }
1329 return 0;
1330}
1331
1332/* Encode a single frame */
1333int s5p_mfc_encode_one_frame_v6(struct s5p_mfc_ctx *ctx)
1334{
1335 struct s5p_mfc_dev *dev = ctx->dev;
1336
1337 mfc_debug(2, "++\n");
1338
1339 /* memory structure cur. frame */
1340
1341 if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC)
1342 s5p_mfc_h264_set_aso_slice_order_v6(ctx);
1343
1344 s5p_mfc_set_slice_mode(ctx);
1345
1346 WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
1347 s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
1348 S5P_FIMV_CH_FRAME_START_V6, NULL);
1349
1350 mfc_debug(2, "--\n");
1351
1352 return 0;
1353}
1354
1355static inline int s5p_mfc_get_new_ctx(struct s5p_mfc_dev *dev)
1356{
1357 unsigned long flags;
1358 int new_ctx;
1359 int cnt;
1360
1361 spin_lock_irqsave(&dev->condlock, flags);
1362 mfc_debug(2, "Previos context: %d (bits %08lx)\n", dev->curr_ctx,
1363 dev->ctx_work_bits);
1364 new_ctx = (dev->curr_ctx + 1) % MFC_NUM_CONTEXTS;
1365 cnt = 0;
1366 while (!test_bit(new_ctx, &dev->ctx_work_bits)) {
1367 new_ctx = (new_ctx + 1) % MFC_NUM_CONTEXTS;
1368 cnt++;
1369 if (cnt > MFC_NUM_CONTEXTS) {
1370 /* No contexts to run */
1371 spin_unlock_irqrestore(&dev->condlock, flags);
1372 return -EAGAIN;
1373 }
1374 }
1375 spin_unlock_irqrestore(&dev->condlock, flags);
1376 return new_ctx;
1377}
1378
1379static inline void s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx)
1380{
1381 struct s5p_mfc_dev *dev = ctx->dev;
1382 struct s5p_mfc_buf *temp_vb;
1383 unsigned long flags;
1384
1385 spin_lock_irqsave(&dev->irqlock, flags);
1386
1387 /* Frames are being decoded */
1388 if (list_empty(&ctx->src_queue)) {
1389 mfc_debug(2, "No src buffers.\n");
1390 spin_unlock_irqrestore(&dev->irqlock, flags);
1391 return;
1392 }
1393 /* Get the next source buffer */
1394 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1395 temp_vb->flags |= MFC_BUF_FLAG_USED;
1396 s5p_mfc_set_dec_stream_buffer_v6(ctx,
1397 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0, 0);
1398 spin_unlock_irqrestore(&dev->irqlock, flags);
1399
1400 dev->curr_ctx = ctx->num;
1401 s5p_mfc_clean_ctx_int_flags(ctx);
1402 s5p_mfc_decode_one_frame_v6(ctx, 1);
1403}
1404
1405static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx)
1406{
1407 struct s5p_mfc_dev *dev = ctx->dev;
1408 struct s5p_mfc_buf *temp_vb;
1409 unsigned long flags;
1410 int last_frame = 0;
1411 unsigned int index;
1412
1413 spin_lock_irqsave(&dev->irqlock, flags);
1414
1415 /* Frames are being decoded */
1416 if (list_empty(&ctx->src_queue)) {
1417 mfc_debug(2, "No src buffers.\n");
1418 spin_unlock_irqrestore(&dev->irqlock, flags);
1419 return -EAGAIN;
1420 }
1421 /* Get the next source buffer */
1422 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1423 temp_vb->flags |= MFC_BUF_FLAG_USED;
1424 s5p_mfc_set_dec_stream_buffer_v6(ctx,
1425 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
1426 ctx->consumed_stream,
1427 temp_vb->b->v4l2_planes[0].bytesused);
1428 spin_unlock_irqrestore(&dev->irqlock, flags);
1429
1430 index = temp_vb->b->v4l2_buf.index;
1431
1432 dev->curr_ctx = ctx->num;
1433 s5p_mfc_clean_ctx_int_flags(ctx);
1434 if (temp_vb->b->v4l2_planes[0].bytesused == 0) {
1435 last_frame = 1;
1436 mfc_debug(2, "Setting ctx->state to FINISHING\n");
1437 ctx->state = MFCINST_FINISHING;
1438 }
1439 s5p_mfc_decode_one_frame_v6(ctx, last_frame);
1440
1441 return 0;
1442}
1443
1444static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
1445{
1446 struct s5p_mfc_dev *dev = ctx->dev;
1447 unsigned long flags;
1448 struct s5p_mfc_buf *dst_mb;
1449 struct s5p_mfc_buf *src_mb;
1450 unsigned long src_y_addr, src_c_addr, dst_addr;
1451 /*
1452 unsigned int src_y_size, src_c_size;
1453 */
1454 unsigned int dst_size;
1455 unsigned int index;
1456
1457 spin_lock_irqsave(&dev->irqlock, flags);
1458
1459 if (list_empty(&ctx->src_queue)) {
1460 mfc_debug(2, "no src buffers.\n");
1461 spin_unlock_irqrestore(&dev->irqlock, flags);
1462 return -EAGAIN;
1463 }
1464
1465 if (list_empty(&ctx->dst_queue)) {
1466 mfc_debug(2, "no dst buffers.\n");
1467 spin_unlock_irqrestore(&dev->irqlock, flags);
1468 return -EAGAIN;
1469 }
1470
1471 src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1472 src_mb->flags |= MFC_BUF_FLAG_USED;
1473 src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
1474 src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
1475
1476 mfc_debug(2, "enc src y addr: 0x%08lx", src_y_addr);
1477 mfc_debug(2, "enc src c addr: 0x%08lx", src_c_addr);
1478
1479 s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr);
1480
1481 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
1482 dst_mb->flags |= MFC_BUF_FLAG_USED;
1483 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
1484 dst_size = vb2_plane_size(dst_mb->b, 0);
1485
1486 s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size);
1487
1488 spin_unlock_irqrestore(&dev->irqlock, flags);
1489
1490 index = src_mb->b->v4l2_buf.index;
1491
1492 dev->curr_ctx = ctx->num;
1493 s5p_mfc_clean_ctx_int_flags(ctx);
1494 s5p_mfc_encode_one_frame_v6(ctx);
1495
1496 return 0;
1497}
1498
1499static inline void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
1500{
1501 struct s5p_mfc_dev *dev = ctx->dev;
1502 unsigned long flags;
1503 struct s5p_mfc_buf *temp_vb;
1504
1505 /* Initializing decoding - parsing header */
1506 spin_lock_irqsave(&dev->irqlock, flags);
1507 mfc_debug(2, "Preparing to init decoding.\n");
1508 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1509 mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
1510 s5p_mfc_set_dec_stream_buffer_v6(ctx,
1511 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0,
1512 temp_vb->b->v4l2_planes[0].bytesused);
1513 spin_unlock_irqrestore(&dev->irqlock, flags);
1514 dev->curr_ctx = ctx->num;
1515 s5p_mfc_clean_ctx_int_flags(ctx);
1516 s5p_mfc_init_decode_v6(ctx);
1517}
1518
1519static inline void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
1520{
1521 struct s5p_mfc_dev *dev = ctx->dev;
1522 unsigned long flags;
1523 struct s5p_mfc_buf *dst_mb;
1524 unsigned long dst_addr;
1525 unsigned int dst_size;
1526
1527 spin_lock_irqsave(&dev->irqlock, flags);
1528
1529 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
1530 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
1531 dst_size = vb2_plane_size(dst_mb->b, 0);
1532 s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size);
1533 spin_unlock_irqrestore(&dev->irqlock, flags);
1534 dev->curr_ctx = ctx->num;
1535 s5p_mfc_clean_ctx_int_flags(ctx);
1536 s5p_mfc_init_encode_v6(ctx);
1537}
1538
1539static inline int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
1540{
1541 struct s5p_mfc_dev *dev = ctx->dev;
1542 int ret;
1543 /* Header was parsed now start processing
1544 * First set the output frame buffers
1545 * s5p_mfc_alloc_dec_buffers(ctx); */
1546
1547 if (ctx->capture_state != QUEUE_BUFS_MMAPED) {
1548 mfc_err("It seems that not all destionation buffers were\n"
1549 "mmaped.MFC requires that all destination are mmaped\n"
1550 "before starting processing.\n");
1551 return -EAGAIN;
1552 }
1553
1554 dev->curr_ctx = ctx->num;
1555 s5p_mfc_clean_ctx_int_flags(ctx);
1556 ret = s5p_mfc_set_dec_frame_buffer_v6(ctx);
1557 if (ret) {
1558 mfc_err("Failed to alloc frame mem.\n");
1559 ctx->state = MFCINST_ERROR;
1560 }
1561 return ret;
1562}
1563
1564static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx)
1565{
1566 struct s5p_mfc_dev *dev = ctx->dev;
1567 int ret;
1568
1569 ret = s5p_mfc_alloc_codec_buffers_v6(ctx);
1570 if (ret) {
1571 mfc_err("Failed to allocate encoding buffers.\n");
1572 return -ENOMEM;
1573 }
1574
1575 /* Header was generated now starting processing
1576 * First set the reference frame buffers
1577 */
1578 if (ctx->capture_state != QUEUE_BUFS_REQUESTED) {
1579 mfc_err("It seems that destionation buffers were not\n"
1580 "requested.MFC requires that header should be generated\n"
1581 "before allocating codec buffer.\n");
1582 return -EAGAIN;
1583 }
1584
1585 dev->curr_ctx = ctx->num;
1586 s5p_mfc_clean_ctx_int_flags(ctx);
1587 ret = s5p_mfc_set_enc_ref_buffer_v6(ctx);
1588 if (ret) {
1589 mfc_err("Failed to alloc frame mem.\n");
1590 ctx->state = MFCINST_ERROR;
1591 }
1592 return ret;
1593}
1594
1595/* Try running an operation on hardware */
1596void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev)
1597{
1598 struct s5p_mfc_ctx *ctx;
1599 int new_ctx;
1600 unsigned int ret = 0;
1601
1602 mfc_debug(1, "Try run dev: %p\n", dev);
1603
1604 /* Check whether hardware is not running */
1605 if (test_and_set_bit(0, &dev->hw_lock) != 0) {
1606 /* This is perfectly ok, the scheduled ctx should wait */
1607 mfc_debug(1, "Couldn't lock HW.\n");
1608 return;
1609 }
1610
1611 /* Choose the context to run */
1612 new_ctx = s5p_mfc_get_new_ctx(dev);
1613 if (new_ctx < 0) {
1614 /* No contexts to run */
1615 if (test_and_clear_bit(0, &dev->hw_lock) == 0) {
1616 mfc_err("Failed to unlock hardware.\n");
1617 return;
1618 }
1619
1620 mfc_debug(1, "No ctx is scheduled to be run.\n");
1621 return;
1622 }
1623
1624 mfc_debug(1, "New context: %d\n", new_ctx);
1625 ctx = dev->ctx[new_ctx];
1626 mfc_debug(1, "Seting new context to %p\n", ctx);
1627 /* Got context to run in ctx */
1628 mfc_debug(1, "ctx->dst_queue_cnt=%d ctx->dpb_count=%d ctx->src_queue_cnt=%d\n",
1629 ctx->dst_queue_cnt, ctx->dpb_count, ctx->src_queue_cnt);
1630 mfc_debug(1, "ctx->state=%d\n", ctx->state);
1631 /* Last frame has already been sent to MFC
1632 * Now obtaining frames from MFC buffer */
1633
1634 s5p_mfc_clock_on();
1635 if (ctx->type == MFCINST_DECODER) {
1636 switch (ctx->state) {
1637 case MFCINST_FINISHING:
1638 s5p_mfc_run_dec_last_frames(ctx);
1639 break;
1640 case MFCINST_RUNNING:
1641 ret = s5p_mfc_run_dec_frame(ctx);
1642 break;
1643 case MFCINST_INIT:
1644 s5p_mfc_clean_ctx_int_flags(ctx);
1645 ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd,
1646 ctx);
1647 break;
1648 case MFCINST_RETURN_INST:
1649 s5p_mfc_clean_ctx_int_flags(ctx);
1650 ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd,
1651 ctx);
1652 break;
1653 case MFCINST_GOT_INST:
1654 s5p_mfc_run_init_dec(ctx);
1655 break;
1656 case MFCINST_HEAD_PARSED:
1657 ret = s5p_mfc_run_init_dec_buffers(ctx);
1658 break;
1659 case MFCINST_RES_CHANGE_INIT:
1660 s5p_mfc_run_dec_last_frames(ctx);
1661 break;
1662 case MFCINST_RES_CHANGE_FLUSH:
1663 s5p_mfc_run_dec_last_frames(ctx);
1664 break;
1665 case MFCINST_RES_CHANGE_END:
1666 mfc_debug(2, "Finished remaining frames after resolution change.\n");
1667 ctx->capture_state = QUEUE_FREE;
1668 mfc_debug(2, "Will re-init the codec`.\n");
1669 s5p_mfc_run_init_dec(ctx);
1670 break;
1671 default:
1672 ret = -EAGAIN;
1673 }
1674 } else if (ctx->type == MFCINST_ENCODER) {
1675 switch (ctx->state) {
1676 case MFCINST_FINISHING:
1677 case MFCINST_RUNNING:
1678 ret = s5p_mfc_run_enc_frame(ctx);
1679 break;
1680 case MFCINST_INIT:
1681 ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd,
1682 ctx);
1683 break;
1684 case MFCINST_RETURN_INST:
1685 ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd,
1686 ctx);
1687 break;
1688 case MFCINST_GOT_INST:
1689 s5p_mfc_run_init_enc(ctx);
1690 break;
1691 case MFCINST_HEAD_PARSED: /* Only for MFC6.x */
1692 ret = s5p_mfc_run_init_enc_buffers(ctx);
1693 break;
1694 default:
1695 ret = -EAGAIN;
1696 }
1697 } else {
1698 mfc_err("invalid context type: %d\n", ctx->type);
1699 ret = -EAGAIN;
1700 }
1701
1702 if (ret) {
1703 /* Free hardware lock */
1704 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
1705 mfc_err("Failed to unlock hardware.\n");
1706
1707 /* This is in deed imporant, as no operation has been
1708 * scheduled, reduce the clock count as no one will
1709 * ever do this, because no interrupt related to this try_run
1710 * will ever come from hardware. */
1711 s5p_mfc_clock_off();
1712 }
1713}
1714
1715
1716void s5p_mfc_cleanup_queue_v6(struct list_head *lh, struct vb2_queue *vq)
1717{
1718 struct s5p_mfc_buf *b;
1719 int i;
1720
1721 while (!list_empty(lh)) {
1722 b = list_entry(lh->next, struct s5p_mfc_buf, list);
1723 for (i = 0; i < b->b->num_planes; i++)
1724 vb2_set_plane_payload(b->b, i, 0);
1725 vb2_buffer_done(b->b, VB2_BUF_STATE_ERROR);
1726 list_del(&b->list);
1727 }
1728}
1729
1730void s5p_mfc_clear_int_flags_v6(struct s5p_mfc_dev *dev)
1731{
1732 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6);
1733 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_INT_V6);
1734}
1735
1736void s5p_mfc_write_info_v6(struct s5p_mfc_ctx *ctx, unsigned int data,
1737 unsigned int ofs)
1738{
1739 struct s5p_mfc_dev *dev = ctx->dev;
1740
1741 s5p_mfc_clock_on();
1742 WRITEL(data, ofs);
1743 s5p_mfc_clock_off();
1744}
1745
1746unsigned int s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned int ofs)
1747{
1748 struct s5p_mfc_dev *dev = ctx->dev;
1749 int ret;
1750
1751 s5p_mfc_clock_on();
1752 ret = READL(ofs);
1753 s5p_mfc_clock_off();
1754
1755 return ret;
1756}
1757
1758int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev)
1759{
1760 return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6);
1761}
1762
1763int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev)
1764{
1765 return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6);
1766}
1767
1768int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev)
1769{
1770 return mfc_read(dev, S5P_FIMV_D_DISPLAY_STATUS_V6);
1771}
1772
1773int s5p_mfc_get_decoded_status_v6(struct s5p_mfc_dev *dev)
1774{
1775 return mfc_read(dev, S5P_FIMV_D_DECODED_STATUS_V6);
1776}
1777
1778int s5p_mfc_get_dec_frame_type_v6(struct s5p_mfc_dev *dev)
1779{
1780 return mfc_read(dev, S5P_FIMV_D_DECODED_FRAME_TYPE_V6) &
1781 S5P_FIMV_DECODE_FRAME_MASK_V6;
1782}
1783
1784int s5p_mfc_get_disp_frame_type_v6(struct s5p_mfc_ctx *ctx)
1785{
1786 return mfc_read(ctx->dev, S5P_FIMV_D_DISPLAY_FRAME_TYPE_V6) &
1787 S5P_FIMV_DECODE_FRAME_MASK_V6;
1788}
1789
1790int s5p_mfc_get_consumed_stream_v6(struct s5p_mfc_dev *dev)
1791{
1792 return mfc_read(dev, S5P_FIMV_D_DECODED_NAL_SIZE_V6);
1793}
1794
1795int s5p_mfc_get_int_reason_v6(struct s5p_mfc_dev *dev)
1796{
1797 return mfc_read(dev, S5P_FIMV_RISC2HOST_CMD_V6) &
1798 S5P_FIMV_RISC2HOST_CMD_MASK;
1799}
1800
1801int s5p_mfc_get_int_err_v6(struct s5p_mfc_dev *dev)
1802{
1803 return mfc_read(dev, S5P_FIMV_ERROR_CODE_V6);
1804}
1805
1806int s5p_mfc_err_dec_v6(unsigned int err)
1807{
1808 return (err & S5P_FIMV_ERR_DEC_MASK_V6) >> S5P_FIMV_ERR_DEC_SHIFT_V6;
1809}
1810
1811int s5p_mfc_err_dspl_v6(unsigned int err)
1812{
1813 return (err & S5P_FIMV_ERR_DSPL_MASK_V6) >> S5P_FIMV_ERR_DSPL_SHIFT_V6;
1814}
1815
1816int s5p_mfc_get_img_width_v6(struct s5p_mfc_dev *dev)
1817{
1818 return mfc_read(dev, S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V6);
1819}
1820
1821int s5p_mfc_get_img_height_v6(struct s5p_mfc_dev *dev)
1822{
1823 return mfc_read(dev, S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V6);
1824}
1825
1826int s5p_mfc_get_dpb_count_v6(struct s5p_mfc_dev *dev)
1827{
1828 return mfc_read(dev, S5P_FIMV_D_MIN_NUM_DPB_V6);
1829}
1830
1831int s5p_mfc_get_mv_count_v6(struct s5p_mfc_dev *dev)
1832{
1833 return mfc_read(dev, S5P_FIMV_D_MIN_NUM_MV_V6);
1834}
1835
1836int s5p_mfc_get_inst_no_v6(struct s5p_mfc_dev *dev)
1837{
1838 return mfc_read(dev, S5P_FIMV_RET_INSTANCE_ID_V6);
1839}
1840
1841int s5p_mfc_get_enc_dpb_count_v6(struct s5p_mfc_dev *dev)
1842{
1843 return mfc_read(dev, S5P_FIMV_E_NUM_DPB_V6);
1844}
1845
1846int s5p_mfc_get_enc_strm_size_v6(struct s5p_mfc_dev *dev)
1847{
1848 return mfc_read(dev, S5P_FIMV_E_STREAM_SIZE_V6);
1849}
1850
1851int s5p_mfc_get_enc_slice_type_v6(struct s5p_mfc_dev *dev)
1852{
1853 return mfc_read(dev, S5P_FIMV_E_SLICE_TYPE_V6);
1854}
1855
1856int s5p_mfc_get_enc_pic_count_v6(struct s5p_mfc_dev *dev)
1857{
1858 return mfc_read(dev, S5P_FIMV_E_PICTURE_COUNT_V6);
1859}
1860
1861int s5p_mfc_get_sei_avail_status_v6(struct s5p_mfc_ctx *ctx)
1862{
1863 return mfc_read(ctx->dev, S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V6);
1864}
1865
1866int s5p_mfc_get_mvc_num_views_v6(struct s5p_mfc_dev *dev)
1867{
1868 return mfc_read(dev, S5P_FIMV_D_MVC_NUM_VIEWS_V6);
1869}
1870
1871int s5p_mfc_get_mvc_view_id_v6(struct s5p_mfc_dev *dev)
1872{
1873 return mfc_read(dev, S5P_FIMV_D_MVC_VIEW_ID_V6);
1874}
1875
1876unsigned int s5p_mfc_get_pic_type_top_v6(struct s5p_mfc_ctx *ctx)
1877{
1878 return s5p_mfc_read_info_v6(ctx, PIC_TIME_TOP_V6);
1879}
1880
1881unsigned int s5p_mfc_get_pic_type_bot_v6(struct s5p_mfc_ctx *ctx)
1882{
1883 return s5p_mfc_read_info_v6(ctx, PIC_TIME_BOT_V6);
1884}
1885
1886unsigned int s5p_mfc_get_crop_info_h_v6(struct s5p_mfc_ctx *ctx)
1887{
1888 return s5p_mfc_read_info_v6(ctx, CROP_INFO_H_V6);
1889}
1890
1891unsigned int s5p_mfc_get_crop_info_v_v6(struct s5p_mfc_ctx *ctx)
1892{
1893 return s5p_mfc_read_info_v6(ctx, CROP_INFO_V_V6);
1894}
1895
1896/* Initialize opr function pointers for MFC v6 */
1897static struct s5p_mfc_hw_ops s5p_mfc_ops_v6 = {
1898 .alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v6,
1899 .release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v6,
1900 .alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v6,
1901 .release_codec_buffers = s5p_mfc_release_codec_buffers_v6,
1902 .alloc_instance_buffer = s5p_mfc_alloc_instance_buffer_v6,
1903 .release_instance_buffer = s5p_mfc_release_instance_buffer_v6,
1904 .alloc_dev_context_buffer =
1905 s5p_mfc_alloc_dev_context_buffer_v6,
1906 .release_dev_context_buffer =
1907 s5p_mfc_release_dev_context_buffer_v6,
1908 .dec_calc_dpb_size = s5p_mfc_dec_calc_dpb_size_v6,
1909 .enc_calc_src_size = s5p_mfc_enc_calc_src_size_v6,
1910 .set_dec_stream_buffer = s5p_mfc_set_dec_stream_buffer_v6,
1911 .set_dec_frame_buffer = s5p_mfc_set_dec_frame_buffer_v6,
1912 .set_enc_stream_buffer = s5p_mfc_set_enc_stream_buffer_v6,
1913 .set_enc_frame_buffer = s5p_mfc_set_enc_frame_buffer_v6,
1914 .get_enc_frame_buffer = s5p_mfc_get_enc_frame_buffer_v6,
1915 .set_enc_ref_buffer = s5p_mfc_set_enc_ref_buffer_v6,
1916 .init_decode = s5p_mfc_init_decode_v6,
1917 .init_encode = s5p_mfc_init_encode_v6,
1918 .encode_one_frame = s5p_mfc_encode_one_frame_v6,
1919 .try_run = s5p_mfc_try_run_v6,
1920 .cleanup_queue = s5p_mfc_cleanup_queue_v6,
1921 .clear_int_flags = s5p_mfc_clear_int_flags_v6,
1922 .write_info = s5p_mfc_write_info_v6,
1923 .read_info = s5p_mfc_read_info_v6,
1924 .get_dspl_y_adr = s5p_mfc_get_dspl_y_adr_v6,
1925 .get_dec_y_adr = s5p_mfc_get_dec_y_adr_v6,
1926 .get_dspl_status = s5p_mfc_get_dspl_status_v6,
1927 .get_dec_status = s5p_mfc_get_dec_status_v6,
1928 .get_dec_frame_type = s5p_mfc_get_dec_frame_type_v6,
1929 .get_disp_frame_type = s5p_mfc_get_disp_frame_type_v6,
1930 .get_consumed_stream = s5p_mfc_get_consumed_stream_v6,
1931 .get_int_reason = s5p_mfc_get_int_reason_v6,
1932 .get_int_err = s5p_mfc_get_int_err_v6,
1933 .err_dec = s5p_mfc_err_dec_v6,
1934 .err_dspl = s5p_mfc_err_dspl_v6,
1935 .get_img_width = s5p_mfc_get_img_width_v6,
1936 .get_img_height = s5p_mfc_get_img_height_v6,
1937 .get_dpb_count = s5p_mfc_get_dpb_count_v6,
1938 .get_mv_count = s5p_mfc_get_mv_count_v6,
1939 .get_inst_no = s5p_mfc_get_inst_no_v6,
1940 .get_enc_strm_size = s5p_mfc_get_enc_strm_size_v6,
1941 .get_enc_slice_type = s5p_mfc_get_enc_slice_type_v6,
1942 .get_enc_dpb_count = s5p_mfc_get_enc_dpb_count_v6,
1943 .get_enc_pic_count = s5p_mfc_get_enc_pic_count_v6,
1944 .get_sei_avail_status = s5p_mfc_get_sei_avail_status_v6,
1945 .get_mvc_num_views = s5p_mfc_get_mvc_num_views_v6,
1946 .get_mvc_view_id = s5p_mfc_get_mvc_view_id_v6,
1947 .get_pic_type_top = s5p_mfc_get_pic_type_top_v6,
1948 .get_pic_type_bot = s5p_mfc_get_pic_type_bot_v6,
1949 .get_crop_info_h = s5p_mfc_get_crop_info_h_v6,
1950 .get_crop_info_v = s5p_mfc_get_crop_info_v_v6,
1951};
1952
1953struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void)
1954{
1955 return &s5p_mfc_ops_v6;
1956}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h
new file mode 100644
index 000000000000..ab164efa127e
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h
@@ -0,0 +1,50 @@
1/*
2 * drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h
3 *
4 * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
5 * Contains declarations of hw related functions.
6 *
7 * 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_V6_H_
16#define S5P_MFC_OPR_V6_H_
17
18#include "s5p_mfc_common.h"
19#include "s5p_mfc_opr.h"
20
21#define MFC_CTRL_MODE_CUSTOM MFC_CTRL_MODE_SFR
22
23#define MB_WIDTH(x_size) DIV_ROUND_UP(x_size, 16)
24#define MB_HEIGHT(y_size) DIV_ROUND_UP(y_size, 16)
25#define S5P_MFC_DEC_MV_SIZE_V6(x, y) (MB_WIDTH(x) * \
26 (((MB_HEIGHT(y)+1)/2)*2) * 64 + 128)
27
28/* Definition */
29#define ENC_MULTI_SLICE_MB_MAX ((1 << 30) - 1)
30#define ENC_MULTI_SLICE_BIT_MIN 2800
31#define ENC_INTRA_REFRESH_MB_MAX ((1 << 18) - 1)
32#define ENC_VBV_BUF_SIZE_MAX ((1 << 30) - 1)
33#define ENC_H264_LOOP_FILTER_AB_MIN -12
34#define ENC_H264_LOOP_FILTER_AB_MAX 12
35#define ENC_H264_RC_FRAME_RATE_MAX ((1 << 16) - 1)
36#define ENC_H263_RC_FRAME_RATE_MAX ((1 << 16) - 1)
37#define ENC_H264_PROFILE_MAX 3
38#define ENC_H264_LEVEL_MAX 42
39#define ENC_MPEG4_VOP_TIME_RES_MAX ((1 << 16) - 1)
40#define FRAME_DELTA_H264_H263 1
41#define TIGHT_CBR_MAX 10
42
43/* Definitions for shared memory compatibility */
44#define PIC_TIME_TOP_V6 S5P_FIMV_D_RET_PICTURE_TAG_TOP_V6
45#define PIC_TIME_BOT_V6 S5P_FIMV_D_RET_PICTURE_TAG_BOT_V6
46#define CROP_INFO_H_V6 S5P_FIMV_D_DISPLAY_CROP_INFO1_V6
47#define CROP_INFO_V_V6 S5P_FIMV_D_DISPLAY_CROP_INFO2_V6
48
49struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void);
50#endif /* S5P_MFC_OPR_V6_H_ */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
index 0503d14ac94e..367db7552289 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
@@ -20,7 +20,6 @@
20#include "s5p_mfc_debug.h" 20#include "s5p_mfc_debug.h"
21#include "s5p_mfc_pm.h" 21#include "s5p_mfc_pm.h"
22 22
23#define MFC_CLKNAME "sclk_mfc"
24#define MFC_GATE_CLK_NAME "mfc" 23#define MFC_GATE_CLK_NAME "mfc"
25 24
26#define CLK_DEBUG 25#define CLK_DEBUG
@@ -51,7 +50,7 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
51 goto err_p_ip_clk; 50 goto err_p_ip_clk;
52 } 51 }
53 52
54 pm->clock = clk_get(&dev->plat_dev->dev, MFC_CLKNAME); 53 pm->clock = clk_get(&dev->plat_dev->dev, dev->variant->mclk_name);
55 if (IS_ERR(pm->clock)) { 54 if (IS_ERR(pm->clock)) {
56 mfc_err("Failed to get MFC clock\n"); 55 mfc_err("Failed to get MFC clock\n");
57 ret = PTR_ERR(pm->clock); 56 ret = PTR_ERR(pm->clock);
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_shm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_shm.c
deleted file mode 100644
index b5933d233a4b..000000000000
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_shm.c
+++ /dev/null
@@ -1,47 +0,0 @@
1/*
2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_shm.c
3 *
4 * Copyright (c) 2010 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#ifdef CONFIG_ARCH_EXYNOS4
14#include <linux/dma-mapping.h>
15#endif
16#include <linux/io.h>
17#include "s5p_mfc_common.h"
18#include "s5p_mfc_debug.h"
19
20int s5p_mfc_init_shm(struct s5p_mfc_ctx *ctx)
21{
22 struct s5p_mfc_dev *dev = ctx->dev;
23 void *shm_alloc_ctx = dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
24
25 ctx->shm_alloc = vb2_dma_contig_memops.alloc(shm_alloc_ctx,
26 SHARED_BUF_SIZE);
27 if (IS_ERR(ctx->shm_alloc)) {
28 mfc_err("failed to allocate shared memory\n");
29 return PTR_ERR(ctx->shm_alloc);
30 }
31 /* shm_ofs only keeps the offset from base (port a) */
32 ctx->shm_ofs = s5p_mfc_mem_cookie(shm_alloc_ctx, ctx->shm_alloc)
33 - dev->bank1;
34 BUG_ON(ctx->shm_ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
35 ctx->shm = vb2_dma_contig_memops.vaddr(ctx->shm_alloc);
36 if (!ctx->shm) {
37 vb2_dma_contig_memops.put(ctx->shm_alloc);
38 ctx->shm_ofs = 0;
39 ctx->shm_alloc = NULL;
40 mfc_err("failed to virt addr of shared memory\n");
41 return -ENOMEM;
42 }
43 memset((void *)ctx->shm, 0, SHARED_BUF_SIZE);
44 wmb();
45 return 0;
46}
47
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index 403d7f17bfab..9fd9d1c5b218 100644
--- a/drivers/media/platform/soc_camera/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -1376,6 +1376,7 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd,
1376 __u32 pixfmt = pix->pixelformat; 1376 __u32 pixfmt = pix->pixelformat;
1377 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1377 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1378 struct mx2_camera_dev *pcdev = ici->priv; 1378 struct mx2_camera_dev *pcdev = ici->priv;
1379 struct mx2_fmt_cfg *emma_prp;
1379 unsigned int width_limit; 1380 unsigned int width_limit;
1380 int ret; 1381 int ret;
1381 1382
@@ -1438,12 +1439,11 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd,
1438 __func__, pcdev->s_width, pcdev->s_height); 1439 __func__, pcdev->s_width, pcdev->s_height);
1439 1440
1440 /* If the sensor does not support image size try PrP resizing */ 1441 /* If the sensor does not support image size try PrP resizing */
1441 pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code, 1442 emma_prp = mx27_emma_prp_get_format(xlate->code,
1442 xlate->host_fmt->fourcc); 1443 xlate->host_fmt->fourcc);
1443 1444
1444 memset(pcdev->resizing, 0, sizeof(pcdev->resizing));
1445 if ((mf.width != pix->width || mf.height != pix->height) && 1445 if ((mf.width != pix->width || mf.height != pix->height) &&
1446 pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) { 1446 emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) {
1447 if (mx2_emmaprp_resize(pcdev, &mf, pix, false) < 0) 1447 if (mx2_emmaprp_resize(pcdev, &mf, pix, false) < 0)
1448 dev_dbg(icd->parent, "%s: can't resize\n", __func__); 1448 dev_dbg(icd->parent, "%s: can't resize\n", __func__);
1449 } 1449 }
@@ -1655,6 +1655,7 @@ static int __devinit mx27_camera_emma_init(struct platform_device *pdev)
1655 irq_emma = platform_get_irq(pdev, 1); 1655 irq_emma = platform_get_irq(pdev, 1);
1656 if (!res_emma || !irq_emma) { 1656 if (!res_emma || !irq_emma) {
1657 dev_err(pcdev->dev, "no EMMA resources\n"); 1657 dev_err(pcdev->dev, "no EMMA resources\n");
1658 err = -ENODEV;
1658 goto out; 1659 goto out;
1659 } 1660 }
1660 1661
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 3be92944f8e7..d3f0b84e2d70 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -950,11 +950,11 @@ static int soc_camera_s_selection(struct file *file, void *fh,
950 950
951 /* In all these cases cropping emulation will not help */ 951 /* In all these cases cropping emulation will not help */
952 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 952 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
953 (s->target != V4L2_SEL_TGT_COMPOSE_ACTIVE && 953 (s->target != V4L2_SEL_TGT_COMPOSE &&
954 s->target != V4L2_SEL_TGT_CROP_ACTIVE)) 954 s->target != V4L2_SEL_TGT_CROP))
955 return -EINVAL; 955 return -EINVAL;
956 956
957 if (s->target == V4L2_SEL_TGT_COMPOSE_ACTIVE) { 957 if (s->target == V4L2_SEL_TGT_COMPOSE) {
958 /* No output size change during a running capture! */ 958 /* No output size change during a running capture! */
959 if (is_streaming(ici, icd) && 959 if (is_streaming(ici, icd) &&
960 (icd->user_width != s->r.width || 960 (icd->user_width != s->r.width ||
@@ -974,7 +974,7 @@ static int soc_camera_s_selection(struct file *file, void *fh,
974 974
975 ret = ici->ops->set_selection(icd, s); 975 ret = ici->ops->set_selection(icd, s);
976 if (!ret && 976 if (!ret &&
977 s->target == V4L2_SEL_TGT_COMPOSE_ACTIVE) { 977 s->target == V4L2_SEL_TGT_COMPOSE) {
978 icd->user_width = s->r.width; 978 icd->user_width = s->r.width;
979 icd->user_height = s->r.height; 979 icd->user_height = s->r.height;
980 if (!icd->streamer) 980 if (!icd->streamer)
@@ -1184,7 +1184,8 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1184 sd->grp_id = soc_camera_grp_id(icd); 1184 sd->grp_id = soc_camera_grp_id(icd);
1185 v4l2_set_subdev_hostdata(sd, icd); 1185 v4l2_set_subdev_hostdata(sd, icd);
1186 1186
1187 if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL)) 1187 ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL);
1188 if (ret < 0)
1188 goto ectrl; 1189 goto ectrl;
1189 1190
1190 /* At this point client .probe() should have run already */ 1191 /* At this point client .probe() should have run already */
@@ -1529,12 +1530,11 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
1529{ 1530{
1530 struct soc_camera_link *icl = pdev->dev.platform_data; 1531 struct soc_camera_link *icl = pdev->dev.platform_data;
1531 struct soc_camera_device *icd; 1532 struct soc_camera_device *icd;
1532 int ret;
1533 1533
1534 if (!icl) 1534 if (!icl)
1535 return -EINVAL; 1535 return -EINVAL;
1536 1536
1537 icd = kzalloc(sizeof(*icd), GFP_KERNEL); 1537 icd = devm_kzalloc(&pdev->dev, sizeof(*icd), GFP_KERNEL);
1538 if (!icd) 1538 if (!icd)
1539 return -ENOMEM; 1539 return -ENOMEM;
1540 1540
@@ -1543,19 +1543,10 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
1543 icd->pdev = &pdev->dev; 1543 icd->pdev = &pdev->dev;
1544 platform_set_drvdata(pdev, icd); 1544 platform_set_drvdata(pdev, icd);
1545 1545
1546 ret = soc_camera_device_register(icd);
1547 if (ret < 0)
1548 goto escdevreg;
1549
1550 icd->user_width = DEFAULT_WIDTH; 1546 icd->user_width = DEFAULT_WIDTH;
1551 icd->user_height = DEFAULT_HEIGHT; 1547 icd->user_height = DEFAULT_HEIGHT;
1552 1548
1553 return 0; 1549 return soc_camera_device_register(icd);
1554
1555escdevreg:
1556 kfree(icd);
1557
1558 return ret;
1559} 1550}
1560 1551
1561/* 1552/*
@@ -1572,8 +1563,6 @@ static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
1572 1563
1573 list_del(&icd->list); 1564 list_del(&icd->list);
1574 1565
1575 kfree(icd);
1576
1577 return 0; 1566 return 0;
1578} 1567}
1579 1568
@@ -1586,18 +1575,7 @@ static struct platform_driver __refdata soc_camera_pdrv = {
1586 }, 1575 },
1587}; 1576};
1588 1577
1589static int __init soc_camera_init(void) 1578module_platform_driver(soc_camera_pdrv);
1590{
1591 return platform_driver_register(&soc_camera_pdrv);
1592}
1593
1594static void __exit soc_camera_exit(void)
1595{
1596 platform_driver_unregister(&soc_camera_pdrv);
1597}
1598
1599module_init(soc_camera_init);
1600module_exit(soc_camera_exit);
1601 1579
1602MODULE_DESCRIPTION("Image capture bus driver"); 1580MODULE_DESCRIPTION("Image capture bus driver");
1603MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); 1581MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");