diff --git a/soc/intel/alder_lake/CMakeLists.txt b/soc/intel/alder_lake/CMakeLists.txt index 7db5fbabfc..918ee2f3e9 100644 --- a/soc/intel/alder_lake/CMakeLists.txt +++ b/soc/intel/alder_lake/CMakeLists.txt @@ -8,5 +8,6 @@ zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) zephyr_cc_option(-march=goldmont) zephyr_library_sources(cpu.c) +zephyr_library_sources(../common/soc_gpio.c) set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/intel/alder_lake/soc.h b/soc/intel/alder_lake/soc.h index e1c6a04e83..b725bd44a2 100644 --- a/soc/intel/alder_lake/soc.h +++ b/soc/intel/alder_lake/soc.h @@ -23,6 +23,10 @@ #include #endif +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(acpi_hid) +#include "../common/soc_gpio.h" +#endif + #ifdef CONFIG_GPIO_INTEL #include "soc_gpio.h" #endif diff --git a/soc/intel/common/soc_gpio.c b/soc/intel/common/soc_gpio.c new file mode 100644 index 0000000000..26954156cc --- /dev/null +++ b/soc/intel/common/soc_gpio.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "soc.h" +#include "soc_gpio.h" + +#define GET_GPIO_BASE_NUM ("\\_SB.GINF") + +static int gpio_info_acpi_get(uint32_t bank_idx, uint32_t field_idx, uint32_t *ret_val) +{ + int status; + ACPI_OBJECT args[2]; + ACPI_OBJECT_LIST arg_list; + ACPI_OBJECT gpio_obj; + + arg_list.Count = ARRAY_SIZE(args); + arg_list.Pointer = args; + + args[0].Type = ACPI_TYPE_INTEGER; + args[0].Integer.Value = bank_idx; + + args[1].Type = ACPI_TYPE_INTEGER; + args[1].Integer.Value = field_idx; + + status = acpi_invoke_method(GET_GPIO_BASE_NUM, &arg_list, &gpio_obj); + if (status) { + return status; + } + + if (gpio_obj.Type == ACPI_TYPE_INTEGER) { + *ret_val = gpio_obj.Integer.Value; + } + + return status; +} + +int soc_acpi_gpio_resource_get(int bank_idx, char *hid, char *uid, struct gpio_acpi_res *res) +{ + int ret; + struct acpi_dev *acpi_child; + struct acpi_irq_resource irq_res; + struct acpi_mmio_resource mmio_res; + uint32_t field_val[7]; + uint16_t irqs[CONFIG_ACPI_IRQ_VECTOR_MAX]; + struct acpi_reg_base reg_base[CONFIG_ACPI_MMIO_ENTRIES_MAX]; + + acpi_child = acpi_device_get(hid, uid); + if (!acpi_child) { + printk("acpi_device_get failed\n"); + return -EIO; + } + + mmio_res.mmio_max = ARRAY_SIZE(reg_base); + mmio_res.reg_base = reg_base; + ret = acpi_device_mmio_get(acpi_child, &mmio_res); + if (ret) { + printk("acpi_device_mmio_get failed\n"); + return ret; + } + + irq_res.irq_vector_max = ARRAY_SIZE(irqs); + irq_res.irqs = irqs; + ret = acpi_device_irq_get(acpi_child, &irq_res); + if (ret) { + printk("acpi_device_irq_get failed\n"); + return ret; + } + + res->irq = irq_res.irqs[0]; + res->irq_flags = irq_res.flags; + + if (ACPI_RESOURCE_TYPE_GET(&mmio_res) == ACPI_RES_TYPE_MEM) { + for (int i = 0; i < ARRAY_SIZE(field_val); i++) { + ret = gpio_info_acpi_get(bank_idx, i, &field_val[i]); + if (ret) { + printk("gpio_info_acpi_get failed\n"); + return ret; + } + } + + res->reg_base = ACPI_MMIO_GET(&mmio_res) & (~0x0FFFFFF); + res->reg_base += field_val[0]; + res->len = ACPI_RESOURCE_SIZE_GET(&mmio_res); + res->num_pins = field_val[1]; + res->pad_base = field_val[2]; + res->host_owner_reg = field_val[3]; + res->pad_owner_reg = field_val[4]; + res->intr_stat_reg = field_val[5] - 0x40; + res->base_num = field_val[6]; + } else { + printk("ACPI_RES_TYPE_MEM failed\n"); + return -ENODEV; + } + + return 0; +} diff --git a/soc/intel/common/soc_gpio.h b/soc/intel/common/soc_gpio.h new file mode 100644 index 0000000000..f7c28963ab --- /dev/null +++ b/soc/intel/common/soc_gpio.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +struct gpio_acpi_res { + uintptr_t reg_base; + uint32_t len; + uint32_t pad_base; + uint8_t num_pins; + uint32_t host_owner_reg; + uint32_t pad_owner_reg; + uint32_t intr_stat_reg; + uint16_t base_num; + uint16_t irq; + uint32_t irq_flags; +}; + +/** + * @brief Retrieve current resource settings of a gpio device from acpi. + * + * @param bank_idx band index of the gpio group (eg: gpp_a, gpp_b etc.) + * @param hid the hardware id of the acpi device + * @param uid the unique id of the acpi device + * @param res the pointer to resource struct on which data return + * @return return 0 on success or error code + */ +int soc_acpi_gpio_resource_get(int bank_idx, char *hid, char *uid, struct gpio_acpi_res *res); diff --git a/soc/intel/raptor_lake/CMakeLists.txt b/soc/intel/raptor_lake/CMakeLists.txt index b3d7da7922..ff999b93f6 100644 --- a/soc/intel/raptor_lake/CMakeLists.txt +++ b/soc/intel/raptor_lake/CMakeLists.txt @@ -3,5 +3,6 @@ zephyr_include_directories(.) zephyr_cc_option(-march=goldmont) +zephyr_library_sources(../common/soc_gpio.c) set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/intel/raptor_lake/soc.h b/soc/intel/raptor_lake/soc.h index bb4adb62fa..af5220f891 100644 --- a/soc/intel/raptor_lake/soc.h +++ b/soc/intel/raptor_lake/soc.h @@ -21,6 +21,10 @@ #include #endif +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(acpi_hid) +#include "../common/soc_gpio.h" +#endif + #ifdef CONFIG_GPIO_INTEL #include "soc_gpio.h" #endif