[coreboot-gerrit] Patch set updated for coreboot: rockchip/rk3399: Add Type-C PHY init

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Fri Oct 7 15:43:19 CEST 2016


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16910

-gerrit

commit e13fe914dbb0c5fab29ca91aea7685caa5cfa52a
Author: William wu <wulf at rock-chips.com>
Date:   Sat Oct 1 20:58:21 2016 +0800

    rockchip/rk3399: Add Type-C PHY init
    
    Though we don't use Type-C PHY to support USB3 in firmware,
    we still need to initialize the Type-C PHY, and make sure
    the power state of pipe is always fixed to U2/P2. After
    this, we can force USB3 controller to work in USB2 only
    mode.
    
    BRANCH=none
    BUG=chrome-os-partner:56425
    TEST=Go to recovery mode, plug a Type-C USB drive containing
    chrome OS image into both ports in all orientations, check if
    system can boot from USB.
    
    Change-Id: I95bb96ff27d4fecafb7b2b9e9dc2839b5c132654
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 8ec98507845276119d8a9d5626934dedcb35f2dd
    Original-Change-Id: Ie3654cd1c1cb76b62aa9b247879b60cbecee0155
    Original-Signed-off-by: William wu <wulf at rock-chips.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/391412
    Original-Commit-Ready: Julius Werner <jwerner at chromium.org>
    Original-Tested-by: Julius Werner <jwerner at chromium.org>
    Original-Reviewed-by: Julius Werner <jwerner at chromium.org>
---
 src/soc/rockchip/rk3399/include/soc/usb.h | 33 ++++++++++++++-
 src/soc/rockchip/rk3399/usb.c             | 68 +++++++++++++++++++++++++++----
 2 files changed, 91 insertions(+), 10 deletions(-)

diff --git a/src/soc/rockchip/rk3399/include/soc/usb.h b/src/soc/rockchip/rk3399/include/soc/usb.h
index 46d3752..c2fa1a2 100644
--- a/src/soc/rockchip/rk3399/include/soc/usb.h
+++ b/src/soc/rockchip/rk3399/include/soc/usb.h
@@ -111,12 +111,41 @@ static struct rockchip_usb_dwc3 * const rockchip_usb_otg0_dwc3 =
 static struct rockchip_usb_dwc3 * const rockchip_usb_otg1_dwc3 =
 		(void *)USB_OTG1_DWC3_BASE;
 
-/* TODO: define struct overlay if we ever need more registers from this */
-#define TCPHY_ISOLATION_CTRL_OFFSET	0x3207c
 #define TCPHY_ISOLATION_CTRL_EN		(1 << 15)
 #define TCPHY_ISOLATION_CTRL_CMN_EN	(1 << 14)
 #define TCPHY_ISOLATION_CTRL_MODE_SEL	(1 << 12)
 #define TCPHY_ISOLATION_CTRL_LN_EN(ln)	(1 << (ln))
+#define TCPHY_CMN_HSCLK_PLL_CONFIG	0x30
+#define TCPHY_CMN_HSCLK_PLL_MASK	0x33
+
+struct rk3399_tcphy {
+	uint8_t _res0[0x780 - 0x0];
+	uint32_t cmn_diag_hsclk_sel;
+	uint8_t _res1[0x10000 - 0x784];
+	struct {
+		uint8_t _res2[0x3c8 - 0x0];
+		uint32_t xcvr_diag_lane_fcm_en_mgn;
+		uint8_t _res3[0x408 - 0x3cc];
+		uint32_t tx_psc_a2;
+		uint8_t _res4[0x488 - 0x40c];
+		uint32_t tx_rcvdet_en_tmr;
+		uint32_t tx_rcvdet_st_tmr;
+		uint8_t _res5[0x784 - 0x490];
+		uint32_t tx_diag_tx_drv;
+		uint8_t _res6[0x800 - 0x788];
+	} lane[4];
+	uint8_t _res7[0x32000 - 0x12000];
+	uint32_t pma_cmn_ctrl1;
+	uint8_t _res8[0x3207c - 0x32004];
+	uint32_t isolation_ctrl;
+};
+check_member(rk3399_tcphy, lane[2].tx_diag_tx_drv, 0x11784);
+check_member(rk3399_tcphy, isolation_ctrl, 0x3207c);
+
+static struct rk3399_tcphy * const rockchip_usb_otg0_phy =
+		(void *)USB_OTG0_TCPHY_BASE;
+static struct rk3399_tcphy * const rockchip_usb_otg1_phy =
+		(void *)USB_OTG1_TCPHY_BASE;
 
 /* Call reset_ before setup_ */
 void reset_usb_otg0(void);
diff --git a/src/soc/rockchip/rk3399/usb.c b/src/soc/rockchip/rk3399/usb.c
index 4c731bd..e6db1e0 100644
--- a/src/soc/rockchip/rk3399/usb.c
+++ b/src/soc/rockchip/rk3399/usb.c
@@ -24,9 +24,9 @@
 
 /* SuperSpeed over Type-C is hard. We don't care about speed in firmware: just
  * gate off the SuperSpeed lines to have an unimpaired USB 2.0 connection. */
