APPLIED: pxe: clear Bootfile before returning

When "pxe boot" downloads the initrd/kernel/DTB, netboot_common() saves
the downloaded filename to global variable BootFile. If the boot
operation is aborted, this global state is not cleared. If "dhcp" is
executed later without any arguments, BootFile is not cleared, and when
the DHCP response is received, BootpCopyNetParams() writes the value into
environment variable bootfile.

This causes the following scenario:

* Boot script executes dhcp; pxe get; pxe boot

* User CTRL-C's the PXE menu, which causes the first menu item to be
  booted, which causes some file to be downloaded.

  (This boot-on-CTRL-C behaviour is arguably a bug too, but it's a
  separate bug and the bug this patch fixes would still exist if the user
  simply waited to press CTRL-C until "pxe boot" started downloading
  files)

* User CTRL-C's the file downloads, but the filename is still written to
  the bootfile environment variable.

* User re-runs the boot command, which in my case executes "dhcp; pxe get;
  pxe boot" again, and "dhcp" picks up the saved bootfile environment
  variable and proceeds to download a file that it shouldn't.

To solve this, modify the implementation of "pxe get" to clear BootFile
if the whole boot operation fails, which avoids this whole mess.

An alternative would be to modify netboot_common() such that the no-
arguments case explicitly clears the global variable BootFile. However,
that would prevent the following command sequences from working:

$ dhcp filename # downloads "filename"
$ dhcp          # downloads $bootfile, i.e. "filename"

or:
$ setenv bootfile filename
$ dhcp          # downloads $bootfile, i.e. "filename"

... and I assume someone relies on U-Boot working that way.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
APPLIED: net: BOOTP retry timeout improvements

Currently, the BOOTP code sends out its initial request as soon as the
Ethernet driver indicates "link up". If this packet is lost or not
replied to for some reason, the code waits for a 1s timeout before
retrying. For some reason, such early packets are often lost on my
system, so this causes an annoying delay.

To optimize this, modify the BOOTP code to have very short timeouts for
the first packet transmitted, but gradually increase the timeout each
time a timeout occurs. This way, if the first packet is lost, the second
packet is transmitted quite quickly and hence the overall delay is low.
However, if there's still no response, we don't keep spewing out packets
at an insane speed.

It's arguably more correct to try and find out why the first packet is
lost. However, it seems to disappear inside my Ethenet chip; the TX chip
indicates no error during TX (not that it has much in the way of
reporting...), yet wireshark on the RX side doesn't see any packet.
FWIW, I'm using an ASIX USB Ethernet adapter. Perhaps "link up" is
reported too early or based on the wrong condition in HW, and we should
add some fixed extra delay into the driver. However, this would slow down
every link up event even if it ends up not being needed in some cases.
Having BOOTP retry quickly applies the fix/WAR to every possible
Ethernet device, and is quite simple to implement, so seems a better
solution.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
APPLIED: config: introduce a generic $bootcmd

This generic $bootcmd, and associated support macros, automatically
searches a defined set of storage devices (or network protocols) for an
extlinux configuration file or U-Boot boot script in various standardized
locations. Distros that install such a boot config file/script in those
standard locations will get easy-to-set-up booting on HW that enables
this generic $bootcmd.

Boards can define the set of devices from which boot is attempted, and
the order in which they are attempted. Users may later customize this
set/order by edting $boot_targets.

Users may interrupt the boot process and boot from a specific device
simply by executing e.g.:

$ run bootcmd_mmc1
or:
$ run bootcmd_pxe

This patch was originally written by Dennis Gilmore based on Tegra and
rpi_b boot scripts. I have made the following modifications since then:

* Boards must define the BOOT_TARGET_DEVICES macro in order to specify
  the set of devices (and order) from which to attempt boot. If needed,
  we can define a default directly in config_distro_bootcmd.h.

* Removed $env_import and related variables; nothing used them, and I
  think it's better for boards to pre-load an environment customization
  file using CONFIG_PREBOOT if they need.

* Renamed a bunch of variables to suit my whims:-)

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Acked-by: Simon Glass <sjg@chromium.org>
APPLIED: ARM: tegra: use new generic $bootcmd

