Merge branch 'master' of git://git.denx.de/u-boot-usb

This commit is contained in:
Tom Rini 2016-08-11 07:22:55 -04:00
commit 2f1eb66e28
22 changed files with 887 additions and 118 deletions

View File

@ -368,7 +368,7 @@
};
usb3@3100000 {
compatible = "snps,dwc3";
compatible = "fsl,layerscape-dwc3";
reg = <0x3100000 0x10000>;
interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "host";

View File

@ -25,6 +25,7 @@ CONFIG_ETH_DESIGNWARE=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_GENERIC=y
CONFIG_USB_STORAGE=y
CONFIG_USE_PRIVATE_LIBGCC=y

View File

@ -30,3 +30,4 @@ CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_DM_USB=y

View File

@ -30,3 +30,4 @@ CONFIG_FSL_LPUART=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_DM_USB=y

View File

@ -29,3 +29,4 @@ CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_DM_USB=y

View File

@ -30,3 +30,4 @@ CONFIG_FSL_LPUART=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_DM_USB=y

View File

@ -7,6 +7,7 @@
*/
#include <common.h>
#include <dm.h>
#include <usb.h>
#include <net.h>
#include <linux/mii.h>
@ -185,6 +186,7 @@
#define FLAG_TYPE_SITECOM (1U << 3)
#define FLAG_TYPE_SAMSUNG (1U << 4)
#define FLAG_TYPE_LENOVO (1U << 5)
#define FLAG_TYPE_GX3 (1U << 6)
/* local vars */
static const struct {
@ -196,10 +198,18 @@ static const struct {
{7, 0xcc, 0x4c, 0x04, 8},
};
#ifndef CONFIG_DM_ETH
static int curr_eth_dev; /* index for name of next device detected */
#endif
/* driver private */
struct asix_private {
#ifdef CONFIG_DM_ETH
struct ueth_data ueth;
unsigned pkt_cnt;
uint8_t *pkt_data;
uint32_t *pkt_hdr;
#endif
int flags;
int rx_urb_size;
int maxpacketsize;
@ -258,36 +268,32 @@ static int asix_read_cmd(struct ueth_data *dev, u8 cmd, u16 value, u16 index,
return len == size ? 0 : ECOMM;
}
static int asix_read_mac(struct eth_device *eth)
static int asix_read_mac(struct ueth_data *dev, uint8_t *enetaddr)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
u8 buf[ETH_ALEN];
int ret;
asix_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, 6, 6, buf);
debug("asix_read_mac() returning %02x:%02x:%02x:%02x:%02x:%02x\n",
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
ret = asix_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, 6, 6, enetaddr);
if (ret < 0)
debug("Failed to read MAC address: %02x\n", ret);
memcpy(eth->enetaddr, buf, ETH_ALEN);
return 0;
return ret;
}
static int asix_write_mac(struct eth_device *eth)
static int asix_write_mac(struct ueth_data *dev, uint8_t *enetaddr)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
int ret;
ret = asix_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
ETH_ALEN, eth->enetaddr);
ETH_ALEN, enetaddr);
if (ret < 0)
debug("Failed to set MAC address: %02x\n", ret);
return ret;
}
static int asix_basic_reset(struct ueth_data *dev)
static int asix_basic_reset(struct ueth_data *dev,
struct asix_private *dev_priv)
{
struct asix_private *dev_priv = (struct asix_private *)dev->dev_priv;
u8 buf[5];
u16 *tmp16;
u8 *tmp;
@ -386,13 +392,9 @@ static int asix_wait_link(struct ueth_data *dev)
}
}
/*
* Asix callbacks
*/
static int asix_init(struct eth_device *eth, bd_t *bd)
static int asix_init_common(struct ueth_data *dev,
struct asix_private *dev_priv)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
struct asix_private *dev_priv = (struct asix_private *)dev->dev_priv;
u8 buf[2], tmp[5], link_sts;
u16 *tmp16, mode;
@ -410,7 +412,7 @@ static int asix_init(struct eth_device *eth, bd_t *bd)
if (asix_wait_link(dev) != 0) {
/*reset device and try again*/
printf("Reset Ethernet Device\n");
asix_basic_reset(dev);
asix_basic_reset(dev, dev_priv);
if (asix_wait_link(dev) != 0)
goto out_err;
}
@ -462,11 +464,10 @@ out_err:
return -1;
}
static int asix_send(struct eth_device *eth, void *packet, int length)
static int asix_send_common(struct ueth_data *dev,
struct asix_private *dev_priv,
void *packet, int length)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
struct asix_private *dev_priv = (struct asix_private *)dev->dev_priv;
int err;
u32 packet_len, tx_hdr2;
int actual_len, framesize;
@ -503,6 +504,33 @@ static int asix_send(struct eth_device *eth, void *packet, int length)
return err;
}
#ifndef CONFIG_DM_ETH
/*
* Asix callbacks
*/
static int asix_init(struct eth_device *eth, bd_t *bd)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
struct asix_private *dev_priv = (struct asix_private *)dev->dev_priv;
return asix_init_common(dev, dev_priv);
}
static int asix_write_hwaddr(struct eth_device *eth)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
return asix_write_mac(dev, eth->enetaddr);
}
static int asix_send(struct eth_device *eth, void *packet, int length)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
struct asix_private *dev_priv = (struct asix_private *)dev->dev_priv;
return asix_send_common(dev, dev_priv, packet, length);
}
static int asix_recv(struct eth_device *eth)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
@ -542,7 +570,7 @@ static int asix_recv(struct eth_device *eth)
rx_hdr = *(u32 *)(recv_buf + actual_len - 4);
le32_to_cpus(&pkt_hdr);
le32_to_cpus(&rx_hdr);
pkt_cnt = (u16)rx_hdr;
hdr_off = (u16)(rx_hdr >> 16);
@ -596,6 +624,7 @@ static const struct asix_dongle asix_dongles[] = {
{ 0x0df6, 0x0072, FLAG_TYPE_SITECOM },
{ 0x04e8, 0xa100, FLAG_TYPE_SAMSUNG },
{ 0x17ef, 0x304b, FLAG_TYPE_LENOVO },
{ 0x04b4, 0x3610, FLAG_TYPE_GX3 },
{ 0x0000, 0x0000, FLAG_NONE } /* END - Do not remove */
};
@ -691,6 +720,8 @@ int ax88179_eth_probe(struct usb_device *dev, unsigned int ifnum,
int ax88179_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
struct eth_device *eth)
{
struct asix_private *dev_priv = (struct asix_private *)ss->dev_priv;
if (!eth) {
debug("%s: missing parameter.\n", __func__);
return 0;
@ -700,16 +731,190 @@ int ax88179_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
eth->send = asix_send;
eth->recv = asix_recv;
eth->halt = asix_halt;
eth->write_hwaddr = asix_write_mac;
eth->write_hwaddr = asix_write_hwaddr;
eth->priv = ss;
if (asix_basic_reset(ss))
if (asix_basic_reset(ss, dev_priv))
return 0;
/* Get the MAC address */
if (asix_read_mac(eth))
if (asix_read_mac(ss, eth->enetaddr))
return 0;
debug("MAC %pM\n", eth->enetaddr);
return 1;
}
#else /* !CONFIG_DM_ETH */
static int ax88179_eth_start(struct udevice *dev)
{
struct asix_private *priv = dev_get_priv(dev);
return asix_init_common(&priv->ueth, priv);
}
void ax88179_eth_stop(struct udevice *dev)
{
struct asix_private *priv = dev_get_priv(dev);
struct ueth_data *ueth = &priv->ueth;
debug("** %s()\n", __func__);
usb_ether_advance_rxbuf(ueth, -1);
priv->pkt_cnt = 0;
priv->pkt_data = NULL;
priv->pkt_hdr = NULL;
}
int ax88179_eth_send(struct udevice *dev, void *packet, int length)
{
struct asix_private *priv = dev_get_priv(dev);
return asix_send_common(&priv->ueth, priv, packet, length);
}
int ax88179_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct asix_private *priv = dev_get_priv(dev);
struct ueth_data *ueth = &priv->ueth;
int ret, len;
u16 pkt_len;
/* No packet left, get a new one */
if (priv->pkt_cnt == 0) {
uint8_t *ptr;
u16 pkt_cnt;
u16 hdr_off;
u32 rx_hdr;
len = usb_ether_get_rx_bytes(ueth, &ptr);
debug("%s: first try, len=%d\n", __func__, len);
if (!len) {
if (!(flags & ETH_RECV_CHECK_DEVICE))
return -EAGAIN;
ret = usb_ether_receive(ueth, priv->rx_urb_size);
if (ret < 0)
return ret;
len = usb_ether_get_rx_bytes(ueth, &ptr);
debug("%s: second try, len=%d\n", __func__, len);
}
if (len < 4) {
usb_ether_advance_rxbuf(ueth, -1);
return -EMSGSIZE;
}
rx_hdr = *(u32 *)(ptr + len - 4);
le32_to_cpus(&rx_hdr);
pkt_cnt = (u16)rx_hdr;
if (pkt_cnt == 0) {
usb_ether_advance_rxbuf(ueth, -1);
return 0;
}
hdr_off = (u16)(rx_hdr >> 16);
if (hdr_off > len - 4) {
usb_ether_advance_rxbuf(ueth, -1);
return -EIO;
}
priv->pkt_cnt = pkt_cnt;
priv->pkt_data = ptr;
priv->pkt_hdr = (u32 *)(ptr + hdr_off);
debug("%s: %d packets received, pkt header at %d\n",
__func__, (int)priv->pkt_cnt, (int)hdr_off);
}
le32_to_cpus(priv->pkt_hdr);
pkt_len = (*priv->pkt_hdr >> 16) & 0x1fff;
*packetp = priv->pkt_data + 2;
priv->pkt_data += (pkt_len + 7) & 0xFFF8;
priv->pkt_cnt--;
priv->pkt_hdr++;
debug("%s: return packet of %d bytes (%d packets left)\n",
__func__, (int)pkt_len, priv->pkt_cnt);
return pkt_len;
}
static int ax88179_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
{
struct asix_private *priv = dev_get_priv(dev);
struct ueth_data *ueth = &priv->ueth;
if (priv->pkt_cnt == 0)
usb_ether_advance_rxbuf(ueth, -1);
return 0;
}
int ax88179_write_hwaddr(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct asix_private *priv = dev_get_priv(dev);
struct ueth_data *ueth = &priv->ueth;
return asix_write_mac(ueth, pdata->enetaddr);
}
static int ax88179_eth_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct asix_private *priv = dev_get_priv(dev);
struct usb_device *usb_dev;
int ret;
priv->flags = dev->driver_data;
ret = usb_ether_register(dev, &priv->ueth, AX_RX_URB_SIZE);
if (ret)
return ret;
usb_dev = priv->ueth.pusb_dev;
priv->maxpacketsize = usb_dev->epmaxpacketout[AX_ENDPOINT_OUT];
/* Get the MAC address */
ret = asix_read_mac(&priv->ueth, pdata->enetaddr);
if (ret)
return ret;
debug("MAC %pM\n", pdata->enetaddr);
return 0;
}
static const struct eth_ops ax88179_eth_ops = {
.start = ax88179_eth_start,
.send = ax88179_eth_send,
.recv = ax88179_eth_recv,
.free_pkt = ax88179_free_pkt,
.stop = ax88179_eth_stop,
.write_hwaddr = ax88179_write_hwaddr,
};
U_BOOT_DRIVER(ax88179_eth) = {
.name = "ax88179_eth",
.id = UCLASS_ETH,
.probe = ax88179_eth_probe,
.ops = &ax88179_eth_ops,
.priv_auto_alloc_size = sizeof(struct asix_private),
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
};
static const struct usb_device_id ax88179_eth_id_table[] = {
{ USB_DEVICE(0x0b95, 0x1790), .driver_info = FLAG_TYPE_AX88179 },
{ USB_DEVICE(0x0b95, 0x178a), .driver_info = FLAG_TYPE_AX88178a },
{ USB_DEVICE(0x2001, 0x4a00), .driver_info = FLAG_TYPE_DLINK_DUB1312 },
{ USB_DEVICE(0x0df6, 0x0072), .driver_info = FLAG_TYPE_SITECOM },
{ USB_DEVICE(0x04e8, 0xa100), .driver_info = FLAG_TYPE_SAMSUNG },
{ USB_DEVICE(0x17ef, 0x304b), .driver_info = FLAG_TYPE_LENOVO },
{ USB_DEVICE(0x04b4, 0x3610), .driver_info = FLAG_TYPE_GX3 },
{ } /* Terminating entry */
};
U_BOOT_USB_DEVICE(ax88179_eth, ax88179_eth_id_table);
#endif /* !CONFIG_DM_ETH */

