diff options
author | Simon Glass | 2020-07-07 13:12:02 -0600 |
---|---|---|
committer | Bin Meng | 2020-07-17 14:32:24 +0800 |
commit | 740630ba73768667a2f87326f2a237d373a5093d (patch) | |
tree | 65f543df914a485cc6f0ce3e5ebdeaaa34559fcc /test/dm/acpigen.c | |
parent | f8054dd8ba533be0e2ebd7965b95446a1f573953 (diff) |
acpi: Add support for a generic power sequence
Add a way for devices to enable and disable themselves using ACPI code
that updates GPIOs. This takes several timing parameters and supports
enable, reset and stop.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'test/dm/acpigen.c')
-rw-r--r-- | test/dm/acpigen.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/test/dm/acpigen.c b/test/dm/acpigen.c index 9b699fc26a3..9e7a928b249 100644 --- a/test/dm/acpigen.c +++ b/test/dm/acpigen.c @@ -806,3 +806,71 @@ static int dm_test_acpi_gpio_toggle(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_acpi_gpio_toggle, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test writing ACPI code to output power-sequence info */ +static int dm_test_acpi_power_seq(struct unit_test_state *uts) +{ + struct gpio_desc reset, enable, stop; + const uint addr = 0xc00dc, addr_act_low = 0x80012; + const int txbit = BIT(2); + struct acpi_ctx *ctx; + struct udevice *dev; + u8 *ptr; + + ut_assertok(acpi_test_alloc_context_size(&ctx, 400)); + + ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); + ut_asserteq_str("a-test", dev->name); + ut_assertok(gpio_request_by_name(dev, "test2-gpios", 0, &reset, 0)); + ut_assertok(gpio_request_by_name(dev, "test2-gpios", 1, &enable, 0)); + ut_assertok(gpio_request_by_name(dev, "test2-gpios", 2, &stop, 0)); + ptr = acpigen_get_current(ctx); + + ut_assertok(acpi_device_add_power_res(ctx, txbit, "\\_SB.GPC0", + "\\_SB.SPC0", &reset, 2, 3, + &enable, 4, 5, &stop, 6, 7)); + ut_asserteq(0x186, acpigen_get_current(ctx) - ptr); + ut_asserteq_strn("PRIC", (char *)ptr + 0x18); + + /* First the 'ON' sequence - spot check */ + ut_asserteq_strn("_ON_", (char *)ptr + 0x38); + + /* reset set */ + ut_asserteq(addr + reset.offset, get_unaligned((u32 *)(ptr + 0x49))); + ut_asserteq(OR_OP, ptr[0x52]); + + /* enable set */ + ut_asserteq(addr + enable.offset, get_unaligned((u32 *)(ptr + 0x72))); + ut_asserteq(OR_OP, ptr[0x7b]); + + /* reset clear */ + ut_asserteq(addr + reset.offset, get_unaligned((u32 *)(ptr + 0x9f))); + ut_asserteq(NOT_OP, ptr[0xa8]); + + /* stop set (disable, active low) */ + ut_asserteq(addr_act_low + stop.offset, + get_unaligned((u32 *)(ptr + 0xcf))); + ut_asserteq(OR_OP, ptr[0xd8]); + + /* Now the 'OFF' sequence */ + ut_asserteq_strn("_OFF", (char *)ptr + 0xf4); + + /* stop clear (enable, active low) */ + ut_asserteq(addr_act_low + stop.offset, + get_unaligned((u32 *)(ptr + 0x105))); + ut_asserteq(NOT_OP, ptr[0x10e]); + + /* reset clear */ + ut_asserteq(addr + reset.offset, get_unaligned((u32 *)(ptr + 0x135))); + ut_asserteq(OR_OP, ptr[0x13e]); + + /* enable clear */ + ut_asserteq(addr + enable.offset, get_unaligned((u32 *)(ptr + 0x162))); + ut_asserteq(NOT_OP, ptr[0x16b]); + + free_context(&ctx); + + return 0; +} + +DM_TEST(dm_test_acpi_power_seq, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |