Skip to content

Commit 7e72c13

Browse files
marcanjannau
authored andcommitted
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 <marcan@marcan.st>
1 parent 4cd1715 commit 7e72c13

3 files changed

Lines changed: 167 additions & 0 deletions

File tree

drivers/soc/apple/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@ config APPLE_RTKIT
3737

3838
Say 'y' here if you have an Apple SoC.
3939

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

drivers/soc/apple/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,8 @@ apple-mailbox-y = mailbox.o
99
obj-$(CONFIG_APPLE_RTKIT) += apple-rtkit.o
1010
apple-rtkit-y = rtkit.o rtkit-crashlog.o
1111

12+
obj-$(CONFIG_APPLE_RTKIT_HELPER) += apple-rtkit-helper.o
13+
apple-rtkit-helper-y = rtkit-helper.o
14+
1215
obj-$(CONFIG_APPLE_SART) += apple-sart.o
1316
apple-sart-y = sart.o

drivers/soc/apple/rtkit-helper.c

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

0 commit comments

Comments
 (0)