summaryrefslogtreecommitdiff
path: root/src/soc/nvidia/tegra
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/nvidia/tegra')
-rw-r--r--src/soc/nvidia/tegra/usb.c154
-rw-r--r--src/soc/nvidia/tegra/usb.h93
2 files changed, 128 insertions, 119 deletions
diff --git a/src/soc/nvidia/tegra/usb.c b/src/soc/nvidia/tegra/usb.c
index e0455ed05c..3268ee1a74 100644
--- a/src/soc/nvidia/tegra/usb.c
+++ b/src/soc/nvidia/tegra/usb.c
@@ -24,9 +24,131 @@
#include "usb.h"
+struct utmip_ctlr {
+ u32 pll0;
+ u32 pll1;
+ u32 xcvr0;
+ u32 bias0;
+ u32 hsrx0;
+ u32 hsrx1;
+ u32 fslsrx0;
+ u32 fslsrx1;
+ u32 tx;
+ u32 misc0;
+ u32 misc1;
+ u32 debounce;
+ u32 batchrgr;
+ u32 spare;
+ u32 xcvr1;
+ u32 bias1;
+ u32 bias_sts;
+ u32 chrgr_debounce;
+ u32 misc_sts;
+ u32 pmc_wakeup;
+};
+check_member(utmip_ctlr, pmc_wakeup, 0x84c - 0x800);
+
+struct usb_ctlr {
+ u32 id;
+ u32 _rsv0;
+ u32 host;
+ u32 device;
+ u32 txbuf; /* 0x010 */
+ u32 rxbuf;
+ u32 _rsv1[58];
+ u16 ehci_caplen; /* 0x100 */
+ u16 ehci_version;
+ u32 ehci_hcsp;
+ u32 ehci_hccp;
+ u32 _rsv2[5];
+ u32 dci_version; /* 0x120 */
+ u32 dcc_params;
+ u32 extsts;
+ u32 extintr;
+ u32 ehci_usbcmd; /* 0x130 */
+ u32 ehci_usbsts;
+ u32 ehci_usbintr;
+ u32 ehci_frindex;
+ u32 _rsv3; /* 0x140 */
+ u32 ehci_periodic_base;
+ u32 ehci_async_base;
+ u32 async_ttsts;
+ u32 burst_size; /* 0x150 */
+ u32 tx_fill_tuning;
+ u32 _rsv4;
+ u32 icusb_ctrl;
+ u32 ulpi_viewport; /* 0x160 */
+ u32 _rsv5[4];
+ u32 ehci_portsc;
+ u32 _rsv6[15];
+ u32 lpm_ctrl;
+ u32 _rsv7[15];
+ u32 otgsc;
+ u32 usb_mode;
+ u32 _rsv8;
+ u32 ep_nak; /* 0x200 */
+ u32 ep_nak_enable;
+ u32 ep_setup;
+ u32 ep_init;
+ u32 ep_deinit;
+ u32 ep_sts;
+ u32 ep_complete;
+ u32 ep_ctrl[16];
+ u32 _rsv9[105];
+ u32 suspend_ctrl; /* 0x400 */
+ u32 vbus_sensors;
+ u32 vbus_wakeup_id;
+ u32 alt_vbus_sts;
+ u32 legacy_ctrl;
+ u32 _rsv10[3];
+ u32 interpacket_delay;
+ u32 _rsv11[27];
+ u32 resume_delay;
+ u32 _rsv12;
+ u32 spare;
+ u32 _rsv13[9];
+ u32 new_ctrl;
+ u32 _rsv14[207];
+ struct utmip_ctlr utmip; /* 0x800 */
+};
+check_member(usb_ctlr, utmip, 0x800);
+
+/*
+ * Tegra EHCI controllers need their usb_mode, lpm_ctrl and tx_fill_tuning
+ * registers initialized after every EHCI reset and before any other actions
+ * (such as Run/Stop bit) are taken. We reset the controller here, set those
+ * registers and rely on the fact that libpayload doesn't reset EHCI controllers
+ * on initialization for whatever weird reason. This is ugly, fragile, and I
+ * really don't like it, but making this work will require an ugly hack one way
+ * or another so we might as well take the path of least resistance for now.
+ */
+static void usb_ehci_reset_and_prepare(struct usb_ctlr *usb, enum usb_phy_type type)
+{
+ int timeout = 1000;
+
+ write32(1 << 1, &usb->ehci_usbcmd); /* Host Controller Reset */
+ /* TODO: Resets are long, find way to parallelize... or just use XHCI */
+ while (--timeout && (read32(&usb->ehci_usbcmd) & 1 << 1))
+ /* wait for HC to reset */;
+
+ if (!timeout) {
+ printk(BIOS_ERR, "ERROR: EHCI(%p) reset timeout", usb);
+ return;
+ }
+
+ /* Controller mode: HOST */
+ write32(3 << 0, &usb->usb_mode);
+ /* Parallel transceiver selct */
+ write32(type << 29, &usb->lpm_ctrl);
+ /* Tx FIFO Burst thresh */
+ write32(0x10 << 16, &usb->tx_fill_tuning);
+}
+
/* Assume USBx clocked, out of reset, UTMI+ PLL set up, SAMP_x out of pwrdn */
-void usb_setup_utmip(struct usb_ctlr *usb)
+void usb_setup_utmip(void *usb_base)
{
+ struct usb_ctlr *usb = (struct usb_ctlr *)usb_base;
+
/* KHz formulas were guessed from U-Boot constants. Formats unclear. */
int khz = clock_get_pll_input_khz();
@@ -90,32 +212,8 @@ void usb_setup_utmip(struct usb_ctlr *usb)
write32(1 << 12 | /* UTMI+ enable */
0 << 11 | /* UTMI+ reset */
0, &usb->suspend_ctrl);
-}
-/*
- * Tegra EHCI controllers need their usb_mode, lpm_ctrl and tx_fill_tuning
- * registers initialized after every EHCI reset and before any other actions
- * (such as Run/Stop bit) are taken. We reset the controller here, set those
- * registers and rely on the fact that libpayload doesn't reset EHCI controllers
- * on initialization for whatever weird reason. This is ugly, fragile, and I
- * really don't like it, but making this work will require an ugly hack one way
- * or another so we might as well take the path of least resistance for now.
- */
-void usb_ehci_reset_and_prepare(struct usb_ctlr *usb, enum usb_phy_type type)
-{
- int timeout = 1000;
-
- write32(1 << 1, &usb->ehci_usbcmd); /* Host Controller Reset */
- /* TODO: Resets are long, find way to parallelize... or just use XHCI */
- while (--timeout && (read32(&usb->ehci_usbcmd) & 1 << 1))
- /* wait for HC to reset */;
-
- if (!timeout) {
- printk(BIOS_ERR, "ERROR: EHCI(%p) reset timeout", usb);
- return;
- }
-
- write32(3 << 0, &usb->usb_mode); /* Controller mode: HOST */
- write32(type << 29, &usb->lpm_ctrl); /* Parallel transceiver selct */
- write32(0x10 << 16, &usb->tx_fill_tuning); /* Tx FIFO Burst thresh */
+ usb_ehci_reset_and_prepare(usb, USB_PHY_UTMIP);
+ printk(BIOS_DEBUG, "USB controller @ %p set up with UTMI+ PHY\n",usb_base);
}
+
diff --git a/src/soc/nvidia/tegra/usb.h b/src/soc/nvidia/tegra/usb.h
index f720c2aab3..9d22b0b867 100644
--- a/src/soc/nvidia/tegra/usb.h
+++ b/src/soc/nvidia/tegra/usb.h
@@ -22,95 +22,6 @@
#include <stdint.h>
-struct utmip_ctlr {
- u32 pll0;
- u32 pll1;
- u32 xcvr0;
- u32 bias0;
- u32 hsrx0;
- u32 hsrx1;
- u32 fslsrx0;
- u32 fslsrx1;
- u32 tx;
- u32 misc0;
- u32 misc1;
- u32 debounce;
- u32 batchrgr;
- u32 spare;
- u32 xcvr1;
- u32 bias1;
- u32 bias_sts;
- u32 chrgr_debounce;
- u32 misc_sts;
- u32 pmc_wakeup;
-};
-check_member(utmip_ctlr, pmc_wakeup, 0x84c - 0x800);
-
-struct usb_ctlr {
- u32 id;
- u32 _rsv0;
- u32 host;
- u32 device;
- u32 txbuf; /* 0x010 */
- u32 rxbuf;
- u32 _rsv1[58];
- u16 ehci_caplen; /* 0x100 */
- u16 ehci_version;
- u32 ehci_hcsp;
- u32 ehci_hccp;
- u32 _rsv2[5];
- u32 dci_version; /* 0x120 */
- u32 dcc_params;
- u32 extsts;
- u32 extintr;
- u32 ehci_usbcmd; /* 0x130 */
- u32 ehci_usbsts;
- u32 ehci_usbintr;
- u32 ehci_frindex;
- u32 _rsv3; /* 0x140 */
- u32 ehci_periodic_base;
- u32 ehci_async_base;
- u32 async_ttsts;
- u32 burst_size; /* 0x150 */
- u32 tx_fill_tuning;
- u32 _rsv4;
- u32 icusb_ctrl;
- u32 ulpi_viewport; /* 0x160 */
- u32 _rsv5[4];
- u32 ehci_portsc;
- u32 _rsv6[15];
- u32 lpm_ctrl;
- u32 _rsv7[15];
- u32 otgsc;
- u32 usb_mode;
- u32 _rsv8;
- u32 ep_nak; /* 0x200 */
- u32 ep_nak_enable;
- u32 ep_setup;
- u32 ep_init;
- u32 ep_deinit;
- u32 ep_sts;
- u32 ep_complete;
- u32 ep_ctrl[16];
- u32 _rsv9[105];
- u32 suspend_ctrl; /* 0x400 */
- u32 vbus_sensors;
- u32 vbus_wakeup_id;
- u32 alt_vbus_sts;
- u32 legacy_ctrl;
- u32 _rsv10[3];
- u32 interpacket_delay;
- u32 _rsv11[27];
- u32 resume_delay;
- u32 _rsv12;
- u32 spare;
- u32 _rsv13[9];
- u32 new_ctrl;
- u32 _rsv14[207];
- struct utmip_ctlr utmip; /* 0x800 */
-};
-check_member(usb_ctlr, utmip, 0x800);
-
enum usb_phy_type { /* For use in lpm_ctrl[31:29] */
USB_PHY_UTMIP = 0,
USB_PHY_ULPI = 2,
@@ -118,6 +29,6 @@ enum usb_phy_type { /* For use in lpm_ctrl[31:29] */
USB_PHY_HSIC = 4,
};
-void usb_setup_utmip(struct usb_ctlr *usb);
-void usb_ehci_reset_and_prepare(struct usb_ctlr *usb, enum usb_phy_type type);
+void usb_setup_utmip(void *usb_base);
+
#endif