View File

@ -3,9 +3,10 @@
*
* SPDX-License-Identifier: GPL-2.0
*
*/
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <usb.h>
@ -15,6 +16,7 @@
#include "usb_ether.h"
#include "r8152.h"
#ifndef CONFIG_DM_ETH
/* local vars */
static int curr_eth_dev; /* index for name of next device detected */
@ -23,12 +25,6 @@ struct r8152_dongle {
unsigned short product;
};
struct r8152_version {
unsigned short tcr;
unsigned short version;
bool gmii;
};
static const struct r8152_dongle const r8152_dongles[] = {
/* Realtek */
{ 0x0bda, 0x8050 },
@ -54,6 +50,13 @@ static const struct r8152_dongle const r8152_dongles[] = {
/* Nvidia */
{ 0x0955, 0x09ff },
};
#endif
struct r8152_version {
unsigned short tcr;
unsigned short version;
bool gmii;
};
static const struct r8152_version const r8152_versions[] = {
{ 0x4c00, RTL_VER_01, 0 },
@ -1176,11 +1179,8 @@ static int rtl_ops_init(struct r8152 *tp)
return ret;
}
static int r8152_init(struct eth_device *eth, bd_t *bd)
static int r8152_init_common(struct r8152 *tp)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
struct r8152 *tp = (struct r8152 *)dev->dev_priv;
u8 speed;
int timeout = 0;
int link_detected;
@ -1210,14 +1210,11 @@ static int r8152_init(struct eth_device *eth, bd_t *bd)
return 0;
}
static int r8152_send(struct eth_device *eth, void *packet, int length)
static int r8152_send_common(struct ueth_data *ueth, void *packet, int length)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
struct usb_device *udev = ueth->pusb_dev;
u32 opts1, opts2 = 0;
int err;
int actual_len;
unsigned char msg[PKTSIZE + sizeof(struct tx_desc)];
struct tx_desc *tx_desc = (struct tx_desc *)msg;
@ -1231,18 +1228,31 @@ static int r8152_send(struct eth_device *eth, void *packet, int length)
memcpy(msg + sizeof(struct tx_desc), (void *)packet, length);
err = usb_bulk_msg(dev->pusb_dev,
usb_sndbulkpipe(dev->pusb_dev, dev->ep_out),
(void *)msg,
length + sizeof(struct tx_desc),
&actual_len,
USB_BULK_SEND_TIMEOUT);
err = usb_bulk_msg(udev, usb_sndbulkpipe(udev, ueth->ep_out),
(void *)msg, length + sizeof(struct tx_desc),
&actual_len, USB_BULK_SEND_TIMEOUT);
debug("Tx: len = %zu, actual = %u, err = %d\n",
length + sizeof(struct tx_desc), actual_len, err);
return err;
}
#ifndef CONFIG_DM_ETH
static int r8152_init(struct eth_device *eth, bd_t *bd)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
struct r8152 *tp = (struct r8152 *)dev->dev_priv;
return r8152_init_common(tp);
}
static int r8152_send(struct eth_device *eth, void *packet, int length)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
return r8152_send_common(dev, packet, length);
}
static int r8152_recv(struct eth_device *eth)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
@ -1454,3 +1464,186 @@ int r8152_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
debug("MAC %pM\n", eth->enetaddr);
return 1;
}
#endif /* !CONFIG_DM_ETH */
#ifdef CONFIG_DM_ETH
static int r8152_eth_start(struct udevice *dev)
{
struct r8152 *tp = dev_get_priv(dev);
debug("** %s (%d)\n", __func__, __LINE__);
return r8152_init_common(tp);
}
void r8152_eth_stop(struct udevice *dev)
{
struct r8152 *tp = dev_get_priv(dev);
debug("** %s (%d)\n", __func__, __LINE__);
tp->rtl_ops.disable(tp);
}
int r8152_eth_send(struct udevice *dev, void *packet, int length)
{
struct r8152 *tp = dev_get_priv(dev);
return r8152_send_common(&tp->ueth, packet, length);
}
int r8152_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct r8152 *tp = dev_get_priv(dev);
struct ueth_data *ueth = &tp->ueth;
uint8_t *ptr;
int ret, len;
struct rx_desc *rx_desc;
u16 packet_len;
len = usb_ether_get_rx_bytes(ueth, &ptr);
debug("%s: first try, len=%d\n", __func__, len);
if (!len) {
if (!(flags & ETH_RECV_CHECK_DEVICE))
return -EAGAIN;
ret = usb_ether_receive(ueth, RTL8152_AGG_BUF_SZ);
if (ret)
return ret;
len = usb_ether_get_rx_bytes(ueth, &ptr);
debug("%s: second try, len=%d\n", __func__, len);
}
rx_desc = (struct rx_desc *)ptr;
packet_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
packet_len -= CRC_SIZE;
if (packet_len > len - (sizeof(struct rx_desc) + CRC_SIZE)) {
debug("Rx: too large packet: %d\n", packet_len);
goto err;
}
*packetp = ptr + sizeof(struct rx_desc);
return packet_len;
err:
usb_ether_advance_rxbuf(ueth, -1);
return -ENOSPC;
}
static int r8152_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
{
struct r8152 *tp = dev_get_priv(dev);
packet_len += sizeof(struct rx_desc) + CRC_SIZE;
packet_len = ALIGN(packet_len, 8);
usb_ether_advance_rxbuf(&tp->ueth, packet_len);
return 0;
}
static int r8152_write_hwaddr(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct r8152 *tp = dev_get_priv(dev);
unsigned char enetaddr[8] = { 0 };
debug("** %s (%d)\n", __func__, __LINE__);
memcpy(enetaddr, pdata->enetaddr, ETH_ALEN);
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG);
pla_ocp_write(tp, PLA_IDR, BYTE_EN_SIX_BYTES, 8, enetaddr);
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
debug("MAC %pM\n", pdata->enetaddr);
return 0;
}
int r8152_read_rom_hwaddr(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct r8152 *tp = dev_get_priv(dev);
debug("** %s (%d)\n", __func__, __LINE__);
r8152_read_mac(tp, pdata->enetaddr);
return 0;
}
static int r8152_eth_probe(struct udevice *dev)
{
struct usb_device *udev = dev_get_parent_priv(dev);
struct eth_pdata *pdata = dev_get_platdata(dev);
struct r8152 *tp = dev_get_priv(dev);
struct ueth_data *ueth = &tp->ueth;
int ret;
tp->udev = udev;
r8152_read_mac(tp, pdata->enetaddr);
r8152b_get_version(tp);
ret = rtl_ops_init(tp);
if (ret)
return ret;
tp->rtl_ops.init(tp);
tp->rtl_ops.up(tp);
rtl8152_set_speed(tp, AUTONEG_ENABLE,
tp->supports_gmii ? SPEED_1000 : SPEED_100,
DUPLEX_FULL);
return usb_ether_register(dev, ueth, RTL8152_AGG_BUF_SZ);
}
static const struct eth_ops r8152_eth_ops = {
.start = r8152_eth_start,
.send = r8152_eth_send,
.recv = r8152_eth_recv,
.free_pkt = r8152_free_pkt,
.stop = r8152_eth_stop,
.write_hwaddr = r8152_write_hwaddr,
.read_rom_hwaddr = r8152_read_rom_hwaddr,
};
U_BOOT_DRIVER(r8152_eth) = {
.name = "r8152_eth",
.id = UCLASS_ETH,
.probe = r8152_eth_probe,
.ops = &r8152_eth_ops,
.priv_auto_alloc_size = sizeof(struct r8152),
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
};
static const struct usb_device_id r8152_eth_id_table[] = {
/* Realtek */
{ USB_DEVICE(0x0bda, 0x8050) },
{ USB_DEVICE(0x0bda, 0x8152) },
{ USB_DEVICE(0x0bda, 0x8153) },
/* Samsung */
{ USB_DEVICE(0x04e8, 0xa101) },
/* Lenovo */
{ USB_DEVICE(0x17ef, 0x304f) },
{ USB_DEVICE(0x17ef, 0x3052) },
{ USB_DEVICE(0x17ef, 0x3054) },
{ USB_DEVICE(0x17ef, 0x3057) },
{ USB_DEVICE(0x17ef, 0x7205) },
{ USB_DEVICE(0x17ef, 0x720a) },
{ USB_DEVICE(0x17ef, 0x720b) },
{ USB_DEVICE(0x17ef, 0x720c) },
/* TP-LINK */
{ USB_DEVICE(0x2357, 0x0601) },
/* Nvidia */
{ USB_DEVICE(0x0955, 0x09ff) },
{ } /* Terminating entry */
};
U_BOOT_USB_DEVICE(r8152_eth, r8152_eth_id_table);
#endif /* CONFIG_DM_ETH */

