blob: 3b7550081959c05eaef59f4a9e75b8448f164e55 [file] [log] [blame]
Hector Martin7466b6d2025-04-20 13:58:05 +02001// SPDX-License-Identifier: GPL-2.0+ OR MIT
2/*
3 * Copyright The Asahi Linux Contributors
4 */
5
6#include <dm.h>
7#include <mailbox.h>
8#include <mapmem.h>
9#include <reset.h>
10
11#include <asm/io.h>
12#include <asm/arch/rtkit.h>
13#include <linux/iopoll.h>
14
15/* ASC registers */
16#define REG_CPU_CTRL 0x0044
17#define REG_CPU_CTRL_RUN BIT(4)
18
19struct rtkit_helper_priv {
20 void *asc; /* ASC registers */
21 struct mbox_chan chan;
22 struct apple_rtkit *rtk;
23};
24
25static int rtkit_helper_probe(struct udevice *dev)
26{
27 struct rtkit_helper_priv *priv = dev_get_priv(dev);
28 u32 ctrl;
29 int ret;
30
31 priv->asc = dev_read_addr_ptr(dev);
32 if (!priv->asc)
33 return -EINVAL;
34
35 ret = mbox_get_by_index(dev, 0, &priv->chan);
36 if (ret < 0)
37 return ret;
38
39 ctrl = readl(priv->asc + REG_CPU_CTRL);
40 writel(ctrl | REG_CPU_CTRL_RUN, priv->asc + REG_CPU_CTRL);
41
42 priv->rtk = apple_rtkit_init(&priv->chan, priv, NULL, NULL);
43 if (!priv->rtk)
44 return -ENOMEM;
45
46 ret = apple_rtkit_boot(priv->rtk);
47 if (ret < 0) {
48 printf("%s: Helper apple_rtkit_boot returned: %d\n", __func__, ret);
49 return ret;
50 }
51
52 ret = apple_rtkit_set_ap_power(priv->rtk, APPLE_RTKIT_PWR_STATE_ON);
53 if (ret < 0) {
54 printf("%s: Helper apple_rtkit_set_ap_power returned: %d\n", __func__, ret);
55 return ret;
56 }
57
58 return 0;
59}
60
61static int rtkit_helper_remove(struct udevice *dev)
62{
63 struct rtkit_helper_priv *priv = dev_get_priv(dev);
64 u32 ctrl;
65
66 apple_rtkit_shutdown(priv->rtk, APPLE_RTKIT_PWR_STATE_QUIESCED);
67
68 ctrl = readl(priv->asc + REG_CPU_CTRL);
69 writel(ctrl & ~REG_CPU_CTRL_RUN, priv->asc + REG_CPU_CTRL);
70
71 apple_rtkit_free(priv->rtk);
72 priv->rtk = NULL;
73
74 return 0;
75}
76
77int apple_rtkit_helper_poll(struct udevice *dev, ulong timeout)
78{
79 struct rtkit_helper_priv *priv = dev_get_priv(dev);
80
81 return apple_rtkit_poll(priv->rtk, timeout);
82}
83
84static const struct udevice_id rtkit_helper_ids[] = {
85 { .compatible = "apple,rtk-helper-asc4" },
86 { /* sentinel */ }
87};
88
89U_BOOT_DRIVER(rtkit_helper) = {
90 .name = "rtkit_helper",
91 .id = UCLASS_MISC,
92 .of_match = rtkit_helper_ids,
93 .priv_auto = sizeof(struct rtkit_helper_priv),
94 .probe = rtkit_helper_probe,
95 .remove = rtkit_helper_remove,
96 .flags = DM_FLAG_OS_PREPARE,
97};