@@ -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
@@ -546,8 +542,12 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
546
542
{
547
543
struct vc4_vec_encoder * vc4_vec_encoder = to_vc4_vec_encoder (encoder );
548
544
struct vc4_vec * vec = vc4_vec_encoder -> vec ;
545
+ struct drm_display_mode * adjusted_mode =
546
+ & encoder -> crtc -> state -> adjusted_mode ;
549
547
unsigned int tv_mode = vec -> connector -> state -> tv .mode ;
550
548
int ret ;
549
+ long eff_clk_rate ;
550
+ u64 chroma_freq ;
551
551
552
552
ret = pm_runtime_get_sync (& vec -> pdev -> dev );
553
553
if (ret < 0 ) {
@@ -562,7 +562,7 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
562
562
* The good news is, these 2 encoders cannot be enabled at the same
563
563
* time, thus preventing incompatible rate requests.
564
564
*/
565
- ret = clk_set_rate (vec -> clock , 108000000 );
565
+ ret = clk_set_rate (vec -> clock , 8000 * adjusted_mode -> clock );
566
566
if (ret ) {
567
567
DRM_ERROR ("Failed to set clock rate: %d\n" , ret );
568
568
return ;
@@ -574,6 +574,9 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
574
574
return ;
575
575
}
576
576
577
+ eff_clk_rate = clk_get_rate (vec -> clock );
578
+ DRM_DEBUG_DRIVER ("Effective clock rate: %ld\n" , eff_clk_rate );
579
+
577
580
/* Reset the different blocks */
578
581
VEC_WRITE (VEC_WSE_RESET , 1 );
579
582
VEC_WRITE (VEC_SOFT_RESET , 1 );
@@ -597,23 +600,29 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
597
600
VEC_WRITE (VEC_CONFIG2 ,
598
601
VEC_CONFIG2_UV_DIG_DIS |
599
602
VEC_CONFIG2_RGB_DIG_DIS |
600
- ((encoder -> crtc -> state -> adjusted_mode . flags &
601
- DRM_MODE_FLAG_INTERLACE ) ? 0 : VEC_CONFIG2_PROG_SCAN ));
603
+ ((adjusted_mode -> flags & DRM_MODE_FLAG_INTERLACE )
604
+ ? 0 : VEC_CONFIG2_PROG_SCAN ));
602
605
VEC_WRITE (VEC_CONFIG3 , VEC_CONFIG3_HORIZ_LEN_STD );
603
606
VEC_WRITE (VEC_DAC_CONFIG , vec -> variant -> dac_config );
604
607
605
608
/* Mask all interrupts. */
606
609
VEC_WRITE (VEC_MASK0 , 0 );
607
610
608
611
VEC_WRITE (VEC_CONFIG0 , vc4_vec_tv_modes [tv_mode ].config0 );
609
- VEC_WRITE (VEC_CONFIG1 , vc4_vec_tv_modes [tv_mode ].config1 );
610
- if (vc4_vec_tv_modes [tv_mode ].custom_freq != 0 ) {
611
- VEC_WRITE (VEC_FREQ3_2 ,
612
- (vc4_vec_tv_modes [tv_mode ].custom_freq >> 16 ) &
613
- 0xffff );
614
- VEC_WRITE (VEC_FREQ1_0 ,
615
- vc4_vec_tv_modes [tv_mode ].custom_freq & 0xffff );
616
- }
612
+ VEC_WRITE (VEC_CONFIG1 ,
613
+ VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ );
614
+
615
+ chroma_freq = vc4_vec_tv_modes [tv_mode ].chroma_freq_millihz << 31 ;
616
+ chroma_freq += (125ull * (u64 )eff_clk_rate ) >> 1 ; /* proper rounding */
617
+ do_div (chroma_freq , eff_clk_rate );
618
+ do_div (chroma_freq , 125 );
619
+ VEC_WRITE (VEC_FREQ3_2 , (chroma_freq >> 16 ) & 0xffff );
620
+ VEC_WRITE (VEC_FREQ1_0 , chroma_freq & 0xffff );
621
+
622
+ /* SECAM Db frequency */
623
+ chroma_freq = ((4250000000ull / 125 ) << 31 ) + eff_clk_rate / 2 ;
624
+ do_div (chroma_freq , eff_clk_rate );
625
+ VEC_WRITE (VEC_FCW_SECAM_B , chroma_freq );
617
626
618
627
VEC_WRITE (VEC_DAC_MISC ,
619
628
VEC_DAC_MISC_VID_ACT | VEC_DAC_MISC_DAC_RST_N );
0 commit comments