diff options
author | Dave Airlie <airlied@redhat.com> | 2018-11-28 19:21:23 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-11-28 19:28:49 -0500 |
commit | 61647c77cb15354a329cbb36fe7a2253b36b51b1 (patch) | |
tree | 59d887f99bc4a2bdddc7cfc1d81794c2a4cdc759 /drivers/gpu/drm/meson/meson_vclk.c | |
parent | 1a31c26ed7b495f152e3103dc7c68e3307a39541 (diff) | |
parent | 08f73d668048ffa3ba6b1426b6ba0a89b16aefd7 (diff) |
Merge tag 'drm-misc-next-2018-11-28' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v4.21:
Core Changes:
- Merge drm_info.c into drm_debugfs.c
- Complete the fake drm_crtc_commit's hw_done/flip_done sooner.
- Remove deprecated drm_obj_ref/unref functions. All drivers use get/put now.
- Decrease stack use of drm_gem_prime_mmap.
- Improve documentation for dumb callbacks.
Driver Changes:
- Add edid support to virtio.
- Wait on implicit fence in meson and sun4i.
- Add support for BGRX8888 to sun4i.
- Preparation patches for sun4i driver to start supporting linear and tiled YUV formats.
- Add support for HDMI 1.4 4k modes to meson, and support for VIC alternate timings.
- Drop custom dumb_map in vkms.
- Small fixes and cleanups to v3d.
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/151a3270-b1be-ed75-bd58-6b29d741f592@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/meson/meson_vclk.c')
-rw-r--r-- | drivers/gpu/drm/meson/meson_vclk.c | 127 |
1 files changed, 86 insertions, 41 deletions
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c index ae5473257f72..f6ba35a405f8 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c | |||
@@ -117,6 +117,8 @@ | |||
117 | #define HDMI_PLL_RESET BIT(28) | 117 | #define HDMI_PLL_RESET BIT(28) |
118 | #define HDMI_PLL_LOCK BIT(31) | 118 | #define HDMI_PLL_LOCK BIT(31) |
119 | 119 | ||
120 | #define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001) | ||
121 | |||
120 | /* VID PLL Dividers */ | 122 | /* VID PLL Dividers */ |
121 | enum { | 123 | enum { |
122 | VID_PLL_DIV_1 = 0, | 124 | VID_PLL_DIV_1 = 0, |
@@ -323,7 +325,7 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv) | |||
323 | enum { | 325 | enum { |
324 | /* PLL O1 O2 O3 VP DV EN TX */ | 326 | /* PLL O1 O2 O3 VP DV EN TX */ |
325 | /* 4320 /4 /4 /1 /5 /1 => /2 /2 */ | 327 | /* 4320 /4 /4 /1 /5 /1 => /2 /2 */ |
326 | MESON_VCLK_HDMI_ENCI_54000 = 1, | 328 | MESON_VCLK_HDMI_ENCI_54000 = 0, |
327 | /* 4320 /4 /4 /1 /5 /1 => /1 /2 */ | 329 | /* 4320 /4 /4 /1 /5 /1 => /1 /2 */ |
328 | MESON_VCLK_HDMI_DDR_54000, | 330 | MESON_VCLK_HDMI_DDR_54000, |
329 | /* 2970 /4 /1 /1 /5 /1 => /1 /2 */ | 331 | /* 2970 /4 /1 /1 /5 /1 => /1 /2 */ |
@@ -339,6 +341,7 @@ enum { | |||
339 | }; | 341 | }; |
340 | 342 | ||
341 | struct meson_vclk_params { | 343 | struct meson_vclk_params { |
344 | unsigned int pixel_freq; | ||
342 | unsigned int pll_base_freq; | 345 | unsigned int pll_base_freq; |
343 | unsigned int pll_od1; | 346 | unsigned int pll_od1; |
344 | unsigned int pll_od2; | 347 | unsigned int pll_od2; |
@@ -347,6 +350,7 @@ struct meson_vclk_params { | |||
347 | unsigned int vclk_div; | 350 | unsigned int vclk_div; |
348 | } params[] = { | 351 | } params[] = { |
349 | [MESON_VCLK_HDMI_ENCI_54000] = { | 352 | [MESON_VCLK_HDMI_ENCI_54000] = { |
353 | .pixel_freq = 54000, | ||
350 | .pll_base_freq = 4320000, | 354 | .pll_base_freq = 4320000, |
351 | .pll_od1 = 4, | 355 | .pll_od1 = 4, |
352 | .pll_od2 = 4, | 356 | .pll_od2 = 4, |
@@ -355,6 +359,7 @@ struct meson_vclk_params { | |||
355 | .vclk_div = 1, | 359 | .vclk_div = 1, |
356 | }, | 360 | }, |
357 | [MESON_VCLK_HDMI_DDR_54000] = { | 361 | [MESON_VCLK_HDMI_DDR_54000] = { |
362 | .pixel_freq = 54000, | ||
358 | .pll_base_freq = 4320000, | 363 | .pll_base_freq = 4320000, |
359 | .pll_od1 = 4, | 364 | .pll_od1 = 4, |
360 | .pll_od2 = 4, | 365 | .pll_od2 = 4, |
@@ -363,6 +368,7 @@ struct meson_vclk_params { | |||
363 | .vclk_div = 1, | 368 | .vclk_div = 1, |
364 | }, | 369 | }, |
365 | [MESON_VCLK_HDMI_DDR_148500] = { | 370 | [MESON_VCLK_HDMI_DDR_148500] = { |
371 | .pixel_freq = 148500, | ||
366 | .pll_base_freq = 2970000, | 372 | .pll_base_freq = 2970000, |
367 | .pll_od1 = 4, | 373 | .pll_od1 = 4, |
368 | .pll_od2 = 1, | 374 | .pll_od2 = 1, |
@@ -371,6 +377,7 @@ struct meson_vclk_params { | |||
371 | .vclk_div = 1, | 377 | .vclk_div = 1, |
372 | }, | 378 | }, |
373 | [MESON_VCLK_HDMI_74250] = { | 379 | [MESON_VCLK_HDMI_74250] = { |
380 | .pixel_freq = 74250, | ||
374 | .pll_base_freq = 2970000, | 381 | .pll_base_freq = 2970000, |
375 | .pll_od1 = 2, | 382 | .pll_od1 = 2, |
376 | .pll_od2 = 2, | 383 | .pll_od2 = 2, |
@@ -379,6 +386,7 @@ struct meson_vclk_params { | |||
379 | .vclk_div = 1, | 386 | .vclk_div = 1, |
380 | }, | 387 | }, |
381 | [MESON_VCLK_HDMI_148500] = { | 388 | [MESON_VCLK_HDMI_148500] = { |
389 | .pixel_freq = 148500, | ||
382 | .pll_base_freq = 2970000, | 390 | .pll_base_freq = 2970000, |
383 | .pll_od1 = 1, | 391 | .pll_od1 = 1, |
384 | .pll_od2 = 2, | 392 | .pll_od2 = 2, |
@@ -387,6 +395,7 @@ struct meson_vclk_params { | |||
387 | .vclk_div = 1, | 395 | .vclk_div = 1, |
388 | }, | 396 | }, |
389 | [MESON_VCLK_HDMI_297000] = { | 397 | [MESON_VCLK_HDMI_297000] = { |
398 | .pixel_freq = 297000, | ||
390 | .pll_base_freq = 2970000, | 399 | .pll_base_freq = 2970000, |
391 | .pll_od1 = 1, | 400 | .pll_od1 = 1, |
392 | .pll_od2 = 1, | 401 | .pll_od2 = 1, |
@@ -395,6 +404,7 @@ struct meson_vclk_params { | |||
395 | .vclk_div = 2, | 404 | .vclk_div = 2, |
396 | }, | 405 | }, |
397 | [MESON_VCLK_HDMI_594000] = { | 406 | [MESON_VCLK_HDMI_594000] = { |
407 | .pixel_freq = 594000, | ||
398 | .pll_base_freq = 5940000, | 408 | .pll_base_freq = 5940000, |
399 | .pll_od1 = 1, | 409 | .pll_od1 = 1, |
400 | .pll_od2 = 1, | 410 | .pll_od2 = 1, |
@@ -402,6 +412,7 @@ struct meson_vclk_params { | |||
402 | .vid_pll_div = VID_PLL_DIV_5, | 412 | .vid_pll_div = VID_PLL_DIV_5, |
403 | .vclk_div = 1, | 413 | .vclk_div = 1, |
404 | }, | 414 | }, |
415 | { /* sentinel */ }, | ||
405 | }; | 416 | }; |
406 | 417 | ||
407 | static inline unsigned int pll_od_to_reg(unsigned int od) | 418 | static inline unsigned int pll_od_to_reg(unsigned int od) |
@@ -626,12 +637,37 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, | |||
626 | pll_freq); | 637 | pll_freq); |
627 | } | 638 | } |
628 | 639 | ||
640 | enum drm_mode_status | ||
641 | meson_vclk_vic_supported_freq(unsigned int freq) | ||
642 | { | ||
643 | int i; | ||
644 | |||
645 | DRM_DEBUG_DRIVER("freq = %d\n", freq); | ||
646 | |||
647 | for (i = 0 ; params[i].pixel_freq ; ++i) { | ||
648 | DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n", | ||
649 | i, params[i].pixel_freq, | ||
650 | FREQ_1000_1001(params[i].pixel_freq)); | ||
651 | /* Match strict frequency */ | ||
652 | if (freq == params[i].pixel_freq) | ||
653 | return MODE_OK; | ||
654 | /* Match 1000/1001 variant */ | ||
655 | if (freq == FREQ_1000_1001(params[i].pixel_freq)) | ||
656 | return MODE_OK; | ||
657 | } | ||
658 | |||
659 | return MODE_CLOCK_RANGE; | ||
660 | } | ||
661 | EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_freq); | ||
662 | |||
629 | static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, | 663 | static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, |
630 | unsigned int od1, unsigned int od2, unsigned int od3, | 664 | unsigned int od1, unsigned int od2, unsigned int od3, |
631 | unsigned int vid_pll_div, unsigned int vclk_div, | 665 | unsigned int vid_pll_div, unsigned int vclk_div, |
632 | unsigned int hdmi_tx_div, unsigned int venc_div, | 666 | unsigned int hdmi_tx_div, unsigned int venc_div, |
633 | bool hdmi_use_enci) | 667 | bool hdmi_use_enci, bool vic_alternate_clock) |
634 | { | 668 | { |
669 | unsigned int m = 0, frac = 0; | ||
670 | |||
635 | /* Set HDMI-TX sys clock */ | 671 | /* Set HDMI-TX sys clock */ |
636 | regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, | 672 | regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, |
637 | CTS_HDMI_SYS_SEL_MASK, 0); | 673 | CTS_HDMI_SYS_SEL_MASK, 0); |
@@ -646,34 +682,38 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, | |||
646 | } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { | 682 | } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { |
647 | switch (pll_base_freq) { | 683 | switch (pll_base_freq) { |
648 | case 2970000: | 684 | case 2970000: |
649 | meson_hdmi_pll_set_params(priv, 0x3d, 0xe00, | 685 | m = 0x3d; |
650 | od1, od2, od3); | 686 | frac = vic_alternate_clock ? 0xd02 : 0xe00; |
651 | break; | 687 | break; |
652 | case 4320000: | 688 | case 4320000: |
653 | meson_hdmi_pll_set_params(priv, 0x5a, 0, | 689 | m = vic_alternate_clock ? 0x59 : 0x5a; |
654 | od1, od2, od3); | 690 | frac = vic_alternate_clock ? 0xe8f : 0; |
655 | break; | 691 | break; |
656 | case 5940000: | 692 | case 5940000: |
657 | meson_hdmi_pll_set_params(priv, 0x7b, 0xc00, | 693 | m = 0x7b; |
658 | od1, od2, od3); | 694 | frac = vic_alternate_clock ? 0xa05 : 0xc00; |
659 | break; | 695 | break; |
660 | } | 696 | } |
697 | |||
698 | meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); | ||
661 | } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || | 699 | } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || |
662 | meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { | 700 | meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { |
663 | switch (pll_base_freq) { | 701 | switch (pll_base_freq) { |
664 | case 2970000: | 702 | case 2970000: |
665 | meson_hdmi_pll_set_params(priv, 0x7b, 0x300, | 703 | m = 0x7b; |
666 | od1, od2, od3); | 704 | frac = vic_alternate_clock ? 0x281 : 0x300; |
667 | break; | 705 | break; |
668 | case 4320000: | 706 | case 4320000: |
669 | meson_hdmi_pll_set_params(priv, 0xb4, 0, | 707 | m = vic_alternate_clock ? 0xb3 : 0xb4; |
670 | od1, od2, od3); | 708 | frac = vic_alternate_clock ? 0x347 : 0; |
671 | break; | 709 | break; |
672 | case 5940000: | 710 | case 5940000: |
673 | meson_hdmi_pll_set_params(priv, 0xf7, 0x200, | 711 | m = 0xf7; |
674 | od1, od2, od3); | 712 | frac = vic_alternate_clock ? 0x102 : 0x200; |
675 | break; | 713 | break; |
676 | } | 714 | } |
715 | |||
716 | meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); | ||
677 | } | 717 | } |
678 | 718 | ||
679 | /* Setup vid_pll divider */ | 719 | /* Setup vid_pll divider */ |
@@ -826,6 +866,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, | |||
826 | unsigned int vclk_freq, unsigned int venc_freq, | 866 | unsigned int vclk_freq, unsigned int venc_freq, |
827 | unsigned int dac_freq, bool hdmi_use_enci) | 867 | unsigned int dac_freq, bool hdmi_use_enci) |
828 | { | 868 | { |
869 | bool vic_alternate_clock = false; | ||
829 | unsigned int freq; | 870 | unsigned int freq; |
830 | unsigned int hdmi_tx_div; | 871 | unsigned int hdmi_tx_div; |
831 | unsigned int venc_div; | 872 | unsigned int venc_div; |
@@ -843,7 +884,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, | |||
843 | * - encp encoder | 884 | * - encp encoder |
844 | */ | 885 | */ |
845 | meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0, | 886 | meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0, |
846 | VID_PLL_DIV_5, 2, 1, 1, false); | 887 | VID_PLL_DIV_5, 2, 1, 1, false, false); |
847 | return; | 888 | return; |
848 | } | 889 | } |
849 | 890 | ||
@@ -863,31 +904,35 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, | |||
863 | return; | 904 | return; |
864 | } | 905 | } |
865 | 906 | ||
866 | switch (vclk_freq) { | 907 | for (freq = 0 ; params[freq].pixel_freq ; ++freq) { |
867 | case 54000: | 908 | if (vclk_freq == params[freq].pixel_freq || |
868 | if (hdmi_use_enci) | 909 | vclk_freq == FREQ_1000_1001(params[freq].pixel_freq)) { |
869 | freq = MESON_VCLK_HDMI_ENCI_54000; | 910 | if (vclk_freq != params[freq].pixel_freq) |
870 | else | 911 | vic_alternate_clock = true; |
871 | freq = MESON_VCLK_HDMI_DDR_54000; | 912 | else |
872 | break; | 913 | vic_alternate_clock = false; |
873 | case 74250: | 914 | |
874 | freq = MESON_VCLK_HDMI_74250; | 915 | if (freq == MESON_VCLK_HDMI_ENCI_54000 && |
875 | break; | 916 | !hdmi_use_enci) |
876 | case 148500: | 917 | continue; |
877 | if (dac_freq != 148500) | 918 | |
878 | freq = MESON_VCLK_HDMI_DDR_148500; | 919 | if (freq == MESON_VCLK_HDMI_DDR_54000 && |
879 | else | 920 | hdmi_use_enci) |
880 | freq = MESON_VCLK_HDMI_148500; | 921 | continue; |
881 | break; | 922 | |
882 | case 297000: | 923 | if (freq == MESON_VCLK_HDMI_DDR_148500 && |
883 | freq = MESON_VCLK_HDMI_297000; | 924 | dac_freq == vclk_freq) |
884 | break; | 925 | continue; |
885 | case 594000: | 926 | |
886 | freq = MESON_VCLK_HDMI_594000; | 927 | if (freq == MESON_VCLK_HDMI_148500 && |
887 | break; | 928 | dac_freq != vclk_freq) |
888 | default: | 929 | continue; |
889 | pr_err("Fatal Error, invalid HDMI vclk freq %d\n", | 930 | break; |
890 | vclk_freq); | 931 | } |
932 | } | ||
933 | |||
934 | if (!params[freq].pixel_freq) { | ||
935 | pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq); | ||
891 | return; | 936 | return; |
892 | } | 937 | } |
893 | 938 | ||
@@ -895,6 +940,6 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, | |||
895 | params[freq].pll_od1, params[freq].pll_od2, | 940 | params[freq].pll_od1, params[freq].pll_od2, |
896 | params[freq].pll_od3, params[freq].vid_pll_div, | 941 | params[freq].pll_od3, params[freq].vid_pll_div, |
897 | params[freq].vclk_div, hdmi_tx_div, venc_div, | 942 | params[freq].vclk_div, hdmi_tx_div, venc_div, |
898 | hdmi_use_enci); | 943 | hdmi_use_enci, vic_alternate_clock); |
899 | } | 944 | } |
900 | EXPORT_SYMBOL_GPL(meson_vclk_setup); | 945 | EXPORT_SYMBOL_GPL(meson_vclk_setup); |