1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (c) 2019 Christoph Hellwig. |
4 | * Copyright (c) 2019 Western Digital Corporation or its affiliates. |
5 | */ |
6 | #include <linux/io.h> |
7 | #include <linux/platform_device.h> |
8 | #include <linux/of_platform.h> |
9 | #include <linux/clk.h> |
10 | #include <asm/soc.h> |
11 | |
12 | #include <soc/canaan/k210-sysctl.h> |
13 | |
14 | static int k210_sysctl_probe(struct platform_device *pdev) |
15 | { |
16 | struct device *dev = &pdev->dev; |
17 | struct clk *pclk; |
18 | int ret; |
19 | |
20 | dev_info(dev, "K210 system controller\n" ); |
21 | |
22 | /* Get power bus clock */ |
23 | pclk = devm_clk_get(dev, NULL); |
24 | if (IS_ERR(ptr: pclk)) |
25 | return dev_err_probe(dev, err: PTR_ERR(ptr: pclk), |
26 | fmt: "Get bus clock failed\n" ); |
27 | |
28 | ret = clk_prepare_enable(clk: pclk); |
29 | if (ret) { |
30 | dev_err(dev, "Enable bus clock failed\n" ); |
31 | return ret; |
32 | } |
33 | |
34 | /* Populate children */ |
35 | ret = devm_of_platform_populate(dev); |
36 | if (ret) |
37 | dev_err(dev, "Populate platform failed %d\n" , ret); |
38 | |
39 | return ret; |
40 | } |
41 | |
42 | static const struct of_device_id k210_sysctl_of_match[] = { |
43 | { .compatible = "canaan,k210-sysctl" , }, |
44 | { /* sentinel */ }, |
45 | }; |
46 | |
47 | static struct platform_driver k210_sysctl_driver = { |
48 | .driver = { |
49 | .name = "k210-sysctl" , |
50 | .of_match_table = k210_sysctl_of_match, |
51 | }, |
52 | .probe = k210_sysctl_probe, |
53 | }; |
54 | builtin_platform_driver(k210_sysctl_driver); |
55 | |
56 | /* |
57 | * System controller registers base address and size. |
58 | */ |
59 | #define K210_SYSCTL_BASE_ADDR 0x50440000ULL |
60 | #define K210_SYSCTL_BASE_SIZE 0x1000 |
61 | |
62 | /* |
63 | * This needs to be called very early during initialization, given that |
64 | * PLL1 needs to be enabled to be able to use all SRAM. |
65 | */ |
66 | static void __init k210_soc_early_init(const void *fdt) |
67 | { |
68 | void __iomem *sysctl_base; |
69 | |
70 | sysctl_base = ioremap(K210_SYSCTL_BASE_ADDR, K210_SYSCTL_BASE_SIZE); |
71 | if (!sysctl_base) |
72 | panic(fmt: "k210-sysctl: ioremap failed" ); |
73 | |
74 | k210_clk_early_init(regs: sysctl_base); |
75 | |
76 | iounmap(addr: sysctl_base); |
77 | } |
78 | SOC_EARLY_INIT_DECLARE(k210_soc, "canaan,kendryte-k210" , k210_soc_early_init); |
79 | |