aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/meson/meson_venc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/meson/meson_venc.c')
-rw-r--r--drivers/gpu/drm/meson/meson_venc.c347
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
700union 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
742union 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
784union 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
826union 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
868union 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
910union 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
952struct 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
700struct meson_hdmi_venc_vic_mode { 1008struct 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
1047bool 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}
1059EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode);
1060
739bool meson_venc_hdmi_supported_vic(int vic) 1061bool 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}
751EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); 1073EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic);
752 1074
1075static 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
753static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic) 1089static 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));