Merge branch 'master' of git://git.denx.de/u-boot
authorStefano Babic <sbabic@denx.de>
Sun, 10 May 2020 11:03:56 +0000 (13:03 +0200)
committerStefano Babic <sbabic@denx.de>
Sun, 10 May 2020 11:03:56 +0000 (13:03 +0200)
arch/arm/include/asm/arch-imx/cpu.h
common/board_f.c
common/spl/Kconfig
common/spl/spl_sdp.c
drivers/cpu/cpu-uclass.c
drivers/cpu/cpu_sandbox.c
drivers/cpu/imx8_cpu.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/f_sdp.c
include/cpu.h
test/dm/cpu.c

index b525654..e9c0078 100644 (file)
@@ -64,6 +64,7 @@
 
 #define CHIP_REV_A             0x0
 #define CHIP_REV_B             0x1
+#define CHIP_REV_C             0x2
 
 #define BOARD_REV_1_0           0x0
 #define BOARD_REV_2_0           0x1
index 5c650f0..5223453 100644 (file)
@@ -183,11 +183,11 @@ static int print_cpuinfo(void)
        char desc[512];
        int ret;
 
-       ret = uclass_first_device_err(UCLASS_CPU, &dev);
-       if (ret) {
-               debug("%s: Could not get CPU device (err = %d)\n",
-                     __func__, ret);
-               return ret;
+       dev = cpu_get_current_dev();
+       if (!dev) {
+               debug("%s: Could not get CPU device\n",
+                     __func__);
+               return -ENODEV;
        }
 
        ret = cpu_get_desc(dev, desc, sizeof(desc));
index 9feadb5..6f37f75 100644 (file)
@@ -1172,6 +1172,14 @@ config SPL_USB_SDP_SUPPORT
          Enable Serial Download Protocol (SDP) device support in SPL. This
          allows to download images into memory and execute (jump to) them
          using the same protocol as implemented by the i.MX family's boot ROM.
+
+config SPL_SDP_USB_DEV
+       int "SDP USB controller index"
+       default 0
+       depends on SPL_USB_SDP_SUPPORT
+       help
+         Some boards have USB controller other than 0. Define this option
+         so it can be used in compiled environment.
 endif
 
 config SPL_WATCHDOG_SUPPORT
index 806bf13..644dfa8 100644 (file)
@@ -14,7 +14,9 @@ static int spl_sdp_load_image(struct spl_image_info *spl_image,
                              struct spl_boot_device *bootdev)
 {
        int ret;
-       const int controller_index = 0;
+       const int controller_index = CONFIG_SPL_SDP_USB_DEV;
+
+       usb_gadget_initialize(controller_index);
 
        g_dnl_clear_detach();
        ret = g_dnl_register("usb_dnl_sdp");
@@ -37,6 +39,7 @@ static int spl_sdp_load_image(struct spl_image_info *spl_image,
        ret = spl_sdp_handle(controller_index, spl_image);
        debug("SDP ended\n");
 
+       usb_gadget_release(controller_index);
        return ret;
 }
 SPL_LOAD_IMAGE_METHOD("USB SDP", 0, BOOT_DEVICE_BOARD, spl_sdp_load_image);
index 457f77b..8352e2e 100644 (file)
@@ -10,6 +10,7 @@
 #include <errno.h>
 #include <dm/lists.h>
 #include <dm/root.h>
+#include <linux/err.h>
 
 int cpu_probe_all(void)
 {
@@ -34,6 +35,39 @@ int cpu_probe_all(void)
        return 0;
 }
 
+int cpu_is_current(struct udevice *cpu)
+{
+       struct cpu_ops *ops = cpu_get_ops(cpu);
+
+       if (ops->is_current) {
+               if (ops->is_current(cpu))
+                       return 1;
+       }
+
+       return -ENOSYS;
+}
+
+struct udevice *cpu_get_current_dev(void)
+{
+       struct udevice *cpu;
+       int ret;
+
+       uclass_foreach_dev_probe(UCLASS_CPU, cpu) {
+               if (cpu_is_current(cpu) > 0)
+                       return cpu;
+       }
+
+       /* If can't find current cpu device, use the first dev instead */
+       ret = uclass_first_device_err(UCLASS_CPU, &cpu);
+       if (ret) {
+               debug("%s: Could not get CPU device (err = %d)\n",
+                     __func__, ret);
+               return NULL;
+       }
+
+       return cpu;
+}
+
 int cpu_get_desc(struct udevice *dev, char *buf, int size)
 {
        struct cpu_ops *ops = cpu_get_ops(dev);
index 05b384f..30a12e5 100644 (file)
@@ -36,11 +36,20 @@ int cpu_sandbox_get_vendor(struct udevice *dev, char *buf, int size)
        return 0;
 }
 
+int cpu_sandbox_is_current(struct udevice *dev)
+{
+       if (!strcmp(dev->name, "cpu-test1"))
+               return 1;
+
+       return 0;
+}
+
 static const struct cpu_ops cpu_sandbox_ops = {
        .get_desc = cpu_sandbox_get_desc,
        .get_info = cpu_sandbox_get_info,
        .get_count = cpu_sandbox_get_count,
        .get_vendor = cpu_sandbox_get_vendor,
+       .is_current = cpu_sandbox_is_current,
 };
 
 int cpu_sandbox_probe(struct udevice *dev)
index 9565368..95c14c9 100644 (file)
@@ -20,6 +20,7 @@ struct cpu_imx_platdata {
        const char *type;
        u32 cpurev;
        u32 freq_mhz;
+       u32 mpidr;
 };
 
 const char *get_imx8_type(u32 imxtype)
@@ -42,31 +43,35 @@ const char *get_imx8_rev(u32 rev)
                return "A";
        case CHIP_REV_B:
                return "B";
+       case CHIP_REV_C:
+               return "C";
        default:
                return "?";
        }
 }
 