Replace the custom $bootcmd with that from <config_distro_bootcmd.h>.
There should be no functional change, since the new generic $bootcmd was
derived strongly from tegra-common-post.h.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Simon Glass <sjg@chromium.org>
APPLIED: ARM: rpi_b: use new generic $bootcmd

Replace the custom $bootcmd with that from <config_distro_bootcmd.h>.
There should be no functional change, since the new generic $bootcmd was
derived strongly from tegra-common-post.h, after which this part of
rpi_b.h was modelled.

The #defines to enable/disable U-Boot commands/features were moved
earlier in rpi_b.h, so they are set up before config_distro_bootcmd.h
is included, since it tests whether certain features should be included
based on those defines.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Simon Glass <sjg@chromium.org>
---
Note that while I've tested the Tegra conversion, I haven't tested this
one yet. I also didn't convert Wanda/Beagle/Panda, since I don't have
those boards to test. If this series is accepted, hopefully Dennis can
convert them, or perhaps I can try doing so blind:-)
APPLIED: lib: lmb: fix overflow in __lmb_alloc_base w/ large RAM

If a 32-bit system has 2GB of RAM, and the base address of that RAM is
2GB, then start+size will overflow a 32-bit value (to a value of 0).

__lmb_alloc_base is affected by this; it calculates the minimum of
(start+size of RAM) and max_addr. However, when start+size is 0, it
is always less than max_addr, which causes the value of max_addr not
to be taken into account when restricting the allocation's location.

Fix this by calculating start+size separately, and if that calculation
underflows, using -1 (interpreted as the max unsigned value) as the
value instead, and then taking the min of that and max_addr. Now that
start+size doesn't overflow, it's typically large, and max_addr
dominates the min() call, and is taken into account.

The user-visible symptom of this bug is that CONFIG_BOOTMAP_SZ is ignored
on Tegra124 systems with 2GB of RAM, which in turn causes the DT to be
relocated at the very end of RAM, which the ARM Linux kernel doesn't map
during early boot, and which causes boot failures. With this fix,
CONFIG_BOOTMAP_SZ correctly restricts the relocated DT to a much lower
address, and everything works.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
ARM: tegra: enable DFU too

Enable DFU protocol support (via the "dfu" command) on Tegra boards where
USB device/gadget mode is enabled.

Note that for DFU to operate correctly on Tegra, we still need some DFU
fixes/enhancements that are going through the DFU -> USB trees. However,
the code builds just fine without those changes, and applying this patch
now will allow both sets of patches to meet in the main U-Boot tree much
more quickly.

In order to run test/dfu/dfu_gadget_test.sh, you would need to add the
following to the board configuration:

CONFIG_EXT4_WRITE
CONFIG_CMD_EXT4_WRITE

However, I haven't enabled those here, since I believe the main use-case
for DFU on Tegra is raw flash writing, rather than filesystem access, so
we don't need the additional code-size hit. However, I could be persuaded
otherwise! We should probably add a separate test script for raw flash
access.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Simon Glass <sjg@chromium.org>
LOCAL: enable ext4 write for DFU testing

Signed-off-by: Stephen Warren <swarren@nvidia.com>
LOCAL: test: dfu: reduce max test binary size

Tegra's DFU buffer is smaller than 8M. Remove that test case since we
know it will fail.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
ARM: tegra: Disable VPR

(Note: Alex Courbot has sent this upstream)

On Tegra114 and Tegra124 platforms, certain display-related registers cannot
be accessed unless the VPR registers are programmed.  For bootloader, we
probably don't care about VPR, so we disable it (which counts as programming
it, and allows those display-related registers to be accessed.

This patch is based on the commit 5f499646c83ba08079f3fdff6591f638a0ce4c0c
in Chromium OS U-Boot project.

