.. | .. |
---|
45 | 45 | #include <media/videobuf2-v4l2.h> |
---|
46 | 46 | #include <soc/rockchip/rockchip-system-status.h> |
---|
47 | 47 | #include <sound/hdmi-codec.h> |
---|
| 48 | +#include <linux/rk_hdmirx_class.h> |
---|
48 | 49 | #include "rk_hdmirx.h" |
---|
49 | 50 | #include "rk_hdmirx_cec.h" |
---|
50 | 51 | #include "rk_hdmirx_hdcp.h" |
---|
51 | 52 | |
---|
52 | | -static struct class *hdmirx_class; |
---|
53 | 53 | static int debug; |
---|
54 | 54 | module_param(debug, int, 0644); |
---|
55 | 55 | MODULE_PARM_DESC(debug, "debug level (0-3)"); |
---|
.. | .. |
---|
269 | 269 | static void hdmirx_cancel_cpu_limit_freq(struct rk_hdmirx_dev *hdmirx_dev); |
---|
270 | 270 | static void hdmirx_plugout(struct rk_hdmirx_dev *hdmirx_dev); |
---|
271 | 271 | static void process_signal_change(struct rk_hdmirx_dev *hdmirx_dev); |
---|
| 272 | +static void hdmirx_interrupts_setup(struct rk_hdmirx_dev *hdmirx_dev, bool en); |
---|
272 | 273 | |
---|
273 | 274 | static u8 edid_init_data_340M[] = { |
---|
274 | 275 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, |
---|
.. | .. |
---|
529 | 530 | struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; |
---|
530 | 531 | u32 dma_cfg1; |
---|
531 | 532 | |
---|
| 533 | + if (port_no_link(hdmirx_dev)) { |
---|
| 534 | + v4l2_err(v4l2_dev, "%s port has no link!\n", __func__); |
---|
| 535 | + return -ENOLINK; |
---|
| 536 | + } |
---|
| 537 | + |
---|
| 538 | + if (signal_not_lock(hdmirx_dev)) { |
---|
| 539 | + v4l2_err(v4l2_dev, "%s signal is not locked!\n", __func__); |
---|
| 540 | + return -ENOLCK; |
---|
| 541 | + } |
---|
| 542 | + |
---|
532 | 543 | *timings = hdmirx_dev->timings; |
---|
533 | 544 | dma_cfg1 = hdmirx_readl(hdmirx_dev, DMA_CONFIG1); |
---|
534 | 545 | v4l2_dbg(1, debug, v4l2_dev, "%s: pix_fmt: %s, DMA_CONFIG1:%#x\n", |
---|
.. | .. |
---|
615 | 626 | static void hdmirx_get_pix_fmt(struct rk_hdmirx_dev *hdmirx_dev) |
---|
616 | 627 | { |
---|
617 | 628 | u32 val; |
---|
| 629 | + int timeout = 10; |
---|
618 | 630 | struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; |
---|
619 | 631 | |
---|
| 632 | +try_loop: |
---|
620 | 633 | val = hdmirx_readl(hdmirx_dev, DMA_STATUS11); |
---|
621 | 634 | hdmirx_dev->pix_fmt = val & HDMIRX_FORMAT_MASK; |
---|
622 | 635 | |
---|
.. | .. |
---|
635 | 648 | break; |
---|
636 | 649 | |
---|
637 | 650 | default: |
---|
| 651 | + if (timeout-- > 0) { |
---|
| 652 | + usleep_range(200 * 1000, 200 * 1010); |
---|
| 653 | + v4l2_err(v4l2_dev, "%s: get format failed, read again!\n", __func__); |
---|
| 654 | + goto try_loop; |
---|
| 655 | + } |
---|
| 656 | + hdmirx_dev->pix_fmt = HDMIRX_RGB888; |
---|
| 657 | + hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_BGR24; |
---|
638 | 658 | v4l2_err(v4l2_dev, |
---|
639 | 659 | "%s: err pix_fmt: %d, set RGB888 as default\n", |
---|
640 | 660 | __func__, hdmirx_dev->pix_fmt); |
---|
641 | | - hdmirx_dev->pix_fmt = HDMIRX_RGB888; |
---|
642 | | - hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_BGR24; |
---|
643 | 661 | break; |
---|
644 | 662 | } |
---|
645 | 663 | |
---|
.. | .. |
---|
880 | 898 | struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; |
---|
881 | 899 | u32 last_w, last_h; |
---|
882 | 900 | struct v4l2_bt_timings *bt = &timings->bt; |
---|
| 901 | + enum hdmirx_pix_fmt last_fmt; |
---|
883 | 902 | |
---|
884 | 903 | last_w = 0; |
---|
885 | 904 | last_h = 0; |
---|
| 905 | + last_fmt = HDMIRX_RGB888; |
---|
| 906 | + |
---|
886 | 907 | for (i = 0; i < try_cnt; i++) { |
---|
887 | 908 | ret = hdmirx_get_detected_timings(hdmirx_dev, timings, from_dma); |
---|
888 | 909 | |
---|
.. | .. |
---|
891 | 912 | last_h = bt->height; |
---|
892 | 913 | } |
---|
893 | 914 | |
---|
894 | | - if (ret || (last_w != bt->width) || (last_h != bt->height)) |
---|
| 915 | + if (ret || (last_w != bt->width) || (last_h != bt->height) |
---|
| 916 | + || (last_fmt != hdmirx_dev->pix_fmt)) |
---|
895 | 917 | cnt = 0; |
---|
896 | 918 | else |
---|
897 | 919 | cnt++; |
---|
.. | .. |
---|
901 | 923 | |
---|
902 | 924 | last_w = bt->width; |
---|
903 | 925 | last_h = bt->height; |
---|
| 926 | + last_fmt = hdmirx_dev->pix_fmt; |
---|
904 | 927 | usleep_range(10*1000, 10*1100); |
---|
905 | 928 | } |
---|
906 | 929 | |
---|
.. | .. |
---|
1545 | 1568 | } |
---|
1546 | 1569 | |
---|
1547 | 1570 | hdmirx_reset_dma(hdmirx_dev); |
---|
1548 | | - usleep_range(200*1000, 200*1010); |
---|
| 1571 | + usleep_range(500*1000, 500*1010); |
---|
1549 | 1572 | hdmirx_format_change(hdmirx_dev); |
---|
1550 | 1573 | |
---|
1551 | 1574 | return 0; |
---|
.. | .. |
---|
2349 | 2372 | FIFO_UNDERFLOW_INT_EN | |
---|
2350 | 2373 | HDMIRX_AXI_ERROR_INT_EN, 0); |
---|
2351 | 2374 | hdmirx_reset_dma(hdmirx_dev); |
---|
| 2375 | + hdmirx_interrupts_setup(hdmirx_dev, false); |
---|
2352 | 2376 | v4l2_event_queue(&stream->vdev, &evt_signal_lost); |
---|
2353 | 2377 | if (hdmirx_dev->hdcp && hdmirx_dev->hdcp->hdcp_stop) |
---|
2354 | 2378 | hdmirx_dev->hdcp->hdcp_stop(hdmirx_dev->hdcp); |
---|
.. | .. |
---|
2459 | 2483 | hdmirx_writel(hdmirx_dev, MAINUNIT_2_INT_FORCE, 0x0); |
---|
2460 | 2484 | } |
---|
2461 | 2485 | |
---|
| 2486 | +/* |
---|
| 2487 | + * In the normal preview, some scenarios will trigger the change interrupt |
---|
| 2488 | + * by mistake, and the trigger source of the interrupt needs to be detected |
---|
| 2489 | + * to avoid the problem. |
---|
| 2490 | + */ |
---|
2462 | 2491 | static void pkt_0_int_handler(struct rk_hdmirx_dev *hdmirx_dev, |
---|
2463 | 2492 | int status, bool *handled) |
---|
2464 | 2493 | { |
---|
2465 | 2494 | struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; |
---|
| 2495 | + u32 pre_fmt_fourcc = hdmirx_dev->cur_fmt_fourcc; |
---|
| 2496 | + u32 pre_color_range = hdmirx_dev->cur_color_range; |
---|
| 2497 | + u32 pre_color_space = hdmirx_dev->cur_color_space; |
---|
2466 | 2498 | |
---|
2467 | 2499 | if ((status & PKTDEC_AVIIF_CHG_IRQ)) { |
---|
2468 | | - process_signal_change(hdmirx_dev); |
---|
| 2500 | + hdmirx_get_color_range(hdmirx_dev); |
---|
| 2501 | + hdmirx_get_color_space(hdmirx_dev); |
---|
| 2502 | + hdmirx_get_pix_fmt(hdmirx_dev); |
---|
| 2503 | + if (hdmirx_dev->cur_fmt_fourcc != pre_fmt_fourcc || |
---|
| 2504 | + hdmirx_dev->cur_color_range != pre_color_range || |
---|
| 2505 | + hdmirx_dev->cur_color_space != pre_color_space) { |
---|
| 2506 | + process_signal_change(hdmirx_dev); |
---|
| 2507 | + } |
---|
2469 | 2508 | v4l2_dbg(2, debug, v4l2_dev, "%s: ptk0_st:%#x\n", |
---|
2470 | 2509 | __func__, status); |
---|
2471 | 2510 | *handled = true; |
---|
.. | .. |
---|
3158 | 3197 | struct rk_hdmirx_dev, |
---|
3159 | 3198 | delayed_work_audio); |
---|
3160 | 3199 | struct hdmirx_audiostate *as = &hdmirx_dev->audio_state; |
---|
3161 | | - u32 fs_audio, ch_audio; |
---|
| 3200 | + u32 fs_audio, ch_audio, sample_flat; |
---|
3162 | 3201 | int cur_state, init_state, pre_state, fifo_status2; |
---|
3163 | 3202 | unsigned long delay = 200; |
---|
3164 | 3203 | |
---|
.. | .. |
---|
3223 | 3262 | } |
---|
3224 | 3263 | } |
---|
3225 | 3264 | as->pre_state = cur_state; |
---|
| 3265 | + |
---|
| 3266 | + sample_flat = hdmirx_readl(hdmirx_dev, AUDIO_PROC_STATUS1) & AUD_SAMPLE_FLAT; |
---|
| 3267 | + hdmirx_update_bits(hdmirx_dev, AUDIO_PROC_CONFIG0, I2S_EN, sample_flat ? 0 : I2S_EN); |
---|
| 3268 | + |
---|
3226 | 3269 | exit: |
---|
3227 | 3270 | schedule_delayed_work_on(hdmirx_dev->bound_cpu, |
---|
3228 | 3271 | &hdmirx_dev->delayed_work_audio, |
---|
.. | .. |
---|
3243 | 3286 | plugin = tx_5v_power_present(hdmirx_dev); |
---|
3244 | 3287 | v4l2_dbg(1, debug, v4l2_dev, "%s: plugin:%d\n", __func__, plugin); |
---|
3245 | 3288 | if (plugin) { |
---|
3246 | | - hdmirx_interrupts_setup(hdmirx_dev, false); |
---|
3247 | 3289 | hdmirx_submodule_init(hdmirx_dev); |
---|
3248 | 3290 | hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, POWERPROVIDED, |
---|
3249 | 3291 | POWERPROVIDED); |
---|
.. | .. |
---|
4280 | 4322 | if (ret) |
---|
4281 | 4323 | goto err_unreg_video_dev; |
---|
4282 | 4324 | |
---|
4283 | | - hdmirx_dev->classdev = device_create_with_groups(hdmirx_class, |
---|
| 4325 | + hdmirx_dev->classdev = device_create_with_groups(rk_hdmirx_class(), |
---|
4284 | 4326 | dev, MKDEV(0, 0), |
---|
4285 | 4327 | hdmirx_dev, |
---|
4286 | 4328 | hdmirx_groups, |
---|
.. | .. |
---|
4438 | 4480 | |
---|
4439 | 4481 | static int __init hdmirx_init(void) |
---|
4440 | 4482 | { |
---|
4441 | | - hdmirx_class = class_create(THIS_MODULE, "hdmirx"); |
---|
4442 | | - if (IS_ERR(hdmirx_class)) |
---|
4443 | | - return PTR_ERR(hdmirx_class); |
---|
4444 | 4483 | return platform_driver_register(&hdmirx_driver); |
---|
4445 | 4484 | } |
---|
4446 | 4485 | module_init(hdmirx_init); |
---|
.. | .. |
---|
4448 | 4487 | static void __exit hdmirx_exit(void) |
---|
4449 | 4488 | { |
---|
4450 | 4489 | platform_driver_unregister(&hdmirx_driver); |
---|
4451 | | - class_destroy(hdmirx_class); |
---|
4452 | 4490 | } |
---|
4453 | 4491 | module_exit(hdmirx_exit); |
---|
4454 | 4492 | |
---|