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 b52565473d59aab6699b98e0ae9040b90f326fd6..e9c0078922677938c78467d15d1247fab68349eb 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 5c650f046cfc7f40e56539ba9ff749d3f047ceff..522345351124df2516ab15bcea7a8088289f78af 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 9feadb5e43e7078268086d08af76c0c963422537..6f37f756501af82ce616a5d269f087cb90c4f29d 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 806bf1327efe8197ac9daaf98757351b40f05228..644dfa8cc3e775a0c84171990a94955c8cd54366 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 457f77b7c89a45f6e4afb24686e895e1e9dcdf1a..8352e2eb0bc5382663a60b633c137d52a6ac1969 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 05b384f6a4577127eabd5db3f3d65d8e382806c2..30a12e5a535de6646278d6b9ddf4dd04874eebd0 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 95653683ac2ddc99dc4101770709134cf0d91c92..95c14c98d861172da766f3a2939df274eb71a95e 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 58ca82d4de6f71341f76a7478dd56fff55f5f6fc..46aa3fe95438d1bdb46608ac0ccb453796aef8c8 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 50836db4a04563bc634269165fb1789dee177e0f..1732a3acf10056495a1ccb3504e28418154664b2 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 6b1b6b37b3bf2446b1f840dc9beb3cd1f117e25a..2f283fe2449dcf620b6b0029ccffa2e4dfdb217f 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 e6dc576ea3c3d9d262a8a0126ebe2f8bb0be998d..def9b64a282fd575f19d5805a7726b45de77ec2d 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"));