-const char *get_core_name(void)
+const char *get_core_name(struct udevice *dev)
 {
-       if (is_cortex_a35())
+       if (!device_is_compatible(dev, "arm,cortex-a35"))
                return "A35";
-       else if (is_cortex_a53())
+       else if (!device_is_compatible(dev, "arm,cortex-a53"))
                return "A53";
-       else if (is_cortex_a72())
+       else if (!device_is_compatible(dev, "arm,cortex-a72"))
                return "A72";
        else
                return "?";
 }
 
 #if IS_ENABLED(CONFIG_IMX_SCU_THERMAL)
-static int cpu_imx_get_temp(void)
+static int cpu_imx_get_temp(struct cpu_imx_platdata *plat)
 {
        struct udevice *thermal_dev;
        int cpu_tmp, ret;
 
-       ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal0",
-                                       &thermal_dev);
+       if (!strcmp(plat->name, "A72"))
+               ret = uclass_get_device(UCLASS_THERMAL, 1, &thermal_dev);
+       else
+               ret = uclass_get_device(UCLASS_THERMAL, 0, &thermal_dev);
 
        if (!ret) {
                ret = thermal_get_temp(thermal_dev, &cpu_tmp);
@@ -79,7 +84,7 @@ static int cpu_imx_get_temp(void)
        return cpu_tmp;
 }
 #else
-static int cpu_imx_get_temp(void)
+static int cpu_imx_get_temp(struct cpu_imx_platdata *plat)
 {
        return 0;
 }