Signed-off-by: Andrew Chew <achew@nvidia.com>
Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Signed-off-by: Bryan Wu <pengw@nvidia.com>
[acourbot: ensure write went through, vpr.c style changes]
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Stephen Warren <swarren@nvidia.com>
Cc: Tom Warren <TWarren@nvidia.com>
Cc: Stephen Warren <swarren@nvidia.com>
Cc: Terje Bergstrom <tbergstrom@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
ARM: tegra: Use mem size from MC rather than ODMDATA

In at least Tegra124, the Tegra memory controller (MC) has a register
that controls the memory size. Read this to determine the memory size
rather than requiring this to be redundantly encoded into the ODMDATA.
This way, changes to the BCT (i.e. MC configuration) automatically
updated SW's view of the memory size, without requiring manual changes
to the ODMDATA.

Future work potentially required:
* Clip the memory size to architectural limits; U-Boot probably doesn't
  and won't support either LPAE or Tegra's "swiss cheese" memory layout,
  at least one of which would be required for >2GB RAM.
* Subtract out any carveout required by firmware on future SoCs.

Based-on-work-by: Tom Warren <twarren@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
Note: this patch depends on Bryan's/Alex's "ARM: tegra: Disable VPR",
since that introduces mc.h, which this patch relies on.
ARM: tegra: remove custom define for Jetson TK1

Now that Kconfig has a per-board option, we can use that directly rather
than inventing a custom define for the AS3722 code to determine which
board it's being built for.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
usb: hub: don't check CONNECTION in hub_port_reset()

One specific USB 3.0 device behaves strangely when reset by
usb_new_device()'s call to hub_port_reset(). For some reason, the device
appears to briefly drop off the bus when this second bus reset is
executed, yet if we retry this loop, it'll eventually come back after
another two resets.

If USB bus reset is executed over and over within usb_new_device()'s call
to hub_port_reset(), I see the following sequence of results, which
repeats as long as you want:

1) STAT_C_CONNECTION = 1 STAT_CONNECTION = 0  USB_PORT_STAT_ENABLE 0
2) STAT_C_CONNECTION = 1 STAT_CONNECTION = 1  USB_PORT_STAT_ENABLE 0
3) STAT_C_CONNECTION = 1 STAT_CONNECTION = 1  USB_PORT_STAT_ENABLE 1

The device in question is a SanDisk Ultra USB 3.0 16GB memory stick with
USB VID/PID 0x0781/0x5581.

In order to allow this device to work with U-Boot, ignore the
{C_,}CONNECTION bits in the status/change registers, and only use the
ENABLE bit to determine if the reset was successful.

To be honest, extensive investigation has failed to determine why this
problem occurs. I'd love to know! I don't know if it's caused by:
* A HW bug in the device
* A HW bug in the Tegra USB controller
* A SW bug in the U-Boot Tegra USB driver
* A SW bug in the U-Boot USB core

This issue only occurs when the device's USB3 pins are attached to the
host; if only the USB2 pins are connected the issue does not occur. The
USB3 controller on Tegra is in reset, so is not actively communicating
with the device at all - a USB3 analyzer confirms this. Slightly
unplugging the device (so the USB3 pins don't contact) or using a USB2
cable or hub as an intermediary avoids the problem. For some reason,
the Linux kernel (either on the same Tegra board, or on an x86 host)
has no issue with the device, and I observe no disconnections during
reset.

This change won't affect any USB device that already works, since such
devices could not currently be triggering the error return this patch
removes, or they wouldn't be working currently.

However, this patch is quite reliable in practice, hence I hope it's
acceptable to solve the problem.

The only potential fallout I can see from this patch is:

* A broken device that triggers C_CONNECTION/!CONNECTION now causes the
  loop in hub_port_reset() to run multiple times. If it never succeeds,
  this will cause "usb start" to take roughly 1s extra to execute.

* If the user unplugs a device while hub_port_reset() is executing, and
  very quickly swaps in a new device, hub_port_reset() might succeed on
  the new device. This would mean that any information cached about the
  original device (from the descriptor read in usb_new_device(), which
  simply caches the max packet size) might be invalid, which would cause
  problems talking to the new device. However, without this change, the
  new device wouldn't work anyway, so this is probably not much of a
  loss.

Signed-off-by: Stephen Warren <swarren@nvidia.com>