@@ -254,8 +254,7 @@ struct vc4_vec_tv_mode {
254
254
const struct drm_display_mode * interlaced_mode ;
255
255
const struct drm_display_mode * progressive_mode ;
256
256
u32 config0 ;
257
- u32 config1 ;
258
- u32 custom_freq ;
257
+ u64 chroma_freq_millihz ;
259
258
};
260
259
261
260
static const struct debugfs_reg32 vec_regs [] = {
@@ -316,54 +315,51 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
316
315
.interlaced_mode = & drm_mode_480i ,
317
316
.progressive_mode = & drm_mode_240p ,
318
317
.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN ,
319
- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
318
+ .chroma_freq_millihz = 3579545455ull ,
320
319
},
321
320
[VC4_VEC_TV_MODE_NTSC_J ] = {
322
321
.interlaced_mode = & drm_mode_480i ,
323
322
.progressive_mode = & drm_mode_240p ,
324
323
.config0 = VEC_CONFIG0_NTSC_STD ,
325
- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
324
+ .chroma_freq_millihz = 3579545455ull ,
326
325
},
327
326
[VC4_VEC_TV_MODE_NTSC_443 ] = {
328
327
/* NTSC with PAL chroma frequency */
329
328
.interlaced_mode = & drm_mode_480i ,
330
329
.progressive_mode = & drm_mode_240p ,
331
330
.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 ,
334
332
},
335
333
[VC4_VEC_TV_MODE_PAL ] = {
336
334
.interlaced_mode = & drm_mode_576i ,
337
335
.progressive_mode = & drm_mode_288p ,
338
336
.config0 = VEC_CONFIG0_PAL_BDGHI_STD ,
339
- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
337
+ .chroma_freq_millihz = 4433618750ull ,
340
338
},
341
339
[VC4_VEC_TV_MODE_PAL_M ] = {
342
340
.interlaced_mode = & drm_mode_480i ,
343
341
.progressive_mode = & drm_mode_240p ,
344
342
.config0 = VEC_CONFIG0_PAL_M_STD ,
345
- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
343
+ .chroma_freq_millihz = 3575611888ull ,
346
344
},
347
345
[VC4_VEC_TV_MODE_PAL_N ] = {
348
346
.interlaced_mode = & drm_mode_576i ,
349
347
.progressive_mode = & drm_mode_288p ,
350
348
.config0 = VEC_CONFIG0_PAL_N_STD ,
351
- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
349
+ .chroma_freq_millihz = 3582056250ull ,
352
350
},
353
351
[VC4_VEC_TV_MODE_PAL60 ] = {
354
352
/* PAL-M with chroma frequency of regular PAL */
355
353
.interlaced_mode = & drm_mode_480i ,
356
354
.progressive_mode = & drm_mode_240p ,
357
355
.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 ,
360
357
},
361
358
[VC4_VEC_TV_MODE_SECAM ] = {
362
359
.interlaced_mode = & drm_mode_576i ,
363
360
.progressive_mode = & drm_mode_288p ,
364
361
.config0 = VEC_CONFIG0_SECAM_STD ,
365
- .config1 = VEC_CONFIG1_C_CVBS_CVBS ,
366
- .custom_freq = 0x29c71c72 ,
362
+ .chroma_freq_millihz = 4406250000ull ,
367
363
},
368
364
};
369
365
@@ -617,8 +613,12 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
617
613
{
618
614
struct vc4_vec_encoder * vc4_vec_encoder = to_vc4_vec_encoder (encoder );
619
615
struct vc4_vec * vec = vc4_vec_encoder -> vec ;
616
+ struct drm_display_mode * adjusted_mode =
617
+ & encoder -> crtc -> state -> adjusted_mode ;
620
618
unsigned int tv_mode = vec -> connector -> state -> tv .mode ;
621
619
int ret ;
620
+ long eff_clk_rate ;
621
+ u64 chroma_freq ;
622
622
623
623
ret = pm_runtime_get_sync (& vec -> pdev -> dev );
624
624
if (ret < 0 ) {
@@ -633,7 +633,7 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
633
633
* The good news is, these 2 encoders cannot be enabled at the same
634
634
* time, thus preventing incompatible rate requests.
635
635
*/
636
- ret = clk_set_rate (vec -> clock , 108000000 );
636
+ ret = clk_set_rate (vec -> clock , 8000 * adjusted_mode -> clock );
637
637
if (ret ) {
638
638
DRM_ERROR ("Failed to set clock rate: %d\n" , ret );
639
639
return ;
@@ -645,6 +645,9 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
645
645
return ;
646
646
}
647
647
648
+ eff_clk_rate = clk_get_rate (vec -> clock );
649
+ DRM_DEBUG_DRIVER ("Effective clock rate: %ld\n" , eff_clk_rate );
650
+
648
651
/* Reset the different blocks */
649
652
VEC_WRITE (VEC_WSE_RESET , 1 );
650
653
VEC_WRITE (VEC_SOFT_RESET , 1 );
@@ -668,23 +671,29 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
668
671
VEC_WRITE (VEC_CONFIG2 ,
669
672
VEC_CONFIG2_UV_DIG_DIS |
670
673
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 ));
673
676
VEC_WRITE (VEC_CONFIG3 , VEC_CONFIG3_HORIZ_LEN_STD );
674
677
VEC_WRITE (VEC_DAC_CONFIG , vec -> variant -> dac_config );
675
678
676
679
/* Mask all interrupts. */
677
680
VEC_WRITE (VEC_MASK0 , 0 );
678
681
679
682
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 );
688
697
689
698
VEC_WRITE (VEC_DAC_MISC ,
690
699
VEC_DAC_MISC_VID_ACT | VEC_DAC_MISC_DAC_RST_N );
0 commit comments