@@ -33,6 +33,8 @@ struct rk628_combrxphy {
3333#define MAX_DATA_NUM 16
3434#define MAX_CHANNEL 3
3535#define CLK_DET_TRY_TIMES 10
36+ #define CLK_STABLE_LOOP_CNT 10
37+ #define CLK_STABLE_THRESHOLD 6
3638
3739static int debug ;
3840module_param (debug , int , 0644 );
@@ -513,27 +515,44 @@ static int
513515rk628_combrxphy_set_hdmi_mode_for_cable (struct rk628_combrxphy * combrxphy ,
514516 int f )
515517{
516- u32 val , data_a , data_b ;
517- u32 i , count , ret ;
518+ u32 val , val_a , val_b , data_a , data_b ;
519+ u32 i , j , count , ret ;
518520 u32 cdr_mode , cdr_data , pll_man ;
519521 u32 tmds_bitrate_per_lane ;
522+ u32 cdr_data_min , cdr_data_max ;
523+
524+ /*
525+ * use the mode of automatic clock detection, only supports fixed TMDS
526+ * frequency.Refer to register 0x6654[21:16]:
527+ * 5'd31:Error mode
528+ * 5'd30:manual mode detected
529+ * 5'd18:rx3p clock = 297MHz
530+ * 5'd17:rx3p clock = 162MHz
531+ * 5'd16:rx3p clock = 148.5MHz
532+ * 5'd15:rx3p clock = 135MHz
533+ * 5'd14:rx3p clock = 119MHz
534+ * 5'd13:rx3p clock = 108MHz
535+ * 5'd12:rx3p clock = 101MHz
536+ * 5'd11:rx3p clock = 92.8125MHz
537+ * 5'd10:rx3p clock = 88.75MHz
538+ * 5'd9:rx3p clock = 85.5MHz
539+ * 5'd8:rx3p clock = 83.5MHz
540+ * 5'd7:rx3p clock = 74.25MHz
541+ * 5'd6:rx3p clock = 68.25MHz
542+ * 5'd5:rx3p clock = 65MHz
543+ * 5'd4:rx3p clock = 59.4MHz
544+ * 5'd3:rx3p clock = 40MHz
545+ * 5'd2:rx3p clock = 33.75MHz
546+ * 5'd1:rx3p clock = 27MHz
547+ * 5'd0:rx3p clock = 25.17MHz
548+ */
520549
521550 const u32 cdr_mode_to_khz [] = {
522551 25170 , 27000 , 33750 , 40000 , 59400 , 65000 , 68250 ,
523552 74250 , 83500 , 85500 , 88750 , 92812 , 101000 , 108000 ,
524553 119000 , 135000 , 148500 , 162000 , 297000 ,
525554 };
526555
527- const struct {
528- u32 data ;
529- u32 mode ;
530- } cdr_data_table [] = {
531- { 80 , 18 }, { 147 , 17 }, { 160 , 16 }, { 176 , 15 }, { 200 , 14 },
532- { 220 , 13 }, { 235 , 12 }, { 256 , 11 }, { 268 , 10 }, { 278 , 9 },
533- { 285 , 8 }, { 320 , 7 }, { 348 , 6 }, { 366 , 5 }, { 400 , 4 },
534- { 594 , 3 }, { 704 , 2 }, { 880 , 1 }, { 944 , 0 },
535- };
536-
537556 for (i = 0 ; i < CLK_DET_TRY_TIMES ; i ++ ) {
538557 if (rk628_combrxphy_try_clk_detect (combrxphy ) >= 0 )
539558 break ;
@@ -557,25 +576,52 @@ rk628_combrxphy_set_hdmi_mode_for_cable(struct rk628_combrxphy *combrxphy,
557576 }
558577
559578 /* step4: get cdr_mode and cdr_data */
579+ for (j = 0 ; j < CLK_STABLE_LOOP_CNT ; j ++ ) {
580+ cdr_data_min = 0xffffffff ;
581+ cdr_data_max = 0 ;
582+
583+ for (i = 0 ; i < CLK_DET_TRY_TIMES ; i ++ ) {
584+ regmap_read (combrxphy -> regmap , REG (0x6654 ), & val );
585+ cdr_data = val & 0xffff ;
586+ if (cdr_data <= cdr_data_min )
587+ cdr_data_min = cdr_data ;
588+ if (cdr_data >= cdr_data_max )
589+ cdr_data_max = cdr_data ;
590+ udelay (50 );
591+ }
592+
593+ if (((cdr_data_max - cdr_data_min ) <= CLK_STABLE_THRESHOLD ) &&
594+ (cdr_data_min >= 60 )) {
595+ dev_info (combrxphy -> dev , "clock stable!" );
596+ break ;
597+ }
598+ }
599+
600+ if (j == CLK_STABLE_LOOP_CNT ) {
601+ regmap_read (combrxphy -> regmap , REG (0x6630 ), & val_a );
602+ regmap_read (combrxphy -> regmap , REG (0x6608 ), & val_b );
603+ dev_err (combrxphy -> dev ,
604+ "err, clk not stable, reg_0x6630:%#x, reg_0x6608:%#x" ,
605+ val_a , val_b );
606+
607+ return - EINVAL ;
608+ }
609+
560610 regmap_read (combrxphy -> regmap , REG (0x6654 ), & val );
561611 if ((val & 0x1f0000 ) == 0x1f0000 ) {
562- dev_err (combrxphy -> dev , "error,clock error!" );
612+ regmap_read (combrxphy -> regmap , REG (0x6630 ), & val_a );
613+ regmap_read (combrxphy -> regmap , REG (0x6608 ), & val_b );
614+ dev_err (combrxphy -> dev ,
615+ "clock error: 0x1f, reg_0x6630:%#x, reg_0x6608:%#x" ,
616+ val_a , val_b );
617+
563618 return - EINVAL ;
564619 }
620+
565621 cdr_mode = (val >> 16 ) & 0x1f ;
566622 cdr_data = val & 0xffff ;
567623 dev_info (combrxphy -> dev , "cdr_mode:%d, cdr_data:%d\n" , cdr_mode ,
568624 cdr_data );
569- if (cdr_mode == 0x1f ) {
570- for (i = 0 ; i < ARRAY_SIZE (cdr_data_table ); i ++ ) {
571- if (cdr_data <= cdr_data_table [i ].data )
572- break ;
573- }
574-
575- if (i == ARRAY_SIZE (cdr_data_table ))
576- -- i ;
577- cdr_mode = cdr_data_table [i ].mode ;
578- }
579625
580626 /* step5: manually configure PLL
581627 * cfg reg 66a8 tmds clock div2 for rgb/yuv444 as default
0 commit comments