aboutsummaryrefslogtreecommitdiff
path: root/test/dm/acpigen.c
diff options
context:
space:
mode:
authorSimon Glass2020-07-07 13:12:02 -0600
committerBin Meng2020-07-17 14:32:24 +0800
commit740630ba73768667a2f87326f2a237d373a5093d (patch)
tree65f543df914a485cc6f0ce3e5ebdeaaa34559fcc /test/dm/acpigen.c
parentf8054dd8ba533be0e2ebd7965b95446a1f573953 (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.c68
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);