View File

@ -594,6 +594,10 @@ struct r8152 {
u16 ocp_base;
u8 version;
#ifdef CONFIG_DM_ETH
struct ueth_data ueth;
#endif
};
int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen,

View File

@ -5,7 +5,9 @@
*
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include "usb_ether.h"
#include "r8152.h"
static u8 r8152b_pla_patch_a[] = {

View File

@ -3,8 +3,12 @@
#
comment "USB Host Controller Drivers"
config USB_HOST
bool
config USB_XHCI_HCD
bool "xHCI HCD (USB 3.0) support"
select USB_HOST
---help---
The eXtensible Host Controller Interface (xHCI) is standard for USB 3.0
"SuperSpeed" host controller hardware.
@ -24,18 +28,11 @@ config USB_XHCI_DWC3
Say Y or if your system has a Dual Role SuperSpeed
USB controller based on the DesignWare USB3 IP Core.
endif
config USB_OHCI_GENERIC
bool "Support for generic OHCI USB controller"
depends on OF_CONTROL
depends on DM_USB
default n
---help---
Enables support for generic OHCI controller.
endif # USB_XHCI_HCD
config USB_EHCI_HCD
bool "EHCI HCD (USB 2.0) support"
select USB_HOST
---help---
The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
"high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
@ -116,4 +113,46 @@ config USB_EHCI_GENERIC
---help---
Enables support for generic EHCI controller.
endif
endif # USB_EHCI_HCD
config USB_OHCI_HCD
bool "OHCI HCD (USB 1.1) support"
---help---
The Open Host Controller Interface (OHCI) is a standard for accessing
USB 1.1 host controller hardware. It does more in hardware than Intel's
UHCI specification. If your USB host controller follows the OHCI spec,
say Y. On most non-x86 systems, and on x86 hardware that's not using a
USB controller from Intel or VIA, this is appropriate. If your host
controller doesn't use PCI, this is probably appropriate. For a PCI
based system where you're not sure, the "lspci -v" entry will list the
right "prog-if" for your USB controller(s): EHCI, OHCI, or UHCI.
if USB_OHCI_HCD
config USB_OHCI_GENERIC
bool "Support for generic OHCI USB controller"
depends on OF_CONTROL
depends on DM_USB
select USB_HOST
---help---
Enables support for generic OHCI controller.
endif # USB_OHCI_HCD
config USB_UHCI_HCD
bool "UHCI HCD (most Intel and VIA) support"
select USB_HOST
---help---
The Universal Host Controller Interface is a standard by Intel for
accessing the USB hardware in the PC (which is also called the USB
host controller). If your USB host controller conforms to this
standard, you may want to say Y, but see below. All recent boards
with Intel PCI chipsets (like intel 430TX, 440FX, 440LX, 440BX,
i810, i820) conform to this standard. Also all VIA PCI chipsets
(like VIA VP2, VP3, MVP3, Apollo Pro, Apollo Pro II or Apollo Pro
133) and LEON/GRLIB SoCs with the GRUSBHC controller.
If unsure, say Y.
if USB_UHCI_HCD
endif # USB_UHCI_HCD

View File

@ -1,5 +1,5 @@
/*
* (C) Copyright 2009, 2011 Freescale Semiconductor, Inc.
* (C) Copyright 2009, 2011, 2016 Freescale Semiconductor, Inc.
*
* (C) Copyright 2008, Excito Elektronik i Sk=E5ne AB
*
@ -16,14 +16,32 @@
#include <hwconfig.h>
#include <fsl_usb.h>
#include <fdt_support.h>
#include <dm.h>
#include "ehci.h"
DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#endif
#ifdef CONFIG_DM_USB
struct ehci_fsl_priv {
struct ehci_ctrl ehci;
fdt_addr_t hcd_base;
char *phy_type;
};
#endif
static void set_txfifothresh(struct usb_ehci *, u32);
#ifdef CONFIG_DM_USB
static int ehci_fsl_init(struct ehci_fsl_priv *priv, struct usb_ehci *ehci,
struct ehci_hccr *hccr, struct ehci_hcor *hcor);
#else
static int ehci_fsl_init(int index, struct usb_ehci *ehci,
struct ehci_hccr *hccr, struct ehci_hcor *hcor);
#endif
/* Check USB PHY clock valid */
static int usb_phy_clk_valid(struct usb_ehci *ehci)
@ -37,6 +55,99 @@ static int usb_phy_clk_valid(struct usb_ehci *ehci)
}
}
#ifdef CONFIG_DM_USB
static int ehci_fsl_ofdata_to_platdata(struct udevice *dev)
{
struct ehci_fsl_priv *priv = dev_get_priv(dev);
const void *prop;
prop = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy_type",
NULL);
if (prop) {
priv->phy_type = (char *)prop;
debug("phy_type %s\n", priv->phy_type);
}
return 0;
}
static int ehci_fsl_init_after_reset(struct ehci_ctrl *ctrl)
{
struct usb_ehci *ehci = NULL;
struct ehci_fsl_priv *priv = container_of(ctrl, struct ehci_fsl_priv,
ehci);
ehci = (struct usb_ehci *)priv->hcd_base;
if (ehci_fsl_init(priv, ehci, priv->ehci.hccr, priv->ehci.hcor) < 0)
return -ENXIO;
return 0;
}
static const struct ehci_ops fsl_ehci_ops = {
.init_after_reset = ehci_fsl_init_after_reset,
};
static int ehci_fsl_probe(struct udevice *dev)
{
struct ehci_fsl_priv *priv = dev_get_priv(dev);
struct usb_ehci *ehci = NULL;
struct ehci_hccr *hccr;
struct ehci_hcor *hcor;
/*
* Get the base address for EHCI controller from the device node
*/
priv->hcd_base = dev_get_addr(dev);
if (priv->hcd_base == FDT_ADDR_T_NONE) {
debug("Can't get the EHCI register base address\n");
return -ENXIO;
}
ehci = (struct usb_ehci *)priv->hcd_base;
hccr = (struct ehci_hccr *)(&ehci->caplength);
hcor = (struct ehci_hcor *)
((u32)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
if (ehci_fsl_init(priv, ehci, hccr, hcor) < 0)
return -ENXIO;
debug("ehci-fsl: init hccr %x and hcor %x hc_length %d\n",
(u32)hccr, (u32)hcor,
(u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
return ehci_register(dev, hccr, hcor, &fsl_ehci_ops, 0, USB_INIT_HOST);
}
static int ehci_fsl_remove(struct udevice *dev)
{
int ret;
ret = ehci_deregister(dev);
if (ret)
return ret;
return 0;
}
static const struct udevice_id ehci_usb_ids[] = {
{ .compatible = "fsl-usb2-mph", },
{ .compatible = "fsl-usb2-dr", },
{ }
};
U_BOOT_DRIVER(ehci_fsl) = {
.name = "ehci_fsl",
.id = UCLASS_USB,
.of_match = ehci_usb_ids,
.ofdata_to_platdata = ehci_fsl_ofdata_to_platdata,
.probe = ehci_fsl_probe,
.remove = ehci_fsl_remove,
.ops = &ehci_usb_ops,
.platdata_auto_alloc_size = sizeof(struct usb_platdata),
.priv_auto_alloc_size = sizeof(struct ehci_fsl_priv),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
#else
/*
* Create the appropriate control structures to manage
* a new EHCI host controller.
@ -47,26 +158,6 @@ int ehci_hcd_init(int index, enum usb_init_type init,
struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
struct usb_ehci *ehci = NULL;
const char *phy_type = NULL;
size_t len;
char current_usb_controller[5];
#ifdef CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
char usb_phy[5];
usb_phy[0] = '\0';
#endif
if (has_erratum_a007075()) {
/*
* A 5ms delay is needed after applying soft-reset to the
* controller to let external ULPI phy come out of reset.
* This delay needs to be added before re-initializing
* the controller after soft-resetting completes
*/
mdelay(5);
}
memset(current_usb_controller, '\0', 5);
snprintf(current_usb_controller, sizeof(current_usb_controller),
"usb%d", index+1);
switch (index) {
case 0:
@ -84,6 +175,47 @@ int ehci_hcd_init(int index, enum usb_init_type init,
*hcor = (struct ehci_hcor *)((uint32_t) *hccr +
HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
return ehci_fsl_init(index, ehci, *hccr, *hcor);
}
/*
* Destroy the appropriate control structures corresponding
* the the EHCI host controller.
*/
int ehci_hcd_stop(int index)
{
return 0;
}
#endif
#ifdef CONFIG_DM_USB
static int ehci_fsl_init(struct ehci_fsl_priv *priv, struct usb_ehci *ehci,
struct ehci_hccr *hccr, struct ehci_hcor *hcor)
#else
static int ehci_fsl_init(int index, struct usb_ehci *ehci,
struct ehci_hccr *hccr, struct ehci_hcor *hcor)
#endif
{
const char *phy_type = NULL;
#ifndef CONFIG_DM_USB
size_t len;
char current_usb_controller[5];
#endif
#ifdef CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
char usb_phy[5];
usb_phy[0] = '\0';
#endif
if (has_erratum_a007075()) {
/*
* A 5ms delay is needed after applying soft-reset to the
* controller to let external ULPI phy come out of reset.
* This delay needs to be added before re-initializing
* the controller after soft-resetting completes
*/
mdelay(5);
}
/* Set to Host mode */
setbits_le32(&ehci->usbmode, CM_HOST);
@ -91,9 +223,18 @@ int ehci_hcd_init(int index, enum usb_init_type init,
out_be32(&ehci->snoop2, 0x80000000 | SNOOP_SIZE_2GB);
/* Init phy */
#ifdef CONFIG_DM_USB
if (priv->phy_type)
phy_type = priv->phy_type;
#else
memset(current_usb_controller, '\0', 5);
snprintf(current_usb_controller, sizeof(current_usb_controller),
"usb%d", index+1);
if (hwconfig_sub(current_usb_controller, "phy_type"))
phy_type = hwconfig_subarg(current_usb_controller,
"phy_type", &len);
#endif
else
phy_type = getenv("usb_phy_type");
@ -116,7 +257,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
UTMI_PHY_EN);
udelay(1000); /* delay required for PHY Clk to appear */
#endif
out_le32(&(*hcor)->or_portsc[0], PORT_PTS_UTMI);
out_le32(&(hcor)->or_portsc[0], PORT_PTS_UTMI);
clrsetbits_be32(&ehci->control, CONTROL_REGISTER_W1C_MASK,
USB_EN);
} else {
@ -127,7 +268,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
udelay(1000); /* delay required for PHY Clk to appear */
if (!usb_phy_clk_valid(ehci))
return -EINVAL;
out_le32(&(*hcor)->or_portsc[0], PORT_PTS_ULPI);
out_le32(&(hcor)->or_portsc[0], PORT_PTS_ULPI);
}
out_be32(&ehci->prictrl, 0x0000000c);
@ -152,15 +293,6 @@ int ehci_hcd_init(int index, enum usb_init_type init,
return 0;
}
/*
* Destroy the appropriate control structures corresponding
* the the EHCI host controller.
*/
int ehci_hcd_stop(int index)
{
return 0;
}
/*
* Setting the value of TXFIFO_THRESH field in TXFILLTUNING register
* to counter DDR latencies in writing data into Tx buffer.

View File

@ -15,6 +15,7 @@
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>
#include <asm/imx-common/iomux-v3.h>
#include <dm.h>
#include "ehci.h"
@ -307,21 +308,10 @@ int __weak board_ehci_power(int port, int on)
return 0;
}
int ehci_hcd_init(int index, enum usb_init_type init,
struct ehci_hccr **hccr, struct ehci_hcor **hcor)
int ehci_mx6_common_init(struct usb_ehci *ehci, int index)
{
enum usb_init_type type;
#if defined(CONFIG_MX6)
u32 controller_spacing = 0x200;
#elif defined(CONFIG_MX7)
u32 controller_spacing = 0x10000;
#endif
struct usb_ehci *ehci = (struct usb_ehci *)(USB_BASE_ADDR +
(controller_spacing * index));
int ret;
if (index > 3)
return -EINVAL;
enable_usboh3_clk(1);
mdelay(1);
@ -337,11 +327,38 @@ int ehci_hcd_init(int index, enum usb_init_type init,
usb_internal_phy_clock_gate(index, 1);
usb_phy_enable(index, ehci);
#endif
return 0;
}
#ifndef CONFIG_DM_USB
int ehci_hcd_init(int index, enum usb_init_type init,
struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
enum usb_init_type type;
#if defined(CONFIG_MX6)
u32 controller_spacing = 0x200;
#elif defined(CONFIG_MX7)
u32 controller_spacing = 0x10000;
#endif
struct usb_ehci *ehci = (struct usb_ehci *)(USB_BASE_ADDR +
(controller_spacing * index));
int ret;
if (index > 3)
return -EINVAL;
ret = ehci_mx6_common_init(ehci, index);
if (ret)
return ret;
type = board_usb_phy_mode(index);
*hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
*hcor = (struct ehci_hcor *)((uint32_t)*hccr +
HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
if (hccr && hcor) {
*hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
*hcor = (struct ehci_hcor *)((uint32_t)*hccr +
HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
}
if ((type == init) || (type == USB_INIT_DEVICE))
board_ehci_power(index, (type == USB_INIT_DEVICE) ? 0 : 1);
@ -363,3 +380,102 @@ int ehci_hcd_stop(int index)
{
return 0;
}
#else
struct ehci_mx6_priv_data {
struct ehci_ctrl ctrl;
struct usb_ehci *ehci;
enum usb_init_type init_type;
int portnr;
};
static int mx6_init_after_reset(struct ehci_ctrl *dev)
{
struct ehci_mx6_priv_data *priv = dev->priv;
enum usb_init_type type = priv->init_type;
struct usb_ehci *ehci = priv->ehci;
int ret;
ret = ehci_mx6_common_init(priv->ehci, priv->portnr);
if (ret)
return ret;
board_ehci_power(priv->portnr, (type == USB_INIT_DEVICE) ? 0 : 1);
if (type == USB_INIT_DEVICE)
return 0;
setbits_le32(&ehci->usbmode, CM_HOST);
writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
setbits_le32(&ehci->portsc, USB_EN);
mdelay(10);
return 0;
}
static const struct ehci_ops mx6_ehci_ops = {
.init_after_reset = mx6_init_after_reset
};
static int ehci_usb_probe(struct udevice *dev)
{
struct usb_platdata *plat = dev_get_platdata(dev);
struct usb_ehci *ehci = (struct usb_ehci *)dev_get_addr(dev);
struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
struct ehci_hccr *hccr;
struct ehci_hcor *hcor;
int ret;
priv->ehci = ehci;
priv->portnr = dev->seq;
priv->init_type = plat->init_type;
ret = ehci_mx6_common_init(ehci, priv->portnr);
if (ret)
return ret;
board_ehci_power(priv->portnr, (priv->init_type == USB_INIT_DEVICE) ? 0 : 1);
if (priv->init_type == USB_INIT_HOST) {
setbits_le32(&ehci->usbmode, CM_HOST);
writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
setbits_le32(&ehci->portsc, USB_EN);
}
mdelay(10);
hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
hcor = (struct ehci_hcor *)((uint32_t)hccr +
HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
return ehci_register(dev, hccr, hcor, &mx6_ehci_ops, 0, priv->init_type);
}
static int ehci_usb_remove(struct udevice *dev)
{
int ret;
ret = ehci_deregister(dev);
if (ret)
return ret;
return 0;
}
static const struct udevice_id mx6_usb_ids[] = {
{ .compatible = "fsl,imx27-usb" },
{ }
};
U_BOOT_DRIVER(usb_mx6) = {
.name = "ehci_mx6",
.id = UCLASS_USB,
.of_match = mx6_usb_ids,
.probe = ehci_usb_probe,
.remove = ehci_usb_remove,
.ops = &ehci_usb_ops,
.platdata_auto_alloc_size = sizeof(struct usb_platdata),
.priv_auto_alloc_size = sizeof(struct ehci_mx6_priv_data),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 Freescale Semiconductor, Inc.
* Copyright 2015,2016 Freescale Semiconductor, Inc.
*
* FSL USB HOST xHCI Controller
*
@ -17,12 +17,21 @@
#include "xhci.h"
#include <fsl_errata.h>
#include <fsl_usb.h>
#include <dm.h>
/* Declare global data pointer */
DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_DM_USB
static struct fsl_xhci fsl_xhci;
unsigned long ctr_addr[] = FSL_USB_XHCI_ADDR;
#else
struct xhci_fsl_priv {
struct xhci_ctrl xhci;
fdt_addr_t hcd_base;
struct fsl_xhci ctx;
};
#endif
__weak int __board_usb_init(int index, enum usb_init_type init)
{
@ -77,6 +86,77 @@ static int fsl_xhci_core_exit(struct fsl_xhci *fsl_xhci)
return 0;
}
#ifdef CONFIG_DM_USB
static int xhci_fsl_probe(struct udevice *dev)
{
struct xhci_fsl_priv *priv = dev_get_priv(dev);
struct xhci_hccr *hccr;
struct xhci_hcor *hcor;
int ret = 0;
/*
* Get the base address for XHCI controller from the device node
*/
priv->hcd_base = dev_get_addr(dev);
if (priv->hcd_base == FDT_ADDR_T_NONE) {
debug("Can't get the XHCI register base address\n");
return -ENXIO;
}
priv->ctx.hcd = (struct xhci_hccr *)priv->hcd_base;
priv->ctx.dwc3_reg = (struct dwc3 *)((char *)(priv->hcd_base) +
DWC3_REG_OFFSET);
fsl_apply_xhci_errata();
ret = fsl_xhci_core_init(&priv->ctx);
if (ret < 0) {
puts("Failed to initialize xhci\n");
return ret;
}
hccr = (struct xhci_hccr *)(priv->ctx.hcd);
hcor = (struct xhci_hcor *)((uintptr_t) hccr
+ HC_LENGTH(xhci_readl(&hccr->cr_capbase)));
debug("xhci-fsl: init hccr %lx and hcor %lx hc_length %lx\n",
(uintptr_t)hccr, (uintptr_t)hcor,
(uintptr_t)HC_LENGTH(xhci_readl(&hccr->cr_capbase)));
return xhci_register(dev, hccr, hcor);
}
static int xhci_fsl_remove(struct udevice *dev)
{
struct xhci_fsl_priv *priv = dev_get_priv(dev);
int ret;
fsl_xhci_core_exit(&priv->ctx);
ret = xhci_deregister(dev);
if (ret)
return ret;
return 0;
}
static const struct udevice_id xhci_usb_ids[] = {
{ .compatible = "fsl,layerscape-dwc3", },
{ }
};
U_BOOT_DRIVER(xhci_fsl) = {
.name = "xhci_fsl",
.id = UCLASS_USB,
.of_match = xhci_usb_ids,
.probe = xhci_fsl_probe,
.remove = xhci_fsl_remove,
.ops = &xhci_usb_ops,
.platdata_auto_alloc_size = sizeof(struct usb_platdata),
.priv_auto_alloc_size = sizeof(struct xhci_fsl_priv),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
#else
int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
{
struct fsl_xhci *ctx = &fsl_xhci;
@ -116,3 +196,4 @@ void xhci_hcd_stop(int index)
fsl_xhci_core_exit(ctx);
}
#endif

View File

@ -98,7 +98,6 @@
#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD)
#define CONFIG_SYS_USB_FAT_BOOT_PARTITION 1
#define CONFIG_USB_HOST
#define CONFIG_USB_XHCI_OMAP
#define CONFIG_USB_STORAGE
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2

View File

@ -63,7 +63,6 @@
#define CONFIG_SUPPORT_EMMC_BOOT
/* USB xHCI HOST */
#define CONFIG_USB_HOST
#define CONFIG_USB_XHCI_OMAP
#define CONFIG_USB_STORAGE
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2

View File

@ -60,7 +60,6 @@
#define CONFIG_SYS_RX_ETH_BUFFER 64
/* USB support */
#define CONFIG_USB_HOST
#define CONFIG_USB_XHCI_OMAP
#define CONFIG_USB_STORAGE
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2

View File

@ -69,7 +69,6 @@
#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
CONFIG_SYS_SCSI_MAX_LUN)
/* USB UHH support options */
#define CONFIG_USB_HOST
#define CONFIG_USB_EHCI
#define CONFIG_USB_EHCI_OMAP
#define CONFIG_USB_STORAGE

View File

@ -209,7 +209,6 @@
#define CONFIG_SUPPORT_EMMC_BOOT
/* USB xHCI HOST */
#define CONFIG_USB_HOST
#define CONFIG_USB_XHCI_OMAP
#define CONFIG_USB_STORAGE
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2

View File

@ -29,7 +29,6 @@
#define CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
/* USB UHH support options */
#define CONFIG_USB_HOST
#define CONFIG_USB_EHCI
#define CONFIG_USB_EHCI_OMAP
#define CONFIG_USB_STORAGE

View File

@ -17,7 +17,6 @@
*/
/* USB UHH support options */
#define CONFIG_USB_HOST
#define CONFIG_USB_EHCI
#define CONFIG_USB_EHCI_OMAP
#define CONFIG_USB_STORAGE

View File

@ -88,7 +88,6 @@
#define CONFIG_SYS_I2C_TCA642X_ADDR 0x22
/* USB UHH support options */
#define CONFIG_USB_HOST
#define CONFIG_USB_EHCI
#define CONFIG_USB_EHCI_OMAP
#define CONFIG_USB_STORAGE