diff options
author | Olof Johansson <olof@lixom.net> | 2018-08-24 11:49:48 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2018-08-24 11:49:48 -0400 |
commit | c37aad3612c4a9e01ca69ad07b8ca41dbd222c46 (patch) | |
tree | e4c31d48a1491b8c78825ba5335bf2d59cd7640e | |
parent | 29ed45fff05899f6f39d05fe1c32b1bc51f8926b (diff) | |
parent | d903779b58be442f3afd2c51c46c7cf19c97684e (diff) |
Merge tag 'reset-for-4.19-2' of git://git.pengutronix.de/git/pza/linux into next/late
Reset controller changes for v4.19, part 2
This adds a single new driver for the Amlogic Meson Audio Memory Arbiter
resets.
* tag 'reset-for-4.19-2' of git://git.pengutronix.de/git/pza/linux:
reset: meson: add meson audio arb driver
reset: meson: add dt-bindings for meson-axg audio arb
Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r-- | Documentation/devicetree/bindings/reset/amlogic,meson-axg-audio-arb.txt | 21 | ||||
-rw-r--r-- | drivers/reset/Kconfig | 7 | ||||
-rw-r--r-- | drivers/reset/Makefile | 1 | ||||
-rw-r--r-- | drivers/reset/reset-meson-audio-arb.c | 168 | ||||
-rw-r--r-- | include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h | 17 |
5 files changed, 214 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/reset/amlogic,meson-axg-audio-arb.txt b/Documentation/devicetree/bindings/reset/amlogic,meson-axg-audio-arb.txt new file mode 100644 index 000000000000..26e542eb96df --- /dev/null +++ b/Documentation/devicetree/bindings/reset/amlogic,meson-axg-audio-arb.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | * Amlogic audio memory arbiter controller | ||
2 | |||
3 | The Amlogic Audio ARB is a simple device which enables or | ||
4 | disables the access of Audio FIFOs to DDR on AXG based SoC. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: 'amlogic,meson-axg-audio-arb' | ||
8 | - reg: physical base address of the controller and length of memory | ||
9 | mapped region. | ||
10 | - clocks: phandle to the fifo peripheral clock provided by the audio | ||
11 | clock controller. | ||
12 | - #reset-cells: must be 1. | ||
13 | |||
14 | Example on the A113 SoC: | ||
15 | |||
16 | arb: reset-controller@280 { | ||
17 | compatible = "amlogic,meson-axg-audio-arb"; | ||
18 | reg = <0x0 0x280 0x0 0x4>; | ||
19 | #reset-cells = <1>; | ||
20 | clocks = <&clkc_audio AUD_CLKID_DDR_ARB>; | ||
21 | }; | ||
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index a70262cb7e56..13d28fdbdbb5 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig | |||
@@ -73,6 +73,13 @@ config RESET_MESON | |||
73 | help | 73 | help |
74 | This enables the reset driver for Amlogic Meson SoCs. | 74 | This enables the reset driver for Amlogic Meson SoCs. |
75 | 75 | ||
76 | config RESET_MESON_AUDIO_ARB | ||
77 | tristate "Meson Audio Memory Arbiter Reset Driver" | ||
78 | depends on ARCH_MESON || COMPILE_TEST | ||
79 | help | ||
80 | This enables the reset driver for Audio Memory Arbiter of | ||
81 | Amlogic's A113 based SoCs | ||
82 | |||
76 | config RESET_OXNAS | 83 | config RESET_OXNAS |
77 | bool | 84 | bool |
78 | 85 | ||
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 0676b6b1976f..4243c38228e2 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile | |||
@@ -12,6 +12,7 @@ obj-$(CONFIG_RESET_IMX7) += reset-imx7.o | |||
12 | obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o | 12 | obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o |
13 | obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o | 13 | obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o |
14 | obj-$(CONFIG_RESET_MESON) += reset-meson.o | 14 | obj-$(CONFIG_RESET_MESON) += reset-meson.o |
15 | obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o | ||
15 | obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o | 16 | obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o |
16 | obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o | 17 | obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o |
17 | obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o | 18 | obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o |
diff --git a/drivers/reset/reset-meson-audio-arb.c b/drivers/reset/reset-meson-audio-arb.c new file mode 100644 index 000000000000..91751617b37a --- /dev/null +++ b/drivers/reset/reset-meson-audio-arb.c | |||
@@ -0,0 +1,168 @@ | |||
1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) | ||
2 | // Copyright (c) 2018 BayLibre, SAS. | ||
3 | // Author: Jerome Brunet <jbrunet@baylibre.com> | ||
4 | |||
5 | #include <linux/clk.h> | ||
6 | #include <linux/io.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/of_platform.h> | ||
9 | #include <linux/reset-controller.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | |||
12 | #include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h> | ||
13 | |||
14 | struct meson_audio_arb_data { | ||
15 | struct reset_controller_dev rstc; | ||
16 | void __iomem *regs; | ||
17 | struct clk *clk; | ||
18 | const unsigned int *reset_bits; | ||
19 | spinlock_t lock; | ||
20 | }; | ||
21 | |||
22 | #define ARB_GENERAL_BIT 31 | ||
23 | |||
24 | static const unsigned int axg_audio_arb_reset_bits[] = { | ||
25 | [AXG_ARB_TODDR_A] = 0, | ||
26 | [AXG_ARB_TODDR_B] = 1, | ||
27 | [AXG_ARB_TODDR_C] = 2, | ||
28 | [AXG_ARB_FRDDR_A] = 4, | ||
29 | [AXG_ARB_FRDDR_B] = 5, | ||
30 | [AXG_ARB_FRDDR_C] = 6, | ||
31 | }; | ||
32 | |||
33 | static int meson_audio_arb_update(struct reset_controller_dev *rcdev, | ||
34 | unsigned long id, bool assert) | ||
35 | { | ||
36 | u32 val; | ||
37 | struct meson_audio_arb_data *arb = | ||
38 | container_of(rcdev, struct meson_audio_arb_data, rstc); | ||
39 | |||
40 | spin_lock(&arb->lock); | ||
41 | val = readl(arb->regs); | ||
42 | |||
43 | if (assert) | ||
44 | val &= ~BIT(arb->reset_bits[id]); | ||
45 | else | ||
46 | val |= BIT(arb->reset_bits[id]); | ||
47 | |||
48 | writel(val, arb->regs); | ||
49 | spin_unlock(&arb->lock); | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static int meson_audio_arb_status(struct reset_controller_dev *rcdev, | ||
55 | unsigned long id) | ||
56 | { | ||
57 | u32 val; | ||
58 | struct meson_audio_arb_data *arb = | ||
59 | container_of(rcdev, struct meson_audio_arb_data, rstc); | ||
60 | |||
61 | val = readl(arb->regs); | ||
62 | |||
63 | return !(val & BIT(arb->reset_bits[id])); | ||
64 | } | ||
65 | |||
66 | static int meson_audio_arb_assert(struct reset_controller_dev *rcdev, | ||
67 | unsigned long id) | ||
68 | { | ||
69 | return meson_audio_arb_update(rcdev, id, true); | ||
70 | } | ||
71 | |||
72 | static int meson_audio_arb_deassert(struct reset_controller_dev *rcdev, | ||
73 | unsigned long id) | ||
74 | { | ||
75 | return meson_audio_arb_update(rcdev, id, false); | ||
76 | } | ||
77 | |||
78 | static const struct reset_control_ops meson_audio_arb_rstc_ops = { | ||
79 | .assert = meson_audio_arb_assert, | ||
80 | .deassert = meson_audio_arb_deassert, | ||
81 | .status = meson_audio_arb_status, | ||
82 | }; | ||
83 | |||
84 | static const struct of_device_id meson_audio_arb_of_match[] = { | ||
85 | { .compatible = "amlogic,meson-axg-audio-arb", }, | ||
86 | {} | ||
87 | }; | ||
88 | MODULE_DEVICE_TABLE(of, meson_audio_arb_of_match); | ||
89 | |||
90 | static int meson_audio_arb_remove(struct platform_device *pdev) | ||
91 | { | ||
92 | struct meson_audio_arb_data *arb = platform_get_drvdata(pdev); | ||
93 | |||
94 | /* Disable all access */ | ||
95 | spin_lock(&arb->lock); | ||
96 | writel(0, arb->regs); | ||
97 | spin_unlock(&arb->lock); | ||
98 | |||
99 | clk_disable_unprepare(arb->clk); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int meson_audio_arb_probe(struct platform_device *pdev) | ||
105 | { | ||
106 | struct device *dev = &pdev->dev; | ||
107 | struct meson_audio_arb_data *arb; | ||
108 | struct resource *res; | ||
109 | int ret; | ||
110 | |||
111 | arb = devm_kzalloc(dev, sizeof(*arb), GFP_KERNEL); | ||
112 | if (!arb) | ||
113 | return -ENOMEM; | ||
114 | platform_set_drvdata(pdev, arb); | ||
115 | |||
116 | arb->clk = devm_clk_get(dev, NULL); | ||
117 | if (IS_ERR(arb->clk)) { | ||
118 | if (PTR_ERR(arb->clk) != -EPROBE_DEFER) | ||
119 | dev_err(dev, "failed to get clock\n"); | ||
120 | return PTR_ERR(arb->clk); | ||
121 | } | ||
122 | |||
123 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
124 | arb->regs = devm_ioremap_resource(dev, res); | ||
125 | if (IS_ERR(arb->regs)) | ||
126 | return PTR_ERR(arb->regs); | ||
127 | |||
128 | spin_lock_init(&arb->lock); | ||
129 | arb->reset_bits = axg_audio_arb_reset_bits; | ||
130 | arb->rstc.nr_resets = ARRAY_SIZE(axg_audio_arb_reset_bits); | ||
131 | arb->rstc.ops = &meson_audio_arb_rstc_ops; | ||
132 | arb->rstc.of_node = dev->of_node; | ||
133 | |||
134 | /* | ||
135 | * Enable general : | ||
136 | * In the initial state, all memory interfaces are disabled | ||
137 | * and the general bit is on | ||
138 | */ | ||
139 | ret = clk_prepare_enable(arb->clk); | ||
140 | if (ret) { | ||
141 | dev_err(dev, "failed to enable arb clock\n"); | ||
142 | return ret; | ||
143 | } | ||
144 | writel(BIT(ARB_GENERAL_BIT), arb->regs); | ||
145 | |||
146 | /* Register reset controller */ | ||
147 | ret = devm_reset_controller_register(dev, &arb->rstc); | ||
148 | if (ret) { | ||
149 | dev_err(dev, "failed to register arb reset controller\n"); | ||
150 | meson_audio_arb_remove(pdev); | ||
151 | } | ||
152 | |||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | static struct platform_driver meson_audio_arb_pdrv = { | ||
157 | .probe = meson_audio_arb_probe, | ||
158 | .remove = meson_audio_arb_remove, | ||
159 | .driver = { | ||
160 | .name = "meson-audio-arb-reset", | ||
161 | .of_match_table = meson_audio_arb_of_match, | ||
162 | }, | ||
163 | }; | ||
164 | module_platform_driver(meson_audio_arb_pdrv); | ||
165 | |||
166 | MODULE_DESCRIPTION("Amlogic A113 Audio Memory Arbiter"); | ||
167 | MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); | ||
168 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h b/include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h new file mode 100644 index 000000000000..05c36367875c --- /dev/null +++ b/include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h | |||
@@ -0,0 +1,17 @@ | |||
1 | /* SPDX-License-Identifier: (GPL-2.0 OR MIT) | ||
2 | * | ||
3 | * Copyright (c) 2018 Baylibre SAS. | ||
4 | * Author: Jerome Brunet <jbrunet@baylibre.com> | ||
5 | */ | ||
6 | |||
7 | #ifndef _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H | ||
8 | #define _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H | ||
9 | |||
10 | #define AXG_ARB_TODDR_A 0 | ||
11 | #define AXG_ARB_TODDR_B 1 | ||
12 | #define AXG_ARB_TODDR_C 2 | ||
13 | #define AXG_ARB_FRDDR_A 3 | ||
14 | #define AXG_ARB_FRDDR_B 4 | ||
15 | #define AXG_ARB_FRDDR_C 5 | ||
16 | |||
17 | #endif /* _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H */ | ||