diff options
author | Olof Johansson <olof@lixom.net> | 2016-07-07 01:32:11 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2016-07-07 01:32:11 -0400 |
commit | 34df3b8bdc54709f78b0d72648fee6e53ffd8598 (patch) | |
tree | 62e112dfa330f2d0243c6b5199397f3ff38c37e0 | |
parent | b85751c761a56232e772f4c2d1aba2cd43d52849 (diff) | |
parent | 46a88534afb596eb4d9de07ddde778d0e9aa0e3a (diff) |
Merge tag 'tegra-for-4.8-bus' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers
bus: NVIDIA Tegra ACONNECT support
Adds support for the Tegra ACONNECT bus that's used to access the APE
(audio processing engine) on Tegra X1.
* tag 'tegra-for-4.8-bus' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
bus: Add support for Tegra ACONNECT
dt-bindings: bus: Add documentation for Tegra210 ACONNECT
Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r-- | Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt | 45 | ||||
-rw-r--r-- | drivers/bus/Kconfig | 13 | ||||
-rw-r--r-- | drivers/bus/Makefile | 1 | ||||
-rw-r--r-- | drivers/bus/tegra-aconnect.c | 112 |
4 files changed, 171 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt b/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt new file mode 100644 index 000000000000..7ff13be1750b --- /dev/null +++ b/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt | |||
@@ -0,0 +1,45 @@ | |||
1 | NVIDIA Tegra ACONNECT Bus | ||
2 | |||
3 | The Tegra ACONNECT bus is an AXI switch which is used to connnect various | ||
4 | components inside the Audio Processing Engine (APE). All CPU accesses to | ||
5 | the APE subsystem go through the ACONNECT via an APB to AXI wrapper. | ||
6 | |||
7 | Required properties: | ||
8 | - compatible: Must be "nvidia,tegra210-aconnect". | ||
9 | - clocks: Must contain the entries for the APE clock (TEGRA210_CLK_APE), | ||
10 | and APE interface clock (TEGRA210_CLK_APB2APE). | ||
11 | - clock-names: Must contain the names "ape" and "apb2ape" for the corresponding | ||
12 | 'clocks' entries. | ||
13 | - power-domains: Must contain a phandle that points to the audio powergate | ||
14 | (namely 'aud') for Tegra210. | ||
15 | - #address-cells: The number of cells used to represent physical base addresses | ||
16 | in the aconnect address space. Should be 1. | ||
17 | - #size-cells: The number of cells used to represent the size of an address | ||
18 | range in the aconnect address space. Should be 1. | ||
19 | - ranges: Mapping of the aconnect address space to the CPU address space. | ||
20 | |||
21 | All devices accessed via the ACONNNECT are described by child-nodes. | ||
22 | |||
23 | Example: | ||
24 | |||
25 | aconnect@702c0000 { | ||
26 | compatible = "nvidia,tegra210-aconnect"; | ||
27 | clocks = <&tegra_car TEGRA210_CLK_APE>, | ||
28 | <&tegra_car TEGRA210_CLK_APB2APE>; | ||
29 | clock-names = "ape", "apb2ape"; | ||
30 | power-domains = <&pd_audio>; | ||
31 | |||
32 | #address-cells = <1>; | ||
33 | #size-cells = <1>; | ||
34 | ranges = <0x702c0000 0x0 0x702c0000 0x00040000>; | ||
35 | |||
36 | status = "disabled"; | ||
37 | |||
38 | child1 { | ||
39 | ... | ||
40 | }; | ||
41 | |||
42 | child2 { | ||
43 | ... | ||
44 | }; | ||
45 | }; | ||
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index c5a7de9bc783..3b205e212337 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig | |||
@@ -132,6 +132,19 @@ config SUNXI_RSB | |||
132 | with various RSB based devices, such as AXP223, AXP8XX PMICs, | 132 | with various RSB based devices, such as AXP223, AXP8XX PMICs, |
133 | and AC100/AC200 ICs. | 133 | and AC100/AC200 ICs. |
134 | 134 | ||
135 | # TODO: This uses pm_clk_*() symbols that aren't exported in v4.7 and hence | ||
136 | # the driver will fail to build as a module. However there are patches to | ||
137 | # address that queued for v4.8, so this can be turned into a tristate symbol | ||
138 | # after v4.8-rc1. | ||
139 | config TEGRA_ACONNECT | ||
140 | bool "Tegra ACONNECT Bus Driver" | ||
141 | depends on ARCH_TEGRA_210_SOC | ||
142 | depends on OF && PM | ||
143 | select PM_CLK | ||
144 | help | ||
145 | Driver for the Tegra ACONNECT bus which is used to interface with | ||
146 | the devices inside the Audio Processing Engine (APE) for Tegra210. | ||
147 | |||
135 | config UNIPHIER_SYSTEM_BUS | 148 | config UNIPHIER_SYSTEM_BUS |
136 | tristate "UniPhier System Bus driver" | 149 | tristate "UniPhier System Bus driver" |
137 | depends on ARCH_UNIPHIER && OF | 150 | depends on ARCH_UNIPHIER && OF |
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index ccff007ee7e8..ac84cc4348e3 100644 --- a/drivers/bus/Makefile +++ b/drivers/bus/Makefile | |||
@@ -17,5 +17,6 @@ obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o | |||
17 | obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o | 17 | obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o |
18 | obj-$(CONFIG_SUNXI_RSB) += sunxi-rsb.o | 18 | obj-$(CONFIG_SUNXI_RSB) += sunxi-rsb.o |
19 | obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o | 19 | obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o |
20 | obj-$(CONFIG_TEGRA_ACONNECT) += tegra-aconnect.o | ||
20 | obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o | 21 | obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o |
21 | obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o | 22 | obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o |
diff --git a/drivers/bus/tegra-aconnect.c b/drivers/bus/tegra-aconnect.c new file mode 100644 index 000000000000..7e4104b74fa8 --- /dev/null +++ b/drivers/bus/tegra-aconnect.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * Tegra ACONNECT Bus Driver | ||
3 | * | ||
4 | * Copyright (C) 2016, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/of_platform.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/pm_clock.h> | ||
16 | #include <linux/pm_runtime.h> | ||
17 | |||
18 | static int tegra_aconnect_add_clock(struct device *dev, char *name) | ||
19 | { | ||
20 | struct clk *clk; | ||
21 | int ret; | ||
22 | |||
23 | clk = clk_get(dev, name); | ||
24 | if (IS_ERR(clk)) { | ||
25 | dev_err(dev, "%s clock not found\n", name); | ||
26 | return PTR_ERR(clk); | ||
27 | } | ||
28 | |||
29 | ret = pm_clk_add_clk(dev, clk); | ||
30 | if (ret) | ||
31 | clk_put(clk); | ||
32 | |||
33 | return ret; | ||
34 | } | ||
35 | |||
36 | static int tegra_aconnect_probe(struct platform_device *pdev) | ||
37 | { | ||
38 | int ret; | ||
39 | |||
40 | if (!pdev->dev.of_node) | ||
41 | return -EINVAL; | ||
42 | |||
43 | ret = pm_clk_create(&pdev->dev); | ||
44 | if (ret) | ||
45 | return ret; | ||
46 | |||
47 | ret = tegra_aconnect_add_clock(&pdev->dev, "ape"); | ||
48 | if (ret) | ||
49 | goto clk_destroy; | ||
50 | |||
51 | ret = tegra_aconnect_add_clock(&pdev->dev, "apb2ape"); | ||
52 | if (ret) | ||
53 | goto clk_destroy; | ||
54 | |||
55 | pm_runtime_enable(&pdev->dev); | ||
56 | |||
57 | of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); | ||
58 | |||
59 | dev_info(&pdev->dev, "Tegra ACONNECT bus registered\n"); | ||
60 | |||
61 | return 0; | ||
62 | |||
63 | clk_destroy: | ||
64 | pm_clk_destroy(&pdev->dev); | ||
65 | |||
66 | return ret; | ||
67 | } | ||
68 | |||
69 | static int tegra_aconnect_remove(struct platform_device *pdev) | ||
70 | { | ||
71 | pm_runtime_disable(&pdev->dev); | ||
72 | |||
73 | pm_clk_destroy(&pdev->dev); | ||
74 | |||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int tegra_aconnect_runtime_resume(struct device *dev) | ||
79 | { | ||
80 | return pm_clk_resume(dev); | ||
81 | } | ||
82 | |||
83 | static int tegra_aconnect_runtime_suspend(struct device *dev) | ||
84 | { | ||
85 | return pm_clk_suspend(dev); | ||
86 | } | ||
87 | |||
88 | static const struct dev_pm_ops tegra_aconnect_pm_ops = { | ||
89 | SET_RUNTIME_PM_OPS(tegra_aconnect_runtime_suspend, | ||
90 | tegra_aconnect_runtime_resume, NULL) | ||
91 | }; | ||
92 | |||
93 | static const struct of_device_id tegra_aconnect_of_match[] = { | ||
94 | { .compatible = "nvidia,tegra210-aconnect", }, | ||
95 | { } | ||
96 | }; | ||
97 | MODULE_DEVICE_TABLE(of, tegra_aconnect_of_match); | ||
98 | |||
99 | static struct platform_driver tegra_aconnect_driver = { | ||
100 | .probe = tegra_aconnect_probe, | ||
101 | .remove = tegra_aconnect_remove, | ||
102 | .driver = { | ||
103 | .name = "tegra-aconnect", | ||
104 | .of_match_table = tegra_aconnect_of_match, | ||
105 | .pm = &tegra_aconnect_pm_ops, | ||
106 | }, | ||
107 | }; | ||
108 | module_platform_driver(tegra_aconnect_driver); | ||
109 | |||
110 | MODULE_DESCRIPTION("NVIDIA Tegra ACONNECT Bus Driver"); | ||
111 | MODULE_AUTHOR("Jon Hunter <jonathanh@nvidia.com>"); | ||
112 | MODULE_LICENSE("GPL v2"); | ||