xen: Port Xen grant table driver from mini-os
[platform/kernel/u-boot.git] / drivers / gpio / intel_gpio.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2019 Google LLC
4  */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <fdtdec.h>
10 #include <log.h>
11 #include <p2sb.h>
12 #include <pch.h>
13 #include <pci.h>
14 #include <syscon.h>
15 #include <acpi/acpi_device.h>
16 #include <asm/cpu.h>
17 #include <asm/gpio.h>
18 #include <asm/intel_pinctrl.h>
19 #include <asm/intel_pinctrl_defs.h>
20 #include <asm/io.h>
21 #include <asm/pci.h>
22 #include <asm/arch/gpio.h>
23 #include <dm/acpi.h>
24 #include <dt-bindings/gpio/x86-gpio.h>
25
26 static int intel_gpio_direction_input(struct udevice *dev, uint offset)
27 {
28         struct udevice *pinctrl = dev_get_parent(dev);
29         uint config_offset;
30
31         config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
32
33         pcr_clrsetbits32(pinctrl, config_offset,
34                          PAD_CFG0_MODE_MASK | PAD_CFG0_TX_STATE |
35                                   PAD_CFG0_RX_DISABLE,
36                          PAD_CFG0_MODE_GPIO | PAD_CFG0_TX_DISABLE);
37
38         return 0;
39 }
40
41 static int intel_gpio_direction_output(struct udevice *dev, uint offset,
42                                        int value)
43 {
44         struct udevice *pinctrl = dev_get_parent(dev);
45         uint config_offset;
46
47         config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
48
49         pcr_clrsetbits32(pinctrl, config_offset,
50                          PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE |
51                                   PAD_CFG0_TX_DISABLE | PAD_CFG0_TX_STATE,
52                          PAD_CFG0_MODE_GPIO | PAD_CFG0_RX_DISABLE |
53                                   (value ? PAD_CFG0_TX_STATE : 0));
54
55         return 0;
56 }
57
58 static int intel_gpio_get_value(struct udevice *dev, uint offset)
59 {
60         struct udevice *pinctrl = dev_get_parent(dev);
61         uint mode, rx_tx;
62         u32 reg;
63
64         reg = intel_pinctrl_get_config_reg(pinctrl, offset);
65         mode = (reg & PAD_CFG0_MODE_MASK) >> PAD_CFG0_MODE_SHIFT;
66         if (!mode) {
67                 rx_tx = reg & (PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE);
68                 if (rx_tx == PAD_CFG0_TX_DISABLE)
69                         return reg & PAD_CFG0_RX_STATE ? 1 : 0;
70                 else if (rx_tx == PAD_CFG0_RX_DISABLE)
71                         return reg & PAD_CFG0_TX_STATE ? 1 : 0;
72         }
73
74         return 0;
75 }
76
77 static int intel_gpio_set_value(struct udevice *dev, unsigned int offset,
78                                 int value)
79 {
80         struct udevice *pinctrl = dev_get_parent(dev);
81         uint config_offset;
82
83         config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
84
85         pcr_clrsetbits32(pinctrl, config_offset, PAD_CFG0_TX_STATE,
86                          value ? PAD_CFG0_TX_STATE : 0);
87
88         return 0;
89 }
90
91 static int intel_gpio_get_function(struct udevice *dev, uint offset)
92 {
93         struct udevice *pinctrl = dev_get_parent(dev);
94         uint mode, rx_tx;
95         u32 reg;
96
97         reg = intel_pinctrl_get_config_reg(pinctrl, offset);
98         mode = (reg & PAD_CFG0_MODE_MASK) >> PAD_CFG0_MODE_SHIFT;
99         if (!mode) {
100                 rx_tx = reg & (PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE);
101                 if (rx_tx == PAD_CFG0_TX_DISABLE)
102                         return GPIOF_INPUT;
103                 else if (rx_tx == PAD_CFG0_RX_DISABLE)
104                         return GPIOF_OUTPUT;
105         }
106
107         return GPIOF_FUNC;
108 }
109
110 static int intel_gpio_xlate(struct udevice *orig_dev, struct gpio_desc *desc,
111                             struct ofnode_phandle_args *args)
112 {
113         struct udevice *pinctrl, *dev;
114         int gpio, ret;
115
116         /*
117          * GPIO numbers are global in the device tree so it doesn't matter
118          * which one is used
119          */
120         gpio = args->args[0];
121         ret = intel_pinctrl_get_pad(gpio, &pinctrl, &desc->offset);
122         if (ret)
123                 return log_msg_ret("bad", ret);
124         device_find_first_child(pinctrl, &dev);
125         if (!dev)
126                 return log_msg_ret("no child", -ENOENT);
127         desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
128         desc->dev = dev;
129
130         return 0;
131 }
132
133 #if CONFIG_IS_ENABLED(ACPIGEN)
134 static int intel_gpio_get_acpi(const struct gpio_desc *desc,
135                                struct acpi_gpio *gpio)
136 {
137         struct udevice *pinctrl;
138         int ret;
139
140         if (!dm_gpio_is_valid(desc))
141                 return -ENOENT;
142         pinctrl = dev_get_parent(desc->dev);
143
144         memset(gpio, '\0', sizeof(*gpio));
145
146         gpio->type = ACPI_GPIO_TYPE_IO;
147         gpio->pull = ACPI_GPIO_PULL_DEFAULT;
148         gpio->io_restrict = ACPI_GPIO_IO_RESTRICT_OUTPUT;
149         gpio->polarity = ACPI_GPIO_ACTIVE_HIGH;
150         gpio->pin_count = 1;
151         gpio->pins[0] = intel_pinctrl_get_acpi_pin(pinctrl, desc->offset);
152         gpio->pin0_addr = intel_pinctrl_get_config_reg_addr(pinctrl,
153                                                             desc->offset);
154         ret = acpi_get_path(pinctrl, gpio->resource, sizeof(gpio->resource));
155         if (ret)
156                 return log_msg_ret("resource", ret);
157
158         return 0;
159 }
160 #endif
161
162 static int intel_gpio_probe(struct udevice *dev)
163 {
164         return 0;
165 }
166
167 static int intel_gpio_ofdata_to_platdata(struct udevice *dev)
168 {
169         struct gpio_dev_priv *upriv = dev_get_uclass_priv(dev);
170         struct intel_pinctrl_priv *pinctrl_priv = dev_get_priv(dev->parent);
171         const struct pad_community *comm = pinctrl_priv->comm;
172
173         upriv->gpio_count = comm->last_pad - comm->first_pad + 1;
174         upriv->bank_name = dev->name;
175
176         return 0;
177 }
178
179 static const struct dm_gpio_ops gpio_intel_ops = {
180         .direction_input        = intel_gpio_direction_input,
181         .direction_output       = intel_gpio_direction_output,
182         .get_value              = intel_gpio_get_value,
183         .set_value              = intel_gpio_set_value,
184         .get_function           = intel_gpio_get_function,
185         .xlate                  = intel_gpio_xlate,
186 #if CONFIG_IS_ENABLED(ACPIGEN)
187         .get_acpi               = intel_gpio_get_acpi,
188 #endif
189 };
190
191 static const struct udevice_id intel_intel_gpio_ids[] = {
192         { .compatible = "intel,gpio" },
193         { }
194 };
195
196 U_BOOT_DRIVER(gpio_intel) = {
197         .name   = "gpio_intel",
198         .id     = UCLASS_GPIO,
199         .of_match = intel_intel_gpio_ids,
200         .ops    = &gpio_intel_ops,
201         .ofdata_to_platdata     = intel_gpio_ofdata_to_platdata,
202         .probe  = intel_gpio_probe,
203 };