@@ -88,7 +93,7 @@ static int cpu_imx_get_temp(void)
 int cpu_imx_get_desc(struct udevice *dev, char *buf, int size)
 {
        struct cpu_imx_platdata *plat = dev_get_platdata(dev);
-       int ret;
+       int ret, temp;
 
        if (size < 100)
                return -ENOSPC;
@@ -97,9 +102,13 @@ int cpu_imx_get_desc(struct udevice *dev, char *buf, int size)
                       plat->type, plat->rev, plat->name, plat->freq_mhz);
 
        if (IS_ENABLED(CONFIG_IMX_SCU_THERMAL)) {
+               temp = cpu_imx_get_temp(plat);
                buf = buf + ret;
                size = size - ret;
-               ret = snprintf(buf, size, " at %dC", cpu_imx_get_temp());
+               if (temp != 0xdeadbeef)
+                       ret = snprintf(buf, size, " at %dC", temp);
+               else
+                       ret = snprintf(buf, size, " - invalid sensor data");
        }
 
        snprintf(buf + ret, size - ret, "\n");
@@ -118,7 +127,24 @@ static int cpu_imx_get_info(struct udevice *dev, struct cpu_info *info)
 
 static int cpu_imx_get_count(struct udevice *dev)
 {
-       return 4;
+       ofnode node;
+       int num = 0;
+
+       ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
+               const char *device_type;
+
+               if (!ofnode_is_available(node))
+                       continue;
+
+               device_type = ofnode_read_string(node, "device_type");
+               if (!device_type)
+                       continue;
+
+               if (!strcmp(device_type, "cpu"))
+                       num++;
+       }
+
+       return num;
 }
 
 static int cpu_imx_get_vendor(struct udevice *dev,  char *buf, int size)
@@ -127,25 +153,44 @@ static int cpu_imx_get_vendor(struct udevice *dev,  char *buf, int size)
        return 0;
 }
 
+static int cpu_imx_is_current(struct udevice *dev)
+{
+       struct cpu_imx_platdata *plat = dev_get_platdata(dev);
+
+       if (plat->mpidr == (read_mpidr() & 0xffff))
+               return 1;
+
+       return 0;
+}
+
 static const struct cpu_ops cpu_imx8_ops = {
        .get_desc       = cpu_imx_get_desc,
        .get_info       = cpu_imx_get_info,
        .get_count      = cpu_imx_get_count,
        .get_vendor     = cpu_imx_get_vendor,
+       .is_current     = cpu_imx_is_current,
 };
 
 static const struct udevice_id cpu_imx8_ids[] = {
        { .compatible = "arm,cortex-a35" },
        { .compatible = "arm,cortex-a53" },
+       { .compatible = "arm,cortex-a72" },
        { }
 };
 
-static ulong imx8_get_cpu_rate(void)
+static ulong imx8_get_cpu_rate(struct udevice *dev)
 {
        ulong rate;
-       int ret;
-       int type = is_cortex_a35() ? SC_R_A35 : is_cortex_a53() ?
-                  SC_R_A53 : SC_R_A72;
+       int ret, type;
+
+       if (!device_is_compatible(dev, "arm,cortex-a35"))
+               type = SC_R_A35;
+       else if (!device_is_compatible(dev, "arm,cortex-a53"))
+               type = SC_R_A53;
+       else if (!device_is_compatible(dev, "arm,cortex-a72"))
+               type = SC_R_A72;
+       else
+               return 0;
 
        ret = sc_pm_get_clock_rate(-1, type, SC_PM_CLK_CPU,
                                   (sc_pm_clock_rate_t *)&rate);
@@ -164,10 +209,16 @@ static int imx8_cpu_probe(struct udevice *dev)
 
        cpurev = get_cpu_rev();
        plat->cpurev = cpurev;
-       plat->name = get_core_name();
+       plat->name = get_core_name(dev);
        plat->rev = get_imx8_rev(cpurev & 0xFFF);
        plat->type = get_imx8_type((cpurev & 0xFF000) >> 12);
-       plat->freq_mhz = imx8_get_cpu_rate() / 1000000;
+       plat->freq_mhz = imx8_get_cpu_rate(dev) / 1000000;
+       plat->mpidr = dev_read_addr(dev);
+       if (plat->mpidr == FDT_ADDR_T_NONE) {
+               printf("%s: Failed to get CPU reg property\n", __func__);
+               return -EINVAL;
+       }
+
        return 0;
 }
 
