x86: coral: Show memory config and SKU ID on startup
authorSimon Glass <sjg@chromium.org>
Sun, 21 Mar 2021 03:50:07 +0000 (16:50 +1300)
committerSimon Glass <sjg@chromium.org>
Sat, 27 Mar 2021 03:26:48 +0000 (16:26 +1300)
Provide the model information through sysinfo so that it shows up on
boot. For memconfig 4 pins are provided, for 16 combinations. For SKU
ID there are two options:

   - two pins provided in a ternary arrangement, for 9 combinations.
   - reading from the EC

Add a binding doc and drop the unused #defines as well.

Example:

   U-Boot 2021.01-rc5

   CPU:   Intel(R) Celeron(R) CPU N3450 @ 1.10GHz
   DRAM:  3.9 GiB
   MMC:   sdmmc@1b,0: 1, emmc@1c,0: 2
   Video: 1024x768x32 @ b0000000
   Model: Google Coral (memconfig 5, SKU 3)

This depends on the GPIO series:

   http://patchwork.ozlabs.org/project/uboot/list/?series=228126

Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Bin Meng <bmeng.cn@gmail.com>
arch/x86/dts/chromebook_coral.dts
board/google/chromebook_coral/coral.c
board/google/chromebook_coral/variant_gpio.h
doc/device-tree-bindings/sysinfo/google,coral.txt [new file with mode: 0644]

index 527c0ad..c8cb4e2 100644 (file)
                recovery-gpios = <&gpio_nw (-1) GPIO_ACTIVE_LOW>;
                write-protect-gpios = <&gpio_nw GPIO_75 GPIO_ACTIVE_HIGH>;
                phase-enforce-gpios = <&gpio_n GPIO_10 GPIO_ACTIVE_HIGH>;
