| /* |
| * Copyright (c) 2019 - 2021, Broadcom |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| #include <stdint.h> |
| |
| #include <common/debug.h> |
| #include <drivers/delay_timer.h> |
| #include <lib/mmio.h> |
| |
| #include <mdio.h> |
| #include <platform_usb.h> |
| #include <sr_utils.h> |
| #include "sr_usb.h" |
| #include <usbh_xhci_regs.h> |
| |
| static uint32_t usb_func = USB3_DRD | USB3H_USB2DRD; |
| |
| static void usb_pm_rescal_init(void) |
| { |
| uint32_t data; |
| uint32_t try; |
| |
| mmio_setbits_32(CDRU_MISC_RESET_CONTROL, CDRU_PM_RESET_N_R); |
| /* release reset */ |
| mmio_setbits_32(CDRU_CHIP_TOP_SPARE_REG0, RESCAL_I_RSTB); |
| udelay(10U); |
| /* power up */ |
| mmio_setbits_32(CDRU_CHIP_TOP_SPARE_REG0, |
| RESCAL_I_RSTB | RESCAL_I_PWRDNB); |
| try = 1000U; |
| do { |
| udelay(1U); |
| data = mmio_read_32(CDRU_CHIP_TOP_SPARE_REG1); |
| try--; |
| } while ((data & RESCAL_I_PWRDNB) == 0x0U && (try != 0U)); |
| |
| if (try == 0U) { |
| ERROR("CDRU_CHIP_TOP_SPARE_REG1: 0x%x\n", data); |
| } |
| |
| INFO("USB and PM Rescal Init done..\n"); |
| } |
| |
| const unsigned int xhc_portsc_reg_offset[MAX_USB_PORTS] = { |
| XHC_PORTSC1_OFFSET, |
| XHC_PORTSC2_OFFSET, |
| XHC_PORTSC3_OFFSET, |
| }; |
| |
| static void usb3h_usb2drd_init(void) |
| { |
| uint32_t val; |
| |
| INFO("USB3H + USB 2DRD init\n"); |
| mmio_clrbits_32(USB3H_U3PHY_CTRL, POR_RESET); |
| val = mmio_read_32(USB3H_PWR_CTRL); |
| val &= ~(0x3U << POWER_CTRL_OVRD); |
| val |= (1U << POWER_CTRL_OVRD); |
| mmio_write_32(USB3H_PWR_CTRL, val); |
| mmio_setbits_32(USB3H_U3PHY_CTRL, PHY_RESET); |
| /* Phy to come out of reset */ |
| udelay(2U); |
| mmio_clrbits_32(USB3H_U3PHY_CTRL, MDIO_RESET); |
| |
| /* MDIO in reset */ |
| udelay(2U); |
| mmio_setbits_32(USB3H_U3PHY_CTRL, MDIO_RESET); |
| |
| /* After MDIO reset release */ |
| udelay(2U); |
| |
| /* USB 3.0 phy Analog Block Initialization */ |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG, |
| USB3_PHY_ANA_BLOCK_BASE); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG0, 0x4646U); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG1, 0x80c9U); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG2, 0x88a6U); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG5, 0x7c12U); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG8, 0x1d07U); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_ANA_REG11, 0x25cU); |
| |
| /* USB 3.0 phy RXPMD Block initialization*/ |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG, |
| USB3_PHY_RXPMD_BLOCK_BASE); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_RXPMD_REG1, 0x4052U); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_RXPMD_REG2, 0x4cU); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_RXPMD_REG5, 0x7U); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_RXPMD_REG7, 0x173U); |
| |
| /* USB 3.0 phy AEQ Block initialization*/ |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG, |
| USB3_PHY_AEQ_BLOCK_BASE); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_AEQ_REG1, 0x3000U); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_AEQ_REG3, 0x2c70U); |
| |
| /* USB 3.0 phy TXPMD Block initialization*/ |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG, |
| USB3_PHY_TXPMD_BLOCK_BASE); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_TXPMD_REG1, 0x100fU); |
| mdio_write(MDIO_BUS_ID, USB3H_PHY_ID, USB3_PHY_TXPMD_REG2, 0x238cU); |
| } |
| |
| static void usb3drd_init(void) |
| { |
| uint32_t val; |
| |
| INFO("USB3DRD init\n"); |
| mmio_clrbits_32(DRDU3_U3PHY_CTRL, POR_RESET); |
| val = mmio_read_32(DRDU3_PWR_CTRL); |
| val &= ~(0x3U << POWER_CTRL_OVRD); |
| val |= (1U << POWER_CTRL_OVRD); |
| mmio_write_32(DRDU3_PWR_CTRL, val); |
| mmio_setbits_32(DRDU3_U3PHY_CTRL, PHY_RESET); |
| /* Phy to come out of reset */ |
| udelay(2U); |
| mmio_clrbits_32(DRDU3_U3PHY_CTRL, MDIO_RESET); |
| |
| /* MDIO in reset */ |
| udelay(2U); |
| mmio_setbits_32(DRDU3_U3PHY_CTRL, MDIO_RESET); |
| |
| /* After MDIO reset release */ |
| udelay(2U); |
| |
| /* USB 3.0 DRD phy Analog Block Initialization */ |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG, |
| USB3_PHY_ANA_BLOCK_BASE); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG0, 0x4646U); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG1, 0x80c9U); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG2, 0x88a6U); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG5, 0x7c12U); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG8, 0x1d07U); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_ANA_REG11, 0x25cU); |
| |
| /* USB 3.0 DRD phy RXPMD Block initialization*/ |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG, |
| USB3_PHY_RXPMD_BLOCK_BASE); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_RXPMD_REG1, 0x4052U); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_RXPMD_REG2, 0x4cU); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_RXPMD_REG5, 0x7U); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_RXPMD_REG7, 0x173U); |
| |
| /* USB 3.0 DRD phy AEQ Block initialization*/ |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG, |
| USB3_PHY_AEQ_BLOCK_BASE); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_AEQ_REG1, 0x3000U); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_AEQ_REG3, 0x2c70U); |
| |
| /* USB 3.0 DRD phy TXPMD Block initialization*/ |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_MDIO_BLOCK_BASE_REG, |
| USB3_PHY_TXPMD_BLOCK_BASE); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_TXPMD_REG1, 0x100fU); |
| mdio_write(MDIO_BUS_ID, USB3DRD_PHY_ID, USB3_PHY_TXPMD_REG2, 0x238cU); |
| } |
| |
| static void usb3_phy_init(void) |
| { |
| usb_pm_rescal_init(); |
| |
| if ((usb_func & USB3H_USB2DRD) != 0U) { |
| usb3h_usb2drd_init(); |
| } |
| |
| if ((usb_func & USB3_DRD) != 0U) { |
| usb3drd_init(); |
| } |
| } |
| |
| #ifdef USB_DMA_COHERENT |
| void usb_enable_coherence(void) |
| { |
| if (usb_func & USB3H_USB2DRD) { |
| mmio_setbits_32(USB3H_SOFT_RESET_CTRL, |
| USB3H_XHC_AXI_SOFT_RST_N); |
| mmio_setbits_32(DRDU2_SOFT_RESET_CTRL, |
| DRDU2_BDC_AXI_SOFT_RST_N); |
| mmio_setbits_32(USB3H_U3PHY_CTRL, USB3H_U3SOFT_RST_N); |
| mmio_setbits_32(DRDU2_PHY_CTRL, DRDU2_U2SOFT_RST_N); |
| |
| mmio_clrsetbits_32(DRD2U3H_XHC_REGS_AXIWRA, |
| (USBAXIWR_UA_MASK | USBAXIWR_SA_MASK), |
| (USBAXIWR_UA_VAL | USBAXIWR_SA_VAL)); |
| |
| mmio_clrsetbits_32(DRD2U3H_XHC_REGS_AXIRDA, |
| (USBAXIRD_UA_MASK | USBAXIRD_SA_MASK), |
| (USBAXIRD_UA_VAL | USBAXIRD_SA_VAL)); |
| |
| mmio_clrsetbits_32(DRDU2D_BDC_REGS_AXIWRA, |
| (USBAXIWR_UA_MASK | USBAXIWR_SA_MASK), |
| (USBAXIWR_UA_VAL | USBAXIWR_SA_VAL)); |
| |
| mmio_clrsetbits_32(DRDU2D_BDC_REGS_AXIRDA, |
| (USBAXIRD_UA_MASK | USBAXIRD_SA_MASK), |
| (USBAXIRD_UA_VAL | USBAXIRD_SA_VAL)); |
| |
| } |
| |
| if (usb_func & USB3_DRD) { |
| mmio_setbits_32(DRDU3_SOFT_RESET_CTRL, |
| (DRDU3_XHC_AXI_SOFT_RST_N | |
| DRDU3_BDC_AXI_SOFT_RST_N)); |
| mmio_setbits_32(DRDU3_U3PHY_CTRL, |
| (DRDU3_U3XHC_SOFT_RST_N | |
| DRDU3_U3BDC_SOFT_RST_N)); |
| |
| mmio_clrsetbits_32(DRDU3H_XHC_REGS_AXIWRA, |
| (USBAXIWR_UA_MASK | USBAXIWR_SA_MASK), |
| (USBAXIWR_UA_VAL | USBAXIWR_SA_VAL)); |
| |
| mmio_clrsetbits_32(DRDU3H_XHC_REGS_AXIRDA, |
| (USBAXIRD_UA_MASK | USBAXIRD_SA_MASK), |
| (USBAXIRD_UA_VAL | USBAXIRD_SA_VAL)); |
| |
| mmio_clrsetbits_32(DRDU3D_BDC_REGS_AXIWRA, |
| (USBAXIWR_UA_MASK | USBAXIWR_SA_MASK), |
| (USBAXIWR_UA_VAL | USBAXIWR_SA_VAL)); |
| |
| mmio_clrsetbits_32(DRDU3D_BDC_REGS_AXIRDA, |
| (USBAXIRD_UA_MASK | USBAXIRD_SA_MASK), |
| (USBAXIRD_UA_VAL | USBAXIRD_SA_VAL)); |
| } |
| } |
| #endif |
| |
| void xhci_phy_init(void) |
| { |
| uint32_t val; |
| |
| INFO("usb init start\n"); |
| mmio_setbits_32(CDRU_MISC_CLK_ENABLE_CONTROL, |
| CDRU_MISC_CLK_USBSS); |
| |
| mmio_setbits_32(CDRU_MISC_RESET_CONTROL, CDRU_USBSS_RESET_N); |
| |
| if (usb_func & USB3_DRD) { |
| VERBOSE(" - configure stream_id = 0x6800 for DRDU3\n"); |
| val = SR_SID_VAL(0x3U, 0x1U, 0x0U) << ICFG_USB_SID_SHIFT; |
| mmio_write_32(ICFG_DRDU3_SID_CTRL + ICFG_USB_SID_AWADDR_OFFSET, |
| val); |
| mmio_write_32(ICFG_DRDU3_SID_CTRL + ICFG_USB_SID_ARADDR_OFFSET, |
| val); |
| |
| /* |
| * DRDU3 Device USB Space, DRDU3 Host USB Space, |
| * DRDU3 SS Config |
| */ |
| mmio_setbits_32(USBIC_GPV_SECURITY10, |
| USBIC_GPV_SECURITY10_FIELD); |
| } |
| |
| if (usb_func & USB3H_USB2DRD) { |
| VERBOSE(" - configure stream_id = 0x6801 for USB3H\n"); |
| val = SR_SID_VAL(0x3U, 0x1U, 0x1U) << ICFG_USB_SID_SHIFT; |
| mmio_write_32(ICFG_USB3H_SID_CTRL + ICFG_USB_SID_AWADDR_OFFSET, |
| val); |
| mmio_write_32(ICFG_USB3H_SID_CTRL + ICFG_USB_SID_ARADDR_OFFSET, |
| val); |
| |
| VERBOSE(" - configure stream_id = 0x6802 for DRDU2\n"); |
| val = SR_SID_VAL(0x3U, 0x1U, 0x2U) << ICFG_USB_SID_SHIFT; |
| mmio_write_32(ICFG_DRDU2_SID_CTRL + ICFG_USB_SID_AWADDR_OFFSET, |
| val); |
| mmio_write_32(ICFG_DRDU2_SID_CTRL + ICFG_USB_SID_ARADDR_OFFSET, |
| val); |
| |
| /* DRDU2 APB Bridge:DRDU2 USB Device, USB3H SS Config */ |
| mmio_setbits_32(USBIC_GPV_SECURITY1, USBIC_GPV_SECURITY1_FIELD); |
| |
| /* |
| * USB3H APB Bridge:DRDU2 Host + USB3 Host USB Space, |
| * USB3H SS Config |
| */ |
| mmio_setbits_32(USBIC_GPV_SECURITY2, USBIC_GPV_SECURITY2_FIELD); |
| } |
| |
| /* Configure Host masters as non-Secure */ |
| mmio_setbits_32(USBSS_TZPCDECPROT0set, USBSS_TZPCDECPROT0); |
| |
| /* CCN Slave on USBIC */ |
| mmio_setbits_32(USBIC_GPV_SECURITY0, USBIC_GPV_SECURITY0_FIELD); |
| |
| /* SLAVE_8:IDM Register Space */ |
| mmio_setbits_32(USBIC_GPV_SECURITY4, USBIC_GPV_SECURITY4_FIELD); |
| |
| usb3_phy_init(); |
| #ifdef USB_DMA_COHERENT |
| usb_enable_coherence(); |
| #endif |
| |
| usb_device_init(usb_func); |
| |
| INFO("PLAT USB: init done.\n"); |
| } |