145
145
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_62M5 (0x20 << 4)
146
146
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_96M_100M (0x40 << 4)
147
147
148
+ /* Exynos850: USB DRD PHY registers */
149
+ #define EXYNOS850_DRD_LINKCTRL 0x04
150
+ #define LINKCTRL_BUS_FILTER_BYPASS (_x ) ((_x) << 4)
151
+ #define LINKCTRL_FORCE_QACT BIT(8)
152
+
153
+ #define EXYNOS850_DRD_CLKRST 0x20
154
+ #define CLKRST_LINK_SW_RST BIT(0)
155
+ #define CLKRST_PORT_RST BIT(1)
156
+ #define CLKRST_PHY_SW_RST BIT(3)
157
+
158
+ #define EXYNOS850_DRD_UTMI 0x50
159
+ #define UTMI_FORCE_SLEEP BIT(0)
160
+ #define UTMI_FORCE_SUSPEND BIT(1)
161
+ #define UTMI_DM_PULLDOWN BIT(2)
162
+ #define UTMI_DP_PULLDOWN BIT(3)
163
+ #define UTMI_FORCE_BVALID BIT(4)
164
+ #define UTMI_FORCE_VBUSVALID BIT(5)
165
+
166
+ #define EXYNOS850_DRD_HSP 0x54
167
+ #define HSP_COMMONONN BIT(8)
168
+ #define HSP_EN_UTMISUSPEND BIT(9)
169
+ #define HSP_VBUSVLDEXT BIT(12)
170
+ #define HSP_VBUSVLDEXTSEL BIT(13)
171
+ #define HSP_FSV_OUT_EN BIT(24)
172
+
173
+ #define EXYNOS850_DRD_HSP_TEST 0x5c
174
+ #define HSP_TEST_SIDDQ BIT(24)
175
+
148
176
#define KHZ 1000
149
177
#define MHZ (KHZ * KHZ)
150
178
@@ -716,6 +744,129 @@ static const struct phy_ops exynos5_usbdrd_phy_ops = {
716
744
.owner = THIS_MODULE ,
717
745
};
718
746
747
+ static void exynos850_usbdrd_utmi_init (struct exynos5_usbdrd_phy * phy_drd )
748
+ {
749
+ void __iomem * regs_base = phy_drd -> reg_phy ;
750
+ u32 reg ;
751
+
752
+ /*
753
+ * Disable HWACG (hardware auto clock gating control). This will force
754
+ * QACTIVE signal in Q-Channel interface to HIGH level, to make sure
755
+ * the PHY clock is not gated by the hardware.
756
+ */
757
+ reg = readl (regs_base + EXYNOS850_DRD_LINKCTRL );
758
+ reg |= LINKCTRL_FORCE_QACT ;
759
+ writel (reg , regs_base + EXYNOS850_DRD_LINKCTRL );
760
+
761
+ /* Start PHY Reset (POR=high) */
762
+ reg = readl (regs_base + EXYNOS850_DRD_CLKRST );
763
+ reg |= CLKRST_PHY_SW_RST ;
764
+ writel (reg , regs_base + EXYNOS850_DRD_CLKRST );
765
+
766
+ /* Enable UTMI+ */
767
+ reg = readl (regs_base + EXYNOS850_DRD_UTMI );
768
+ reg &= ~(UTMI_FORCE_SUSPEND | UTMI_FORCE_SLEEP | UTMI_DP_PULLDOWN |
769
+ UTMI_DM_PULLDOWN );
770
+ writel (reg , regs_base + EXYNOS850_DRD_UTMI );
771
+
772
+ /* Set PHY clock and control HS PHY */
773
+ reg = readl (regs_base + EXYNOS850_DRD_HSP );
774
+ reg |= HSP_EN_UTMISUSPEND | HSP_COMMONONN ;
775
+ writel (reg , regs_base + EXYNOS850_DRD_HSP );
776
+
777
+ /* Set VBUS Valid and D+ pull-up control by VBUS pad usage */
778
+ reg = readl (regs_base + EXYNOS850_DRD_LINKCTRL );
779
+ reg |= LINKCTRL_BUS_FILTER_BYPASS (0xf );
780
+ writel (reg , regs_base + EXYNOS850_DRD_LINKCTRL );
781
+
782
+ reg = readl (regs_base + EXYNOS850_DRD_UTMI );
783
+ reg |= UTMI_FORCE_BVALID | UTMI_FORCE_VBUSVALID ;
784
+ writel (reg , regs_base + EXYNOS850_DRD_UTMI );
785
+
786
+ reg = readl (regs_base + EXYNOS850_DRD_HSP );
787
+ reg |= HSP_VBUSVLDEXT | HSP_VBUSVLDEXTSEL ;
788
+ writel (reg , regs_base + EXYNOS850_DRD_HSP );
789
+
790
+ /* Power up PHY analog blocks */
791
+ reg = readl (regs_base + EXYNOS850_DRD_HSP_TEST );
792
+ reg &= ~HSP_TEST_SIDDQ ;
793
+ writel (reg , regs_base + EXYNOS850_DRD_HSP_TEST );
794
+
795
+ /* Finish PHY reset (POR=low) */
796
+ udelay (10 ); /* required before doing POR=low */
797
+ reg = readl (regs_base + EXYNOS850_DRD_CLKRST );
798
+ reg &= ~(CLKRST_PHY_SW_RST | CLKRST_PORT_RST );
799
+ writel (reg , regs_base + EXYNOS850_DRD_CLKRST );
800
+ udelay (75 ); /* required after POR=low for guaranteed PHY clock */
801
+
802
+ /* Disable single ended signal out */
803
+ reg = readl (regs_base + EXYNOS850_DRD_HSP );
804
+ reg &= ~HSP_FSV_OUT_EN ;
805
+ writel (reg , regs_base + EXYNOS850_DRD_HSP );
806
+ }
807
+
808
+ static int exynos850_usbdrd_phy_init (struct phy * phy )
809
+ {
810
+ struct phy_usb_instance * inst = phy_get_drvdata (phy );
811
+ struct exynos5_usbdrd_phy * phy_drd = to_usbdrd_phy (inst );
812
+ int ret ;
813
+
814
+ ret = clk_prepare_enable (phy_drd -> clk );
815
+ if (ret )
816
+ return ret ;
817
+
818
+ /* UTMI or PIPE3 specific init */
819
+ inst -> phy_cfg -> phy_init (phy_drd );
820
+
821
+ clk_disable_unprepare (phy_drd -> clk );
822
+
823
+ return 0 ;
824
+ }
825
+
826
+ static int exynos850_usbdrd_phy_exit (struct phy * phy )
827
+ {
828
+ struct phy_usb_instance * inst = phy_get_drvdata (phy );
829
+ struct exynos5_usbdrd_phy * phy_drd = to_usbdrd_phy (inst );
830
+ void __iomem * regs_base = phy_drd -> reg_phy ;
831
+ u32 reg ;
832
+ int ret ;
833
+
834
+ ret = clk_prepare_enable (phy_drd -> clk );
835
+ if (ret )
836
+ return ret ;
837
+
838
+ /* Set PHY clock and control HS PHY */
839
+ reg = readl (regs_base + EXYNOS850_DRD_UTMI );
840
+ reg &= ~(UTMI_DP_PULLDOWN | UTMI_DM_PULLDOWN );
841
+ reg |= UTMI_FORCE_SUSPEND | UTMI_FORCE_SLEEP ;
842
+ writel (reg , regs_base + EXYNOS850_DRD_UTMI );
843
+
844
+ /* Power down PHY analog blocks */
845
+ reg = readl (regs_base + EXYNOS850_DRD_HSP_TEST );
846
+ reg |= HSP_TEST_SIDDQ ;
847
+ writel (reg , regs_base + EXYNOS850_DRD_HSP_TEST );
848
+
849
+ /* Link reset */
850
+ reg = readl (regs_base + EXYNOS850_DRD_CLKRST );
851
+ reg |= CLKRST_LINK_SW_RST ;
852
+ writel (reg , regs_base + EXYNOS850_DRD_CLKRST );
853
+ udelay (10 ); /* required before doing POR=low */
854
+ reg &= ~CLKRST_LINK_SW_RST ;
855
+ writel (reg , regs_base + EXYNOS850_DRD_CLKRST );
856
+
857
+ clk_disable_unprepare (phy_drd -> clk );
858
+
859
+ return 0 ;
860
+ }
861
+
862
+ static const struct phy_ops exynos850_usbdrd_phy_ops = {
863
+ .init = exynos850_usbdrd_phy_init ,
864
+ .exit = exynos850_usbdrd_phy_exit ,
865
+ .power_on = exynos5_usbdrd_phy_power_on ,
866
+ .power_off = exynos5_usbdrd_phy_power_off ,
867
+ .owner = THIS_MODULE ,
868
+ };
869
+
719
870
static int exynos5_usbdrd_phy_clk_handle (struct exynos5_usbdrd_phy * phy_drd )
720
871
{
721
872
unsigned long ref_rate ;
@@ -782,6 +933,14 @@ static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = {
782
933
},
783
934
};
784
935
936
+ static const struct exynos5_usbdrd_phy_config phy_cfg_exynos850 [] = {
937
+ {
938
+ .id = EXYNOS5_DRDPHY_UTMI ,
939
+ .phy_isol = exynos5_usbdrd_phy_isol ,
940
+ .phy_init = exynos850_usbdrd_utmi_init ,
941
+ },
942
+ };
943
+
785
944
static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = {
786
945
.phy_cfg = phy_cfg_exynos5 ,
787
946
.phy_ops = & exynos5_usbdrd_phy_ops ,
@@ -812,6 +971,13 @@ static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = {
812
971
.has_common_clk_gate = false,
813
972
};
814
973
974
+ static const struct exynos5_usbdrd_phy_drvdata exynos850_usbdrd_phy = {
975
+ .phy_cfg = phy_cfg_exynos850 ,
976
+ .phy_ops = & exynos850_usbdrd_phy_ops ,
977
+ .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL ,
978
+ .has_common_clk_gate = true,
979
+ };
980
+
815
981
static const struct of_device_id exynos5_usbdrd_phy_of_match [] = {
816
982
{
817
983
.compatible = "samsung,exynos5250-usbdrd-phy" ,
@@ -825,6 +991,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
825
991
}, {
826
992
.compatible = "samsung,exynos7-usbdrd-phy" ,
827
993
.data = & exynos7_usbdrd_phy
994
+ }, {
995
+ .compatible = "samsung,exynos850-usbdrd-phy" ,
996
+ .data = & exynos850_usbdrd_phy
828
997
},
829
998
{ },
830
999
};
0 commit comments