@@ -254,8 +254,7 @@ struct vc4_vec_tv_mode {
254254 const struct drm_display_mode * interlaced_mode ;
255255 const struct drm_display_mode * progressive_mode ;
256256 u32 config0 ;
257- u32 config1 ;
258- u32 custom_freq ;
257+ u64 chroma_freq_millihz ;
259258};
260259
261260static const struct debugfs_reg32 vec_regs [] = {
@@ -316,54 +315,51 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
316315 .interlaced_mode = & drm_mode_480i ,
317316 .progressive_mode = & drm_mode_240p ,
318317 .config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN ,
319- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
318+ .chroma_freq_millihz = 3579545455ull ,
320319 },
321320 [VC4_VEC_TV_MODE_NTSC_J ] = {
322321 .interlaced_mode = & drm_mode_480i ,
323322 .progressive_mode = & drm_mode_240p ,
324323 .config0 = VEC_CONFIG0_NTSC_STD ,
325- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
324+ .chroma_freq_millihz = 3579545455ull ,
326325 },
327326 [VC4_VEC_TV_MODE_NTSC_443 ] = {
328327 /* NTSC with PAL chroma frequency */
329328 .interlaced_mode = & drm_mode_480i ,
330329 .progressive_mode = & drm_mode_240p ,
331330 .config0 = VEC_CONFIG0_NTSC_STD ,
332- .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ ,
333- .custom_freq = 0x2a098acb ,
331+ .chroma_freq_millihz = 4433618750ull ,
334332 },
335333 [VC4_VEC_TV_MODE_PAL ] = {
336334 .interlaced_mode = & drm_mode_576i ,
337335 .progressive_mode = & drm_mode_288p ,
338336 .config0 = VEC_CONFIG0_PAL_BDGHI_STD ,
339- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
337+ .chroma_freq_millihz = 4433618750ull ,
340338 },
341339 [VC4_VEC_TV_MODE_PAL_M ] = {
342340 .interlaced_mode = & drm_mode_480i ,
343341 .progressive_mode = & drm_mode_240p ,
344342 .config0 = VEC_CONFIG0_PAL_M_STD ,
345- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
343+ .chroma_freq_millihz = 3575611888ull ,
346344 },
347345 [VC4_VEC_TV_MODE_PAL_N ] = {
348346 .interlaced_mode = & drm_mode_576i ,
349347 .progressive_mode = & drm_mode_288p ,
350348 .config0 = VEC_CONFIG0_PAL_N_STD ,
351- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
349+ .chroma_freq_millihz = 3582056250ull ,
352350 },
353351 [VC4_VEC_TV_MODE_PAL60 ] = {
354352 /* PAL-M with chroma frequency of regular PAL */
355353 .interlaced_mode = & drm_mode_480i ,
356354 .progressive_mode = & drm_mode_240p ,
357355 .config0 = VEC_CONFIG0_PAL_M_STD ,
358- .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ ,
359- .custom_freq = 0x2a098acb ,
356+ .chroma_freq_millihz = 4433618750ull ,
360357 },
361358 [VC4_VEC_TV_MODE_SECAM ] = {
362359 .interlaced_mode = & drm_mode_576i ,
363360 .progressive_mode = & drm_mode_288p ,
364361 .config0 = VEC_CONFIG0_SECAM_STD ,
365- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
366- .custom_freq = 0x29c71c72 ,
362+ .chroma_freq_millihz = 4406250000ull ,
367363 },
368364};
369365
@@ -617,8 +613,12 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
617613{
618614 struct vc4_vec_encoder * vc4_vec_encoder = to_vc4_vec_encoder (encoder );
619615 struct vc4_vec * vec = vc4_vec_encoder -> vec ;
616+ struct drm_display_mode * adjusted_mode =
617+ & encoder -> crtc -> state -> adjusted_mode ;
620618 unsigned int tv_mode = vec -> connector -> state -> tv .mode ;
621619 int ret ;
620+ long eff_clk_rate ;
621+ u64 chroma_freq ;
622622
623623 ret = pm_runtime_get_sync (& vec -> pdev -> dev );
624624 if (ret < 0 ) {
@@ -633,7 +633,7 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
633633 * The good news is, these 2 encoders cannot be enabled at the same
634634 * time, thus preventing incompatible rate requests.
635635 */
636- ret = clk_set_rate (vec -> clock , 108000000 );
636+ ret = clk_set_rate (vec -> clock , 8000 * adjusted_mode -> clock );
637637 if (ret ) {
638638 DRM_ERROR ("Failed to set clock rate: %d\n" , ret );
639639 return ;
@@ -645,6 +645,9 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
645645 return ;
646646 }
647647
648+ eff_clk_rate = clk_get_rate (vec -> clock );
649+ DRM_DEBUG_DRIVER ("Effective clock rate: %ld\n" , eff_clk_rate );
650+
648651 /* Reset the different blocks */
649652 VEC_WRITE (VEC_WSE_RESET , 1 );
650653 VEC_WRITE (VEC_SOFT_RESET , 1 );
@@ -668,23 +671,29 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
668671 VEC_WRITE (VEC_CONFIG2 ,
669672 VEC_CONFIG2_UV_DIG_DIS |
670673 VEC_CONFIG2_RGB_DIG_DIS |
671- ((encoder -> crtc -> state -> adjusted_mode . flags &
672- DRM_MODE_FLAG_INTERLACE ) ? 0 : VEC_CONFIG2_PROG_SCAN ));
674+ ((adjusted_mode -> flags & DRM_MODE_FLAG_INTERLACE )
675+ ? 0 : VEC_CONFIG2_PROG_SCAN ));
673676 VEC_WRITE (VEC_CONFIG3 , VEC_CONFIG3_HORIZ_LEN_STD );
674677 VEC_WRITE (VEC_DAC_CONFIG , vec -> variant -> dac_config );
675678
676679 /* Mask all interrupts. */
677680 VEC_WRITE (VEC_MASK0 , 0 );
678681
679682 VEC_WRITE (VEC_CONFIG0 , vc4_vec_tv_modes [tv_mode ].config0 );
680- VEC_WRITE (VEC_CONFIG1 , vc4_vec_tv_modes [tv_mode ].config1 );
681- if (vc4_vec_tv_modes [tv_mode ].custom_freq != 0 ) {
682- VEC_WRITE (VEC_FREQ3_2 ,
683- (vc4_vec_tv_modes [tv_mode ].custom_freq >> 16 ) &
684- 0xffff );
685- VEC_WRITE (VEC_FREQ1_0 ,
686- vc4_vec_tv_modes [tv_mode ].custom_freq & 0xffff );
687- }
683+ VEC_WRITE (VEC_CONFIG1 ,
684+ VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ );
685+
686+ chroma_freq = vc4_vec_tv_modes [tv_mode ].chroma_freq_millihz << 31 ;
687+ chroma_freq += (125ull * (u64 ) eff_clk_rate ) >> 1 ; /* proper rounding */
688+ do_div (chroma_freq , eff_clk_rate );
689+ do_div (chroma_freq , 125 );
690+ VEC_WRITE (VEC_FREQ3_2 , (chroma_freq >> 16 ) & 0xffff );
691+ VEC_WRITE (VEC_FREQ1_0 , chroma_freq & 0xffff );
692+
693+ /* SECAM Db frequency */
694+ chroma_freq = ((4250000000ull / 125 ) << 31 ) + eff_clk_rate / 2 ;
695+ do_div (chroma_freq , eff_clk_rate );
696+ VEC_WRITE (VEC_FCW_SECAM_B , chroma_freq );
688697
689698 VEC_WRITE (VEC_DAC_MISC ,
690699 VEC_DAC_MISC_VID_ACT | VEC_DAC_MISC_DAC_RST_N );
0 commit comments