From 2e372b80ad3b5d59e572fcfef317740ac977a232 Mon Sep 17 00:00:00 2001 From: Vicente Bergas Date: Wed, 11 Jan 2017 20:32:05 +0100 Subject: [PATCH 1/9] scripts/omap4_usbboot: use libusb Signed-off-by: Vicente Bergas Signed-off-by: Sascha Hauer --- scripts/.gitignore | 1 + scripts/Makefile | 4 +- scripts/{omap4_usbboot => }/omap4_usbboot.c | 78 ++-- scripts/omap4_usbboot/.gitignore | 1 - scripts/omap4_usbboot/Makefile | 5 - scripts/omap4_usbboot/usb.h | 61 --- scripts/omap4_usbboot/usb_linux.c | 397 -------------------- 7 files changed, 55 insertions(+), 492 deletions(-) rename scripts/{omap4_usbboot => }/omap4_usbboot.c (87%) delete mode 100644 scripts/omap4_usbboot/.gitignore delete mode 100644 scripts/omap4_usbboot/Makefile delete mode 100644 scripts/omap4_usbboot/usb.h delete mode 100644 scripts/omap4_usbboot/usb_linux.c diff --git a/scripts/.gitignore b/scripts/.gitignore index 533bffd97..2a9ae6bdc 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -25,3 +25,4 @@ mk-am35xx-spi-image mxsimage mxsboot mxs-usb-loader +omap4_usbboot diff --git a/scripts/Makefile b/scripts/Makefile index a5c16b2f3..7f2527d1c 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -28,9 +28,11 @@ hostprogs-$(CONFIG_ARCH_MXS_USBLOADER) += mxs-usb-loader HOSTCFLAGS_omap3-usb-loader.o = `pkg-config --cflags libusb-1.0` HOSTLOADLIBES_omap3-usb-loader = `pkg-config --libs libusb-1.0` hostprogs-$(CONFIG_OMAP3_USB_LOADER) += omap3-usb-loader +HOSTCFLAGS_omap4_usbboot.o = `pkg-config --cflags libusb-1.0` +HOSTLOADLIBES_omap4_usbboot = -lpthread `pkg-config --libs libusb-1.0` +hostprogs-$(CONFIG_OMAP4_USBBOOT) += omap4_usbboot subdir-y += mod -subdir-$(CONFIG_OMAP4_USBBOOT) += omap4_usbboot subdir-$(CONFIG_ARCH_IMX) += imx subdir-$(CONFIG_X86) += setupmbr subdir-$(CONFIG_DTC) += dtc diff --git a/scripts/omap4_usbboot/omap4_usbboot.c b/scripts/omap4_usbboot.c similarity index 87% rename from scripts/omap4_usbboot/omap4_usbboot.c rename to scripts/omap4_usbboot.c index 0e5abcb15..329668d1d 100644 --- a/scripts/omap4_usbboot/omap4_usbboot.c +++ b/scripts/omap4_usbboot.c @@ -8,6 +8,8 @@ * 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. + * + * Inspired by: https://github.com/simu/usbboot-omap4.git */ #include @@ -18,11 +20,10 @@ #include #include #include +#include #include #include -#include "usb.h" - #define USBBOOT_FS_MAGIC 0x5562464D #define USBBOOT_FS_CMD_OPEN 0x46530000 #define USBBOOT_FS_CMD_CLOSE 0x46530001 @@ -42,6 +43,20 @@ #define host_print(fmt, arg...) printf(HFORMAT fmt TFORMAT, \ HOST_FORMAT, ##arg, TARGET_FORMAT) +int usb_write(void *h, void const *data, int len) +{ + int actual; + return libusb_bulk_transfer(h, 0x01, (void *)data, len, &actual, 5000) ? + 0 : actual; +} + +int usb_read(void *h, void *data, int len) +{ + int actual; + return libusb_bulk_transfer(h, 0x81, data, len, &actual, 5000) ? + 0 : actual; +} + void panic(struct termios *t_restore) { tcsetattr(STDIN_FILENO, TCSANOW, t_restore); @@ -50,7 +65,7 @@ void panic(struct termios *t_restore) } struct thread_vars { - struct usb_handle *usb; + struct libusb_device_handle *usb; pthread_mutex_t usb_mutex; struct termios t_restore; }; @@ -73,7 +88,7 @@ void *listenerTask(void *argument) return NULL; } -int read_asic_id(struct usb_handle *usb) +int read_asic_id(struct libusb_device_handle *usb) { #define LINEWIDTH 16 const uint32_t msg_getid = 0xF0030003; @@ -174,7 +189,7 @@ struct file_data { void *data; }; -int process_file(struct usb_handle *usb, const char *rootfs, +int process_file(struct libusb_device_handle *usb, const char *rootfs, struct file_data *fd_vector, struct termios *t_restore) { uint32_t i, j, pos, size; @@ -324,8 +339,8 @@ open_ok: return ret; } -int usb_boot( - struct usb_handle *usb, void *data, unsigned sz, const char *rootfs) +int usb_boot(struct libusb_device_handle *usb, + void *data, unsigned sz, const char *rootfs) { const uint32_t msg_boot = 0xF0030002; uint32_t msg_size = sz; @@ -373,30 +388,21 @@ int usb_boot( printf("%c", i); fflush(stdout); } - usb_close(usb); pthread_mutex_destroy(&vars.usb_mutex); tcsetattr(STDIN_FILENO, TCSANOW, &vars.t_restore); printf(HFORMAT, HOST_FORMAT); return 0; } -int match_omap4_bootloader(struct usb_ifc_info *ifc) -{ - if (ifc->dev_vendor != 0x0451) - return -1; - if ((ifc->dev_product != 0xD010) && (ifc->dev_product != 0xD00F)) - return -1; - return 0; -} - int main(int argc, char **argv) { void *data; unsigned sz; struct stat s; int fd; - struct usb_handle *usb; - int once; + int ret; + struct libusb_context *ctx = NULL; + struct libusb_device_handle *usb = NULL; if (argc != 3) { printf("usage: %s \n", argv[0]); @@ -416,16 +422,34 @@ int main(int argc, char **argv) sz = s.st_size; close(fd); argv++; + if (libusb_init(&ctx)) { + printf("cannot initialize libusb\n"); + return -1; + } printf(HFORMAT, HOST_FORMAT); - for (once = 1;;) { - usb = usb_open(match_omap4_bootloader); - if (usb) - return usb_boot(usb, data, sz, argv[0]); - if (once) { - once = 0; - printf("waiting for OMAP44xx device...\n"); + printf("waiting for OMAP44xx device...\n"); + while (1) { + if (!usb) + usb = libusb_open_device_with_vid_pid( + ctx, 0x0451, 0xD010); + if (!usb) + usb = libusb_open_device_with_vid_pid( + ctx, 0x0451, 0xD00F); + if (usb) { + libusb_detach_kernel_driver(usb, 0); + ret = libusb_set_configuration(usb, 1); + if (ret) + break; + ret = libusb_claim_interface(usb, 0); + if (ret) + break; + ret = usb_boot(usb, data, sz, argv[0]); + break; } usleep(250000); } - return -1; + libusb_release_interface(usb, 0); + libusb_close(usb); + libusb_exit(ctx); + return ret; } diff --git a/scripts/omap4_usbboot/.gitignore b/scripts/omap4_usbboot/.gitignore deleted file mode 100644 index 1975a2172..000000000 --- a/scripts/omap4_usbboot/.gitignore +++ /dev/null @@ -1 +0,0 @@ -omap4_usbboot diff --git a/scripts/omap4_usbboot/Makefile b/scripts/omap4_usbboot/Makefile deleted file mode 100644 index af6444b0e..000000000 --- a/scripts/omap4_usbboot/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -HOSTLOADLIBES_omap4_usbboot = -lpthread -omap4_usbboot-objs := usb_linux.o omap4_usbboot.o -hostprogs-$(CONFIG_OMAP4_USBBOOT) += omap4_usbboot - -always := $(hostprogs-y) diff --git a/scripts/omap4_usbboot/usb.h b/scripts/omap4_usbboot/usb.h deleted file mode 100644 index d50aa6aa6..000000000 --- a/scripts/omap4_usbboot/usb.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _USB_H_ -#define _USB_H_ - -struct usb_ifc_info { - /* from device descriptor */ - unsigned short dev_vendor; - unsigned short dev_product; - - unsigned char dev_class; - unsigned char dev_subclass; - unsigned char dev_protocol; - - unsigned char ifc_class; - unsigned char ifc_subclass; - unsigned char ifc_protocol; - - unsigned char has_bulk_in; - unsigned char has_bulk_out; - - unsigned char writable; - - char serial_number[256]; -}; - -typedef int (*ifc_match_func)(struct usb_ifc_info *ifc); - -struct usb_handle *usb_open(ifc_match_func callback); -int usb_close(struct usb_handle *h); -int usb_read(struct usb_handle *h, void *_data, int len); -int usb_write(struct usb_handle *h, const void *_data, int len); - - -#endif diff --git a/scripts/omap4_usbboot/usb_linux.c b/scripts/omap4_usbboot/usb_linux.c deleted file mode 100644 index 9a6e0b84d..000000000 --- a/scripts/omap4_usbboot/usb_linux.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "usb.h" - -#define MAX_RETRIES 2 - -#ifdef TRACE_USB -#define DBG1(x...) fprintf(stderr, x) -#define DBG(x...) fprintf(stderr, x) -#else -#define DBG(x...) -#define DBG1(x...) -#endif - -struct usb_handle { - char fname[64]; - int desc; - unsigned char ep_in; - unsigned char ep_out; -}; - -static inline int badname(const char *name) -{ - while (*name) { - if (!isdigit(*name++)) - return 1; - } - return 0; -} - -static int check(void *_desc, int len, unsigned type, int size) -{ - unsigned char *desc = _desc; - - if (len < size) - return -1; - if (desc[0] < size) - return -1; - if (desc[0] > len) - return -1; - if (desc[1] != type) - return -1; - - return 0; -} - -static int filter_usb_device(int fd, char *ptr, int len, int writable, - ifc_match_func callback, int *ept_in_id, int *ept_out_id, int *ifc_id) -{ - struct usb_device_descriptor *dev; - struct usb_config_descriptor *cfg; - struct usb_interface_descriptor *ifc; - struct usb_endpoint_descriptor *ept; - struct usb_ifc_info info; - - int in, out; - unsigned i; - unsigned e; - - if (check(ptr, len, USB_DT_DEVICE, USB_DT_DEVICE_SIZE)) - return -1; - dev = (void *) ptr; - len -= dev->bLength; - ptr += dev->bLength; - - if (check(ptr, len, USB_DT_CONFIG, USB_DT_CONFIG_SIZE)) - return -1; - cfg = (void *) ptr; - len -= cfg->bLength; - ptr += cfg->bLength; - - info.dev_vendor = dev->idVendor; - info.dev_product = dev->idProduct; - info.dev_class = dev->bDeviceClass; - info.dev_subclass = dev->bDeviceSubClass; - info.dev_protocol = dev->bDeviceProtocol; - info.writable = writable; - - /* read device serial number (if there is one) */ - info.serial_number[0] = 0; - if (dev->iSerialNumber) { - struct usbdevfs_ctrltransfer ctrl; - __u16 buffer[128]; - int result; - - memset(buffer, 0, sizeof(buffer)); - - ctrl.bRequestType = USB_DIR_IN| - USB_TYPE_STANDARD|USB_RECIP_DEVICE; - ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; - ctrl.wValue = (USB_DT_STRING << 8) | dev->iSerialNumber; - ctrl.wIndex = 0; - ctrl.wLength = sizeof(buffer); - ctrl.data = buffer; - ctrl.timeout = 50; - - result = ioctl(fd, USBDEVFS_CONTROL, &ctrl); - if (result > 0) { - int i; - /* skip first word, and copy the rest to the serial - string, changing shorts to bytes. */ - result /= 2; - for (i = 1; i < result; i++) - info.serial_number[i - 1] = buffer[i]; - info.serial_number[i - 1] = 0; - } - } - - for (i = 0; i < cfg->bNumInterfaces; i++) { - if (check(ptr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE)) - return -1; - ifc = (void *) ptr; - len -= ifc->bLength; - ptr += ifc->bLength; - - in = -1; - out = -1; - info.ifc_class = ifc->bInterfaceClass; - info.ifc_subclass = ifc->bInterfaceSubClass; - info.ifc_protocol = ifc->bInterfaceProtocol; - - for (e = 0; e < ifc->bNumEndpoints; e++) { - if (check(ptr, len, USB_DT_ENDPOINT, - USB_DT_ENDPOINT_SIZE) - ) - return -1; - ept = (void *) ptr; - len -= ept->bLength; - ptr += ept->bLength; - - if ((ept->bmAttributes & 0x03) != 0x02) - continue; - - if (ept->bEndpointAddress & 0x80) - in = ept->bEndpointAddress; - else - out = ept->bEndpointAddress; - } - - info.has_bulk_in = (in != -1); - info.has_bulk_out = (out != -1); - - if (callback(&info) == 0) { - *ept_in_id = in; - *ept_out_id = out; - *ifc_id = ifc->bInterfaceNumber; - return 0; - } - } - - return -1; -} - -static struct usb_handle *find_usb_device( - const char *base, ifc_match_func callback) -{ - struct usb_handle *usb = 0; - char busname[64], devname[64]; - char desc[1024]; - int n, in, out, ifc; - - DIR *busdir, *devdir; - struct dirent *de; - int fd; - int writable; - - busdir = opendir(base); - if (busdir == 0) - return 0; - - while ((de = readdir(busdir)) && (usb == 0)) { - if (badname(de->d_name)) - continue; - - sprintf(busname, "%s/%s", base, de->d_name); - devdir = opendir(busname); - if (devdir == 0) - continue; - - /* DBG("[ scanning %s ]\n", busname); */ - while ((de = readdir(devdir)) && (usb == 0)) { - - if (badname(de->d_name)) - continue; - sprintf(devname, "%s/%s", busname, de->d_name); - - /* DBG("[ scanning %s ]\n", devname); */ - writable = 1; - fd = open(devname, O_RDWR); - if (fd < 0) { - /* Check if we have read-only access, - so we can give a helpful diagnostic - like "adb devices" does. */ - writable = 0; - fd = open(devname, O_RDONLY); - if (fd < 0) - continue; - } - - n = read(fd, desc, sizeof(desc)); - - if (filter_usb_device(fd, desc, n, writable, - callback, &in, &out, &ifc) == 0 - ) { - usb = calloc(1, sizeof(struct usb_handle)); - strcpy(usb->fname, devname); - usb->ep_in = in; - usb->ep_out = out; - usb->desc = fd; - - n = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &ifc); - if (n != 0) { - close(fd); - free(usb); - usb = 0; - continue; - } - } else - close(fd); - } - closedir(devdir); - } - closedir(busdir); - - return usb; -} - -int usb_write(struct usb_handle *h, const void *_data, int len) -{ - unsigned char *data = (unsigned char *) _data; - unsigned count = 0; - struct usbdevfs_bulktransfer bulk; - int n; - - if (h->ep_out == 0) - return -1; - - if (len == 0) { - bulk.ep = h->ep_out; - bulk.len = 0; - bulk.data = data; - bulk.timeout = 0; - - n = ioctl(h->desc, USBDEVFS_BULK, &bulk); - if (n != 0) { - fprintf(stderr, "ERROR: n = %d, errno = %d (%s)\n", - n, errno, strerror(errno)); - return -1; - } - return 0; - } - - while (len > 0) { - int xfer; - xfer = (len > 4096) ? 4096 : len; - - bulk.ep = h->ep_out; - bulk.len = xfer; - bulk.data = data; - bulk.timeout = 0; - - n = ioctl(h->desc, USBDEVFS_BULK, &bulk); - if (n != xfer) { - DBG("ERROR: n = %d, errno = %d (%s)\n", - n, errno, strerror(errno)); - return -1; - } - - count += xfer; - len -= xfer; - data += xfer; - } - - return count; -} - -int usb_read(struct usb_handle *h, void *_data, int len) -{ - unsigned char *data = (unsigned char *) _data; - unsigned count = 0; - struct usbdevfs_bulktransfer bulk; - int n, retry; - - if (h->ep_in == 0) - return -1; - - while (len > 0) { - int xfer = (len > 4096) ? 4096 : len; - - bulk.ep = h->ep_in; - bulk.len = xfer; - bulk.data = data; - bulk.timeout = 0; - retry = 0; - - do { - DBG("[ usb read %d fd = %d], fname=%s\n", - xfer, h->desc, h->fname); - n = ioctl(h->desc, USBDEVFS_BULK, &bulk); - DBG("[ usb read %d ] = %d, fname=%s, Retry %d\n", - xfer, n, h->fname, retry); - - if (n < 0) { - DBG1("ERROR: n = %d, errno = %d (%s)\n", - n, errno, strerror(errno)); - if (++retry > MAX_RETRIES) - return -1; - usleep(10000); - } - } while (n < 0); - - count += n; - len -= n; - data += n; - - if (n < xfer) - break; - } - - return count; -} - -void usb_kick(struct usb_handle *h) -{ - int fd; - - fd = h->desc; - h->desc = -1; - if (fd >= 0) { - close(fd); - DBG("[ usb closed %d ]\n", fd); - } -} - -int usb_close(struct usb_handle *h) -{ - int fd; - - fd = h->desc; - h->desc = -1; - if (fd >= 0) { - close(fd); - DBG("[ usb closed %d ]\n", fd); - } - - return 0; -} - -struct usb_handle *usb_open(ifc_match_func callback) -{ - return find_usb_device("/dev/bus/usb", callback); -} From 2428227a907fb4ccd9d36ba8cb50a3eeadc7c8bc Mon Sep 17 00:00:00 2001 From: Juergen Borleis Date: Wed, 7 Dec 2016 15:25:23 +0100 Subject: [PATCH 2/9] ARM: Makefile: format fix Signed-off-by: Juergen Borleis --- arch/arm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 96ec588da..620a3ccb0 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -32,7 +32,7 @@ endif # testing for a specific architecture or later rather impossible. arch-$(CONFIG_CPU_64v8) := -D__LINUX_ARM_ARCH__=8 $(call cc-option,-march=armv8-a) arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a) -arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) +arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t From aa01ab27ffbee9a225cf96576c94f31986820b7e Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 18 Jan 2017 10:51:41 +0100 Subject: [PATCH 3/9] arm: omap: OMAP_SERIALBOOT needs console support It is quite useless without a console and breaks the build. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- arch/arm/mach-omap/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig index 93fa35a20..9c41741b5 100644 --- a/arch/arm/mach-omap/Kconfig +++ b/arch/arm/mach-omap/Kconfig @@ -149,6 +149,7 @@ config OMAP_SERIALBOOT select XYMODEM select FS_RAMFS depends on ARCH_AM33XX && SHELL_NONE + depends on !CONSOLE_NONE help Say Y here if you want to load the 2nd stage barebox.bin with xmodem after booting from serial line. From 80807102b904fbd418621a5865a3796107b3684d Mon Sep 17 00:00:00 2001 From: Daniel Schultz Date: Thu, 26 Jan 2017 09:25:44 +0100 Subject: [PATCH 4/9] arm: am33xx: Initialize EMIF REG_PR_OLD_COUNT This patch is based on a patch from the U-Boot and fixes two errors with the LCDC. Original commit message from Jyri Sarha [1]: "Initialize EMIF OCP_CONFIG registers REG_COS_COUNT_1, REG_COS_COUNT_2, and REG_PR_OLD_COUNT field for Beaglebone-Black and am335x-evm. With the default values LCDC suffers from DMA FIFO underflows and frame synchronization lost errors. The initialization values are the highest that work flawlessly when heavy memory load is generated by CPU. 32bpp colors were used in the test. On BBB the video mode used 110MHz pixel clock. The mode supported by the panel of am335x-evm uses 30MHz pixel clock." The register values are generated by testing, because there is no formula to calculate them. Also from Jyri Sarha [1]: "In practice the only rule to find an optimal value is to find as high as possible REG_PR_OLD_COUNT value that does not produce LCDC FIFO underflows under worst case scenario. The worst case happens when the highest pixel clock videomode with maximum bpp is used while memory subsystem is stressed by endless stream of writes hitting the same memory memory bank (can be the same address)." It only contains the BeagleBone Black and the Phytec SoM, because I don't have other boards. [1] https://patchwork.ozlabs.org/patch/704013/ Signed-off-by: Daniel Schultz Signed-off-by: Sascha Hauer --- arch/arm/boards/beaglebone/lowlevel.c | 2 ++ arch/arm/boards/phytec-som-am335x/ram-timings.h | 11 +++++++++++ arch/arm/mach-omap/am33xx_generic.c | 3 +++ arch/arm/mach-omap/include/mach/am33xx-silicon.h | 2 ++ 4 files changed, 18 insertions(+) diff --git a/arch/arm/boards/beaglebone/lowlevel.c b/arch/arm/boards/beaglebone/lowlevel.c index 100f64fdd..a56b4b624 100644 --- a/arch/arm/boards/beaglebone/lowlevel.c +++ b/arch/arm/boards/beaglebone/lowlevel.c @@ -41,6 +41,7 @@ static const struct am33xx_emif_regs ddr2_regs = { .emif_tim1 = 0x0666B3C9, .emif_tim2 = 0x243631CA, .emif_tim3 = 0x0000033F, + .ocp_config = 0x00141414, .sdram_config = 0x41805332, .sdram_config2 = 0x41805332, .sdram_ref_ctrl = 0x0000081A, @@ -97,6 +98,7 @@ static const struct am33xx_emif_regs ddr3_regs = { .emif_tim1 = 0x0AAAD4DB, .emif_tim2 = 0x266B7FDA, .emif_tim3 = 0x501F867F, + .ocp_config = 0x00141414, .zq_config = 0x50074BE4, .sdram_config = 0x61C05332, .sdram_config2 = 0x0, diff --git a/arch/arm/boards/phytec-som-am335x/ram-timings.h b/arch/arm/boards/phytec-som-am335x/ram-timings.h index 9576d265e..4ea654db1 100644 --- a/arch/arm/boards/phytec-som-am335x/ram-timings.h +++ b/arch/arm/boards/phytec-som-am335x/ram-timings.h @@ -45,6 +45,7 @@ struct am335x_sdram_timings physom_timings[] = { .emif_tim1 = 0x0AAAD4DB, .emif_tim2 = 0x26437FDA, .emif_tim3 = 0x501F83FF, + .ocp_config = 0x003d3d3d, .sdram_config = 0x61C052B2, .zq_config = 0x50074BE4, .sdram_ref_ctrl = 0x00000C30, @@ -66,6 +67,7 @@ struct am335x_sdram_timings physom_timings[] = { .emif_tim1 = 0x0AAAE4DB, .emif_tim2 = 0x266B7FDA, .emif_tim3 = 0x501F867F, + .ocp_config = 0x003d3d3d, .sdram_config = 0x61C05332, .zq_config = 0x50074BE4, .sdram_ref_ctrl = 0x00000C30, @@ -87,6 +89,7 @@ struct am335x_sdram_timings physom_timings[] = { .emif_tim1 = 0x0AAAD4DB, .emif_tim2 = 0x26437FDA, .emif_tim3 = 0x501F83FF, + .ocp_config = 0x003d3d3d, .sdram_config = 0x61C052B2, .zq_config = 0x50074BE4, .sdram_ref_ctrl = 0x00000C30, @@ -106,6 +109,7 @@ struct am335x_sdram_timings physom_timings[] = { .emif_tim1 = 0x0AAAE4DB, .emif_tim2 = 0x262F7FDA, .emif_tim3 = 0x501F82BF, + .ocp_config = 0x003d3d3d, .sdram_config = 0x61C05232, .zq_config = 0x50074BE4, .sdram_ref_ctrl = 0x00000C30, @@ -125,6 +129,7 @@ struct am335x_sdram_timings physom_timings[] = { .emif_tim1 = 0x0AAAE4DB, .emif_tim2 = 0x266B7FDA, .emif_tim3 = 0x501F867F, + .ocp_config = 0x003d3d3d, .sdram_config = 0x61C05332, .zq_config = 0x50074BE4, .sdram_ref_ctrl = 0x00000C30 @@ -144,6 +149,7 @@ struct am335x_sdram_timings physom_timings[] = { .emif_tim1 = 0x0AAAE4DB, .emif_tim2 = 0x266B7FDA, .emif_tim3 = 0x501F867F, + .ocp_config = 0x003d3d3d, .sdram_config = 0x61C053B2, .zq_config = 0x50074BE4, .sdram_ref_ctrl = 0x00000C30 @@ -163,6 +169,7 @@ struct am335x_sdram_timings physom_timings[] = { .emif_tim1 = 0x0AAAE4DB, .emif_tim2 = 0x268F7FDA, .emif_tim3 = 0x501F88BF, + .ocp_config = 0x003d3d3d, .sdram_config = 0x61C053B2, .zq_config = 0x50074BE4, .sdram_ref_ctrl = 0x00000C30 @@ -182,6 +189,7 @@ struct am335x_sdram_timings physom_timings[] = { .emif_tim1 = 0x0AAAD4DB, .emif_tim2 = 0x26437FDA, .emif_tim3 = 0x501F83FF, + .ocp_config = 0x003d3d3d, .sdram_config = 0x61C052B2, .zq_config = 0x50074BE4, .sdram_ref_ctrl = 0x00000C30, @@ -203,6 +211,7 @@ struct am335x_sdram_timings physom_timings[] = { .emif_tim1 = 0x0AAAD4DB, .emif_tim2 = 0x266B7FDA, .emif_tim3 = 0x501F867F, + .ocp_config = 0x003d3d3d, .sdram_config = 0x61C05332, .zq_config = 0x50074BE4, .sdram_ref_ctrl = 0x00000C30, @@ -222,6 +231,7 @@ struct am335x_sdram_timings physom_timings[] = { .emif_tim1 = 0x0AAAD4DB, .emif_tim2 = 0x26437FDA, .emif_tim3 = 0x501F83FF, + .ocp_config = 0x003d3d3d, .sdram_config = 0x61C052B2, .zq_config = 0x50074BE4, .sdram_ref_ctrl = 0x00000C30, @@ -241,6 +251,7 @@ struct am335x_sdram_timings physom_timings[] = { .emif_tim1 = 0x0AAAD4DB, .emif_tim2 = 0x268F7FDA, .emif_tim3 = 0x501F88BF, + .ocp_config = 0x003d3d3d, .sdram_config = 0x61C053B2, .zq_config = 0x50074BE4, .sdram_ref_ctrl = 0x00000C30, diff --git a/arch/arm/mach-omap/am33xx_generic.c b/arch/arm/mach-omap/am33xx_generic.c index 5eead5c58..513746248 100644 --- a/arch/arm/mach-omap/am33xx_generic.c +++ b/arch/arm/mach-omap/am33xx_generic.c @@ -341,6 +341,9 @@ void am33xx_config_sdram(const struct am33xx_emif_regs *regs) writel(regs->emif_tim3, AM33XX_EMIF4_0_REG(SDRAM_TIM_3)); writel(regs->emif_tim3, AM33XX_EMIF4_0_REG(SDRAM_TIM_3_SHADOW)); + if (regs->ocp_config) + writel(regs->ocp_config, AM33XX_EMIF4_0_REG(OCP_CONFIG)); + if (regs->zq_config) { /* * A value of 0x2800 for the REF CTRL will give us diff --git a/arch/arm/mach-omap/include/mach/am33xx-silicon.h b/arch/arm/mach-omap/include/mach/am33xx-silicon.h index 10595d5ee..072936925 100644 --- a/arch/arm/mach-omap/include/mach/am33xx-silicon.h +++ b/arch/arm/mach-omap/include/mach/am33xx-silicon.h @@ -114,6 +114,7 @@ #define EMIF4_SDRAM_TIM_3_SHADOW 0x2C #define EMIF0_SDRAM_MGMT_CTRL 0x38 #define EMIF0_SDRAM_MGMT_CTRL_SHD 0x3C +#define EMIF4_OCP_CONFIG 0x54 #define EMIF4_ZQ_CONFIG 0xC8 #define EMIF4_DDR_PHY_CTRL_1 0xE4 #define EMIF4_DDR_PHY_CTRL_1_SHADOW 0xE8 @@ -217,6 +218,7 @@ struct am33xx_emif_regs { u32 emif_tim1; u32 emif_tim2; u32 emif_tim3; + u32 ocp_config; u32 sdram_config; u32 sdram_config2; u32 zq_config; From f7165017f41fab86c1dd97e40de2355fc64dde2f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 20 Jan 2017 11:47:41 +0100 Subject: [PATCH 5/9] ARM: start: Fix boarddata allocation It's essential that we always pass the same size value to arm_mem_barebox_image(), otherwise the result will be inconsistent. Pass arm_barebox_size instead of barebox_image_size as the latter does not contain the max bss segment size. Signed-off-by: Sascha Hauer --- arch/arm/cpu/start.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c index a62b0d556..171e6ad0e 100644 --- a/arch/arm/cpu/start.c +++ b/arch/arm/cpu/start.c @@ -116,7 +116,7 @@ static inline unsigned long arm_mem_boarddata(unsigned long membase, { unsigned long mem; - mem = arm_mem_barebox_image(membase, endmem, barebox_image_size); + mem = arm_mem_barebox_image(membase, endmem, arm_barebox_size); mem -= ALIGN(size, 64); return mem; From 857f69ba8c66e3b4834bcaafd373a83043629326 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 6 Feb 2017 11:18:07 +0100 Subject: [PATCH 6/9] ARM: start: Fix image size calculation In barebox_non_pbl_start() we do not run at the address we are linked at, so we must read linker variables using ld_var(). Since ld_var() current is not available on arm64 we create two zero sized arrays, one at the begin of the image and one at the end. The difference between both is the image size we are looking for. Signed-off-by: Sascha Hauer --- arch/arm/boards/avnet-zedboard/flash_header.c | 4 ++-- arch/arm/boards/friendlyarm-tiny210/lowlevel.c | 2 +- arch/arm/cpu/common.c | 3 +++ arch/arm/include/asm/barebox-arm.h | 2 ++ arch/arm/lib32/barebox.lds.S | 2 ++ arch/arm/lib32/runtime-offset.S | 1 - drivers/mtd/nand/nand_s3c24xx.c | 2 +- include/asm-generic/sections.h | 3 ++- 8 files changed, 13 insertions(+), 6 deletions(-) diff --git a/arch/arm/boards/avnet-zedboard/flash_header.c b/arch/arm/boards/avnet-zedboard/flash_header.c index ea2052405..d9eb35b0d 100644 --- a/arch/arm/boards/avnet-zedboard/flash_header.c +++ b/arch/arm/boards/avnet-zedboard/flash_header.c @@ -52,10 +52,10 @@ struct zynq_flash_header __flash_header_section flash_header = { .enc_stat = 0x0, .user = 0x0, .flash_offset = 0x8c0, - .length = barebox_image_size, + .length = (unsigned int)&_barebox_image_size, .res0 = 0x0, .start_of_exec = 0x0, - .total_len = barebox_image_size, + .total_len = (unsigned int)&_barebox_image_size, .res1 = 0x1, .checksum = 0x0, .res2 = 0x0, diff --git a/arch/arm/boards/friendlyarm-tiny210/lowlevel.c b/arch/arm/boards/friendlyarm-tiny210/lowlevel.c index 3ab8d6606..fea00ef50 100644 --- a/arch/arm/boards/friendlyarm-tiny210/lowlevel.c +++ b/arch/arm/boards/friendlyarm-tiny210/lowlevel.c @@ -97,7 +97,7 @@ void __bare_init barebox_arm_reset_vector(void) debug_led(1, 1); if (! load_stage2((void*)(ld_var(_text) - 16), - ld_var(_barebox_image_size) + 16)) { + barebox_image_size + 16)) { debug_led(3, 1); while (1) { } /* hang */ } diff --git a/arch/arm/cpu/common.c b/arch/arm/cpu/common.c index 46ce94218..dcd8f0b73 100644 --- a/arch/arm/cpu/common.c +++ b/arch/arm/cpu/common.c @@ -78,3 +78,6 @@ int __pure cpu_architecture(void) return __cpu_architecture; } #endif + +char __image_start[0] __attribute__((section(".__image_start"))); +char __image_end[0] __attribute__((section(".__image_end"))); \ No newline at end of file diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index e8dfd0238..3aea2e070 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -179,4 +179,6 @@ static inline unsigned long arm_mem_barebox_image(unsigned long membase, */ #define MAX_BSS_SIZE SZ_1M +#define barebox_image_size (__image_end - __image_start) + #endif /* _BAREBOX_ARM_H_ */ diff --git a/arch/arm/lib32/barebox.lds.S b/arch/arm/lib32/barebox.lds.S index 6dc8bd2f3..5fd39dc66 100644 --- a/arch/arm/lib32/barebox.lds.S +++ b/arch/arm/lib32/barebox.lds.S @@ -30,6 +30,7 @@ SECTIONS #else . = TEXT_BASE; #endif + .image_start : { *(.__image_start) } #ifndef CONFIG_PBL_IMAGE PRE_IMAGE @@ -116,6 +117,7 @@ SECTIONS } _edata = .; + .image_end : { *(.__image_end) } . = ALIGN(4); __bss_start = .; diff --git a/arch/arm/lib32/runtime-offset.S b/arch/arm/lib32/runtime-offset.S index f10c4c846..7375cb961 100644 --- a/arch/arm/lib32/runtime-offset.S +++ b/arch/arm/lib32/runtime-offset.S @@ -39,7 +39,6 @@ ld_var_entry __rel_dyn_start ld_var_entry __rel_dyn_end ld_var_entry __dynsym_start ld_var_entry __dynsym_end -ld_var_entry _barebox_image_size ld_var_entry __bss_start ld_var_entry __bss_stop #ifdef __PBL__ diff --git a/drivers/mtd/nand/nand_s3c24xx.c b/drivers/mtd/nand/nand_s3c24xx.c index 83d45172b..df2273548 100644 --- a/drivers/mtd/nand/nand_s3c24xx.c +++ b/drivers/mtd/nand/nand_s3c24xx.c @@ -614,7 +614,7 @@ void __nand_boot_init s3c24x0_nand_load_image(void *dest, int size, int page) void __nand_boot_init nand_boot(void) { void *dest = _text; - int size = ld_var(_barebox_image_size); + int size = barebox_image_size; int page = 0; s3c24x0_nand_load_image(dest, size, page); diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index 984f8b606..0eb18f614 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -6,12 +6,13 @@ extern char __bss_start[], __bss_stop[]; extern char _sdata[], _edata[]; extern char __bare_init_start[], __bare_init_end[]; extern char _end[]; +extern char __image_start[]; extern char __image_end[]; extern void *_barebox_image_size; extern void *_barebox_bare_init_size; extern void *_barebox_pbl_size; -#define barebox_image_size (unsigned int)&_barebox_image_size +#define barebox_image_size (__image_end - __image_start) #define barebox_bare_init_size (unsigned int)&_barebox_bare_init_size #define barebox_pbl_size (unsigned int)&_barebox_pbl_size From 14c6fc99e1a338fc3804a1e858a60e8b32d4dd0a Mon Sep 17 00:00:00 2001 From: Wadim Egorov Date: Thu, 9 Feb 2017 10:36:41 +0100 Subject: [PATCH 7/9] ARM: phycore-rk3288: Use UART2 as debug output RK3288's UART2 is the default debug uart interface. Signed-off-by: Wadim Egorov Signed-off-by: Sascha Hauer --- arch/arm/boards/phytec-som-rk3288/lowlevel.c | 11 +++++------ arch/arm/dts/rk3288-phycore-som.dts | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/arm/boards/phytec-som-rk3288/lowlevel.c b/arch/arm/boards/phytec-som-rk3288/lowlevel.c index 7804a55bc..7649ef864 100644 --- a/arch/arm/boards/phytec-som-rk3288/lowlevel.c +++ b/arch/arm/boards/phytec-som-rk3288/lowlevel.c @@ -30,14 +30,13 @@ ENTRY_FUNCTION(start_rk3288_phycore_som, r0, r1, r2) if (IS_ENABLED(CONFIG_DEBUG_LL)) { struct rk3288_grf * const grf = (void *)RK3288_GRF_BASE; - rk_clrsetreg(&grf->gpio4c_iomux, - GPIO4C1_MASK << GPIO4C1_SHIFT | - GPIO4C0_MASK << GPIO4C0_SHIFT, - GPIO4C1_UART0BT_SOUT << GPIO4C1_SHIFT | - GPIO4C0_UART0BT_SIN << GPIO4C0_SHIFT); + rk_clrsetreg(&grf->gpio7ch_iomux, + GPIO7C7_MASK << GPIO7C7_SHIFT | + GPIO7C6_MASK << GPIO7C6_SHIFT, + GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT | + GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT); INIT_LL(); } - fdt = __dtb_rk3288_phycore_som_start - get_runtime_offset(); barebox_arm_entry(0x0, SZ_1G, fdt); diff --git a/arch/arm/dts/rk3288-phycore-som.dts b/arch/arm/dts/rk3288-phycore-som.dts index 5410bd1f7..dd74bcfb1 100644 --- a/arch/arm/dts/rk3288-phycore-som.dts +++ b/arch/arm/dts/rk3288-phycore-som.dts @@ -44,7 +44,7 @@ }; chosen { - stdout-path = &uart0; + stdout-path = &uart2; environment-emmc { compatible = "barebox,environment"; From 49b321fb89bc3310ae902af4ca47b66747a41145 Mon Sep 17 00:00:00 2001 From: Wadim Egorov Date: Thu, 9 Feb 2017 10:36:42 +0100 Subject: [PATCH 8/9] serial: ns16550: Set read/write functions depending on reg-io-width Set proper register read/write functions depending on reg-io-width device tree property. Signed-off-by: Wadim Egorov Signed-off-by: Sascha Hauer --- drivers/serial/serial_ns16550.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index c6548e3b8..439b7d551 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -287,12 +287,31 @@ static int ns16550_tstc(struct console_device *cdev) static void ns16550_probe_dt(struct device_d *dev, struct ns16550_priv *priv) { struct device_node *np = dev->device_node; + u32 width; if (!IS_ENABLED(CONFIG_OFDEVICE)) return; of_property_read_u32(np, "clock-frequency", &priv->plat.clock); of_property_read_u32(np, "reg-shift", &priv->plat.shift); + if (!of_property_read_u32(np, "reg-io-width", &width)) + switch (width) { + case 1: + priv->read_reg = ns16550_read_reg_mmio_8; + priv->write_reg = ns16550_write_reg_mmio_8; + break; + case 2: + priv->read_reg = ns16550_read_reg_mmio_16; + priv->write_reg = ns16550_write_reg_mmio_16; + break; + case 4: + priv->read_reg = ns16550_read_reg_mmio_32; + priv->write_reg = ns16550_write_reg_mmio_32; + break; + default: + dev_err(dev, "unsupported reg-io-width (%d)\n", + width); + } } static struct ns16550_drvdata ns16450_drvdata = { From 436fb44220fdc9d50d17a2ba5c9408f752a0ad9f Mon Sep 17 00:00:00 2001 From: Wadim Egorov Date: Thu, 9 Feb 2017 10:36:43 +0100 Subject: [PATCH 9/9] config: Set UART port 2 as debug port Signed-off-by: Wadim Egorov Signed-off-by: Sascha Hauer --- arch/arm/configs/rk3288_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/configs/rk3288_defconfig b/arch/arm/configs/rk3288_defconfig index f54f4cc3c..15e6c15a0 100644 --- a/arch/arm/configs/rk3288_defconfig +++ b/arch/arm/configs/rk3288_defconfig @@ -26,7 +26,7 @@ CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y CONFIG_RESET_SOURCE=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_LL=y -CONFIG_DEBUG_ROCKCHIP_UART_PORT=0 +CONFIG_DEBUG_ROCKCHIP_UART_PORT=2 CONFIG_CMD_DMESG=y CONFIG_LONGHELP=y CONFIG_CMD_IOMEM=y