Shaunak Saha has uploaded this change for review. ( https://review.coreboot.org/21231
Change subject: soc/common/gpio: Add acpigen functions in common GPIO ......................................................................
soc/common/gpio: Add acpigen functions in common GPIO
This patch adds acpigen functions to common gpio block as those are actually used to set/get gpio DW0/DW1 Rx/Tx bits.
Change-Id: I4e9ae9f37a4b524521c346f54b8281d1eb26c8d0 Signed-off-by: Shaunak Saha shaunak.saha@intel.com --- M src/soc/intel/apollolake/acpi.c M src/soc/intel/common/block/gpio/gpio.c 2 files changed, 91 insertions(+), 89 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/31/21231/1
diff --git a/src/soc/intel/apollolake/acpi.c b/src/soc/intel/apollolake/acpi.c index 1826b48..0fc1b03 100644 --- a/src/soc/intel/apollolake/acpi.c +++ b/src/soc/intel/apollolake/acpi.c @@ -277,92 +277,3 @@ { return ACPI_BASE_ADDRESS; } - -static void acpigen_soc_get_dw0_in_local5(uintptr_t addr) -{ - /* - * Store (_SB.GPC0 (addr), Local5) - * _SB.GPC0 is used to read cfg0 value from dw0. It is defined in - * gpiolib.asl. - */ - acpigen_write_store(); - acpigen_emit_namestring("\_SB.GPC0"); - acpigen_write_integer(addr); - acpigen_emit_byte(LOCAL5_OP); -} - -static int acpigen_soc_get_gpio_val(unsigned int gpio_num, uint32_t mask) -{ - assert(gpio_num < TOTAL_PADS); - uintptr_t addr = (uintptr_t)gpio_dwx_address(gpio_num); - - acpigen_soc_get_dw0_in_local5(addr); - - /* If (And (Local5, mask)) */ - acpigen_write_if_and(LOCAL5_OP, mask); - - /* Store (One, Local0) */ - acpigen_write_store_ops(ONE_OP, LOCAL0_OP); - - acpigen_pop_len(); /* If */ - - /* Else */ - acpigen_write_else(); - - /* Store (Zero, Local0) */ - acpigen_write_store_ops(ZERO_OP, LOCAL0_OP); - - acpigen_pop_len(); /* Else */ - - return 0; -} - -static int acpigen_soc_set_gpio_val(unsigned int gpio_num, uint32_t val) -{ - assert(gpio_num < TOTAL_PADS); - uintptr_t addr = (uintptr_t)gpio_dwx_address(gpio_num); - - acpigen_soc_get_dw0_in_local5(addr); - - if (val) { - /* Or (Local5, PAD_CFG0_TX_STATE, Local5) */ - acpigen_write_or(LOCAL5_OP, PAD_CFG0_TX_STATE, LOCAL5_OP); - } else { - /* Not (PAD_CFG0_TX_STATE, Local6) */ - acpigen_write_not(PAD_CFG0_TX_STATE, LOCAL6_OP); - - /* And (Local5, Local6, Local5) */ - acpigen_write_and(LOCAL5_OP, LOCAL6_OP, LOCAL5_OP); - } - - /* - * _SB.SPC0 (addr, Local5) - * _SB.SPC0 is used to write cfg0 value in dw0. It is defined in - * gpiolib.asl. - */ - acpigen_emit_namestring("\_SB.SPC0"); - acpigen_write_integer(addr); - acpigen_emit_byte(LOCAL5_OP); - - return 0; -} - -int acpigen_soc_read_rx_gpio(unsigned int gpio_num) -{ - return acpigen_soc_get_gpio_val(gpio_num, PAD_CFG0_RX_STATE); -} - -int acpigen_soc_get_tx_gpio(unsigned int gpio_num) -{ - return acpigen_soc_get_gpio_val(gpio_num, PAD_CFG0_TX_STATE); -} - -int acpigen_soc_set_tx_gpio(unsigned int gpio_num) -{ - return acpigen_soc_set_gpio_val(gpio_num, 1); -} - -int acpigen_soc_clear_tx_gpio(unsigned int gpio_num) -{ - return acpigen_soc_set_gpio_val(gpio_num, 0); -} diff --git a/src/soc/intel/common/block/gpio/gpio.c b/src/soc/intel/common/block/gpio/gpio.c index f77f88f..2370f2b 100644 --- a/src/soc/intel/common/block/gpio/gpio.c +++ b/src/soc/intel/common/block/gpio/gpio.c @@ -13,6 +13,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ +#include <arch/acpigen.h> #include <assert.h> #include <intelblocks/gpio.h> #include <gpio.h> @@ -483,3 +484,93 @@ const struct pad_community *comm = gpio_get_community(gpio_num); return comm->acpi_path; } + +static void acpigen_soc_get_dw0_in_local5(uintptr_t addr) +{ + /* + * Store (_SB.GPC0 (addr), Local5) + * _SB.GPC0 is used to read cfg0 value from dw0. It is defined in + * gpiolib.asl. + */ + acpigen_write_store(); + acpigen_emit_namestring("\_SB.GPC0"); + acpigen_write_integer(addr); + acpigen_emit_byte(LOCAL5_OP); +} + +static int acpigen_soc_get_gpio_val(unsigned int gpio_num, uint32_t bit_mask) +{ + assert(gpio_num < TOTAL_PADS); + uintptr_t addr = (uintptr_t) gpio_dwx_address(gpio_num); + + acpigen_soc_get_dw0_in_local5(addr); + + /* If (And (Local5, mask)) */ + acpigen_write_if_and(LOCAL5_OP, bit_mask); + + /* Store (One, Local0) */ + acpigen_write_store_ops(ONE_OP, LOCAL0_OP); + + acpigen_pop_len(); /* If */ + + /* Else */ + acpigen_write_else(); + + /* Store (Zero, Local0) */ + acpigen_write_store_ops(ZERO_OP, LOCAL0_OP); + + acpigen_pop_len(); /* Else */ + + return 0; +} + +static int acpigen_soc_set_gpio_val(unsigned int gpio_num, uint32_t val) +{ + assert(gpio_num < TOTAL_PADS); + uintptr_t addr = (uintptr_t) gpio_dwx_address(gpio_num); + + acpigen_soc_get_dw0_in_local5(addr); + + if (val) { + /* Or (Local5, PAD_CFG0_TX_STATE, Local5) */ + acpigen_write_or(LOCAL5_OP, PAD_CFG0_TX_STATE, LOCAL5_OP); + } else { + /* Not (PAD_CFG0_TX_STATE, Local6) */ + acpigen_write_not(PAD_CFG0_TX_STATE, LOCAL6_OP); + + /* And (Local5, Local6, Local5) */ + acpigen_write_and(LOCAL5_OP, LOCAL6_OP, LOCAL5_OP); + } + + /* + * _SB.SPC0 (addr, Local5) + * _SB.SPC0 is used to write cfg0 value in dw0. It is defined in + * gpiolib.asl. + */ + acpigen_emit_namestring("\_SB.SPC0"); + acpigen_write_integer(addr); + acpigen_emit_byte(LOCAL5_OP); + + return 0; +} + +int acpigen_soc_read_rx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_get_gpio_val(gpio_num, PAD_CFG0_RX_STATE); +} + +int acpigen_soc_get_tx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_get_gpio_val(gpio_num, PAD_CFG0_TX_STATE); +} + +int acpigen_soc_set_tx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_set_gpio_val(gpio_num, 1); +} + +int acpigen_soc_clear_tx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_set_gpio_val(gpio_num, 0); +} +