tegra: Clean up USB code
Pull out the common usb setup utmip functions from t124 into tegra usb.h. These can be reused for t132 as well. BUG=chrome-os-partner:31293 BRANCH=None TEST=Compiles successfully for nyan, big and blaze Change-Id: Idddd40e409b56875436db6918d05f2889d83870b Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 12f12cb30a033cce645f53457d13a987aeec22a1 Original-Change-Id: I83f83bafad0f52ad651fe5989430f41142803f2b Original-Signed-off-by: Furquan Shaikh <furquan@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/211200 Original-Tested-by: Furquan Shaikh <furquan@chromium.org> Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Original-Commit-Queue: Furquan Shaikh <furquan@chromium.org> Reviewed-on: http://review.coreboot.org/8927 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
6941b77c87
commit
2296774af6
|
@ -29,7 +29,7 @@
|
||||||
#include <soc/nvidia/tegra124/mc.h>
|
#include <soc/nvidia/tegra124/mc.h>
|
||||||
#include <soc/nvidia/tegra124/pmc.h>
|
#include <soc/nvidia/tegra124/pmc.h>
|
||||||
#include <soc/nvidia/tegra124/spi.h>
|
#include <soc/nvidia/tegra124/spi.h>
|
||||||
#include <soc/nvidia/tegra124/usb.h>
|
#include <soc/nvidia/tegra/usb.h>
|
||||||
#include <vendorcode/google/chromeos/chromeos.h>
|
#include <vendorcode/google/chromeos/chromeos.h>
|
||||||
|
|
||||||
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
|
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
|
||||||
|
@ -232,9 +232,9 @@ static void mainboard_init(device_t dev)
|
||||||
CLK_X_AFC2 | CLK_X_AFC3 | CLK_X_AFC4 |
|
CLK_X_AFC2 | CLK_X_AFC3 | CLK_X_AFC4 |
|
||||||
CLK_X_AFC5);
|
CLK_X_AFC5);
|
||||||
|
|
||||||
usb_setup_utmip1();
|
usb_setup_utmip((void*)TEGRA_USBD_BASE);
|
||||||
/* USB2 is the camera, we don't need it in firmware */
|
/* USB2 is the camera, we don't need it in firmware */
|
||||||
usb_setup_utmip3();
|
usb_setup_utmip((void*)TEGRA_USB3_BASE);
|
||||||
|
|
||||||
setup_pinmux();
|
setup_pinmux();
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include <soc/nvidia/tegra124/mc.h>
|
#include <soc/nvidia/tegra124/mc.h>
|
||||||
#include <soc/nvidia/tegra124/pmc.h>
|
#include <soc/nvidia/tegra124/pmc.h>
|
||||||
#include <soc/nvidia/tegra124/spi.h>
|
#include <soc/nvidia/tegra124/spi.h>
|
||||||
#include <soc/nvidia/tegra124/usb.h>
|
#include <soc/nvidia/tegra/usb.h>
|
||||||
#include <vendorcode/google/chromeos/chromeos.h>
|
#include <vendorcode/google/chromeos/chromeos.h>
|
||||||
|
|
||||||
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
|
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
|
||||||
|
@ -230,9 +230,9 @@ static void mainboard_init(device_t dev)
|
||||||
CLK_X_AFC2 | CLK_X_AFC3 | CLK_X_AFC4 |
|
CLK_X_AFC2 | CLK_X_AFC3 | CLK_X_AFC4 |
|
||||||
CLK_X_AFC5);
|
CLK_X_AFC5);
|
||||||
|
|
||||||
usb_setup_utmip1();
|
usb_setup_utmip((void*)TEGRA_USBD_BASE);
|
||||||
/* USB2 is the camera, we don't need it in firmware */
|
/* USB2 is the camera, we don't need it in firmware */
|
||||||
usb_setup_utmip3();
|
usb_setup_utmip((void*)TEGRA_USB3_BASE);
|
||||||
|
|
||||||
setup_pinmux();
|
setup_pinmux();
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include <soc/nvidia/tegra124/mc.h>
|
#include <soc/nvidia/tegra124/mc.h>
|
||||||
#include <soc/nvidia/tegra124/pmc.h>
|
#include <soc/nvidia/tegra124/pmc.h>
|
||||||
#include <soc/nvidia/tegra124/spi.h>
|
#include <soc/nvidia/tegra124/spi.h>
|
||||||
#include <soc/nvidia/tegra124/usb.h>
|
#include <soc/nvidia/tegra/usb.h>
|
||||||
#include <vendorcode/google/chromeos/chromeos.h>
|
#include <vendorcode/google/chromeos/chromeos.h>
|
||||||
|
|
||||||
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
|
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
|
||||||
|
@ -230,9 +230,9 @@ static void mainboard_init(device_t dev)
|
||||||
CLK_X_AFC2 | CLK_X_AFC3 | CLK_X_AFC4 |
|
CLK_X_AFC2 | CLK_X_AFC3 | CLK_X_AFC4 |
|
||||||
CLK_X_AFC5);
|
CLK_X_AFC5);
|
||||||
|
|
||||||
usb_setup_utmip1();
|
usb_setup_utmip((void*)TEGRA_USBD_BASE);
|
||||||
usb_setup_utmip2();
|
usb_setup_utmip((void*)TEGRA_USB2_BASE);
|
||||||
usb_setup_utmip3();
|
usb_setup_utmip((void*)TEGRA_USB3_BASE);
|
||||||
|
|
||||||
setup_pinmux();
|
setup_pinmux();
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,131 @@
|
||||||
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
/* Assume USBx clocked, out of reset, UTMI+ PLL set up, SAMP_x out of pwrdn */
|
struct utmip_ctlr {
|
||||||
void usb_setup_utmip(struct usb_ctlr *usb)
|
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(void *usb_base)
|
||||||
|
{
|
||||||
|
struct usb_ctlr *usb = (struct usb_ctlr *)usb_base;
|
||||||
|
|
||||||
/* KHz formulas were guessed from U-Boot constants. Formats unclear. */
|
/* KHz formulas were guessed from U-Boot constants. Formats unclear. */
|
||||||
int khz = clock_get_pll_input_khz();
|
int khz = clock_get_pll_input_khz();
|
||||||
|
|
||||||
|
@ -90,32 +212,8 @@ void usb_setup_utmip(struct usb_ctlr *usb)
|
||||||
write32(1 << 12 | /* UTMI+ enable */
|
write32(1 << 12 | /* UTMI+ enable */
|
||||||
0 << 11 | /* UTMI+ reset */
|
0 << 11 | /* UTMI+ reset */
|
||||||
0, &usb->suspend_ctrl);
|
0, &usb->suspend_ctrl);
|
||||||
|
|
||||||
|
usb_ehci_reset_and_prepare(usb, USB_PHY_UTMIP);
|
||||||
|
printk(BIOS_DEBUG, "USB controller @ %p set up with UTMI+ PHY\n",usb_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 */
|
|
||||||
}
|
|
||||||
|
|
|
@ -22,95 +22,6 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#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] */
|
enum usb_phy_type { /* For use in lpm_ctrl[31:29] */
|
||||||
USB_PHY_UTMIP = 0,
|
USB_PHY_UTMIP = 0,
|
||||||
USB_PHY_ULPI = 2,
|
USB_PHY_ULPI = 2,
|
||||||
|
@ -118,6 +29,6 @@ enum usb_phy_type { /* For use in lpm_ctrl[31:29] */
|
||||||
USB_PHY_HSIC = 4,
|
USB_PHY_HSIC = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
void usb_setup_utmip(struct usb_ctlr *usb);
|
void usb_setup_utmip(void *usb_base);
|
||||||
void usb_ehci_reset_and_prepare(struct usb_ctlr *usb, enum usb_phy_type type);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of the coreboot project.
|
|
||||||
*
|
|
||||||
* Copyright 2013, Google Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SOC_NVIDIA_TEGRA124_USB_H_
|
|
||||||
#define __SOC_NVIDIA_TEGRA124_USB_H_
|
|
||||||
|
|
||||||
#include <console/console.h>
|
|
||||||
#include <soc/addressmap.h>
|
|
||||||
#include <soc/nvidia/tegra/usb.h>
|
|
||||||
|
|
||||||
static inline void usb_setup_utmip1(void)
|
|
||||||
{
|
|
||||||
struct usb_ctlr *usb = (void *)TEGRA_USBD_BASE;
|
|
||||||
usb_setup_utmip(usb);
|
|
||||||
usb_ehci_reset_and_prepare(usb, USB_PHY_UTMIP);
|
|
||||||
printk(BIOS_DEBUG, "USBD controller set up with UTMI+ PHY\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void usb_setup_utmip2(void)
|
|
||||||
{
|
|
||||||
struct usb_ctlr *usb = (void *)TEGRA_USB2_BASE;
|
|
||||||
usb_setup_utmip(usb);
|
|
||||||
usb_ehci_reset_and_prepare(usb, USB_PHY_UTMIP);
|
|
||||||
printk(BIOS_DEBUG, "USB2 controller set up with UTMI+ PHY\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void usb_setup_utmip3(void)
|
|
||||||
{
|
|
||||||
struct usb_ctlr *usb = (void *)TEGRA_USB3_BASE;
|
|
||||||
usb_setup_utmip(usb);
|
|
||||||
usb_ehci_reset_and_prepare(usb, USB_PHY_UTMIP);
|
|
||||||
printk(BIOS_DEBUG, "USB3 controller set up with UTMI+ PHY\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __SOC_NVIDIA_TEGRA124_USB_H_ */
|
|
Loading…
Reference in New Issue