Skip to content

Commit 5a9202a

Browse files
committed
soc: apple: Add RTKit helper driver
This driver can be used for coprocessors that do some background task or communicate out-of-band, and do not do any mailbox I/O beyond the standard RTKit initialization. Signed-off-by: Hector Martin <[email protected]>
1 parent af53f3f commit 5a9202a

3 files changed

Lines changed: 169 additions & 0 deletions

File tree

drivers/soc/apple/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ config APPLE_RTKIT
3030

3131
Say 'y' here if you have an Apple SoC.
3232

33+
config APPLE_RTKIT_HELPER
34+
tristate "Apple Generic RTKit helper co-processor"
35+
depends on APPLE_RTKIT
36+
depends on ARCH_APPLE || COMPILE_TEST
37+
default ARCH_APPLE
38+
help
39+
Apple SoCs such as the M1 come with various co-processors running
40+
their proprietary RTKit operating system. This option enables support
41+
for a generic co-processor that does not implement any additional
42+
in-band communications. It can be used for testing purposes, or for
43+
coprocessors such as MTP that communicate over a different interface.
44+
45+
Say 'y' here if you have an Apple SoC.
46+
3347
config APPLE_SART
3448
tristate "Apple SART DMA address filter"
3549
depends on ARCH_APPLE || COMPILE_TEST

drivers/soc/apple/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ obj-$(CONFIG_APPLE_PMGR_PWRSTATE) += apple-pmgr-pwrstate.o
44
obj-$(CONFIG_APPLE_RTKIT) += apple-rtkit.o
55
apple-rtkit-y = rtkit.o rtkit-crashlog.o
66

7+
obj-$(CONFIG_APPLE_RTKIT_HELPER) += apple-rtkit-helper.o
8+
apple-rtkit-helper-y = rtkit-helper.o
9+
710
obj-$(CONFIG_APPLE_SART) += apple-sart.o
811
apple-sart-y = sart.o
912