index 58ca82d..46aa3fe 100644 (file)
@@ -122,6 +122,10 @@ config USB_GADGET_VBUS_DRAW
           This value will be used except for system-specific gadget
           drivers that have more specific information.
 
+config SDP_LOADADDR
+       hex "Default load address at SDP_WRITE and SDP_JUMP"
+       default 0
+
 # Selected by UDC drivers that support high-speed operation.
 config USB_GADGET_DUALSPEED
        bool
index 50836db..1732a3a 100644 (file)
@@ -276,7 +276,7 @@ static void sdp_rx_command_complete(struct usb_ep *ep, struct usb_request *req)
                sdp->error_status = SDP_WRITE_FILE_COMPLETE;
 
                sdp->state = SDP_STATE_RX_FILE_DATA;
-               sdp->dnl_address = be32_to_cpu(cmd->addr);
+               sdp->dnl_address = cmd->addr ? be32_to_cpu(cmd->addr) : CONFIG_SDP_LOADADDR;
                sdp->dnl_bytes_remaining = be32_to_cpu(cmd->cnt);
                sdp->dnl_bytes = sdp->dnl_bytes_remaining;
                sdp->next_state = SDP_STATE_IDLE;
@@ -304,7 +304,7 @@ static void sdp_rx_command_complete(struct usb_ep *ep, struct usb_request *req)
                sdp->always_send_status = false;
                sdp->error_status = 0;
 
-               sdp->jmp_address = be32_to_cpu(cmd->addr);
+               sdp->jmp_address = cmd->addr ? be32_to_cpu(cmd->addr) : CONFIG_SDP_LOADADDR;
                sdp->state = SDP_STATE_TX_SEC_CONF;
                sdp->next_state = SDP_STATE_JUMP;
                break;
index 6b1b6b3..2f283fe 100644 (file)
@@ -89,6 +89,15 @@ struct cpu_ops {
         * @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error
         */
        int (*get_vendor)(struct udevice *dev, char *buf, int size);
+
+       /**
+        * is_current() - Check if the CPU that U-Boot is currently running from
+        *
+        * @dev:        Device to check (UCLASS_CPU)
+        * @return 1 if the CPU that U-Boot is currently running from, 0
+        *         if not.
+        */
+       int (*is_current)(struct udevice *dev);
 };
 
 #define cpu_get_ops(dev)        ((struct cpu_ops *)(dev)->driver->ops)
@@ -137,4 +146,18 @@ int cpu_get_vendor(struct udevice *dev, char *buf, int size);
  */
 int cpu_probe_all(void);
 
+/**
+ * cpu_is_current() - Check if the CPU that U-Boot is currently running from
+ *
+ * Return: 1 if yes, - 0 if not
+ */
+int cpu_is_current(struct udevice *cpu);
+
+/**
+ * cpu_get_current_dev() - Get CPU udevice for current CPU
+ *
+ * Return: udevice if OK, - NULL on error
+ */
+struct udevice *cpu_get_current_dev(void);
+
 #endif
index e6dc576..def9b64 100644 (file)
@@ -26,6 +26,8 @@ static int dm_test_cpu(struct unit_test_state *uts)
                ut_assert(dev->flags & DM_FLAG_ACTIVATED);
 
        ut_assertok(uclass_get_device_by_name(UCLASS_CPU, "cpu-test1", &dev));
+       ut_asserteq_ptr(cpu_get_current_dev(), dev);
+       ut_asserteq(cpu_is_current(dev), 1);
 
        ut_assertok(cpu_get_desc(dev, text, sizeof(text)));
        ut_assertok(strcmp(text, "LEG Inc. SuperMegaUltraTurbo CPU No. 1"));