diff options
Diffstat (limited to 'drivers/gpu/drm/meson/meson_venc.c')
-rw-r--r-- | drivers/gpu/drm/meson/meson_venc.c | 347 |
1 files changed, 343 insertions, 4 deletions
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c index 9509017dbded..6e2701389801 100644 --- a/drivers/gpu/drm/meson/meson_venc.c +++ b/drivers/gpu/drm/meson/meson_venc.c | |||
@@ -697,6 +697,314 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = { | |||
697 | }, | 697 | }, |
698 | }; | 698 | }; |
699 | 699 | ||
700 | union meson_hdmi_venc_mode meson_hdmi_encp_mode_640x480_60 = { | ||
701 | .encp = { | ||
702 | .dvi_settings = 0x21, | ||
703 | .video_mode = 0x4040, | ||
704 | .video_mode_adv = 0x18, | ||
705 | /* video_prog_mode */ | ||
706 | /* video_sync_mode */ | ||
707 | /* video_yc_dly */ | ||
708 | /* video_rgb_ctrl */ | ||
709 | /* video_filt_ctrl */ | ||
710 | /* video_ofld_voav_ofst */ | ||
711 | /* yfp1_htime */ | ||
712 | /* yfp2_htime */ | ||
713 | .max_pxcnt = 0x31f, | ||
714 | /* hspuls_begin */ | ||
715 | /* hspuls_end */ | ||
716 | /* hspuls_switch */ | ||
717 | /* vspuls_begin */ | ||
718 | /* vspuls_end */ | ||
719 | /* vspuls_bline */ | ||
720 | /* vspuls_eline */ | ||
721 | .havon_begin = 0x90, | ||
722 | .havon_end = 0x30f, | ||
723 | .vavon_bline = 0x23, | ||
724 | .vavon_eline = 0x202, | ||
725 | /* eqpuls_begin */ | ||
726 | /* eqpuls_end */ | ||
727 | /* eqpuls_bline */ | ||
728 | /* eqpuls_eline */ | ||
729 | .hso_begin = 0, | ||
730 | .hso_end = 0x60, | ||
731 | .vso_begin = 0x1e, | ||
732 | .vso_end = 0x32, | ||
733 | .vso_bline = 0, | ||
734 | .vso_eline = 2, | ||
735 | .vso_eline_present = true, | ||
736 | /* sy_val */ | ||
737 | /* sy2_val */ | ||
738 | .max_lncnt = 0x20c, | ||
739 | }, | ||
740 | }; | ||
741 | |||
742 | union meson_hdmi_venc_mode meson_hdmi_encp_mode_800x600_60 = { | ||
743 | .encp = { | ||
744 | .dvi_settings = 0x21, | ||
745 | .video_mode = 0x4040, | ||
746 | .video_mode_adv = 0x18, | ||
747 | /* video_prog_mode */ | ||
748 | /* video_sync_mode */ | ||
749 | /* video_yc_dly */ | ||
750 | /* video_rgb_ctrl */ | ||
751 | /* video_filt_ctrl */ | ||
752 | /* video_ofld_voav_ofst */ | ||
753 | /* yfp1_htime */ | ||
754 | /* yfp2_htime */ | ||
755 | .max_pxcnt = 0x41f, | ||
756 | /* hspuls_begin */ | ||
757 | /* hspuls_end */ | ||
758 | /* hspuls_switch */ | ||
759 | /* vspuls_begin */ | ||
760 | /* vspuls_end */ | ||
761 | /* vspuls_bline */ | ||
762 | /* vspuls_eline */ | ||
763 | .havon_begin = 0xD8, | ||
764 | .havon_end = 0x3f7, | ||
765 | .vavon_bline = 0x1b, | ||
766 | .vavon_eline = 0x272, | ||
767 | /* eqpuls_begin */ | ||
768 | /* eqpuls_end */ | ||
769 | /* eqpuls_bline */ | ||
770 | /* eqpuls_eline */ | ||
771 | .hso_begin = 0, | ||
772 | .hso_end = 0x80, | ||
773 | .vso_begin = 0x1e, | ||
774 | .vso_end = 0x32, | ||
775 | .vso_bline = 0, | ||
776 | .vso_eline = 4, | ||
777 | .vso_eline_present = true, | ||
778 | /* sy_val */ | ||
779 | /* sy2_val */ | ||
780 | .max_lncnt = 0x273, | ||
781 | }, | ||
782 | }; | ||
783 | |||
784 | union meson_hdmi_venc_mode meson_hdmi_encp_mode_1024x768_60 = { | ||
785 | .encp = { | ||
786 | .dvi_settings = 0x21, | ||
787 | .video_mode = 0x4040, | ||
788 | .video_mode_adv = 0x18, | ||
789 | /* video_prog_mode */ | ||
790 | /* video_sync_mode */ | ||
791 | /* video_yc_dly */ | ||
792 | /* video_rgb_ctrl */ | ||
793 | /* video_filt_ctrl */ | ||
794 | /* video_ofld_voav_ofst */ | ||
795 | /* yfp1_htime */ | ||
796 | /* yfp2_htime */ | ||
797 | .max_pxcnt = 1343, | ||
798 | /* hspuls_begin */ | ||
799 | /* hspuls_end */ | ||
800 | /* hspuls_switch */ | ||
801 | /* vspuls_begin */ | ||
802 | /* vspuls_end */ | ||
803 | /* vspuls_bline */ | ||
804 | /* vspuls_eline */ | ||
805 | .havon_begin = 296, | ||
806 | .havon_end = 1319, | ||
807 | .vavon_bline = 35, | ||
808 | .vavon_eline = 802, | ||
809 | /* eqpuls_begin */ | ||
810 | /* eqpuls_end */ | ||
811 | /* eqpuls_bline */ | ||
812 | /* eqpuls_eline */ | ||
813 | .hso_begin = 0, | ||
814 | .hso_end = 136, | ||
815 | .vso_begin = 30, | ||
816 | .vso_end = 50, | ||
817 | .vso_bline = 0, | ||
818 | .vso_eline = 6, | ||
819 | .vso_eline_present = true, | ||
820 | /* sy_val */ | ||
821 | /* sy2_val */ | ||
822 | .max_lncnt = 805, | ||
823 | }, | ||
824 | }; | ||
825 | |||
826 | union meson_hdmi_venc_mode meson_hdmi_encp_mode_1152x864_75 = { | ||
827 | .encp = { | ||
828 | .dvi_settings = 0x21, | ||
829 | .video_mode = 0x4040, | ||
830 | .video_mode_adv = 0x18, | ||
831 | /* video_prog_mode */ | ||
832 | /* video_sync_mode */ | ||
833 | /* video_yc_dly */ | ||
834 | /* video_rgb_ctrl */ | ||
835 | /* video_filt_ctrl */ | ||
836 | /* video_ofld_voav_ofst */ | ||
837 | /* yfp1_htime */ | ||
838 | /* yfp2_htime */ | ||
839 | .max_pxcnt = 0x63f, | ||
840 | /* hspuls_begin */ | ||
841 | /* hspuls_end */ | ||
842 | /* hspuls_switch */ | ||
843 | /* vspuls_begin */ | ||
844 | /* vspuls_end */ | ||
845 | /* vspuls_bline */ | ||
846 | /* vspuls_eline */ | ||
847 | .havon_begin = 0x180, | ||
848 | .havon_end = 0x5ff, | ||
849 | .vavon_bline = 0x23, | ||
850 | .vavon_eline = 0x382, | ||
851 | /* eqpuls_begin */ | ||
852 | /* eqpuls_end */ | ||
853 | /* eqpuls_bline */ | ||
854 | /* eqpuls_eline */ | ||
855 | .hso_begin = 0, | ||
856 | .hso_end = 0x80, | ||
857 | .vso_begin = 0x1e, | ||
858 | .vso_end = 0x32, | ||
859 | .vso_bline = 0, | ||
860 | .vso_eline = 3, | ||
861 | .vso_eline_present = true, | ||
862 | /* sy_val */ | ||
863 | /* sy2_val */ | ||
864 | .max_lncnt = 0x383, | ||
865 | }, | ||
866 | }; | ||
867 | |||
868 | union meson_hdmi_venc_mode meson_hdmi_encp_mode_1280x1024_60 = { | ||
869 | .encp = { | ||
870 | .dvi_settings = 0x21, | ||
871 | .video_mode = 0x4040, | ||
872 | .video_mode_adv = 0x18, | ||
873 | /* video_prog_mode */ | ||
874 | /* video_sync_mode */ | ||
875 | /* video_yc_dly */ | ||
876 | /* video_rgb_ctrl */ | ||
877 | /* video_filt_ctrl */ | ||
878 | /* video_ofld_voav_ofst */ | ||
879 | /* yfp1_htime */ | ||
880 | /* yfp2_htime */ | ||
881 | .max_pxcnt = 0x697, | ||
882 | /* hspuls_begin */ | ||
883 | /* hspuls_end */ | ||
884 | /* hspuls_switch */ | ||
885 | /* vspuls_begin */ | ||
886 | /* vspuls_end */ | ||
887 | /* vspuls_bline */ | ||
888 | /* vspuls_eline */ | ||
889 | .havon_begin = 0x168, | ||
890 | .havon_end = 0x667, | ||
891 | .vavon_bline = 0x29, | ||
892 | .vavon_eline = 0x428, | ||
893 | /* eqpuls_begin */ | ||
894 | /* eqpuls_end */ | ||
895 | /* eqpuls_bline */ | ||
896 | /* eqpuls_eline */ | ||
897 | .hso_begin = 0, | ||
898 | .hso_end = 0x70, | ||
899 | .vso_begin = 0x1e, | ||
900 | .vso_end = 0x32, | ||
901 | .vso_bline = 0, | ||
902 | .vso_eline = 3, | ||
903 | .vso_eline_present = true, | ||
904 | /* sy_val */ | ||
905 | /* sy2_val */ | ||
906 | .max_lncnt = 0x429, | ||
907 | }, | ||
908 | }; | ||
909 | |||
910 | union meson_hdmi_venc_mode meson_hdmi_encp_mode_1600x1200_60 = { | ||
911 | .encp = { | ||
912 | .dvi_settings = 0x21, | ||
913 | .video_mode = 0x4040, | ||
914 | .video_mode_adv = 0x18, | ||
915 | /* video_prog_mode */ | ||
916 | /* video_sync_mode */ | ||
917 | /* video_yc_dly */ | ||
918 | /* video_rgb_ctrl */ | ||
919 | /* video_filt_ctrl */ | ||
920 | /* video_ofld_voav_ofst */ | ||
921 | /* yfp1_htime */ | ||
922 | /* yfp2_htime */ | ||
923 | .max_pxcnt = 0x86f, | ||
924 | /* hspuls_begin */ | ||
925 | /* hspuls_end */ | ||
926 | /* hspuls_switch */ | ||
927 | /* vspuls_begin */ | ||
928 | /* vspuls_end */ | ||
929 | /* vspuls_bline */ | ||
930 | /* vspuls_eline */ | ||
931 | .havon_begin = 0x1f0, | ||
932 | .havon_end = 0x82f, | ||
933 | .vavon_bline = 0x31, | ||
934 | .vavon_eline = 0x4e0, | ||
935 | /* eqpuls_begin */ | ||
936 | /* eqpuls_end */ | ||
937 | /* eqpuls_bline */ | ||
938 | /* eqpuls_eline */ | ||
939 | .hso_begin = 0, | ||
940 | .hso_end = 0xc0, | ||
941 | .vso_begin = 0x1e, | ||
942 | .vso_end = 0x32, | ||
943 | .vso_bline = 0, | ||
944 | .vso_eline = 3, | ||
945 | .vso_eline_present = true, | ||
946 | /* sy_val */ | ||
947 | /* sy2_val */ | ||
948 | .max_lncnt = 0x4e1, | ||
949 | }, | ||
950 | }; | ||
951 | |||
952 | struct meson_hdmi_venc_dmt_mode { | ||
953 | struct drm_display_mode drm_mode; | ||
954 | union meson_hdmi_venc_mode *mode; | ||
955 | } meson_hdmi_venc_dmt_modes[] = { | ||
956 | /* 640x480@60Hz */ | ||
957 | { | ||
958 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, | ||
959 | 752, 800, 0, 480, 490, 492, 525, 0, | ||
960 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
961 | &meson_hdmi_encp_mode_640x480_60, | ||
962 | }, | ||
963 | /* 800x600@60Hz */ | ||
964 | { | ||
965 | { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, | ||
966 | 968, 1056, 0, 600, 601, 605, 628, 0, | ||
967 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
968 | &meson_hdmi_encp_mode_800x600_60, | ||
969 | }, | ||
970 | /* 1024x768@60Hz */ | ||
971 | { | ||
972 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, | ||
973 | 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, | ||
974 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
975 | &meson_hdmi_encp_mode_1024x768_60, | ||
976 | }, | ||
977 | /* 1152x864@75Hz */ | ||
978 | { | ||
979 | { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, | ||
980 | 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, | ||
981 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
982 | &meson_hdmi_encp_mode_1152x864_75, | ||
983 | }, | ||
984 | /* 1280x1024@60Hz */ | ||
985 | { | ||
986 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, | ||
987 | 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, | ||
988 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
989 | &meson_hdmi_encp_mode_1280x1024_60, | ||
990 | }, | ||
991 | /* 1600x1200@60Hz */ | ||
992 | { | ||
993 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, | ||
994 | 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, | ||
995 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
996 | &meson_hdmi_encp_mode_1600x1200_60, | ||
997 | }, | ||
998 | /* 1920x1080@60Hz */ | ||
999 | { | ||
1000 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, | ||
1001 | 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, | ||
1002 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
1003 | &meson_hdmi_encp_mode_1080p60 | ||
1004 | }, | ||
1005 | { }, /* sentinel */ | ||
1006 | }; | ||
1007 | |||
700 | struct meson_hdmi_venc_vic_mode { | 1008 | struct meson_hdmi_venc_vic_mode { |
701 | unsigned int vic; | 1009 | unsigned int vic; |
702 | union meson_hdmi_venc_mode *mode; | 1010 | union meson_hdmi_venc_mode *mode; |
@@ -736,6 +1044,20 @@ static unsigned long modulo(unsigned long a, unsigned long b) | |||
736 | return a; | 1044 | return a; |
737 | } | 1045 | } |
738 | 1046 | ||
1047 | bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode) | ||
1048 | { | ||
1049 | struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes; | ||
1050 | |||
1051 | while (vmode->mode) { | ||
1052 | if (drm_mode_equal(&vmode->drm_mode, mode)) | ||
1053 | return true; | ||
1054 | vmode++; | ||
1055 | } | ||
1056 | |||
1057 | return false; | ||
1058 | } | ||
1059 | EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode); | ||
1060 | |||
739 | bool meson_venc_hdmi_supported_vic(int vic) | 1061 | bool meson_venc_hdmi_supported_vic(int vic) |
740 | { | 1062 | { |
741 | struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; | 1063 | struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; |
@@ -750,6 +1072,20 @@ bool meson_venc_hdmi_supported_vic(int vic) | |||
750 | } | 1072 | } |
751 | EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); | 1073 | EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); |
752 | 1074 | ||
1075 | static union meson_hdmi_venc_mode | ||
1076 | *meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode) | ||
1077 | { | ||
1078 | struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes; | ||
1079 | |||
1080 | while (vmode->mode) { | ||
1081 | if (drm_mode_equal(&vmode->drm_mode, mode)) | ||
1082 | return vmode->mode; | ||
1083 | vmode++; | ||
1084 | } | ||
1085 | |||
1086 | return NULL; | ||
1087 | } | ||
1088 | |||
753 | static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic) | 1089 | static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic) |
754 | { | 1090 | { |
755 | struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; | 1091 | struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; |
@@ -811,10 +1147,13 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, | |||
811 | unsigned int sof_lines; | 1147 | unsigned int sof_lines; |
812 | unsigned int vsync_lines; | 1148 | unsigned int vsync_lines; |
813 | 1149 | ||
814 | vmode = meson_venc_hdmi_get_vic_vmode(vic); | 1150 | if (meson_venc_hdmi_supported_vic(vic)) |
1151 | vmode = meson_venc_hdmi_get_vic_vmode(vic); | ||
1152 | else | ||
1153 | vmode = meson_venc_hdmi_get_dmt_vmode(mode); | ||
815 | if (!vmode) { | 1154 | if (!vmode) { |
816 | dev_err(priv->dev, "%s: Fatal Error, unsupported vic %d\n", | 1155 | dev_err(priv->dev, "%s: Fatal Error, unsupported mode " |
817 | __func__, vic); | 1156 | DRM_MODE_FMT "\n", __func__, DRM_MODE_ARG(mode)); |
818 | return; | 1157 | return; |
819 | } | 1158 | } |
820 | 1159 | ||
@@ -864,7 +1203,7 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, | |||
864 | hsync_pixels_venc *= 2; | 1203 | hsync_pixels_venc *= 2; |
865 | 1204 | ||
866 | /* Disable VDACs */ | 1205 | /* Disable VDACs */ |
867 | writel_bits_relaxed(0x1f, 0x1f, | 1206 | writel_bits_relaxed(0xff, 0xff, |
868 | priv->io_base + _REG(VENC_VDAC_SETTING)); | 1207 | priv->io_base + _REG(VENC_VDAC_SETTING)); |
869 | 1208 | ||
870 | writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); | 1209 | writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); |