drivers/soc/apple/rtkit-helper.c

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// SPDX-License-Identifier: GPL-2.0-only OR MIT
2+
/*
3+
* Apple Generic RTKit helper coprocessor
4+
* Copyright The Asahi Linux Contributors
5+
*/
6+
7+
#include <linux/device.h>
8+
#include <linux/dma-mapping.h>
9+
#include <linux/io.h>
10+
#include <linux/ioport.h>
11+
#include <linux/of.h>
12+
#include <linux/of_platform.h>
13+
#include <linux/soc/apple/rtkit.h>
14+
15+
#define APPLE_ASC_CPU_CONTROL 0x44
16+
#define APPLE_ASC_CPU_CONTROL_RUN BIT(4)
17+
18+
struct apple_rtkit_helper {
19+
struct device *dev;
20+
struct apple_rtkit *rtk;
21+
22+
void __iomem *asc_base;
23+
24+
struct resource *sram;
25+
void __iomem *sram_base;
26+
};
27+
28+
static int apple_rtkit_helper_shmem_setup(void *cookie, struct apple_rtkit_shmem *bfr)
29+
{
30+
struct apple_rtkit_helper *helper = cookie;
31+
struct resource res = {
32+
.start = bfr->iova,
33+
.end = bfr->iova + bfr->size - 1,
34+
.name = "rtkit_map",
35+
};
36+
37+
if (!bfr->iova) {
38+
bfr->buffer = dma_alloc_coherent(helper->dev, bfr->size,
39+
&bfr->iova, GFP_KERNEL);
40+
if (!bfr->buffer)
41+
return -ENOMEM;
42+
return 0;
43+
}
44+
45+
if (!helper->sram) {
46+
dev_err(helper->dev,
47+
"RTKit buffer request with no SRAM region: %pR", &res);
48+
return -EFAULT;
49+
}
50+
51+
res.flags = helper->sram->flags;
52+
53+
if (res.end < res.start || !resource_contains(helper->sram, &res)) {
54+
dev_err(helper->dev,
55+
"RTKit buffer request outside SRAM region: %pR", &res);
56+
return -EFAULT;
57+
}
58+
59+
bfr->iomem = helper->sram_base + (res.start - helper->sram->start);
60+
bfr->is_mapped = true;
61+
62+
return 0;
63+
}
64+
65+
static void apple_rtkit_helper_shmem_destroy(void *cookie, struct apple_rtkit_shmem *bfr)
66+
{
67+
// no-op
68+
}
69+
70+
static const struct apple_rtkit_ops apple_rtkit_helper_ops = {
71+
.shmem_setup = apple_rtkit_helper_shmem_setup,
72+
.shmem_destroy = apple_rtkit_helper_shmem_destroy,
73+
};
74+
75+
static int apple_rtkit_helper_probe(struct platform_device *pdev)
76+
{
77+
struct device *dev = &pdev->dev;
78+
struct apple_rtkit_helper *helper;
79+
int ret;
80+
81+
/* 44 bits for addresses in standard RTKit requests */
82+
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44));
83+
if (ret)
84+
return ret;
85+
86+
helper = devm_kzalloc(dev, sizeof(*helper), GFP_KERNEL);
87+
if (!helper)
88+
return -ENOMEM;
89+
90+
helper->dev = dev;
91+
platform_set_drvdata(pdev, helper);
92+
93+
helper->asc_base = devm_platform_ioremap_resource_byname(pdev, "asc");
94+
if (IS_ERR(helper->asc_base))
95+
return PTR_ERR(helper->asc_base);
96+
97+
helper->sram = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
98+
if (helper->sram) {
99+
helper->sram_base = devm_ioremap_resource(dev, helper->sram);
100+
if (IS_ERR(helper->sram_base))
101+
return dev_err_probe(dev, PTR_ERR(helper->sram_base),
102+
"Failed to map SRAM region");
103+
}
104+
105+
helper->rtk =
106+
devm_apple_rtkit_init(dev, helper, NULL, 0, &apple_rtkit_helper_ops);
107+
if (IS_ERR(helper->rtk))
108+
return dev_err_probe(dev, PTR_ERR(helper->rtk),
109+
"Failed to intialize RTKit");
110+
111+
writel_relaxed(APPLE_ASC_CPU_CONTROL_RUN,
112+
helper->asc_base + APPLE_ASC_CPU_CONTROL);
113+
114+
/* Works for both wake and boot */
115+
ret = apple_rtkit_wake(helper->rtk);
116+
if (ret != 0)
117+
return dev_err_probe(dev, ret, "Failed to wake up coprocessor");
118+
119+
return 0;
120+
}
121+
122+
static int apple_rtkit_helper_remove(struct platform_device *pdev)
123+
{
124+
struct apple_rtkit_helper *helper = platform_get_drvdata(pdev);
125+
126+
if (apple_rtkit_is_running(helper->rtk))
127+
apple_rtkit_quiesce(helper->rtk);
128+
129+
writel_relaxed(0, helper->asc_base + APPLE_ASC_CPU_CONTROL);
130+
131+
return 0;
132+
}
133+
134+
static const struct of_device_id apple_rtkit_helper_of_match[] = {
135+
{ .compatible = "apple,rtk-helper-asc4" },
136+
{},
137+
};
138+
MODULE_DEVICE_TABLE(of, apple_rtkit_helper_of_match);
139+
140+
static struct platform_driver apple_rtkit_helper_driver = {
141+
.driver = {
142+
.name = "rtkit-helper",
143+
.of_match_table = apple_rtkit_helper_of_match,
144+
},
145+
.probe = apple_rtkit_helper_probe,
146+
.remove = apple_rtkit_helper_remove,
147+
};
148+
module_platform_driver(apple_rtkit_helper_driver);
149+
150+
MODULE_AUTHOR("Hector Martin <[email protected]>");
151+
MODULE_LICENSE("Dual MIT/GPL");
152+
MODULE_DESCRIPTION("Apple RTKit helper driver");

0 commit comments

Comments
 (0)