-static void isolate_tcphy(uintptr_t base)
+static void isolate_tcphy(struct rk3399_tcphy *tcphy)
 {
-	write32((void *)(base + TCPHY_ISOLATION_CTRL_OFFSET),
+	write32(&tcphy->isolation_ctrl,
 		TCPHY_ISOLATION_CTRL_EN |
 		TCPHY_ISOLATION_CTRL_CMN_EN |
 		TCPHY_ISOLATION_CTRL_MODE_SEL |
@@ -40,6 +40,42 @@ static void isolate_tcphy(uintptr_t base)
 		TCPHY_ISOLATION_CTRL_LN_EN(0));
 }
 
+static void tcphy_cfg_24m(struct rk3399_tcphy *tcphy)
+{
+	u32 i;
+
+	/* cmn_ref_clk_sel = 3, select the 24Mhz for clk parent
+	 * cmn_psm_clk_dig_div = 2, set the clk division to 2 */
+	write32(&tcphy->pma_cmn_ctrl1, 2 << 10 | 3 << 4);
+	for (i = 0; i < 4; i++) {
+		/* The following PHY configuration assumes a
+		 * 24 MHz reference clock */
+		write32(&tcphy->lane[i].xcvr_diag_lane_fcm_en_mgn, 0x90);
+		write32(&tcphy->lane[i].tx_rcvdet_en_tmr, 0x960);
+		write32(&tcphy->lane[i].tx_rcvdet_st_tmr, 0x30);
+	}
+
+	clrsetbits_le32(&tcphy->cmn_diag_hsclk_sel,
+			TCPHY_CMN_HSCLK_PLL_MASK, TCPHY_CMN_HSCLK_PLL_CONFIG);
+}
+
+static void tcphy_phy_init(struct rk3399_tcphy *tcphy)
+{
+	u32 i;
+
+	tcphy_cfg_24m(tcphy);
+
+	for (i = 0; i < 4; i++) {
+		/* Enable transmitter reset pull down override for all lanes*/
+		write32(&tcphy->lane[i].tx_diag_tx_drv, 0x2000);
+		/* Disable transmitter low current mode, disable TX
+		 * driver common mode, disable TX post-emphasis*/
+		write32(&tcphy->lane[i].tx_psc_a2, 0x0000);
+	}
+
+	isolate_tcphy(tcphy);
+}
+
 static void reset_dwc3(struct rockchip_usb_dwc3 *dwc3)
 {
 	/* Before Resetting PHY, put Core in Reset */
@@ -89,38 +125,54 @@ static void setup_dwc3(struct rockchip_usb_dwc3 *dwc3)
 
 void reset_usb_otg0(void)
 {
+	printk(BIOS_DEBUG, "Starting DWC3 and TCPHY reset for USB OTG0\n");
+
 	/* Keep whole USB OTG0 controller in reset, then
 	 * configure controller to work in USB 2.0 only mode. */
 	write32(&cru_ptr->softrst_con[18], RK_SETBITS(1 << 5));
 	write32(&rk3399_grf->usb3otg0_con1, RK_CLRSETBITS(0xf << 12, 1 << 0));
 	write32(&cru_ptr->softrst_con[18], RK_CLRBITS(1 << 5));
 
-	printk(BIOS_DEBUG, "Starting DWC3 reset for USB OTG0\n");
+	tcphy_phy_init(rockchip_usb_otg0_phy);
+
+	/* Clear TCPHY0 reset */
+	write32(&cru_ptr->softrst_con[9], RK_CLRBITS(1 << 5));
+
 	reset_dwc3(rockchip_usb_otg0_dwc3);
 }
 
 void reset_usb_otg1(void)
 {
+	printk(BIOS_DEBUG, "Starting DWC3 and TCPHY reset for USB OTG1\n");
+
 	/* Keep whole USB OTG1 controller in reset, then
 	 * configure controller to work in USB 2.0 only mode. */
 	write32(&cru_ptr->softrst_con[18], RK_SETBITS(1 << 6));
 	write32(&rk3399_grf->usb3otg1_con1, RK_CLRSETBITS(0xf << 12, 1 << 0));
 	write32(&cru_ptr->softrst_con[18], RK_CLRBITS(1 << 6));
 
-	printk(BIOS_DEBUG, "Starting DWC3 reset for USB OTG1\n");
+	tcphy_phy_init(rockchip_usb_otg1_phy);
+
+	/* Clear TCPHY1 reset */
+	write32(&cru_ptr->softrst_con[9], RK_CLRBITS(1 << 13));
+
 	reset_dwc3(rockchip_usb_otg1_dwc3);
 }
 
 void setup_usb_otg0(void)
 {
-	isolate_tcphy(USB_OTG0_TCPHY_BASE);
+	/* Clear pipe reset */
+	write32(&cru_ptr->softrst_con[9], RK_CLRBITS(1 << 4));
+
 	setup_dwc3(rockchip_usb_otg0_dwc3);
-	printk(BIOS_DEBUG, "DWC3 setup for USB OTG0 finished\n");
+	printk(BIOS_DEBUG, "DWC3 and TCPHY setup for USB OTG0 finished\n");
 }
 
 void setup_usb_otg1(void)
 {
-	isolate_tcphy(USB_OTG1_TCPHY_BASE);
+	/* Clear pipe reset */
+	write32(&cru_ptr->softrst_con[9], RK_CLRBITS(1 << 12));
+
 	setup_dwc3(rockchip_usb_otg1_dwc3);
-	printk(BIOS_DEBUG, "DWC3 setup for USB OTG1 finished\n");
+	printk(BIOS_DEBUG, "DWC3 and TCPHY setup for USB OTG1 finished\n");
 }



More information about the coreboot-gerrit mailing list