@@ -78,6 +78,9 @@ __FBSDID("$FreeBSD$");
7878#define CTRL_INTR_EN_GLO_MASK 0x04
7979#define TDA_INT_FLAGS_2 MKREG(0x00, 0x11)
8080#define INT_FLAGS_2_EDID_BLK_RD (1 << 1)
81+ #define TDA_ENA_VP_0 MKREG(0x00, 0x18)
82+ #define TDA_ENA_VP_1 MKREG(0x00, 0x19)
83+ #define TDA_ENA_VP_2 MKREG(0x00, 0x1a)
8184
8285#define TDA_VIP_CNTRL_0 MKREG(0x00, 0x20)
8386#define TDA_VIP_CNTRL_1 MKREG(0x00, 0x21)
@@ -268,7 +271,6 @@ struct tda19988_softc {
268271 struct drm_encoder encoder ;
269272 struct drm_connector connector __subobject_use_container_bounds ;
270273 struct drm_bridge bridge __subobject_use_container_bounds ;
271- struct drm_display_mode mode ;
272274};
273275
274276static int
@@ -443,152 +445,6 @@ tda19988_probe(device_t dev)
443445 return (BUS_PROBE_DEFAULT );
444446}
445447
446- static void
447- tda19988_init_encoder (struct tda19988_softc * sc )
448- {
449- const struct drm_display_mode * mode ;
450- uint16_t ref_pix , ref_line , n_pix , n_line ;
451- uint16_t hs_pix_start , hs_pix_stop ;
452- uint16_t vs1_pix_start , vs1_pix_stop ;
453- uint16_t vs1_line_start , vs1_line_end ;
454- uint16_t vs2_pix_start , vs2_pix_stop ;
455- uint16_t vs2_line_start , vs2_line_end ;
456- uint16_t vwin1_line_start , vwin1_line_end ;
457- uint16_t vwin2_line_start , vwin2_line_end ;
458- uint16_t de_start , de_stop ;
459- uint8_t reg , div ;
460-
461- mode = & sc -> mode ;
462-
463- n_pix = mode -> htotal ;
464- n_line = mode -> vtotal ;
465-
466- hs_pix_stop = mode -> hsync_end - mode -> hdisplay ;
467- hs_pix_start = mode -> hsync_start - mode -> hdisplay ;
468-
469- de_stop = mode -> htotal ;
470- de_start = mode -> htotal - mode -> hdisplay ;
471- ref_pix = hs_pix_start + 3 ;
472-
473- if (mode -> flags & DRM_MODE_FLAG_HSKEW )
474- ref_pix += mode -> hskew ;
475-
476- if ((mode -> flags & DRM_MODE_FLAG_INTERLACE ) == 0 ) {
477- ref_line = 1 + mode -> vsync_start - mode -> vdisplay ;
478- vwin1_line_start = mode -> vtotal - mode -> vdisplay - 1 ;
479- vwin1_line_end = vwin1_line_start + mode -> vdisplay ;
480-
481- vs1_pix_start = vs1_pix_stop = hs_pix_start ;
482- vs1_line_start = mode -> vsync_start - mode -> vdisplay ;
483- vs1_line_end = vs1_line_start + mode -> vsync_end - mode -> vsync_start ;
484-
485- vwin2_line_start = vwin2_line_end = 0 ;
486- vs2_pix_start = vs2_pix_stop = 0 ;
487- vs2_line_start = vs2_line_end = 0 ;
488- } else {
489- ref_line = 1 + (mode -> vsync_start - mode -> vdisplay )/2 ;
490- vwin1_line_start = (mode -> vtotal - mode -> vdisplay )/2 ;
491- vwin1_line_end = vwin1_line_start + mode -> vdisplay /2 ;
492-
493- vs1_pix_start = vs1_pix_stop = hs_pix_start ;
494- vs1_line_start = (mode -> vsync_start - mode -> vdisplay )/2 ;
495- vs1_line_end = vs1_line_start + (mode -> vsync_end - mode -> vsync_start )/2 ;
496-
497- vwin2_line_start = vwin1_line_start + mode -> vtotal /2 ;
498- vwin2_line_end = vwin2_line_start + mode -> vdisplay /2 ;
499-
500- vs2_pix_start = vs2_pix_stop = hs_pix_start + mode -> htotal /2 ;
501- vs2_line_start = vs1_line_start + mode -> vtotal /2 ;
502- vs2_line_end = vs2_line_start + (mode -> vsync_end - mode -> vsync_start )/2 ;
503- }
504-
505- div = 148500 / mode -> crtc_clock ;
506- if (div != 0 ) {
507- div -- ;
508- if (div > 3 )
509- div = 3 ;
510- }
511-
512- /* set HDMI HDCP mode off */
513- tda19988_reg_set (sc , TDA_TBG_CNTRL_1 , TBG_CNTRL_1_DWIN_DIS );
514- tda19988_reg_clear (sc , TDA_HDCP_TX33 , HDCP_TX33_HDMI );
515- tda19988_reg_write (sc , TDA_ENC_CNTRL , ENC_CNTRL_DVI_MODE );
516-
517- /* no pre-filter or interpolator */
518- tda19988_reg_write (sc , TDA_HVF_CNTRL_0 ,
519- HVF_CNTRL_0_INTPOL_BYPASS | HVF_CNTRL_0_PREFIL_NONE );
520- tda19988_reg_write (sc , TDA_VIP_CNTRL_5 , VIP_CNTRL_5_SP_CNT (0 ));
521- tda19988_reg_write (sc , TDA_VIP_CNTRL_4 ,
522- VIP_CNTRL_4_BLANKIT_NDE | VIP_CNTRL_4_BLC_NONE );
523-
524- tda19988_reg_clear (sc , TDA_PLL_SERIAL_3 , PLL_SERIAL_3_SRL_CCIR );
525- tda19988_reg_clear (sc , TDA_PLL_SERIAL_1 , PLL_SERIAL_1_SRL_MAN_IP );
526- tda19988_reg_clear (sc , TDA_PLL_SERIAL_3 , PLL_SERIAL_3_SRL_DE );
527- tda19988_reg_write (sc , TDA_SERIALIZER , 0 );
528- tda19988_reg_write (sc , TDA_HVF_CNTRL_1 , HVF_CNTRL_1_VQR_FULL );
529-
530- tda19988_reg_write (sc , TDA_RPT_CNTRL , 0 );
531- tda19988_reg_write (sc , TDA_SEL_CLK , SEL_CLK_SEL_VRF_CLK (0 ) |
532- SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK );
533-
534- tda19988_reg_write (sc , TDA_PLL_SERIAL_2 , PLL_SERIAL_2_SRL_NOSC (div ) |
535- PLL_SERIAL_2_SRL_PR (0 ));
536-
537- tda19988_reg_set (sc , TDA_MAT_CONTRL , MAT_CONTRL_MAT_BP );
538-
539- tda19988_reg_write (sc , TDA_ANA_GENERAL , 0x09 );
540-
541- tda19988_reg_clear (sc , TDA_TBG_CNTRL_0 , TBG_CNTRL_0_SYNC_MTHD );
542-
543- /*
544- * Sync on rising HSYNC/VSYNC
545- */
546- reg = VIP_CNTRL_3_SYNC_HS ;
547- if (mode -> flags & DRM_MODE_FLAG_NHSYNC )
548- reg |= VIP_CNTRL_3_H_TGL ;
549- if (mode -> flags & DRM_MODE_FLAG_NVSYNC )
550- reg |= VIP_CNTRL_3_V_TGL ;
551- tda19988_reg_write (sc , TDA_VIP_CNTRL_3 , reg );
552-
553- reg = TBG_CNTRL_1_TGL_EN ;
554- if (mode -> flags & DRM_MODE_FLAG_NHSYNC )
555- reg |= TBG_CNTRL_1_H_TGL ;
556- if (mode -> flags & DRM_MODE_FLAG_NVSYNC )
557- reg |= TBG_CNTRL_1_V_TGL ;
558- tda19988_reg_write (sc , TDA_TBG_CNTRL_1 , reg );
559-
560- /* Program timing */
561- tda19988_reg_write (sc , TDA_VIDFORMAT , 0x00 );
562-
563- tda19988_reg_write2 (sc , TDA_REFPIX_MSB , ref_pix );
564- tda19988_reg_write2 (sc , TDA_REFLINE_MSB , ref_line );
565- tda19988_reg_write2 (sc , TDA_NPIX_MSB , n_pix );
566- tda19988_reg_write2 (sc , TDA_NLINE_MSB , n_line );
567-
568- tda19988_reg_write2 (sc , TDA_VS_LINE_STRT_1_MSB , vs1_line_start );
569- tda19988_reg_write2 (sc , TDA_VS_PIX_STRT_1_MSB , vs1_pix_start );
570- tda19988_reg_write2 (sc , TDA_VS_LINE_END_1_MSB , vs1_line_end );
571- tda19988_reg_write2 (sc , TDA_VS_PIX_END_1_MSB , vs1_pix_stop );
572- tda19988_reg_write2 (sc , TDA_VS_LINE_STRT_2_MSB , vs2_line_start );
573- tda19988_reg_write2 (sc , TDA_VS_PIX_STRT_2_MSB , vs2_pix_start );
574- tda19988_reg_write2 (sc , TDA_VS_LINE_END_2_MSB , vs2_line_end );
575- tda19988_reg_write2 (sc , TDA_VS_PIX_END_2_MSB , vs2_pix_stop );
576- tda19988_reg_write2 (sc , TDA_HS_PIX_START_MSB , hs_pix_start );
577- tda19988_reg_write2 (sc , TDA_HS_PIX_STOP_MSB , hs_pix_stop );
578- tda19988_reg_write2 (sc , TDA_VWIN_START_1_MSB , vwin1_line_start );
579- tda19988_reg_write2 (sc , TDA_VWIN_END_1_MSB , vwin1_line_end );
580- tda19988_reg_write2 (sc , TDA_VWIN_START_2_MSB , vwin2_line_start );
581- tda19988_reg_write2 (sc , TDA_VWIN_END_2_MSB , vwin2_line_end );
582- tda19988_reg_write2 (sc , TDA_DE_START_MSB , de_start );
583- tda19988_reg_write2 (sc , TDA_DE_STOP_MSB , de_stop );
584-
585- if (sc -> sc_version == TDA19988 )
586- tda19988_reg_write (sc , TDA_ENABLE_SPACE , 0x00 );
587-
588- /* must be last register set */
589- tda19988_reg_clear (sc , TDA_TBG_CNTRL_0 , TBG_CNTRL_0_SYNC_ONCE );
590- }
591-
592448static int
593449tda19988_read_edid_block (void * context , uint8_t * buf , unsigned int block ,
594450 size_t len )
@@ -863,20 +719,165 @@ tda19988_bridge_mode_valid(struct drm_bridge *bridge,
863719
864720static void
865721tda19988_bridge_mode_set (struct drm_bridge * bridge ,
866- const struct drm_display_mode * orig_mode ,
867- const struct drm_display_mode * mode )
722+ const struct drm_display_mode * mode ,
723+ const struct drm_display_mode * adjusted_mode )
868724{
869725 struct tda19988_softc * sc ;
726+ uint16_t ref_pix , ref_line , n_pix , n_line ;
727+ uint16_t hs_pix_start , hs_pix_stop ;
728+ uint16_t vs1_pix_start , vs1_pix_stop ;
729+ uint16_t vs1_line_start , vs1_line_end ;
730+ uint16_t vs2_pix_start , vs2_pix_stop ;
731+ uint16_t vs2_line_start , vs2_line_end ;
732+ uint16_t vwin1_line_start , vwin1_line_end ;
733+ uint16_t vwin2_line_start , vwin2_line_end ;
734+ uint16_t de_start , de_stop ;
735+ uint8_t reg , div ;
870736
871737 sc = container_of (bridge , struct tda19988_softc , bridge );
872738
873- memcpy (& sc -> mode , mode , sizeof (struct drm_display_mode ));
739+ n_pix = mode -> htotal ;
740+ n_line = mode -> vtotal ;
741+
742+ hs_pix_stop = mode -> hsync_end - mode -> hdisplay ;
743+ hs_pix_start = mode -> hsync_start - mode -> hdisplay ;
744+
745+ de_stop = mode -> htotal ;
746+ de_start = mode -> htotal - mode -> hdisplay ;
747+ ref_pix = hs_pix_start + 3 ;
748+
749+ if (adjusted_mode -> flags & DRM_MODE_FLAG_HSKEW )
750+ ref_pix += adjusted_mode -> hskew ;
751+
752+ if ((mode -> flags & DRM_MODE_FLAG_INTERLACE ) == 0 ) {
753+ ref_line = 1 + mode -> vsync_start - mode -> vdisplay ;
754+ vwin1_line_start = mode -> vtotal - mode -> vdisplay - 1 ;
755+ vwin1_line_end = vwin1_line_start + mode -> vdisplay ;
756+
757+ vs1_pix_start = vs1_pix_stop = hs_pix_start ;
758+ vs1_line_start = mode -> vsync_start - mode -> vdisplay ;
759+ vs1_line_end = vs1_line_start + mode -> vsync_end - mode -> vsync_start ;
760+
761+ vwin2_line_start = vwin2_line_end = 0 ;
762+ vs2_pix_start = vs2_pix_stop = 0 ;
763+ vs2_line_start = vs2_line_end = 0 ;
764+ } else {
765+ ref_line = 1 + (mode -> vsync_start - mode -> vdisplay )/2 ;
766+ vwin1_line_start = (mode -> vtotal - mode -> vdisplay )/2 ;
767+ vwin1_line_end = vwin1_line_start + mode -> vdisplay /2 ;
768+
769+ vs1_pix_start = vs1_pix_stop = hs_pix_start ;
770+ vs1_line_start = (mode -> vsync_start - mode -> vdisplay )/2 ;
771+ vs1_line_end = vs1_line_start + (mode -> vsync_end - mode -> vsync_start )/2 ;
772+
773+ vwin2_line_start = vwin1_line_start + mode -> vtotal /2 ;
774+ vwin2_line_end = vwin2_line_start + mode -> vdisplay /2 ;
775+
776+ vs2_pix_start = vs2_pix_stop = hs_pix_start + mode -> htotal /2 ;
777+ vs2_line_start = vs1_line_start + mode -> vtotal /2 ;
778+ vs2_line_end = vs2_line_start + (mode -> vsync_end - mode -> vsync_start )/2 ;
779+ }
780+
781+ div = 148500 / mode -> crtc_clock ;
782+ if (div != 0 ) {
783+ div -- ;
784+ if (div > 3 )
785+ div = 3 ;
786+ }
787+
788+ /* set HDMI HDCP mode off */
789+ tda19988_reg_set (sc , TDA_TBG_CNTRL_1 , TBG_CNTRL_1_DWIN_DIS );
790+ tda19988_reg_clear (sc , TDA_HDCP_TX33 , HDCP_TX33_HDMI );
791+ tda19988_reg_write (sc , TDA_ENC_CNTRL , ENC_CNTRL_DVI_MODE );
792+
793+ /* no pre-filter or interpolator */
794+ tda19988_reg_write (sc , TDA_HVF_CNTRL_0 ,
795+ HVF_CNTRL_0_INTPOL_BYPASS | HVF_CNTRL_0_PREFIL_NONE );
796+ tda19988_reg_write (sc , TDA_VIP_CNTRL_5 , VIP_CNTRL_5_SP_CNT (0 ));
797+ tda19988_reg_write (sc , TDA_VIP_CNTRL_4 ,
798+ VIP_CNTRL_4_BLANKIT_NDE | VIP_CNTRL_4_BLC_NONE );
799+
800+ tda19988_reg_clear (sc , TDA_PLL_SERIAL_3 , PLL_SERIAL_3_SRL_CCIR );
801+ tda19988_reg_clear (sc , TDA_PLL_SERIAL_1 , PLL_SERIAL_1_SRL_MAN_IP );
802+ tda19988_reg_clear (sc , TDA_PLL_SERIAL_3 , PLL_SERIAL_3_SRL_DE );
803+ tda19988_reg_write (sc , TDA_SERIALIZER , 0 );
804+ tda19988_reg_write (sc , TDA_HVF_CNTRL_1 , HVF_CNTRL_1_VQR_FULL );
805+
806+ tda19988_reg_write (sc , TDA_RPT_CNTRL , 0 );
807+ tda19988_reg_write (sc , TDA_SEL_CLK , SEL_CLK_SEL_VRF_CLK (0 ) |
808+ SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK );
809+
810+ tda19988_reg_write (sc , TDA_PLL_SERIAL_2 , PLL_SERIAL_2_SRL_NOSC (div ) |
811+ PLL_SERIAL_2_SRL_PR (0 ));
812+
813+ tda19988_reg_set (sc , TDA_MAT_CONTRL , MAT_CONTRL_MAT_BP );
814+
815+ tda19988_reg_write (sc , TDA_ANA_GENERAL , 0x09 );
816+
817+ tda19988_reg_clear (sc , TDA_TBG_CNTRL_0 , TBG_CNTRL_0_SYNC_MTHD );
818+
819+ /*
820+ * Sync on rising HSYNC/VSYNC
821+ */
822+ reg = VIP_CNTRL_3_SYNC_HS ;
823+ if (mode -> flags & DRM_MODE_FLAG_NHSYNC )
824+ reg |= VIP_CNTRL_3_H_TGL ;
825+ if (mode -> flags & DRM_MODE_FLAG_NVSYNC )
826+ reg |= VIP_CNTRL_3_V_TGL ;
827+ tda19988_reg_write (sc , TDA_VIP_CNTRL_3 , reg );
828+
829+ reg = TBG_CNTRL_1_TGL_EN ;
830+ if (mode -> flags & DRM_MODE_FLAG_NHSYNC )
831+ reg |= TBG_CNTRL_1_H_TGL ;
832+ if (mode -> flags & DRM_MODE_FLAG_NVSYNC )
833+ reg |= TBG_CNTRL_1_V_TGL ;
834+ tda19988_reg_write (sc , TDA_TBG_CNTRL_1 , reg );
835+
836+ /* Program timing */
837+ tda19988_reg_write (sc , TDA_VIDFORMAT , 0x00 );
838+
839+ tda19988_reg_write2 (sc , TDA_REFPIX_MSB , ref_pix );
840+ tda19988_reg_write2 (sc , TDA_REFLINE_MSB , ref_line );
841+ tda19988_reg_write2 (sc , TDA_NPIX_MSB , n_pix );
842+ tda19988_reg_write2 (sc , TDA_NLINE_MSB , n_line );
843+
844+ tda19988_reg_write2 (sc , TDA_VS_LINE_STRT_1_MSB , vs1_line_start );
845+ tda19988_reg_write2 (sc , TDA_VS_PIX_STRT_1_MSB , vs1_pix_start );
846+ tda19988_reg_write2 (sc , TDA_VS_LINE_END_1_MSB , vs1_line_end );
847+ tda19988_reg_write2 (sc , TDA_VS_PIX_END_1_MSB , vs1_pix_stop );
848+ tda19988_reg_write2 (sc , TDA_VS_LINE_STRT_2_MSB , vs2_line_start );
849+ tda19988_reg_write2 (sc , TDA_VS_PIX_STRT_2_MSB , vs2_pix_start );
850+ tda19988_reg_write2 (sc , TDA_VS_LINE_END_2_MSB , vs2_line_end );
851+ tda19988_reg_write2 (sc , TDA_VS_PIX_END_2_MSB , vs2_pix_stop );
852+ tda19988_reg_write2 (sc , TDA_HS_PIX_START_MSB , hs_pix_start );
853+ tda19988_reg_write2 (sc , TDA_HS_PIX_STOP_MSB , hs_pix_stop );
854+ tda19988_reg_write2 (sc , TDA_VWIN_START_1_MSB , vwin1_line_start );
855+ tda19988_reg_write2 (sc , TDA_VWIN_END_1_MSB , vwin1_line_end );
856+ tda19988_reg_write2 (sc , TDA_VWIN_START_2_MSB , vwin2_line_start );
857+ tda19988_reg_write2 (sc , TDA_VWIN_END_2_MSB , vwin2_line_end );
858+ tda19988_reg_write2 (sc , TDA_DE_START_MSB , de_start );
859+ tda19988_reg_write2 (sc , TDA_DE_STOP_MSB , de_stop );
860+
861+ if (sc -> sc_version == TDA19988 )
862+ tda19988_reg_write (sc , TDA_ENABLE_SPACE , 0x00 );
863+
864+ /* must be last register set */
865+ tda19988_reg_clear (sc , TDA_TBG_CNTRL_0 , TBG_CNTRL_0_SYNC_ONCE );
874866}
875867
876868static void
877869tda19988_bridge_disable (struct drm_bridge * bridge )
878870{
871+ struct tda19988_softc * sc ;
879872
873+ sc = container_of (bridge , struct tda19988_softc , bridge );
874+
875+ /* Disable Video Ports */
876+ tda19988_reg_write (sc , TDA_ENA_VP_0 , 0 );
877+ tda19988_reg_write (sc , TDA_ENA_VP_1 , 0 );
878+ tda19988_reg_write (sc , TDA_ENA_VP_2 , 0 );
879+
880+ tda19988_reg_write (sc , TDA_BUFFER_OUT , 0x8 );
880881}
881882
882883static void
@@ -886,25 +887,12 @@ tda19988_bridge_enable(struct drm_bridge *bridge)
886887
887888 sc = container_of (bridge , struct tda19988_softc , bridge );
888889
889- dprintf (sc -> dev , "Mode information:\n"
890- "hdisplay: %d\n"
891- "vdisplay: %d\n"
892- "htotal: %d\n"
893- "vtotal: %d\n"
894- "hsync_start: %d\n"
895- "hsync_end: %d\n"
896- "vsync_start: %d\n"
897- "vsync_end: %d\n" ,
898- sc -> mode .hdisplay ,
899- sc -> mode .vdisplay ,
900- sc -> mode .htotal ,
901- sc -> mode .vtotal ,
902- sc -> mode .hsync_start ,
903- sc -> mode .hsync_end ,
904- sc -> mode .vsync_start ,
905- sc -> mode .vsync_end );
906-
907- tda19988_init_encoder (sc );
890+ /* Enable Video Ports */
891+ tda19988_reg_write (sc , TDA_ENA_VP_0 , 0xff );
892+ tda19988_reg_write (sc , TDA_ENA_VP_1 , 0xff );
893+ tda19988_reg_write (sc , TDA_ENA_VP_2 , 0xff );
894+
895+ tda19988_reg_write (sc , TDA_BUFFER_OUT , 0 );
908896}
909897
910898static const struct drm_bridge_funcs tda19988_bridge_funcs = {
0 commit comments