+               memconfig-gpios = <&gpio_nw GPIO_101 GPIO_ACTIVE_HIGH
+                       &gpio_nw GPIO_102 GPIO_ACTIVE_HIGH
+                       &gpio_n GPIO_38 GPIO_ACTIVE_HIGH
+                       &gpio_n GPIO_45 GPIO_ACTIVE_HIGH>;
+
+               /*
+                * This is used for reef only:
+                *
+                * skuconfig-gpios = <&gpio_nw GPIO_16 GPIO_ACTIVE_HIGH
+                *      &gpio_nw GPIO_17 GPIO_ACTIVE_HIGH>;
+                */
                smbios {
                        /* Type 1 table */
                        system {
index b255bf6..3f9235c 100644 (file)
@@ -3,9 +3,12 @@
  * Copyright 2019 Google LLC
  */
 
+#define LOG_CATEGORY   UCLASS_SYSINFO
+
 #include <common.h>
 #include <bloblist.h>
 #include <command.h>
+#include <cros_ec.h>
 #include <dm.h>
 #include <log.h>
 #include <sysinfo.h>
@@ -15,6 +18,7 @@
 #include <asm/intel_gnvs.h>
 #include <asm/intel_pinctrl.h>
 #include <dm/acpi.h>
+#include <linux/delay.h>
 #include "variant_gpio.h"
 
 struct cros_gpio_info {
@@ -29,10 +33,125 @@ int arch_misc_init(void)
        return 0;
 }
 
-/* This function is needed if CONFIG_CMDLINE is not enabled */
-int board_run_command(const char *cmdline)
+static int get_memconfig(struct udevice *dev)
 {
-       printf("No command line\n");
+       struct gpio_desc gpios[4];
+       int cfg;
+       int ret;
+
+       ret = gpio_request_list_by_name(dev, "memconfig-gpios", gpios,
+                                       ARRAY_SIZE(gpios),
+                                       GPIOD_IS_IN | GPIOD_PULL_UP);
+       if (ret < 0) {
+               log_debug("Cannot get GPIO list '%s' (%d)\n", dev->name, ret);
+               return ret;
+       }
+
+       /* Give the lines time to settle */
+       udelay(10);
+
+       ret = dm_gpio_get_values_as_int(gpios, ARRAY_SIZE(gpios));
+       if (ret < 0)
+               return log_msg_ret("get", ret);
+       cfg = ret;
+
+       ret = gpio_free_list(dev, gpios, ARRAY_SIZE(gpios));
+       if (ret)
+               return log_msg_ret("free", ret);
+
+       return cfg;
+}
+
+/**
+ * get_skuconfig() - Get the SKU number either from pins or the EC
+ *
+ * Two options are supported:
+ *     skuconfig-gpios - two pins in the device tree (tried first)
+ *     EC              - reading from the EC (backup)
+ *
+ * @dev: sysinfo device to use
+ * @return SKU ID, or -ve error if not found
+ */
+static int get_skuconfig(struct udevice *dev)
+{
+       struct gpio_desc gpios[2];
+       int cfg;
+       int ret;
+
+       ret = gpio_request_list_by_name(dev, "skuconfig-gpios", gpios,
+                                       ARRAY_SIZE(gpios),
+                                       GPIOD_IS_IN);
+       if (ret != ARRAY_SIZE(gpios)) {
+               struct udevice *cros_ec;
+
+               log_debug("Cannot get GPIO list '%s' (%d)\n", dev->name, ret);
+
+               /* Try the EC */
+               ret = uclass_first_device_err(UCLASS_CROS_EC, &cros_ec);
+               if (ret < 0) {
+                       log_err("Cannot find EC for SKU details\n");
+                       return log_msg_ret("sku", ret);
+               }
+               ret = cros_ec_get_sku_id(cros_ec);
+               if (ret < 0) {
+                       log_err("Cannot read SKU details\n");
+                       return log_msg_ret("sku", ret);
+               }
+
+               return ret;
+       }
+
+       ret = dm_gpio_get_values_as_int_base3(gpios, ARRAY_SIZE(gpios));
+       if (ret < 0)
+               return log_msg_ret("get", ret);
+       cfg = ret;
+
+       ret = gpio_free_list(dev, gpios, ARRAY_SIZE(gpios));
+       if (ret)
+               return log_msg_ret("free", ret);
+
+       return cfg;
+}
+
+static int coral_get_str(struct udevice *dev, int id, size_t size, char *val)
+{
+       int ret;
+
+       if (IS_ENABLED(CONFIG_SPL_BUILD))
+               return -ENOSYS;
+
+       switch (id) {
+       case SYSINFO_ID_SMBIOS_SYSTEM_VERSION:
+       case SYSINFO_ID_SMBIOS_BASEBOARD_VERSION: {
+               ret = get_skuconfig(dev);
+
+               if (ret < 0)
+                       return ret;
+               if (size < 15)
+                       return -ENOSPC;
+               sprintf(val, "rev%d", ret);
+               break;
+       }
+       case SYSINFO_ID_BOARD_MODEL: {
+               int mem_config, sku_config;
+               const char *model;
+
+               ret = get_memconfig(dev);
+               if (ret < 0)
+                       log_warning("Unable to read memconfig (err=%d)\n", ret);
+               mem_config = ret;
+               ret = get_skuconfig(dev);
+               if (ret < 0)
+                       log_warning("Unable to read skuconfig (err=%d)\n", ret);
+               sku_config = ret;
+               model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+               snprintf(val, size, "%s (memconfig %d, SKU %d)", model,
+                        mem_config, sku_config);
+               break;
+       }
+       default:
+               return -ENOENT;
+       }
 
        return 0;
 }
@@ -45,12 +164,15 @@ int chromeos_get_gpio(const struct udevice *dev, const char *prop,
        int ret;
 
        ret = gpio_request_by_name((struct udevice *)dev, prop, 0, &desc, 0);
-       if (ret == -ENOTBLK)
+       if (ret == -ENOTBLK) {
                info->gpio_num = CROS_GPIO_VIRTUAL;
-       else if (ret)
+               log_debug("GPIO '%s' is virtual\n", prop);
+       } else if (ret) {
                return log_msg_ret("gpio", ret);
-       else
+       } else {
                info->gpio_num = desc.offset;
+               dm_gpio_free((struct udevice *)dev, &desc);
+       }
        info->linux_name = dev_read_string(desc.dev, "linux-name");
        if (!info->linux_name)
                return log_msg_ret("linux-name", -ENOENT);
@@ -83,11 +205,11 @@ static int chromeos_acpi_gpio_generate(const struct udevice *dev,
        ret = chromeos_get_gpio(dev, "write-protect-gpios", CROS_GPIO_WP,
                                &info[1]);
        if (ret)
-               return log_msg_ret("rec", ret);
+               return log_msg_ret("wp", ret);
        ret = chromeos_get_gpio(dev, "phase-enforce-gpios", CROS_GPIO_PE,
                                &info[2]);
        if (ret)
-               return log_msg_ret("rec", ret);
+               return log_msg_ret("phase", ret);
        acpigen_write_scope(ctx, "\\");
        acpigen_write_name(ctx, "OIPG");
        acpigen_write_package(ctx, count);
@@ -147,6 +269,7 @@ struct acpi_ops coral_acpi_ops = {
 };
 
 struct sysinfo_ops coral_sysinfo_ops = {
+       .get_str        = coral_get_str,
 };
 
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
index f516d88..403e241 100644 (file)
 /* Determine if board is in final shipping mode. */
 #define GPIO_SHIP_MODE GPIO_10
 
-/*  Memory SKU GPIOs. */
-#define MEM_CONFIG3    GPIO_45
-#define MEM_CONFIG2    GPIO_38
-#define MEM_CONFIG1    GPIO_102
-#define MEM_CONFIG0    GPIO_101
-
 /* DMIC_CONFIG_PIN: High for 1-DMIC and low for 4-DMIC's */
 #define DMIC_CONFIG_PIN        GPIO_17
 
diff --git a/doc/device-tree-bindings/sysinfo/google,coral.txt b/doc/device-tree-bindings/sysinfo/google,coral.txt
new file mode 100644 (file)
index 0000000..d8a1a79
--- /dev/null
@@ -0,0 +1,37 @@
+Google Coral sysinfo information
+================================
+
+This binding allows information about the board to be described. It includes
+the SMBIOS binding as well.
+
+Required properties:
+
+  - compatible: "google,coral"
+  - recovery-gpios: GPIO to use for recovery button (-1 if none)
+  - wite-protect-gpios: GPIO to use for write-protect screw
+  - phase-enforce-gpios: GPIO to indicate the board is in final ship mode
+  - memconfig-gpios: 4 GPIOs to use to read memory config (as base2 int)
+
+Optional properties:
+  - skuconfig-gpios: 2 GPIOs to use to read SKU ID. If not present, the
+       Chromium OS EC SKU_ID is used instead
+
+Example:
+
+board: board {
+       compatible = "google,coral";
+       recovery-gpios = <&gpio_nw (-1) GPIO_ACTIVE_LOW>;
+       write-protect-gpios = <&gpio_nw GPIO_75 GPIO_ACTIVE_HIGH>;
+       phase-enforce-gpios = <&gpio_n GPIO_10 GPIO_ACTIVE_HIGH>;
+       memconfig-gpios = <&gpio_nw GPIO_101 GPIO_ACTIVE_HIGH
+               &gpio_nw GPIO_102 GPIO_ACTIVE_HIGH
+               &gpio_n GPIO_38 GPIO_ACTIVE_HIGH
+               &gpio_n GPIO_45 GPIO_ACTIVE_HIGH>;
+
+       /*
+        * This is used for reef only:
+        *
+        * skuconfig-gpios = <&gpio_nw GPIO_16 GPIO_ACTIVE_HIGH
+        *      &gpio_nw GPIO_17 GPIO_ACTIVE_HIGH>;
+        */
+ };