145145#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_62M5 (0x20 << 4)
146146#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_96M_100M (0x40 << 4)
147147
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+
148176#define KHZ 1000
149177#define MHZ (KHZ * KHZ)
150178
@@ -716,6 +744,129 @@ static const struct phy_ops exynos5_usbdrd_phy_ops = {
716744 .owner = THIS_MODULE ,
717745};
718746
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+
719870static int exynos5_usbdrd_phy_clk_handle (struct exynos5_usbdrd_phy * phy_drd )
720871{
721872 unsigned long ref_rate ;
@@ -782,6 +933,14 @@ static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = {
782933 },
783934};
784935
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+
785944static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = {
786945 .phy_cfg = phy_cfg_exynos5 ,
787946 .phy_ops = & exynos5_usbdrd_phy_ops ,
@@ -812,6 +971,13 @@ static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = {
812971 .has_common_clk_gate = false,
813972};
814973
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+
815981static const struct of_device_id exynos5_usbdrd_phy_of_match [] = {
816982 {
817983 .compatible = "samsung,exynos5250-usbdrd-phy" ,
@@ -825,6 +991,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
825991 }, {
826992 .compatible = "samsung,exynos7-usbdrd-phy" ,
827993 .data = & exynos7_usbdrd_phy
994+ }, {
995+ .compatible = "samsung,exynos850-usbdrd-phy" ,
996+ .data = & exynos850_usbdrd_phy
828997 },
829998 { },
830999};
0 commit comments