1 # GPIO toggling in ACPI AML for coreboot
7 - Implementation details
8 - Arguments and Local Variables Management
12 ACPI provides platform-independent interfaces enabling the operating
13 system to perform power management for devices as well as the entire
14 system. An operating system can simply call into Method()s implemented
15 by the interface to request different power management operations. In
16 order to be able to perform these operations, an interface might
17 require toggling of GPIOs. e.g. a touchscreen device interface might
18 require toggling of reset-gpio in order to take the device out of
19 reset or to put it back into reset.
21 Thus, any coreboot driver that implements such an ACPI interface might
22 require the ability to toggle GPIOs. However, toggling of GPIO is not
23 the same across different platforms and it will require the driver to
24 depend upon platform to do the required work. This document presents a
25 simple interface that can be used by any coreboot driver to generate
26 ACPI AML code for reading or toggling platform GPIOs.
30 All platforms that use drivers requiring ACPI AML code for GPIO
31 interactions need to be implement the following functions:
32 1. Return GPIO Rx value if it is acting as input
33 int acpigen_soc_read_rx_gpio(unsigned int gpio_num)
34 2. Return GPIO Tx value if it is acting as output
35 int acpigen_soc_get_tx_gpio(unsigned int gpio_num)
36 3. Set GPIO Tx value to 1 if it is acting as output
37 int acpigen_soc_set_tx_gpio(unsigned int gpio_num)
38 4. Set GPIO Tx value to 0 if it is acting as output
39 int acpigen_soc_clear_tx_gpio(unsigned int gpio_num)
41 Each of the above functions takes as input gpio_num which is the gpio
42 number that needs to be read or toggled and returns an integer which
47 Above callback functions are chosen to be implemented in C rather than
48 adding them as AML code callbacks for the following reasons:
49 1. It is easier to add error prints in C which will inform the
50 developer that these callbacks are missing. It restricts debugging
52 2. GPIO conversion from number to register offset can be easily done
53 in C by reusing implemented functions rather than adding all the
54 logic to AML code or depending upon complicated macros to be added
56 3. Allows GPIO AML methods to be present under any device scope and
57 gives SoC the flexibility to call them without any restrictions.
61 In order to relieve drivers of the task of implementing the same code
62 for enabling/disabling Tx GPIOs based on the GPIO polarity, helper
63 routines are provided which implement this common code and can be used
64 directly in the driver routines:
66 int acpigen_enable_tx_gpio(struct acpi_gpio gpio)
68 int acpigen_disable_tx_gpio(struct acpi_gpio gpio)
70 Both the above functions take as input struct acpi_gpio type and
71 return -1 on error and 0 on success. These helper routines end up
72 calling the platform specific acpigen_soc_{set,clear}_tx_gpio
73 functions internally. Thus, all the ACPI AML calling conventions for
74 the platform functions apply to these helper functions as well.
77 int acpigen_get_rx_gpio(struct acpi_gpio gpio)
79 This function takes as input, an struct acpi_gpio type and outputs
80 AML code to read the *logical* value of a gpio (after taking its
81 polarity into consideration), into the Local0 variable. It calls
82 the platform specific acpigen_soc_read_rx_gpio() to actually read
83 the raw Rx gpio value.
85 ## Implementation Details
87 Platforms are restricted to using Local5, Local6 and Local7 variables
88 only in implementations of the above functions. Any AML methods called
89 by the above functions do not have any such restrictions on use of
90 Local variables in AML code. Local0 is to be used for all get/read
91 functions to return values. This means that the driver code should not
92 make any assumptions about the values in Local5, Local6 and Local7
96 **Function** **Operation** **Return**
97 acpigen_soc_read_rx_gpio Generate ACPI AML code to Error = -1
98 read value of Rx in Local0. Success = 0
99 acpigen_soc_get_tx_gpio Generate ACPI AML code to Error = -1
100 get value of Tx in Local0. Success = 0
101 acpigen_soc_set_tx_gpio Generate ACPI AML code to Error = -1
102 set Tx to 1. Success = 0
103 acpigen_soc_clear_tx_gpio Generate ACPI AML code to Error = -1
104 set Tx to 0. Success = 0
107 Ideally, the operation column in the above table should use one or
108 more functions implemented by the platform in AML code library (like
109 gpiolib.asl). In the example below SPC0 and GPC0 need to be
110 implemented by the SoC in AML code library and they can be used by
111 acpi_soc_set_tx_gpio to read and set bit in the appropriate register
114 **acpigen_soc_set_tx_gpio**
116 uint64_t gpio_reg_offset = gpio_get_reg_offset(gpio_num);
118 /* Store (\_SB.GPC0(gpio_reg_offset, Local5) */
119 acpigen_write_store();
120 acpigen_emit_namestring(“\\_SB.GPC0”);
121 acpigen_write_integer(gpio_reg_offset);
122 acpigen_emit_byte(LOCAL5_OP);
125 /* Or (Local5, TX_BIT, Local5) */
126 acpigen_write_or(LOCAL5_OP, TX_BIT, LOCAL5_OP);
128 /* \_SB.SPC0(gpio_reg_offset, LOCAL5) */
129 acpigen_emit_namestring(“\\_SB.SPC0”);
130 acpigen_write_integer(gpio_reg_offset);
131 acpigen_emit_byte(LOCAL5_OP);
135 **acpigen_soc_get_tx_gpio**
137 uint64_t gpio_reg_offset = gpio_get_reg_offset(gpio_num);
140 /* Store (\_SB.GPC0(gpio_reg_offset, Local5) */
141 acpigen_write_store();
142 acpigen_emit_namestring(“\\_SB.GPC0”);
143 acpigen_write_integer(gpio_reg_offset);
144 acpigen_emit_byte(LOCAL5_OP);
148 * If (And (Local5, TX_BIT)) Store (One, Local0) Else Store (Zero,
151 acpigen_write_if_and(Local5, TX_BIT);
152 acpigen_write_store_args(ONE_OP, LOCAL0_OP);
153 acpigen_write_else();
154 acpigen_write_store_args(ZERO_OP, LOCAL0_OP);
160 These are reference implementations and the platforms are free to
161 implement these functions in any way they like. coreboot driver can
162 then simply call into these functions to generate ACPI AML code to
163 get/set/clear any GPIO. In order to decide whether GPIO operations are
164 required, driver code can rely either on some config option or read
165 device-tree to use any user-provided GPIOs.
167 ## Arguments and Local Variables Management
169 Platform-defined functions can call methods using the same calling
170 conventions provided by AML code. However, use of Local Variables is
171 restricted to Local5, Local6 and Local7 unless they call into some
172 other method. Called method can use any Local variables, Local0 -
173 Local7. In case of functions expected to return back value to the
174 caller, this value is expected to be returned in Local0.
176 Driver code should not make any assumptions about the contents of
177 Local5, Local6 and Local7 across callbacks to SoC code. If it makes a
178 read or get call to SoC, the return value should be used from Local0
179 on return. However, if it makes a set or clear call to SoC, the value
180 in Local0 is undefined.