blob: 4495dfba44a31b167da625a47bf424c4a0d4cf40 [file] [log] [blame]
developere5e687d2023-08-08 16:05:33 +08001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2023 MediaTek Inc. All Rights Reserved.
4 *
5 * Author: Ren-Ting Wang <ren-ting.wang@mediatek.com>
6 */
7
developer6a0a7102023-09-18 18:03:07 +08008#include <linux/debugfs.h>
developere5e687d2023-08-08 16:05:33 +08009#include <linux/device.h>
developer6a0a7102023-09-18 18:03:07 +080010#include <linux/err.h>
11#include <linux/io.h>
developere5e687d2023-08-08 16:05:33 +080012#include <linux/module.h>
developer6a0a7102023-09-18 18:03:07 +080013#include <linux/of.h>
14#include <linux/of_address.h>
developere5e687d2023-08-08 16:05:33 +080015#include <linux/of_platform.h>
16#include <linux/platform_device.h>
17
developer0fb30d52023-12-04 09:51:36 +080018#include "tops/ctrl.h"
19#include "tops/debugfs.h"
20#include "tops/firmware.h"
21#include "tops/hpdma.h"
22#include "tops/hwspinlock.h"
23#include "tops/internal.h"
24#include "tops/mbox.h"
25#include "tops/mcu.h"
developerd80acd02024-02-20 14:28:44 +080026#include "tops/misc.h"
developer0fb30d52023-12-04 09:51:36 +080027#include "tops/netsys.h"
28#include "tops/net-event.h"
29#include "tops/ser.h"
30#include "tops/tdma.h"
31#include "tops/trm-mcu.h"
32#include "tops/trm.h"
33#include "tops/tunnel.h"
34#include "tops/wdt.h"
developer5d86c142023-12-06 14:18:27 +080035#include "tops/seq_gen.h"
developere5e687d2023-08-08 16:05:33 +080036
developer6a0a7102023-09-18 18:03:07 +080037#define EFUSE_TOPS_POWER_OFF (0xD08)
38
developere5e687d2023-08-08 16:05:33 +080039struct device *tops_dev;
developerfbdb5112023-08-21 15:12:14 +080040struct dentry *tops_debugfs_root;
developere5e687d2023-08-08 16:05:33 +080041
42static int mtk_tops_post_init(struct platform_device *pdev)
43{
44 int ret = 0;
45
46 /* kick core */
47 ret = mtk_tops_mcu_bring_up(pdev);
48 if (ret) {
49 TOPS_ERR("mcu post init failed: %d\n", ret);
50 return ret;
51 }
52
53 /* offload tunnel protocol initialization */
54 ret = mtk_tops_tnl_offload_proto_setup(pdev);
55 if (ret) {
56 TOPS_ERR("tnl offload protocol init failed: %d\n", ret);
57 goto err_mcu_tear_down;
58 }
59
60 ret = mtk_tops_netevent_register(pdev);
61 if (ret) {
62 TOPS_ERR("netevent register fail: %d\n", ret);
63 goto err_offload_proto_tear_down;
64 }
65
66 /* create sysfs file */
67 ret = mtk_tops_ctrl_init(pdev);
68 if (ret) {
69 TOPS_ERR("ctrl init failed: %d\n", ret);
70 goto err_netevent_unregister;
71 }
72
73 ret = mtk_tops_ser_init(pdev);
74 if (ret) {
75 TOPS_ERR("ser init failed: %d\n", ret);
76 goto err_ctrl_deinit;
77 }
78
79 ret = mtk_tops_wdt_init(pdev);
80 if (ret) {
81 TOPS_ERR("wdt init failed: %d\n", ret);
82 goto err_ser_deinit;
83 }
84
developer0fb30d52023-12-04 09:51:36 +080085 ret = mtk_tops_debugfs_init(pdev);
86 if (ret) {
87 TOPS_ERR("debugfs init failed: %d\n", ret);
88 goto err_wdt_deinit;
89 }
90
developere5e687d2023-08-08 16:05:33 +080091 return ret;
92
developer0fb30d52023-12-04 09:51:36 +080093err_wdt_deinit:
94 mtk_tops_wdt_deinit(pdev);
95
developere5e687d2023-08-08 16:05:33 +080096err_ser_deinit:
97 mtk_tops_ser_deinit(pdev);
98
99err_ctrl_deinit:
100 mtk_tops_ctrl_deinit(pdev);
101
102err_netevent_unregister:
103 mtk_tops_netevent_unregister(pdev);
104
105err_offload_proto_tear_down:
106 mtk_tops_tnl_offload_proto_teardown(pdev);
107
108err_mcu_tear_down:
109 mtk_tops_mcu_tear_down(pdev);
110
111 return ret;
112}
113
114static int mtk_tops_probe(struct platform_device *pdev)
115{
116 int ret = 0;
117
118 tops_dev = &pdev->dev;
119
120 ret = mtk_tops_hwspinlock_init(pdev);
121 if (ret) {
122 TOPS_ERR("hwspinlock init failed: %d\n", ret);
123 return ret;
124 }
125
126 ret = mtk_tops_fw_init(pdev);
127 if (ret) {
128 TOPS_ERR("firmware init failed: %d\n", ret);
129 return ret;
130 }
131
132 ret = mtk_tops_mcu_init(pdev);
133 if (ret) {
134 TOPS_ERR("mcu init failed: %d\n", ret);
135 return ret;
136 }
137
138 ret = mtk_tops_netsys_init(pdev);
139 if (ret) {
140 TOPS_ERR("netsys init failed: %d\n", ret);
141 goto err_mcu_deinit;
142 }
143
144 ret = mtk_tops_tdma_init(pdev);
145 if (ret) {
146 TOPS_ERR("tdma init failed: %d\n", ret);
147 goto err_netsys_deinit;
148 }
149
developer5d86c142023-12-06 14:18:27 +0800150 ret = mtk_tops_seq_gen_init(pdev);
151 if (ret) {
152 TOPS_ERR("sequence generator init failed: %d\n", ret);
153 goto err_tdma_deinit;
154 }
155
developere5e687d2023-08-08 16:05:33 +0800156 ret = mtk_tops_tnl_offload_init(pdev);
157 if (ret) {
158 TOPS_ERR("tunnel table init failed: %d\n", ret);
159 goto err_tdma_deinit;
160 }
161
developerd80acd02024-02-20 14:28:44 +0800162 ret = mtk_tops_misc_init(pdev);
developere5e687d2023-08-08 16:05:33 +0800163 if (ret)
164 goto err_tnl_offload_deinit;
165
developerd80acd02024-02-20 14:28:44 +0800166 ret = mtk_tops_post_init(pdev);
167 if (ret)
168 goto err_misc_deinit;
169
developere5e687d2023-08-08 16:05:33 +0800170 TOPS_ERR("init done\n");
171 return ret;
172
developerd80acd02024-02-20 14:28:44 +0800173err_misc_deinit:
174 mtk_tops_misc_deinit(pdev);
175
developere5e687d2023-08-08 16:05:33 +0800176err_tnl_offload_deinit:
177 mtk_tops_tnl_offload_deinit(pdev);
178
179err_tdma_deinit:
180 mtk_tops_tdma_deinit(pdev);
181
182err_netsys_deinit:
183 mtk_tops_netsys_deinit(pdev);
184
185err_mcu_deinit:
186 mtk_tops_mcu_deinit(pdev);
187
188 return ret;
189}
190
191static int mtk_tops_remove(struct platform_device *pdev)
192{
developer0fb30d52023-12-04 09:51:36 +0800193 mtk_tops_debugfs_init(pdev);
194
developere5e687d2023-08-08 16:05:33 +0800195 mtk_tops_wdt_deinit(pdev);
196
197 mtk_tops_ser_deinit(pdev);
198
199 mtk_tops_ctrl_deinit(pdev);
200
201 mtk_tops_netevent_unregister(pdev);
202
203 mtk_tops_tnl_offload_proto_teardown(pdev);
204
205 mtk_tops_mcu_tear_down(pdev);
206
developerd80acd02024-02-20 14:28:44 +0800207 mtk_tops_misc_deinit(pdev);
208
developere5e687d2023-08-08 16:05:33 +0800209 mtk_tops_tnl_offload_deinit(pdev);
210
211 mtk_tops_tdma_deinit(pdev);
212
213 mtk_tops_netsys_deinit(pdev);
214
215 mtk_tops_mcu_deinit(pdev);
216
217 return 0;
218}
219
220static const struct of_device_id tops_match[] = {
221 { .compatible = "mediatek,tops", },
222 { },
223};
224MODULE_DEVICE_TABLE(of, tops_match);
225
226static struct platform_driver mtk_tops_driver = {
227 .probe = mtk_tops_probe,
228 .remove = mtk_tops_remove,
229 .driver = {
230 .name = "mediatek,tops",
231 .owner = THIS_MODULE,
232 .of_match_table = tops_match,
233 },
234};
235
developer6a0a7102023-09-18 18:03:07 +0800236static int __init mtk_tops_hw_disabled(void)
237{
238 struct platform_device *efuse_pdev;
239 struct device_node *efuse_node;
240 struct resource res;
241 void __iomem *efuse_base;
242 int ret = 0;
243
244 efuse_node = of_find_compatible_node(NULL, NULL, "mediatek,efuse");
245 if (!efuse_node)
246 return -ENODEV;
247
248 efuse_pdev = of_find_device_by_node(efuse_node);
249 if (!efuse_pdev) {
250 ret = -ENODEV;
251 goto out;
252 }
253
254 if (of_address_to_resource(efuse_node, 0, &res)) {
255 ret = -ENXIO;
256 goto out;
257 }
258
259 /* since we are not probed yet, we cannot use devm_* API */
260 efuse_base = ioremap(res.start, resource_size(&res));
261 if (!efuse_base) {
262 ret = -ENOMEM;
263 goto out;
264 }
265
266 if (readl(efuse_base + EFUSE_TOPS_POWER_OFF))
267 ret = -ENODEV;
268
269 iounmap(efuse_base);
270
271out:
272 of_node_put(efuse_node);
273
274 return ret;
275}
276
developere5e687d2023-08-08 16:05:33 +0800277static int __init mtk_tops_init(void)
278{
developer6a0a7102023-09-18 18:03:07 +0800279 if (mtk_tops_hw_disabled())
280 return -ENODEV;
281
developerfbdb5112023-08-21 15:12:14 +0800282 tops_debugfs_root = debugfs_create_dir("tops", NULL);
283 if (IS_ERR(tops_debugfs_root)) {
284 TOPS_ERR("create tops debugfs root directory failed\n");
285 return PTR_ERR(tops_debugfs_root);
286 }
287
developere5e687d2023-08-08 16:05:33 +0800288 mtk_tops_mbox_init();
289
290 mtk_tops_hpdma_init();
291
292 mtk_tops_trm_init();
293
294 return platform_driver_register(&mtk_tops_driver);
295}
296
297static void __exit mtk_tops_exit(void)
298{
299 platform_driver_unregister(&mtk_tops_driver);
300
301 mtk_tops_trm_exit();
302
303 mtk_tops_hpdma_exit();
304
305 mtk_tops_mbox_exit();
developerfbdb5112023-08-21 15:12:14 +0800306
307 debugfs_remove_recursive(tops_debugfs_root);
developere5e687d2023-08-08 16:05:33 +0800308}
309
310module_init(mtk_tops_init);
311module_exit(mtk_tops_exit);
312
313MODULE_LICENSE("GPL v2");
314MODULE_DESCRIPTION("MediaTek TOPS Driver");
315MODULE_AUTHOR("Ren-Ting Wang <ren-ting.wang@mediatek.com>");