From b2da1813de81a8fe397bfa4a7857082b10ae7cb4 Mon Sep 17 00:00:00 2001 From: Vandhiadevan Karunamoorthy Date: Tue, 21 Jun 2022 13:57:19 +0530 Subject: [PATCH] board: arm: devsoc: update USB PHY & Clk config Change-Id: Ie1216d3b191aef1f221df91ec254e162e57e099a Signed-off-by: Vandhiadevan Karunamoorthy --- arch/arm/include/asm/arch-devsoc/clk.h | 70 +++++++++++- board/qca/arm/devsoc/clock.c | 27 ++--- board/qca/arm/devsoc/devsoc.c | 147 ++++++++++++++++++++++--- board/qca/arm/devsoc/devsoc.h | 57 ++++++++++ 4 files changed, 265 insertions(+), 36 deletions(-) diff --git a/arch/arm/include/asm/arch-devsoc/clk.h b/arch/arm/include/asm/arch-devsoc/clk.h index 1ee6deb265..3581c282a1 100644 --- a/arch/arm/include/asm/arch-devsoc/clk.h +++ b/arch/arm/include/asm/arch-devsoc/clk.h @@ -129,6 +129,74 @@ #define NSS_CC_PORT1_RX_CBCR 0x39B00480 #define NSS_CC_UNIPHY_PORT1_RX_CBCR 0x39B004B4 + +#define GCC_USB_BCR 0x182C000 +#define GCC_USB0_MASTER_CMD_RCGR 0x182C004 +#define GCC_USB0_MASTER_CFG_RCGR 0x182C008 +#define GCC_USB0_MASTER_M 0x182C00C +#define GCC_USB0_MASTER_N 0x182C010 +#define GCC_USB0_MASTER_D 0x182C014 +#define GCC_USB0_AUX_CMD_RCGR 0x182C018 +#define GCC_USB0_AUX_CFG_RCGR 0x182C01C +#define GCC_USB0_AUX_M 0x182C020 +#define GCC_USB0_AUX_N 0x182C024 +#define GCC_USB0_AUX_D 0x182C028 +#define GCC_USB0_MOCK_UTMI_CMD_RCGR 0x182C02C +#define GCC_USB0_MOCK_UTMI_CFG_RCGR 0x182C030 +#define GCC_USB0_MOCK_UTMI_M 0x182C034 +#define GCC_USB0_MOCK_UTMI_N 0x182C038 +#define GCC_USB0_MOCK_UTMI_D 0x182C03C +#define GCC_USB0_MOCK_UTMI_DIV_CDIVR 0x182C040 +#define GCC_USB0_MASTER_CBCR 0x182C048 +#define GCC_USB0_MASTER_SREGR 0x182C04C +#define GCC_USB0_AUX_CBCR 0x182C050 +#define GCC_USB0_MOCK_UTMI_CBCR 0x182C054 +#define GCC_USB0_SLEEP_CBCR 0x182C058 +#define GCC_USB0_PHY_CFG_AHB_CBCR 0x182C05C +#define GCC_USB0_BOOT_CLOCK_CTL 0x182C060 +#define GCC_USB0_PHY_BCR 0x182C06C +#define GCC_USB3PHY_0_PHY_BCR 0x182C070 +#define GCC_USB0_PHY_PIPE_MISC 0x182C074 +#define GCC_USB0_PIPE_CBCR 0x182C078 +#define GCC_USB0_LFPS_CMD_RCGR 0x182C07C +#define GCC_USB0_LFPS_CFG_RCGR 0x182C080 +#define GCC_USB0_LFPS_M 0x182C084 +#define GCC_USB0_LFPS_N 0x182C088 +#define GCC_USB0_LFPS_D 0x182C08C +#define GCC_USB0_LFPS_CBCR 0x182C090 +#define GCC_USB0_EUD_AT_CBCR 0x1830004 + +#define GCC_USB0_BOOT_CLOCK_CTL 0x182C060 +#define GCC_QUSB2_0_PHY_BCR 0x182C068 + +#define GCC_USB0_LFPS_CFG_SRC_SEL (0x1 << 8) +#define GCC_USB0_LFPS_CFG_SRC_DIV (0x1F << 0) +#define LFPS_M 0x1 +#define LFPS_N 0xFE +#define LFPS_D 0xFD +#define GCC_USB0_LFPS_MODE (0x2 << 12) + +#define GCC_USB0_AUX_CFG_MODE_DUAL_EDGE (2 << 12) +#define GCC_USB0_AUX_CFG_SRC_SEL (0 << 8) +#define GCC_USB0_AUX_CFG_SRC_DIV (0x3 << 0) + +#define AUX_M 0x0 +#define AUX_N 0x0 +#define AUX_D 0x0 + +#define GCC_USB0_MASTER_CFG_RCGR_SRC_SEL (1 << 8) +#define GCC_USB0_MASTER_CFG_RCGR_SRC_DIV (0x7 << 0) + +#define GCC_USB_MOCK_UTMI_SRC_SEL (1 << 8) +#define GCC_USB_MOCK_UTMI_SRC_DIV (0x13 << 0) +#define MOCK_UTMI_M 0x1 +#define MOCK_UTMI_N 0xFE +#define MOCK_UTMI_D 0xFD + +#define PIPE_UTMI_CLK_SEL 0x1 +#define PIPE3_PHYSTATUS_SW (0x1 << 3) +#define PIPE_UTMI_CLK_DIS (0x1 << 8) + #ifdef CONFIG_QCA_MMC void emmc_clock_init(void); void emmc_clock_reset(void); @@ -139,7 +207,7 @@ void pcie_v2_clock_deinit(int pcie_id); #endif int uart_clock_config(struct ipq_serial_platdata *plat); #ifdef CONFIG_USB_XHCI_IPQ -void usb_clock_init(int id, int ssphy); +void usb_clock_init(void); void usb_clock_deinit(void); #endif diff --git a/board/qca/arm/devsoc/clock.c b/board/qca/arm/devsoc/clock.c index ce3dfaa2e5..53e8910ace 100644 --- a/board/qca/arm/devsoc/clock.c +++ b/board/qca/arm/devsoc/clock.c @@ -234,15 +234,11 @@ void pcie_v2_clock_deinit(int pcie_id) } #endif #ifdef CONFIG_USB_XHCI_IPQ -void usb_clock_init(int id, int ssphy) +void usb_clock_init(void) { #ifdef QCA_CLOCK_ENABLE int cfg; - /* select usb phy mux */ - if (ssphy) - writel(0x1, TCSR_USB_PCIE_SEL); - /* Configure usb0_master_clk_src */ cfg = (GCC_USB0_MASTER_CFG_RCGR_SRC_SEL | GCC_USB0_MASTER_CFG_RCGR_SRC_DIV); @@ -255,7 +251,9 @@ void usb_clock_init(int id, int ssphy) cfg = (GCC_USB_MOCK_UTMI_SRC_SEL | GCC_USB_MOCK_UTMI_SRC_DIV); writel(cfg, GCC_USB0_MOCK_UTMI_CFG_RCGR); - writel(GCC_USB_MOCK_UTMI_CLK_DIV, GCC_USB0_MOCK_UTMI_CBCR); + writel(MOCK_UTMI_M, GCC_USB0_MOCK_UTMI_M); + writel(MOCK_UTMI_N, GCC_USB0_MOCK_UTMI_N); + writel(MOCK_UTMI_D, GCC_USB0_MOCK_UTMI_D); writel(CMD_UPDATE, GCC_USB0_MOCK_UTMI_CMD_RCGR); mdelay(100); writel(ROOT_EN, GCC_USB0_MOCK_UTMI_CMD_RCGR); @@ -282,8 +280,6 @@ void usb_clock_init(int id, int ssphy) writel(ROOT_EN, GCC_USB0_LFPS_CMD_RCGR); /* Configure CBCRs */ - writel(CLK_DISABLE, GCC_SYS_NOC_USB0_AXI_CBCR); - writel(CLK_ENABLE, GCC_SYS_NOC_USB0_AXI_CBCR); writel((readl(GCC_USB0_MASTER_CBCR) | CLK_ENABLE), GCC_USB0_MASTER_CBCR); writel(CLK_ENABLE, GCC_USB0_SLEEP_CBCR); @@ -300,16 +296,13 @@ void usb_clock_init(int id, int ssphy) void usb_clock_deinit(void) { - #ifdef QCA_CLOCK_ENABLE - /* Disable clocks */ - writel(0x8000, GCC_USB0_PHY_CFG_AHB_CBCR); - writel(0xcff0, GCC_USB0_MASTER_CBCR); - writel(0, GCC_USB0_SLEEP_CBCR); - writel(0, GCC_USB0_MOCK_UTMI_CBCR); - writel(0, GCC_USB0_AUX_CBCR); - writel(0, GCC_ANOC_USB_AXI_CBCR); - writel(0, GCC_SNOC_USB_CBCR); + writel(0x0, GCC_USB0_PHY_CFG_AHB_CBCR); + writel(0x4220, GCC_USB0_MASTER_CBCR); + writel(0x0, GCC_USB0_SLEEP_CBCR); + writel(0x0, GCC_USB0_MOCK_UTMI_CBCR); + writel(0x0, GCC_USB0_AUX_CBCR); + writel(0x0, GCC_USB0_LFPS_CBCR); #else return; #endif diff --git a/board/qca/arm/devsoc/devsoc.c b/board/qca/arm/devsoc/devsoc.c index aa10b25fd2..64d9df4fdd 100644 --- a/board/qca/arm/devsoc/devsoc.c +++ b/board/qca/arm/devsoc/devsoc.c @@ -355,36 +355,147 @@ void board_pci_deinit() #ifdef CONFIG_USB_XHCI_IPQ void board_usb_deinit(int id) { - int nodeoff; + int nodeoff, ssphy; char node_name[8]; snprintf(node_name, sizeof(node_name), "usb%d", id); nodeoff = fdt_path_offset(gd->fdt_blob, node_name); if (fdtdec_get_int(gd->fdt_blob, nodeoff, "qcom,emulation", 0)) return; + + ssphy = fdtdec_get_int(gd->fdt_blob, nodeoff, "ssphy", 0); + /* Enable USB PHY Power down */ + setbits_le32(QUSB2PHY_BASE + 0xA4, 0x0); + /* Disable clocks */ + usb_clock_deinit(); + /* GCC_QUSB2_0_PHY_BCR */ + set_mdelay_clearbits_le32(GCC_QUSB2_0_PHY_BCR, 0x1, 10); + /* GCC_USB0_PHY_BCR */ + if (ssphy) + set_mdelay_clearbits_le32(GCC_USB0_PHY_BCR, 0x1, 10); + /* GCC Reset USB BCR */ + set_mdelay_clearbits_le32(GCC_USB_BCR, 0x1, 10); + /* Deselect the usb phy mux */ + if (ssphy) + writel(TCSR_USB_PCIE_SEL_PCI, TCSR_USB_PCIE_SEL); + +} + +static void usb_init_hsphy(void __iomem *phybase, int ssphy) +{ + if (!ssphy) { + /*Enable utmi instead of pipe*/ + writel((readl(USB30_GENERAL_CFG) | + PIPE_UTMI_CLK_DIS), USB30_GENERAL_CFG); + udelay(100); + writel((readl(USB30_GENERAL_CFG) | + PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW), + USB30_GENERAL_CFG); + udelay(100); + writel((readl(USB30_GENERAL_CFG) & + ~PIPE_UTMI_CLK_DIS), USB30_GENERAL_CFG); + } + /* Disable USB PHY Power down */ + setbits_le32(phybase + 0xA4, 0x1); + /* Enable override ctrl */ + writel(UTMI_PHY_OVERRIDE_EN, phybase + USB_PHY_CFG0); + /* Enable POR*/ + writel(POR_EN, phybase + USB_PHY_UTMI_CTRL5); + udelay(15); + /* Configure frequency select value*/ + writel(FREQ_SEL, phybase + USB_PHY_FSEL_SEL); + /* Configure refclk frequency */ + + writel(FSEL_VALUE << FSEL, phybase + USB_PHY_HS_PHY_CTRL_COMMON0); + + writel(readl(phybase + USB_PHY_UTMI_CTRL5) & ATERESET, + phybase + USB_PHY_UTMI_CTRL5); + + writel(USB2_SUSPEND_N_SEL | USB2_SUSPEND_N, + phybase + USB_PHY_HS_PHY_CTRL2); + + writel(SLEEPM, phybase + USB_PHY_UTMI_CTRL0); + + writel(XCFG_COARSE_TUNE_NUM | XCFG_COARSE_TUNE_NUM, + phybase + USB2PHY_USB_PHY_M31_XCFGI_11); + + udelay(100); + + writel(readl(phybase + USB_PHY_UTMI_CTRL5) & ~POR_EN, + phybase + USB_PHY_UTMI_CTRL5); + + writel(readl(phybase + USB_PHY_HS_PHY_CTRL2) & USB2_SUSPEND_N_SEL, + phybase + USB_PHY_HS_PHY_CTRL2); +} + +static void usb_init_ssphy(void __iomem *phybase) +{ + writel(CLK_ENABLE, GCC_USB0_PHY_CFG_AHB_CBCR); + writel(CLK_ENABLE, GCC_USB0_PIPE_CBCR); + udelay(100); + /*set frequency initial value*/ + writel(0x1cb9, phybase + SSCG_CTRL_REG_4); + writel(0x023a, phybase + SSCG_CTRL_REG_5); + /*set spectrum spread count*/ + writel(0xd360, phybase + SSCG_CTRL_REG_3); + /*set fstep*/ + writel(0x1, phybase + SSCG_CTRL_REG_1); + writel(0xeb, phybase + SSCG_CTRL_REG_2); + return; +} + +static void usb_init_phy(int ssphy) +{ + void __iomem *boot_clk_ctl, *usb_bcr, *qusb2_phy_bcr; + + boot_clk_ctl = (u32 *)GCC_USB0_BOOT_CLOCK_CTL; + usb_bcr = (u32 *)GCC_USB_BCR; + qusb2_phy_bcr = (u32 *)GCC_QUSB2_0_PHY_BCR; + + /* Disable USB Boot Clock */ + clrbits_le32(boot_clk_ctl, 0x0); + + /* GCC Reset USB BCR */ + set_mdelay_clearbits_le32(usb_bcr, 0x1, 10); + + if (ssphy) + setbits_le32(GCC_USB0_PHY_BCR, 0x1); + setbits_le32(qusb2_phy_bcr, 0x1); + udelay(1); + /* Config user control register */ + writel(0x4004010, USB30_GUCTL); + writel(0x4945920, USB30_FLADJ); + if (ssphy) + clrbits_le32(GCC_USB0_PHY_BCR, 0x1); + clrbits_le32(qusb2_phy_bcr, 0x1); + udelay(30); + + if (ssphy) + usb_init_ssphy((u32 *)USB3PHY_APB_BASE); + usb_init_hsphy((u32 *)QUSB2PHY_BASE, ssphy); } int ipq_board_usb_init(void) { - int i, nodeoff, ssphy; - char node_name[8]; + int nodeoff, ssphy; - for (i=0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { - snprintf(node_name, sizeof(node_name), "usb%d", i); - nodeoff = fdt_path_offset(gd->fdt_blob, node_name); - if (nodeoff < 0){ - printf("USB: Node Not found, skipping initialization\n"); - return 0; - } + nodeoff = fdt_path_offset(gd->fdt_blob, "usb0"); + if (nodeoff < 0){ + printf("USB: Node Not found,skipping initialization\n"); + return 0; + } - ssphy = fdtdec_get_int(gd->fdt_blob, nodeoff, "ssphy", 0); - if (!fdtdec_get_int(gd->fdt_blob, nodeoff, "qcom,emulation", 0)) { - - usb_clock_init(i, ssphy); - }else { - /* Config user control register */ - writel(0x0C804010, USB30_GUCTL); - } + ssphy = fdtdec_get_int(gd->fdt_blob, nodeoff, "ssphy", 0); + if (!fdtdec_get_int(gd->fdt_blob, nodeoff, "qcom,emulation", 0)) { + /* select usb phy mux */ + if (ssphy) + writel(TCSR_USB_PCIE_SEL_USB, + TCSR_USB_PCIE_SEL); + usb_clock_init(); + usb_init_phy(ssphy); + } else { + /* Config user control register */ + writel(0x0C804010, USB30_GUCTL); } return 0; diff --git a/board/qca/arm/devsoc/devsoc.h b/board/qca/arm/devsoc/devsoc.h index b01b1f990b..df69145517 100644 --- a/board/qca/arm/devsoc/devsoc.h +++ b/board/qca/arm/devsoc/devsoc.h @@ -39,6 +39,63 @@ extern const add_node_t add_fdt_node[]; #define TCSR_MODE_CTRL_2PORT_2LANE 0x1947544 #define USB30_GUCTL 0x8A0C12C + +/* USB Registers */ +#define TCSR_USB_PCIE_SEL 0x01947540 +#define TCSR_USB_PCIE_SEL_USB 0x1 +#define TCSR_USB_PCIE_SEL_PCI 0x0 +#define USB30_GENERAL_CFG 0x8AF8808 +#define USB30_GUCTL 0x8A0C12C +#define USB30_FLADJ 0x8A0C630 +#define GUCTL 0x700C12C +#define FLADJ 0x700C630 + +#define SW_COLLAPSE_ENABLE (1 << 0) +#define SW_OVERRIDE_ENABLE (1 << 2) +#define XCFG_COARSE_TUNE_NUM (2 << 0) +#define XCFG_FINE_TUNE_NUM (1 << 3) +#define FSEL_VALUE (5 << 4) + +#define QUSB2PHY_BASE 0x7B000 + +#define USB3PHY_APB_BASE 0x4B0000 + +#define SSCG_CTRL_REG_1 0x9c +#define SSCG_CTRL_REG_2 0xa0 +#define SSCG_CTRL_REG_3 0xa4 +#define SSCG_CTRL_REG_4 0xa8 +#define SSCG_CTRL_REG_5 0xac +#define SSCG_CTRL_REG_6 0xb0 +#define CDR_CTRL_REG_1 0x80 +#define CDR_CTRL_REG_2 0x84 +#define CDR_CTRL_REG_3 0x88 +#define CDR_CTRL_REG_4 0x8C +#define CDR_CTRL_REG_5 0x90 +#define CDR_CTRL_REG_6 0x94 +#define CDR_CTRL_REG_7 0x98 + +#define USB_PHY_CFG0 0x94 +#define USB_PHY_UTMI_CTRL0 0x3C +#define USB_PHY_UTMI_CTRL5 0x50 +#define USB_PHY_FSEL_SEL 0xB8 +#define USB_PHY_HS_PHY_CTRL_COMMON0 0x54 +#define USB_PHY_REFCLK_CTRL 0xA0 +#define USB_PHY_HS_PHY_CTRL2 0x64 +#define USB2PHY_USB_PHY_M31_XCFGI_11 0xE4 + +#define UTMI_PHY_OVERRIDE_EN BIT(1) +#define SLEEPM BIT(1) +#define POR_EN BIT(1) +#define FREQ_SEL BIT(0) +#define COMMONONN BIT(7) +#define FSEL BIT(4) +#define RETENABLEN BIT(3) +#define USB2_SUSPEND_N_SEL BIT(3) +#define USB2_SUSPEND_N BIT(2) +#define USB2_UTMI_CLK_EN BIT(1) +#define CLKCORE BIT(1) +#define ATERESET ~BIT(0) + /* * weak function */