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