summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/README.android-fastboot9
-rw-r--r--doc/README.drivers.eth18
-rw-r--r--doc/README.enetaddr2
-rw-r--r--doc/README.fdt-control16
-rw-r--r--doc/README.link-local4
-rw-r--r--doc/device-tree-bindings/i2c/i2c-gpio.txt37
-rw-r--r--doc/device-tree-bindings/net/allwinner,sun4i-emac.txt19
-rw-r--r--doc/device-tree-bindings/net/allwinner,sun4i-mdio.txt27
-rw-r--r--doc/device-tree-bindings/net/allwinner,sun7i-a20-gmac.txt27
-rw-r--r--doc/device-tree-bindings/net/ethernet.txt25
-rw-r--r--doc/device-tree-bindings/net/stmmac.txt63
-rw-r--r--doc/driver-model/README.txt58
-rw-r--r--doc/driver-model/pci-info.txt70
-rw-r--r--doc/driver-model/usb-info.txt415
-rw-r--r--doc/git-mailrc4
15 files changed, 776 insertions, 18 deletions
diff --git a/doc/README.android-fastboot b/doc/README.android-fastboot
index 5526a43..04411e9 100644
--- a/doc/README.android-fastboot
+++ b/doc/README.android-fastboot
@@ -50,6 +50,15 @@ buffer should be as large as possible for a platform. The location of the
buffer and size are set with CONFIG_USB_FASTBOOT_BUF_ADDR and
CONFIG_USB_FASTBOOT_BUF_SIZE.
+Fastboot partition aliases can also be defined for devices where GPT
+limitations prevent user-friendly partition names such as "boot", "system"
+and "cache". Or, where the actual partition name doesn't match a standard
+partition name used commonly with fastboot. Current implentation checks
+aliases when accessing partitions by name (flash_write and erase functions).
+To define a partition alias add an environment variable similar to:
+fastboot_partition_alias_<alias partition name>=<actual partition name>
+Example: fastboot_partition_alias_boot=LNX
+
In Action
=========
Enter into fastboot by executing the fastboot command in u-boot and you
diff --git a/doc/README.drivers.eth b/doc/README.drivers.eth
index 42af442..1a9a23b 100644
--- a/doc/README.drivers.eth
+++ b/doc/README.drivers.eth
@@ -1,3 +1,9 @@
+!!! WARNING !!!
+
+This guide describes to the old way of doing things. No new Ethernet drivers
+should be implemented this way. All new drivers should be written against the
+U-Boot core driver model. See doc/driver-model/README.txt
+
-----------------------
Ethernet Driver Guide
-----------------------
@@ -135,11 +141,11 @@ function can be called multiple times in a row.
The recv function should process packets as long as the hardware has them
readily available before returning. i.e. you should drain the hardware fifo.
-For each packet you receive, you should call the NetReceive() function on it
+For each packet you receive, you should call the net_process_received_packet() function on it
along with the packet length. The common code sets up packet buffers for you
-already in the .bss (NetRxPackets), so there should be no need to allocate your
-own. This doesn't mean you must use the NetRxPackets array however; you're
-free to call the NetReceive() function with any buffer you wish. So the pseudo
+already in the .bss (net_rx_packets), so there should be no need to allocate your
+own. This doesn't mean you must use the net_rx_packets array however; you're
+free to call the net_process_received_packet() function with any buffer you wish. So the pseudo
code here would look something like:
int ape_recv(struct eth_device *dev)
{
@@ -147,9 +153,9 @@ int ape_recv(struct eth_device *dev)
...
while (packets_are_available()) {
...
- length = ape_get_packet(&NetRxPackets[i]);
+ length = ape_get_packet(&net_rx_packets[i]);
...
- NetReceive(&NetRxPackets[i], length);
+ net_process_received_packet(&net_rx_packets[i], length);
...
if (++i >= PKTBUFSRX)
i = 0;
diff --git a/doc/README.enetaddr b/doc/README.enetaddr
index 1eaeaf9..0fafd2c 100644
--- a/doc/README.enetaddr
+++ b/doc/README.enetaddr
@@ -87,7 +87,7 @@ eth_parse_enetaddr(addr, enetaddr);
Look up an environment variable and convert the stored address. If the address
is valid, then the function returns 1. Otherwise, the function returns 0. In
all cases, the enetaddr memory is initialized. If the env var is not found,
-then it is set to all zeros. The common function is_valid_ether_addr() is used
+then it is set to all zeros. The common function is_valid_ethaddr() is used
to determine address validity.
uchar enetaddr[6];
if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
diff --git a/doc/README.fdt-control b/doc/README.fdt-control
index d8fe4a8..e6d5ed0 100644
--- a/doc/README.fdt-control
+++ b/doc/README.fdt-control
@@ -171,6 +171,22 @@ After board configuration is done, fdt supported u-boot can be build in two ways
$ make DEVICE_TREE=<dts-file-name>
+Configuration Options
+---------------------
+
+A number of run-time configuration options are provided in the /config node
+of the control device tree. You can access these using fdtdec_get_config_int(),
+fdtdec_get_config_bool() and fdtdec_get_config_string().
+
+Available options are:
+
+silent-console
+ If present and non-zero, the console is silenced by default on boot.
+
+no-keyboard
+ Tells U-Boot not to expect an attached keyboard with a VGA console
+
+
Limitations
-----------
diff --git a/doc/README.link-local b/doc/README.link-local
index 9586eca..148b498 100644
--- a/doc/README.link-local
+++ b/doc/README.link-local
@@ -32,11 +32,11 @@ after successful negotiation to enable network access.
-------------
RFC3927 requires that addresses are continuously checked to
-avoid conflicts, however this can only happen when the NetLoop
+avoid conflicts, however this can only happen when the net_loop
is getting called. It is possible for a conflict to go undetected
until a command that accesses the network is executed.
-Using NetConsole is one way to ensure that NetLoop is always
+Using NetConsole is one way to ensure that net_loop is always
processing packets and monitoring for conflicts.
This is also not a concern if the feature is use to connect
diff --git a/doc/device-tree-bindings/i2c/i2c-gpio.txt b/doc/device-tree-bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000..ba56ed5
--- /dev/null
+++ b/doc/device-tree-bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,37 @@
+I2C gpio device binding
+=======================
+
+Driver:
+- drivers/i2c/i2c-gpio.c
+
+Software i2c device-tree node properties:
+Required:
+* #address-cells = <1>;
+* #size-cells = <0>;
+* compatible = "i2c-gpio";
+* gpios = <sda ...>, <scl ...>;
+
+Optional:
+* i2c-gpio,delay-us = <5>;
+ The resulting transfer speed can be adjusted by setting the delay[us]
+ between gpio-toggle operations. Speed [Hz] = 1000000 / 4 * udelay[us],
+ It not defined, then default is 5us (~50KHz).
+
+Example:
+
+i2c-gpio@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "i2c-gpio";
+ gpios = <&gpd1 0 GPIO_ACTIVE_HIGH>, /* SDA */
+ <&gpd1 1 GPIO_ACTIVE_HIGH>; /* CLK */
+
+ i2c-gpio,delay-us = <5>;
+
+ some_device@5 {
+ compatible = "some_device";
+ reg = <0x5>;
+ ...
+ };
+};
diff --git a/doc/device-tree-bindings/net/allwinner,sun4i-emac.txt b/doc/device-tree-bindings/net/allwinner,sun4i-emac.txt
new file mode 100644
index 0000000..10640b1
--- /dev/null
+++ b/doc/device-tree-bindings/net/allwinner,sun4i-emac.txt
@@ -0,0 +1,19 @@
+* Allwinner EMAC ethernet controller
+
+Required properties:
+- compatible: should be "allwinner,sun4i-a10-emac" (Deprecated:
+ "allwinner,sun4i-emac")
+- reg: address and length of the register set for the device.
+- interrupts: interrupt for the device
+- phy: see ethernet.txt file in the same directory.
+- clocks: A phandle to the reference clock for this device
+
+Example:
+
+emac: ethernet@01c0b000 {
+ compatible = "allwinner,sun4i-a10-emac";
+ reg = <0x01c0b000 0x1000>;
+ interrupts = <55>;
+ clocks = <&ahb_gates 17>;
+ phy = <&phy0>;
+};
diff --git a/doc/device-tree-bindings/net/allwinner,sun4i-mdio.txt b/doc/device-tree-bindings/net/allwinner,sun4i-mdio.txt
new file mode 100644
index 0000000..4ec5641
--- /dev/null
+++ b/doc/device-tree-bindings/net/allwinner,sun4i-mdio.txt
@@ -0,0 +1,27 @@
+* Allwinner A10 MDIO Ethernet Controller interface
+
+Required properties:
+- compatible: should be "allwinner,sun4i-a10-mdio"
+ (Deprecated: "allwinner,sun4i-mdio").
+- reg: address and length of the register set for the device.
+
+Optional properties:
+- phy-supply: phandle to a regulator if the PHY needs one
+
+Example at the SoC level:
+mdio@01c0b080 {
+ compatible = "allwinner,sun4i-a10-mdio";
+ reg = <0x01c0b080 0x14>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+};
+
+And at the board level:
+
+mdio@01c0b080 {
+ phy-supply = <&reg_emac_3v3>;
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
diff --git a/doc/device-tree-bindings/net/allwinner,sun7i-a20-gmac.txt b/doc/device-tree-bindings/net/allwinner,sun7i-a20-gmac.txt
new file mode 100644
index 0000000..ea4d752
--- /dev/null
+++ b/doc/device-tree-bindings/net/allwinner,sun7i-a20-gmac.txt
@@ -0,0 +1,27 @@
+* Allwinner GMAC ethernet controller
+
+This device is a platform glue layer for stmmac.
+Please see stmmac.txt for the other unchanged properties.
+
+Required properties:
+ - compatible: Should be "allwinner,sun7i-a20-gmac"
+ - clocks: Should contain the GMAC main clock, and tx clock
+ The tx clock type should be "allwinner,sun7i-a20-gmac-clk"
+ - clock-names: Should contain the clock names "stmmaceth",
+ and "allwinner_gmac_tx"
+
+Optional properties:
+- phy-supply: phandle to a regulator if the PHY needs one
+
+Examples:
+
+ gmac: ethernet@01c50000 {
+ compatible = "allwinner,sun7i-a20-gmac";
+ reg = <0x01c50000 0x10000>,
+ <0x01c20164 0x4>;
+ interrupts = <0 85 1>;
+ interrupt-names = "macirq";
+ clocks = <&ahb_gates 49>, <&gmac_tx>;
+ clock-names = "stmmaceth", "allwinner_gmac_tx";
+ phy-mode = "mii";
+ };
diff --git a/doc/device-tree-bindings/net/ethernet.txt b/doc/device-tree-bindings/net/ethernet.txt
new file mode 100644
index 0000000..3fc3605
--- /dev/null
+++ b/doc/device-tree-bindings/net/ethernet.txt
@@ -0,0 +1,25 @@
+The following properties are common to the Ethernet controllers:
+
+- local-mac-address: array of 6 bytes, specifies the MAC address that was
+ assigned to the network device;
+- mac-address: array of 6 bytes, specifies the MAC address that was last used by
+ the boot program; should be used in cases where the MAC address assigned to
+ the device by the boot program is different from the "local-mac-address"
+ property;
+- max-speed: number, specifies maximum speed in Mbit/s supported by the device;
+- max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
+ the maximum frame size (there's contradiction in ePAPR).
+- phy-mode: string, operation mode of the PHY interface; supported values are
+ "mii", "gmii", "sgmii", "qsgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id",
+ "rgmii-rxid", "rgmii-txid", "rtbi", "smii", "xgmii"; this is now a de-facto
+ standard property;
+- phy-connection-type: the same as "phy-mode" property but described in ePAPR;
+- phy-handle: phandle, specifies a reference to a node representing a PHY
+ device; this property is described in ePAPR and so preferred;
+- phy: the same as "phy-handle" property, not recommended for new bindings.
+- phy-device: the same as "phy-handle" property, not recommended for new
+ bindings.
+
+Child nodes of the Ethernet controller are typically the individual PHY devices
+connected via the MDIO bus (sometimes the MDIO bus controller is separate).
+They are described in the phy.txt file in this same directory.
diff --git a/doc/device-tree-bindings/net/stmmac.txt b/doc/device-tree-bindings/net/stmmac.txt
new file mode 100644
index 0000000..5f02517
--- /dev/null
+++ b/doc/device-tree-bindings/net/stmmac.txt
@@ -0,0 +1,63 @@
+* STMicroelectronics 10/100/1000 Ethernet driver (GMAC)
+
+Required properties:
+- compatible: Should be "snps,dwmac-<ip_version>" "snps,dwmac"
+ For backwards compatibility: "st,spear600-gmac" is also supported.
+- reg: Address and length of the register set for the device
+- interrupt-parent: Should be the phandle for the interrupt controller
+ that services interrupts for this device
+- interrupts: Should contain the STMMAC interrupts
+- interrupt-names: Should contain the interrupt names "macirq"
+ "eth_wake_irq" if this interrupt is supported in the "interrupts"
+ property
+- phy-mode: See ethernet.txt file in the same directory.
+- snps,reset-gpio gpio number for phy reset.
+- snps,reset-active-low boolean flag to indicate if phy reset is active low.
+- snps,reset-delays-us is triplet of delays
+ The 1st cell is reset pre-delay in micro seconds.
+ The 2nd cell is reset pulse in micro seconds.
+ The 3rd cell is reset post-delay in micro seconds.
+- snps,pbl Programmable Burst Length
+- snps,fixed-burst Program the DMA to use the fixed burst mode
+- snps,mixed-burst Program the DMA to use the mixed burst mode
+- snps,force_thresh_dma_mode Force DMA to use the threshold mode for
+ both tx and rx
+- snps,force_sf_dma_mode Force DMA to use the Store and Forward
+ mode for both tx and rx. This flag is
+ ignored if force_thresh_dma_mode is set.
+- snps,multicast-filter-bins: Number of multicast filter hash bins
+ supported by this device instance
+- snps,perfect-filter-entries: Number of perfect filter entries supported
+ by this device instance
+
+Optional properties:
+- resets: Should contain a phandle to the STMMAC reset signal, if any
+- reset-names: Should contain the reset signal name "stmmaceth", if a
+ reset phandle is given
+- max-frame-size: See ethernet.txt file in the same directory
+- clocks: If present, the first clock should be the GMAC main clock,
+ further clocks may be specified in derived bindings.
+- clock-names: One name for each entry in the clocks property, the
+ first one should be "stmmaceth".
+- clk_ptp_ref: this is the PTP reference clock; in case of the PTP is
+ available this clock is used for programming the Timestamp Addend Register.
+ If not passed then the system clock will be used and this is fine on some
+ platforms.
+- snps,burst_len: The AXI burst lenth value of the AXI BUS MODE register.
+
+Examples:
+
+ gmac0: ethernet@e0800000 {
+ compatible = "st,spear600-gmac";
+ reg = <0xe0800000 0x8000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <24 23>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ mac-address = [000000000000]; /* Filled in by U-Boot */
+ max-frame-size = <3800>;
+ phy-mode = "gmii";
+ snps,multicast-filter-bins = <256>;
+ snps,perfect-filter-entries = <128>;
+ clocks = <&clock>;
+ clock-names = "stmmaceth";
+ };
diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt
index f83264d..f0276b1 100644
--- a/doc/driver-model/README.txt
+++ b/doc/driver-model/README.txt
@@ -95,43 +95,82 @@ are provided in test/dm. To run them, try:
You should see something like this:
<...U-Boot banner...>
- Running 29 driver model tests
+ Running 53 driver model tests
Test: dm_test_autobind
Test: dm_test_autoprobe
+ Test: dm_test_bus_child_post_bind
+ Test: dm_test_bus_child_post_bind_uclass
+ Test: dm_test_bus_child_pre_probe_uclass
Test: dm_test_bus_children
- Device 'd-test': seq 3 is in use by 'b-test'
- Device 'c-test@0': seq 0 is in use by 'a-test'
- Device 'c-test@1': seq 1 is in use by 'd-test'
+ Device 'c-test@0': seq 0 is in use by 'd-test'
+ Device 'c-test@1': seq 1 is in use by 'f-test'
Test: dm_test_bus_children_funcs
Test: dm_test_bus_children_iterators
Test: dm_test_bus_parent_data
+ Test: dm_test_bus_parent_data_uclass
Test: dm_test_bus_parent_ops
+ Test: dm_test_bus_parent_platdata
+ Test: dm_test_bus_parent_platdata_uclass
Test: dm_test_children
+ Test: dm_test_device_get_uclass_id
+ Test: dm_test_eth
+ Using eth@10002000 device
+ Using eth@10003000 device
+ Using eth@10004000 device
+ Test: dm_test_eth_alias
+ Using eth@10002000 device
+ Using eth@10004000 device
+ Using eth@10002000 device
+ Using eth@10003000 device
+ Test: dm_test_eth_prime
+ Using eth@10003000 device
+ Using eth@10002000 device
+ Test: dm_test_eth_rotate
+
+ Error: eth@10004000 address not set.
+
+ Error: eth@10004000 address not set.
+ Using eth@10002000 device
+
+ Error: eth@10004000 address not set.
+
+ Error: eth@10004000 address not set.
+ Using eth@10004000 device
Test: dm_test_fdt
- Device 'd-test': seq 3 is in use by 'b-test'
Test: dm_test_fdt_offset
Test: dm_test_fdt_pre_reloc
Test: dm_test_fdt_uclass_seq
- Device 'd-test': seq 3 is in use by 'b-test'
- Device 'a-test': seq 0 is in use by 'd-test'
Test: dm_test_gpio
extra-gpios: get_value: error: gpio b5 not reserved
Test: dm_test_gpio_anon
Test: dm_test_gpio_copy
Test: dm_test_gpio_leak
extra-gpios: get_value: error: gpio b5 not reserved
+ Test: dm_test_gpio_phandles
Test: dm_test_gpio_requestf
+ Test: dm_test_i2c_bytewise
+ Test: dm_test_i2c_find
+ Test: dm_test_i2c_offset
+ Test: dm_test_i2c_offset_len
+ Test: dm_test_i2c_probe_empty
+ Test: dm_test_i2c_read_write
+ Test: dm_test_i2c_speed
Test: dm_test_leak
Test: dm_test_lifecycle
+ Test: dm_test_net_retry
+ Using eth@10004000 device
+ Using eth@10002000 device
+ Using eth@10004000 device
Test: dm_test_operations
Test: dm_test_ordering
+ Test: dm_test_pci_base
+ Test: dm_test_pci_swapcase
Test: dm_test_platdata
Test: dm_test_pre_reloc
Test: dm_test_remove
Test: dm_test_spi_find
Invalid chip select 0:0 (err=-19)
SF: Failed to get idcodes
- Device 'name-emul': seq 0 is in use by 'name-emul'
SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
Test: dm_test_spi_flash
2097152 bytes written in 0 ms
@@ -150,6 +189,9 @@ You should see something like this:
SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
Test: dm_test_uclass
Test: dm_test_uclass_before_ready
+ Test: dm_test_usb_base
+ Test: dm_test_usb_flash
+ USB-1: scanning bus 1 for devices... 2 USB Device(s) found
Failures: 0
diff --git a/doc/driver-model/pci-info.txt b/doc/driver-model/pci-info.txt
new file mode 100644
index 0000000..63efcb7
--- /dev/null
+++ b/doc/driver-model/pci-info.txt
@@ -0,0 +1,70 @@
+PCI with Driver Model
+=====================
+
+How busses are scanned
+----------------------
+
+Any config read will end up at pci_read_config(). This uses
+uclass_get_device_by_seq() to get the PCI bus for a particular bus number.
+Bus number 0 will need to be requested first, and the alias in the device
+tree file will point to the correct device:
+
+
+ aliases {
+ pci0 = &pci;
+ };
+
+ pci: pci-controller {
+ compatible = "sandbox,pci";
+ ...
+ };
+
+
+If there is no alias the devices will be numbered sequentially in the device
+tree.
+
+The call to uclass_get_device by seq() will cause the PCI bus to be probed.
+This does a scan of the bus to locate available devices. These devices are
+bound to their appropriate driver if available. If there is no driver, then
+they are bound to a generic PCI driver which does nothing.
+
+After probing a bus, the available devices will appear in the device tree
+under that bus.
+
+Note that this is all done on a lazy basis, as needed, so until something is
+touched on PCI it will not be probed.
+
+PCI devices can appear in the device tree. If they do this serves to specify
+the driver to use for the device. In this case they will be bound at
+start-up.
+
+
+Sandbox
+-------
+
+With sandbox we need a device emulator for each device on the bus since there
+is no real PCI bus. This works by looking in the device tree node for a
+driver. For example:
+
+
+ pci@1f,0 {
+ compatible = "pci-generic";
+ reg = <0xf800 0 0 0 0>;
+ emul@1f,0 {
+ compatible = "sandbox,swap-case";
+ };
+ };
+
+This means that there is a 'sandbox,swap-case' driver at that bus position.
+Note that the first cell in the 'reg' value is the bus/device/function. See
+PCI_BDF() for the encoding (it is also specified in the IEEE Std 1275-1994
+PCI bus binding document, v2.1)
+
+When this bus is scanned we will end up with something like this:
+
+`- * pci-controller @ 05c660c8, 0
+ `- pci@1f,0 @ 05c661c8, 63488
+ `- emul@1f,0 @ 05c662c8
+
+When accesses go to the pci@1f,0 device they are forwarded to its child, the
+emulator.
diff --git a/doc/driver-model/usb-info.txt b/doc/driver-model/usb-info.txt
new file mode 100644
index 0000000..66f2dae
--- /dev/null
+++ b/doc/driver-model/usb-info.txt
@@ -0,0 +1,415 @@
+How USB works with driver model
+===============================
+
+Introduction
+------------
+
+Driver model USB support makes use of existing features but changes how
+drivers are found. This document provides some information intended to help
+understand how things work with USB in U-Boot when driver model is enabled.
+
+
+Enabling driver model for USB
+-----------------------------
+
+A new CONFIG_DM_USB option is provided to enable driver model for USB. This
+causes the USB uclass to be included, and drops the equivalent code in
+usb.c. In particular the usb_init() function is then implemented by the
+uclass.
+
+
+Support for EHCI and XHCI
+-------------------------
+
+So far OHCI is not supported. Both EHCI and XHCI drivers should be declared
+as drivers in the USB uclass. For example:
+
+static const struct udevice_id ehci_usb_ids[] = {
+ { .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
+ { .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
+ { .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
+ { }
+};
+
+U_BOOT_DRIVER(usb_ehci) = {
+ .name = "ehci_tegra",
+ .id = UCLASS_USB,
+ .of_match = ehci_usb_ids,
+ .ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
+ .probe = tegra_ehci_usb_probe,
+ .remove = tegra_ehci_usb_remove,
+ .ops = &ehci_usb_ops,
+ .platdata_auto_alloc_size = sizeof(struct usb_platdata),
+ .priv_auto_alloc_size = sizeof(struct fdt_usb),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+
+Here ehci_usb_ids is used to list the controllers that the driver supports.
+Each has its own data value. Controllers must be in the UCLASS_USB uclass.
+
+The ofdata_to_platdata() method allows the controller driver to grab any
+necessary settings from the device tree.
+
+The ops here are ehci_usb_ops. All EHCI drivers will use these same ops in
+most cases, since they are all EHCI-compatible. For EHCI there are also some
+special operations that can be overridden when calling ehci_register().
+
+The driver can use priv_auto_alloc_size to set the size of its private data.
+This can hold run-time information needed by the driver for operation. It
+exists when the device is probed (not when it is bound) and is removed when
+the driver is removed.
+
+Note that usb_platdata is currently only used to deal with setting up a bus
+in USB device mode (OTG operation). It can be omitted if that is not
+supported.
+
+The driver's probe() method should do the basic controller init and then
+call ehci_register() to register itself as an EHCI device. It should call
+ehci_deregister() in the remove() method. Registering a new EHCI device
+does not by itself cause the bus to be scanned.
+
+The old ehci_hcd_init() function is no-longer used. Nor is it necessary to
+set up the USB controllers from board init code. When 'usb start' is used,
+each controller will be probed and its bus scanned.
+
+XHCI works in a similar way.
+
+
+Data structures
+---------------
+
+The following primary data structures are in use:
+
+- struct usb_device
+ This holds information about a device on the bus. All devices have
+ this structure, even the root hub. The controller itself does not
+ have this structure. You can access it for a device 'dev' with
+ dev_get_parentdata(dev). It matches the old structure except that the
+ parent and child information is not present (since driver model
+ handles that). Once the device is set up, you can find the device
+ descriptor and current configuration descriptor in this structure.
+
+- struct usb_platdata
+ This holds platform data for a controller. So far this is only used
+ as a work-around for controllers which can act as USB devices in OTG
+ mode, since the gadget framework does not use driver model.
+
+- struct usb_dev_platdata
+ This holds platform data for a device. You can access it for a
+ device 'dev' with dev_get_parent_platdata(dev). It holds the device
+ address and speed - anything that can be determined before the device
+ driver is actually set up. When probing the bus this structure is
+ used to provide essential information to the device driver.
+
+- struct usb_bus_priv
+ This is private information for each controller, maintained by the
+ controller uclass. It is mostly used to keep track of the next
+ device address to use.
+
+Of these, only struct usb_device was used prior to driver model.
+
+
+USB buses
+---------
+
+Given a controller, you know the bus - it is the one attached to the
+controller. Each controller handles exactly one bus. Every controller has a
+root hub attached to it. This hub, which is itself a USB device, can provide
+one or more 'ports' to which additional devices can be attached. It is
+possible to power up a hub and find out which of its ports have devices
+attached.
+
+Devices are given addresses starting at 1. The root hub is always address 1,
+and from there the devices are numbered in sequence. The USB uclass takes
+care of this numbering automatically during enumeration.
+
+USB devices are enumerated by finding a device on a particular hub, and
+setting its address to the next available address. The USB bus stretches out
+in a tree structure, potentially with multiple hubs each with several ports
+and perhaps other hubs. Some hubs will have their own power since otherwise
+the 5V 500mA power supplied by the controller will not be sufficient to run
+very many devices.
+
+Enumeration in U-Boot takes a long time since devices are probed one at a
+time, and each is given sufficient time to wake up and announce itself. The
+timeouts are set for the slowest device.
+
+Up to 127 devices can be on each bus. USB has four bus speeds: low
+(1.5Mbps), full (12Mbps), high (480Mbps) which is only available with USB2
+and newer (EHCI), and super (5Gbps) which is only available with USB3 and
+newer (XHCI). If you connect a super-speed device to a high-speed hub, you
+will only get high-speed.
+
+
+USB operations
+--------------
+
+As before driver model, messages can be sent using submit_bulk_msg() and the
+like. These are now implemented by the USB uclass and route through the
+controller drivers. Note that messages are not sent to the driver of the
+device itself - i.e. they don't pass down the stack to the controller.
+U-Boot simply finds the controller to which the device is attached, and sends
+the message there with an appropriate 'pipe' value so it can be addressed
+properly. Having said that, the USB device which should receive the message
+is passed in to the driver methods, for use by sandbox. This design decision
+is open for review and the code impact of changing it is small since the
+methods are typically implemented by the EHCI and XHCI stacks.
+
+Controller drivers (in UCLASS_USB) themselves provide methods for sending
+each message type. For XHCI an additional alloc_device() method is provided
+since XHCI needs to allocate a device context before it can even read the
+device's descriptor.
+
+These methods use a 'pipe' which is a collection of bit fields used to
+describe the type of message, direction of transfer and the intended
+recipient (device number).
+
+
+USB Devices
+-----------
+
+USB devices are found using a simple algorithm which works through the
+available hubs in a depth-first search. Devices can be in any uclass, but
+are attached to a parent hub (or controller in the case of the root hub) and
+so have parent data attached to them (this is struct usb_device).
+
+By the time the device's probe() method is called, it is enumerated and is
+ready to talk to the host.
+
+The enumeration process needs to work out which driver to attach to each USB
+device. It does this by examining the device class, interface class, vendor
+ID, product ID, etc. See struct usb_driver_entry for how drivers are matched
+with USB devices - you can use the USB_DEVICE() macro to declare a USB
+driver. For example, usb_storage.c defines a USB_DEVICE() to handle storage
+devices, and it will be used for all USB devices which match.
+
+
+
+Technical details on enumeration flow
+-------------------------------------
+
+It is useful to understand precisely how a USB bus is enumerating to avoid
+confusion when dealing with USB devices.
+
+Device initialisation happens roughly like this:
+
+- At some point the 'usb start' command is run
+- This calls usb_init() which works through each controller in turn
+- The controller is probed(). This does no enumeration.
+- Then usb_scan_bus() is called. This calls usb_scan_device() to scan the
+(only) device that is attached to the controller - a root hub
+- usb_scan_device() sets up a fake struct usb_device and calls
+usb_setup_device(), passing the port number to be scanned, in this case port
+0
+- usb_setup_device() first calls usb_prepare_device() to set the device
+address, then usb_select_config() to select the first configuration
+- at this point the device is enumerated but we do not have a real struct
+udevice for it. But we do have the descriptor in struct usb_device so we can
+use this to figure out what driver to use
+- back in usb_scan_device(), we call usb_find_child() to try to find an
+existing device which matches the one we just found on the bus. This can
+happen if the device is mentioned in the device tree, or if we previously
+scanned the bus and so the device was created before
+- if usb_find_child() does not find an existing device, we call
+usb_find_and_bind_driver() which tries to bind one
+- usb_find_and_bind_driver() searches all available USB drivers (declared
+with USB_DEVICE()). If it finds a match it binds that driver to create a new
+device.
+- If it does not, it binds a generic driver. A generic driver is good enough
+to allow access to the device (sending it packets, etc.) but all
+functionality will need to be implemented outside the driver model.
+- in any case, when usb_find_child() and/or usb_find_and_bind_driver() are
+done, we have a device with the correct uclass. At this point we want to
+probe the device
+- first we store basic information about the new device (address, port,
+speed) in its parent platform data. We cannot store it its private data
+since that will not exist until the device is probed.
+- then we call device_probe() which probes the device
+- the first probe step is actually the USB controller's (or USB hubs's)
+child_pre_probe() method. This gets called before anything else and is
+intended to set up a child device ready to be used with its parent bus. For
+USB this calls usb_child_pre_probe() which grabs the information that was
+stored in the parent platform data and stores it in the parent private data
+(which is struct usb_device, a real one this time). It then calls
+usb_select_config() again to make sure that everything about the device is
+set up
+- note that we have called usb_select_config() twice. This is inefficient
+but the alternative is to store additional information in the platform data.
+The time taken is minimal and this way is simpler
+- at this point the device is set up and ready for use so far as the USB
+subsystem is concerned
+- the device's probe() method is then called. It can send messages and do
+whatever else it wants to make the device work.
+
+Note that the first device is always a root hub, and this must be scanned to
+find any devices. The above steps will have created a hub (UCLASS_USB_HUB),
+given it address 1 and set the configuration.
+
+For hubs, the hub uclass has a post_probe() method. This means that after
+any hub is probed, the uclass gets to do some processing. In this case
+usb_hub_post_probe() is called, and the following steps take place:
+
+- usb_hub_post_probe() calls usb_hub_scan() to scan the hub, which in turn
+calls usb_hub_configure()
+- hub power is enabled
+- we loop through each port on the hub, performing the same steps for each
+- first, check if there is a device present. This happens in
+usb_hub_port_connect_change(). If so, then usb_scan_device() is called to
+scan the device, passing the appropriate port number.
+- you will recognise usb_scan_device() from the steps above. It sets up the
+device ready for use. If it is a hub, it will scan that hub before it
+continues here (recursively, depth-first)
+- once all hub ports are scanned in this way, the hub is ready for use and
+all of its downstream devices also
+- additional controllers are scanned in the same way
+
+The above method has some nice properties:
+
+- the bus enumeration happens by virtue of driver model's natural device flow
+- most logic is in the USB controller and hub uclasses; the actual device
+drivers do not need to know they are on a USB bus, at least so far as
+enumeration goes
+- hub scanning happens automatically after a hub is probed
+
+
+Hubs
+----
+
+USB hubs are scanned as in the section above. While hubs have their own
+uclass, they share some common elements with controllers:
+
+- they both attach private data to their children (struct usb_device,
+accessible for a child with dev_get_parentdata(child))
+- they both use usb_child_pre_probe() to set up their children as proper USB
+devices
+
+
+Example - Mass Storage
+----------------------
+
+As an example of a USB device driver, see usb_storage.c. It uses its own
+uclass and declares itself as follows:
+
+U_BOOT_DRIVER(usb_mass_storage) = {
+ .name = "usb_mass_storage",
+ .id = UCLASS_MASS_STORAGE,
+ .of_match = usb_mass_storage_ids,
+ .probe = usb_mass_storage_probe,
+};
+
+static const struct usb_device_id mass_storage_id_table[] = {
+ { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
+ .bInterfaceClass = USB_CLASS_MASS_STORAGE},
+ { } /* Terminating entry */
+};
+
+USB_DEVICE(usb_mass_storage, mass_storage_id_table);
+
+The USB_DEVICE() macro attaches the given table of matching information to
+the given driver. Note that the driver is declared in U_BOOT_DRIVER() as
+'usb_mass_storage' and this must match the first parameter of USB_DEVICE.
+
+When usb_find_and_bind_driver() is called on a USB device with the
+bInterfaceClass value of USB_CLASS_MASS_STORAGE, it will automatically find
+this driver and use it.
+
+
+Counter-example: USB Ethernet
+-----------------------------
+
+As an example of the old way of doing things, see usb_ether.c. When the bus
+is scanned, all Ethernet devices will be created as generic USB devices (in
+uclass UCLASS_USB_DEV_GENERIC). Then, when the scan is completed,
+usb_host_eth_scan() will be called. This looks through all the devices on
+each bus and manually figures out which are Ethernet devices in the ways of
+yore.
+
+In fact, usb_ether should be moved to driver model. Each USB Ethernet driver
+(e.g drivers/usb/eth/asix.c) should include a USB_DEVICE() declaration, so
+that it will be found as part of normal USB enumeration. Then, instead of a
+generic USB driver, a real (driver-model-aware) driver will be used. Since
+Ethernet now supports driver model, this should be fairly easy to achieve,
+and then usb_ether.c and the usb_host_eth_scan() will melt away.
+
+
+Sandbox
+-------
+
+All driver model uclasses must have tests and USB is no exception. To
+achieve this, a sandbox USB controller is provided. This can make use of
+emulation drivers which pretend to be USB devices. Emulations are provided
+for a hub and a flash stick. These are enough to create a pretend USB bus
+(defined by the sandbox device tree sandbox.dts) which can be scanned and
+used.
+
+Tests in test/dm/usb.c make use of this feature. It allows much of the USB
+stack to be tested without real hardware being needed.
+
+Here is an example device tree fragment:
+
+ usb@1 {
+ compatible = "sandbox,usb";
+ hub {
+ compatible = "usb-hub";
+ usb,device-class = <USB_CLASS_HUB>;
+ hub-emul {
+ compatible = "sandbox,usb-hub";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ flash-stick {
+ reg = <0>;
+ compatible = "sandbox,usb-flash";
+ sandbox,filepath = "flash.bin";
+ };
+ };
+ };
+ };
+
+This defines a single controller, containing a root hub (which is required).
+The hub is emulated by a hub emulator, and the emulated hub has a single
+flash stick to emulate on one of its ports.
+
+When 'usb start' is used, the following 'dm tree' output will be available:
+
+ usb [ + ] `-- usb@1
+ usb_hub [ + ] `-- hub
+ usb_emul [ + ] |-- hub-emul
+ usb_emul [ + ] | `-- flash-stick
+ usb_mass_st [ + ] `-- usb_mass_storage
+
+
+This may look confusing. Most of it mirrors the device tree, but the
+'usb_mass_storage' device is not in the device tree. This is created by
+usb_find_and_bind_driver() based on the USB_DRIVER in usb_storage.c. While
+'flash-stick' is the emulation device, 'usb_mass_storage' is the real U-Boot
+USB device driver that talks to it.
+
+
+Future work
+-----------
+
+It is pretty uncommon to have a large USB bus with lots of hubs on an
+embedded system. In fact anything other than a root hub is uncommon. Still
+it would be possible to speed up enumeration in two ways:
+
+- breadth-first search would allow devices to be reset and probed in
+parallel to some extent
+- enumeration could be lazy, in the sense that we could enumerate just the
+root hub at first, then only progress to the next 'level' when a device is
+used that we cannot find. This could be made easier if the devices were
+statically declared in the device tree (which is acceptable for production
+boards where the same, known, things are on each bus).
+
+But in common cases the current algorithm is sufficient.
+
+Other things that need doing:
+- Convert usb_ether to use driver model as described above
+- Test that keyboards work (and convert to driver model)
+- Move the USB gadget framework to driver model
+- Implement OHCI in driver model
+- Implement USB PHYs in driver model
+- Work out a clever way to provide lazy init for USB devices
+
+--
+Simon Glass <sjg@chromium.org>
+23-Mar-15
diff --git a/doc/git-mailrc b/doc/git-mailrc
index 5f8438e..174109f 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -24,7 +24,7 @@ alias ijc Ian Campbell <ijc+uboot@hellion.org.uk>
alias iwamatsu Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
alias jagan Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
alias jasonjin Jason Jin <jason.jin@freescale.com>
-alias jhersh Joe Hershberger <joe.hershberger@gmail.com>
+alias jhersh Joe Hershberger <joe.hershberger@ni.com>
alias jwrdegoede Hans de Goede <hdegoede@redhat.com>
alias kimphill Kim Phillips <kim.phillips@freescale.com>
alias luka Luka Perkov <luka.perkov@sartura.hr>
@@ -113,6 +113,7 @@ alias x86 uboot, sjg, gruss
alias dm uboot, sjg
alias cfi uboot, stroese
alias dfu uboot, lukma
+alias eth uboot, jhersh
alias kerneldoc uboot, marex
alias fdt uboot, sjg
alias i2c uboot, hs
@@ -120,6 +121,7 @@ alias kconfig uboot, masahiro
alias mmc uboot, panto
alias nand uboot, scottwood
alias net uboot, jhersh
+alias phy uboot, jhersh
alias spi uboot, jagan
alias ubi uboot, hs
alias usb uboot, marex