37
37
#define PHYREG8 0x1C
38
38
#define PHYREG8_SSC_EN BIT(4)
39
39
40
+ #define PHYREG10 0x24
41
+ #define PHYREG10_SSC_PCM_MASK GENMASK(3, 0)
42
+ #define PHYREG10_SSC_PCM_3500PPM 7
43
+
40
44
#define PHYREG11 0x28
41
45
#define PHYREG11_SU_TRIM_0_7 0xF0
42
46
61
65
#define PHYREG16 0x3C
62
66
#define PHYREG16_SSC_CNT_VALUE 0x5f
63
67
68
+ #define PHYREG17 0x40
69
+
64
70
#define PHYREG18 0x44
65
71
#define PHYREG18_PLL_LOOP 0x32
66
72
73
+ #define PHYREG21 0x50
74
+ #define PHYREG21_RX_SQUELCH_VAL 0x0D
75
+
67
76
#define PHYREG27 0x6C
68
77
#define PHYREG27_RX_TRIM_RK3588 0x4C
69
78
79
+ #define PHYREG30 0x74
80
+
70
81
#define PHYREG32 0x7C
71
82
#define PHYREG32_SSC_MASK GENMASK(7, 4)
83
+ #define PHYREG32_SSC_DIR_MASK GENMASK(5, 4)
72
84
#define PHYREG32_SSC_DIR_SHIFT 4
73
85
#define PHYREG32_SSC_UPWARD 0
74
86
#define PHYREG32_SSC_DOWNWARD 1
87
+ #define PHYREG32_SSC_OFFSET_MASK GENMASK(7, 6)
75
88
#define PHYREG32_SSC_OFFSET_SHIFT 6
76
89
#define PHYREG32_SSC_OFFSET_500PPM 1
77
90
78
91
#define PHYREG33 0x80
79
92
#define PHYREG33_PLL_KVCO_MASK GENMASK(4, 2)
80
93
#define PHYREG33_PLL_KVCO_SHIFT 2
81
94
#define PHYREG33_PLL_KVCO_VALUE 2
95
+ #define PHYREG33_PLL_KVCO_VALUE_RK3576 4
82
96
83
97
struct rockchip_combphy_priv ;
84
98
@@ -98,6 +112,7 @@ struct rockchip_combphy_grfcfg {
98
112
struct combphy_reg pipe_rxterm_set ;
99
113
struct combphy_reg pipe_txelec_set ;
100
114
struct combphy_reg pipe_txcomp_set ;
115
+ struct combphy_reg pipe_clk_24m ;
101
116
struct combphy_reg pipe_clk_25m ;
102
117
struct combphy_reg pipe_clk_100m ;
103
118
struct combphy_reg pipe_phymode_sel ;
@@ -584,6 +599,266 @@ static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
584
599
.combphy_cfg = rk3568_combphy_cfg ,
585
600
};
586
601
602
+ static int rk3576_combphy_cfg (struct rockchip_combphy_priv * priv )
603
+ {
604
+ const struct rockchip_combphy_grfcfg * cfg = priv -> cfg -> grfcfg ;
605
+ unsigned long rate ;
606
+ u32 val ;
607
+
608
+ switch (priv -> type ) {
609
+ case PHY_TYPE_PCIE :
610
+ /* Set SSC downward spread spectrum */
611
+ val = FIELD_PREP (PHYREG32_SSC_MASK , PHYREG32_SSC_DOWNWARD );
612
+ rockchip_combphy_updatel (priv , PHYREG32_SSC_MASK , val , PHYREG32 );
613
+
614
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> con0_for_pcie , true);
615
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> con1_for_pcie , true);
616
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> con2_for_pcie , true);
617
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> con3_for_pcie , true);
618
+ break ;
619
+
620
+ case PHY_TYPE_USB3 :
621
+ /* Set SSC downward spread spectrum */
622
+ val = FIELD_PREP (PHYREG32_SSC_MASK , PHYREG32_SSC_DOWNWARD );
623
+ rockchip_combphy_updatel (priv , PHYREG32_SSC_MASK , val , PHYREG32 );
624
+
625
+ /* Enable adaptive CTLE for USB3.0 Rx */
626
+ val = readl (priv -> mmio + PHYREG15 );
627
+ val |= PHYREG15_CTLE_EN ;
628
+ writel (val , priv -> mmio + PHYREG15 );
629
+
630
+ /* Set PLL KVCO fine tuning signals */
631
+ rockchip_combphy_updatel (priv , PHYREG33_PLL_KVCO_MASK , BIT (3 ), PHYREG33 );
632
+
633
+ /* Set PLL LPF R1 to su_trim[10:7]=1001 */
634
+ writel (PHYREG12_PLL_LPF_ADJ_VALUE , priv -> mmio + PHYREG12 );
635
+
636
+ /* Set PLL input clock divider 1/2 */
637
+ val = FIELD_PREP (PHYREG6_PLL_DIV_MASK , PHYREG6_PLL_DIV_2 );
638
+ rockchip_combphy_updatel (priv , PHYREG6_PLL_DIV_MASK , val , PHYREG6 );
639
+
640
+ /* Set PLL loop divider */
641
+ writel (PHYREG18_PLL_LOOP , priv -> mmio + PHYREG18 );
642
+
643
+ /* Set PLL KVCO to min and set PLL charge pump current to max */
644
+ writel (PHYREG11_SU_TRIM_0_7 , priv -> mmio + PHYREG11 );
645
+
646
+ /* Set Rx squelch input filler bandwidth */
647
+ writel (PHYREG21_RX_SQUELCH_VAL , priv -> mmio + PHYREG21 );
648
+
649
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> pipe_txcomp_sel , false);
650
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> pipe_txelec_sel , false);
651
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> usb_mode_set , true);
652
+ break ;
653
+
654
+ case PHY_TYPE_SATA :
655
+ /* Enable adaptive CTLE for SATA Rx */
656
+ val = readl (priv -> mmio + PHYREG15 );
657
+ val |= PHYREG15_CTLE_EN ;
658
+ writel (val , priv -> mmio + PHYREG15 );
659
+
660
+ /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
661
+ val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT ;
662
+ val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT ;
663
+ writel (val , priv -> mmio + PHYREG7 );
664
+
665
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> con0_for_sata , true);
666
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> con1_for_sata , true);
667
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> con2_for_sata , true);
668
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> con3_for_sata , true);
669
+ rockchip_combphy_param_write (priv -> pipe_grf , & cfg -> pipe_con0_for_sata , true);
670
+ rockchip_combphy_param_write (priv -> pipe_grf , & cfg -> pipe_con1_for_sata , true);
671
+ break ;
672
+
673
+ default :
674
+ dev_err (priv -> dev , "incompatible PHY type\n" );
675
+ return - EINVAL ;
676
+ }
677
+
678
+ rate = clk_get_rate (priv -> refclk );
679
+
680
+ switch (rate ) {
681
+ case REF_CLOCK_24MHz :
682
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> pipe_clk_24m , true);
683
+ if (priv -> type == PHY_TYPE_USB3 || priv -> type == PHY_TYPE_SATA ) {
684
+ /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */
685
+ val = FIELD_PREP (PHYREG15_SSC_CNT_MASK , PHYREG15_SSC_CNT_VALUE );
686
+ rockchip_combphy_updatel (priv , PHYREG15_SSC_CNT_MASK ,
687
+ val , PHYREG15 );
688
+
689
+ writel (PHYREG16_SSC_CNT_VALUE , priv -> mmio + PHYREG16 );
690
+ } else if (priv -> type == PHY_TYPE_PCIE ) {
691
+ /* PLL KVCO tuning fine */
692
+ val = FIELD_PREP (PHYREG33_PLL_KVCO_MASK , PHYREG33_PLL_KVCO_VALUE_RK3576 );
693
+ rockchip_combphy_updatel (priv , PHYREG33_PLL_KVCO_MASK ,
694
+ val , PHYREG33 );
695
+
696
+ /* Set up rx_pck invert and rx msb to disable */
697
+ writel (0x00 , priv -> mmio + PHYREG27 );
698
+
699
+ /*
700
+ * Set up SU adjust signal:
701
+ * su_trim[7:0], PLL KVCO adjust bits[2:0] to min
702
+ * su_trim[15:8], PLL LPF R1 adujst bits[9:7]=3'b011
703
+ * su_trim[31:24], CKDRV adjust
704
+ */
705
+ writel (0x90 , priv -> mmio + PHYREG11 );
706
+ writel (0x02 , priv -> mmio + PHYREG12 );
707
+ writel (0x57 , priv -> mmio + PHYREG14 );
708
+
709
+ writel (PHYREG16_SSC_CNT_VALUE , priv -> mmio + PHYREG16 );
710
+ }
711
+ break ;
712
+
713
+ case REF_CLOCK_25MHz :
714
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> pipe_clk_25m , true);
715
+ break ;
716
+
717
+ case REF_CLOCK_100MHz :
718
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> pipe_clk_100m , true);
719
+ if (priv -> type == PHY_TYPE_PCIE ) {
720
+ /* gate_tx_pck_sel length select work for L1SS */
721
+ writel (0xc0 , priv -> mmio + PHYREG30 );
722
+
723
+ /* PLL KVCO tuning fine */
724
+ val = FIELD_PREP (PHYREG33_PLL_KVCO_MASK , PHYREG33_PLL_KVCO_VALUE_RK3576 );
725
+ rockchip_combphy_updatel (priv , PHYREG33_PLL_KVCO_MASK ,
726
+ val , PHYREG33 );
727
+
728
+ /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
729
+ writel (0x4c , priv -> mmio + PHYREG27 );
730
+
731
+ /*
732
+ * Set up SU adjust signal:
733
+ * su_trim[7:0], PLL KVCO adjust bits[2:0] to min
734
+ * su_trim[15:8], bypass PLL loop divider code, and
735
+ * PLL LPF R1 adujst bits[9:7]=3'b101
736
+ * su_trim[23:16], CKRCV adjust
737
+ * su_trim[31:24], CKDRV adjust
738
+ */
739
+ writel (0x90 , priv -> mmio + PHYREG11 );
740
+ writel (0x43 , priv -> mmio + PHYREG12 );
741
+ writel (0x88 , priv -> mmio + PHYREG13 );
742
+ writel (0x56 , priv -> mmio + PHYREG14 );
743
+ } else if (priv -> type == PHY_TYPE_SATA ) {
744
+ /* downward spread spectrum +500ppm */
745
+ val = FIELD_PREP (PHYREG32_SSC_DIR_MASK , PHYREG32_SSC_DOWNWARD );
746
+ val |= FIELD_PREP (PHYREG32_SSC_OFFSET_MASK , PHYREG32_SSC_OFFSET_500PPM );
747
+ rockchip_combphy_updatel (priv , PHYREG32_SSC_MASK , val , PHYREG32 );
748
+
749
+ /* ssc ppm adjust to 3500ppm */
750
+ rockchip_combphy_updatel (priv , PHYREG10_SSC_PCM_MASK ,
751
+ PHYREG10_SSC_PCM_3500PPM ,
752
+ PHYREG10 );
753
+ }
754
+ break ;
755
+
756
+ default :
757
+ dev_err (priv -> dev , "Unsupported rate: %lu\n" , rate );
758
+ return - EINVAL ;
759
+ }
760
+
761
+ if (priv -> ext_refclk ) {
762
+ rockchip_combphy_param_write (priv -> phy_grf , & cfg -> pipe_clk_ext , true);
763
+ if (priv -> type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz ) {
764
+ val = FIELD_PREP (PHYREG33_PLL_KVCO_MASK , PHYREG33_PLL_KVCO_VALUE_RK3576 );
765
+ rockchip_combphy_updatel (priv , PHYREG33_PLL_KVCO_MASK ,
766
+ val , PHYREG33 );
767
+
768
+ /* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */
769
+ writel (0x0c , priv -> mmio + PHYREG27 );
770
+
771
+ /*
772
+ * Set up SU adjust signal:
773
+ * su_trim[7:0], PLL KVCO adjust bits[2:0] to min
774
+ * su_trim[15:8], bypass PLL loop divider code, and
775
+ * PLL LPF R1 adujst bits[9:7]=3'b101.
776
+ * su_trim[23:16], CKRCV adjust
777
+ * su_trim[31:24], CKDRV adjust
778
+ */
779
+ writel (0x90 , priv -> mmio + PHYREG11 );
780
+ writel (0x43 , priv -> mmio + PHYREG12 );
781
+ writel (0x88 , priv -> mmio + PHYREG13 );
782
+ writel (0x56 , priv -> mmio + PHYREG14 );
783
+ }
784
+ }
785
+
786
+ if (priv -> enable_ssc ) {
787
+ val = readl (priv -> mmio + PHYREG8 );
788
+ val |= PHYREG8_SSC_EN ;
789
+ writel (val , priv -> mmio + PHYREG8 );
790
+
791
+ if (priv -> type == PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz ) {
792
+ /* Set PLL loop divider */
793
+ writel (0x00 , priv -> mmio + PHYREG17 );
794
+ writel (PHYREG18_PLL_LOOP , priv -> mmio + PHYREG18 );
795
+
796
+ /* Set up rx_pck invert and rx msb to disable */
797
+ writel (0x00 , priv -> mmio + PHYREG27 );
798
+
799
+ /*
800
+ * Set up SU adjust signal:
801
+ * su_trim[7:0], PLL KVCO adjust bits[2:0] to min
802
+ * su_trim[15:8], PLL LPF R1 adujst bits[9:7]=3'b101
803
+ * su_trim[23:16], CKRCV adjust
804
+ * su_trim[31:24], CKDRV adjust
805
+ */
806
+ writel (0x90 , priv -> mmio + PHYREG11 );
807
+ writel (0x02 , priv -> mmio + PHYREG12 );
808
+ writel (0x08 , priv -> mmio + PHYREG13 );
809
+ writel (0x57 , priv -> mmio + PHYREG14 );
810
+ writel (0x40 , priv -> mmio + PHYREG15 );
811
+
812
+ writel (PHYREG16_SSC_CNT_VALUE , priv -> mmio + PHYREG16 );
813
+
814
+ val = FIELD_PREP (PHYREG33_PLL_KVCO_MASK , PHYREG33_PLL_KVCO_VALUE_RK3576 );
815
+ writel (val , priv -> mmio + PHYREG33 );
816
+ }
817
+ }
818
+
819
+ return 0 ;
820
+ }
821
+
822
+ static const struct rockchip_combphy_grfcfg rk3576_combphy_grfcfgs = {
823
+ /* pipe-phy-grf */
824
+ .pcie_mode_set = { 0x0000 , 5 , 0 , 0x00 , 0x11 },
825
+ .usb_mode_set = { 0x0000 , 5 , 0 , 0x00 , 0x04 },
826
+ .pipe_rxterm_set = { 0x0000 , 12 , 12 , 0x00 , 0x01 },
827
+ .pipe_txelec_set = { 0x0004 , 1 , 1 , 0x00 , 0x01 },
828
+ .pipe_txcomp_set = { 0x0004 , 4 , 4 , 0x00 , 0x01 },
829
+ .pipe_clk_24m = { 0x0004 , 14 , 13 , 0x00 , 0x00 },
830
+ .pipe_clk_25m = { 0x0004 , 14 , 13 , 0x00 , 0x01 },
831
+ .pipe_clk_100m = { 0x0004 , 14 , 13 , 0x00 , 0x02 },
832
+ .pipe_phymode_sel = { 0x0008 , 1 , 1 , 0x00 , 0x01 },
833
+ .pipe_rate_sel = { 0x0008 , 2 , 2 , 0x00 , 0x01 },
834
+ .pipe_rxterm_sel = { 0x0008 , 8 , 8 , 0x00 , 0x01 },
835
+ .pipe_txelec_sel = { 0x0008 , 12 , 12 , 0x00 , 0x01 },
836
+ .pipe_txcomp_sel = { 0x0008 , 15 , 15 , 0x00 , 0x01 },
837
+ .pipe_clk_ext = { 0x000c , 9 , 8 , 0x02 , 0x01 },
838
+ .pipe_phy_status = { 0x0034 , 6 , 6 , 0x01 , 0x00 },
839
+ .con0_for_pcie = { 0x0000 , 15 , 0 , 0x00 , 0x1000 },
840
+ .con1_for_pcie = { 0x0004 , 15 , 0 , 0x00 , 0x0000 },
841
+ .con2_for_pcie = { 0x0008 , 15 , 0 , 0x00 , 0x0101 },
842
+ .con3_for_pcie = { 0x000c , 15 , 0 , 0x00 , 0x0200 },
843
+ .con0_for_sata = { 0x0000 , 15 , 0 , 0x00 , 0x0129 },
844
+ .con1_for_sata = { 0x0004 , 15 , 0 , 0x00 , 0x0000 },
845
+ .con2_for_sata = { 0x0008 , 15 , 0 , 0x00 , 0x80c1 },
846
+ .con3_for_sata = { 0x000c , 15 , 0 , 0x00 , 0x0407 },
847
+ /* php-grf */
848
+ .pipe_con0_for_sata = { 0x001C , 2 , 0 , 0x00 , 0x2 },
849
+ .pipe_con1_for_sata = { 0x0020 , 2 , 0 , 0x00 , 0x2 },
850
+ };
851
+
852
+ static const struct rockchip_combphy_cfg rk3576_combphy_cfgs = {
853
+ .num_phys = 2 ,
854
+ .phy_ids = {
855
+ 0x2b050000 ,
856
+ 0x2b060000
857
+ },
858
+ .grfcfg = & rk3576_combphy_grfcfgs ,
859
+ .combphy_cfg = rk3576_combphy_cfg ,
860
+ };
861
+
587
862
static int rk3588_combphy_cfg (struct rockchip_combphy_priv * priv )
588
863
{
589
864
const struct rockchip_combphy_grfcfg * cfg = priv -> cfg -> grfcfg ;
@@ -775,6 +1050,10 @@ static const struct of_device_id rockchip_combphy_of_match[] = {
775
1050
.compatible = "rockchip,rk3568-naneng-combphy" ,
776
1051
.data = & rk3568_combphy_cfgs ,
777
1052
},
1053
+ {
1054
+ .compatible = "rockchip,rk3576-naneng-combphy" ,
1055
+ .data = & rk3576_combphy_cfgs ,
1056
+ },
778
1057
{
779
1058
.compatible = "rockchip,rk3588-naneng-combphy" ,
780
1059
.data = & rk3588_combphy_cfgs ,
0 commit comments