Merge branch '2021-02-02-drop-asm_global_data-when-unused'
[platform/kernel/u-boot.git] / board / google / chromebook_coral / coral.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2019 Google LLC
4  */
5
6 #include <common.h>
7 #include <bloblist.h>
8 #include <command.h>
9 #include <dm.h>
10 #include <log.h>
11 #include <sysinfo.h>
12 #include <acpi/acpigen.h>
13 #include <asm-generic/gpio.h>
14 #include <asm/acpi_nhlt.h>
15 #include <asm/intel_gnvs.h>
16 #include <asm/intel_pinctrl.h>
17 #include <dm/acpi.h>
18 #include "variant_gpio.h"
19
20 struct cros_gpio_info {
21         const char *linux_name;
22         enum cros_gpio_t type;
23         int gpio_num;
24         int flags;
25 };
26
27 int arch_misc_init(void)
28 {
29         return 0;
30 }
31
32 /* This function is needed if CONFIG_CMDLINE is not enabled */
33 int board_run_command(const char *cmdline)
34 {
35         printf("No command line\n");
36
37         return 0;
38 }
39
40 int chromeos_get_gpio(const struct udevice *dev, const char *prop,
41                       enum cros_gpio_t type, struct cros_gpio_info *info)
42 {
43         struct udevice *pinctrl;
44         struct gpio_desc desc;
45         int ret;
46
47         ret = gpio_request_by_name((struct udevice *)dev, prop, 0, &desc, 0);
48         if (ret == -ENOTBLK)
49                 info->gpio_num = CROS_GPIO_VIRTUAL;
50         else if (ret)
51                 return log_msg_ret("gpio", ret);
52         else
53                 info->gpio_num = desc.offset;
54         info->linux_name = dev_read_string(desc.dev, "linux-name");
55         if (!info->linux_name)
56                 return log_msg_ret("linux-name", -ENOENT);
57         info->type = type;
58         /* Get ACPI pin from GPIO library if available */
59         if (info->gpio_num != CROS_GPIO_VIRTUAL) {
60                 pinctrl = dev_get_parent(desc.dev);
61                 info->gpio_num = intel_pinctrl_get_acpi_pin(pinctrl,
62                                                             info->gpio_num);
63         }
64         info->flags = desc.flags & GPIOD_ACTIVE_LOW ? CROS_GPIO_ACTIVE_LOW :
65                 CROS_GPIO_ACTIVE_HIGH;
66
67         return 0;
68 }
69
70 static int chromeos_acpi_gpio_generate(const struct udevice *dev,
71                                        struct acpi_ctx *ctx)
72 {
73         struct cros_gpio_info info[3];
74         int count, i;
75         int ret;
76
77         count = 3;
78         ret = chromeos_get_gpio(dev, "recovery-gpios", CROS_GPIO_REC, &info[0]);
79         if (ret)
80                 return log_msg_ret("rec", ret);
81         ret = chromeos_get_gpio(dev, "write-protect-gpios", CROS_GPIO_WP,
82                                 &info[1]);
83         if (ret)
84                 return log_msg_ret("rec", ret);
85         ret = chromeos_get_gpio(dev, "phase-enforce-gpios", CROS_GPIO_PE,
86                                 &info[2]);
87         if (ret)
88                 return log_msg_ret("rec", ret);
89         acpigen_write_scope(ctx, "\\");
90         acpigen_write_name(ctx, "OIPG");
91         acpigen_write_package(ctx, count);
92         for (i = 0; i < count; i++) {
93                 acpigen_write_package(ctx, 4);
94                 acpigen_write_integer(ctx, info[i].type);
95                 acpigen_write_integer(ctx, info[i].flags);
96                 acpigen_write_integer(ctx, info[i].gpio_num);
97                 acpigen_write_string(ctx, info[i].linux_name);
98                 acpigen_pop_len(ctx);
99         }
100
101         acpigen_pop_len(ctx);
102         acpigen_pop_len(ctx);
103
104         return 0;
105 }
106
107 static int coral_write_acpi_tables(const struct udevice *dev,
108                                    struct acpi_ctx *ctx)
109 {
110         struct acpi_global_nvs *gnvs;
111         struct nhlt *nhlt;
112         const char *oem_id = "coral";
113         const char *oem_table_id = "coral";
114         u32 oem_revision = 3;
115         int ret;
116
117         gnvs = bloblist_find(BLOBLISTT_ACPI_GNVS, sizeof(*gnvs));
118         if (!gnvs)
119                 return log_msg_ret("bloblist", -ENOENT);
120
121         nhlt = nhlt_init();
122         if (!nhlt)
123                 return -ENOMEM;
124
125         log_debug("Setting up NHLT\n");
126         ret = acpi_setup_nhlt(ctx, nhlt);
127         if (ret)
128                 return log_msg_ret("setup", ret);
129
130         /* Update NHLT GNVS Data */
131         gnvs->nhla = (uintptr_t)ctx->current;
132         gnvs->nhll = nhlt_current_size(nhlt);
133
134         ret = nhlt_serialise_oem_overrides(ctx, nhlt, oem_id, oem_table_id,
135                                            oem_revision);
136         if (ret)
137                 return log_msg_ret("serialise", ret);
138
139         return 0;
140 }
141
142 struct acpi_ops coral_acpi_ops = {
143         .write_tables   = coral_write_acpi_tables,
144         .inject_dsdt    = chromeos_acpi_gpio_generate,
145 };
146
147 struct sysinfo_ops coral_sysinfo_ops = {
148 };
149
150 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
151 static const struct udevice_id coral_ids[] = {
152         { .compatible = "google,coral" },
153         { }
154 };
155 #endif
156
157 U_BOOT_DRIVER(coral_drv) = {
158         .name           = "coral",
159         .id             = UCLASS_SYSINFO,
160         .of_match       = of_match_ptr(coral_ids),
161         .ops            = &coral_sysinfo_ops,
162         ACPI_OPS_PTR(&coral_acpi_ops)
163 };