aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/amba
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-26 15:22:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-26 15:22:27 -0400
commitce53044c68cf4fb6c50a2a0d88786be65fae7235 (patch)
tree19c21da7d261412192e189ef3fd1a9ff4e7ba5c2 /drivers/amba
parent0877aa3908aaeeae8fc2850691668c4315d3db56 (diff)
parent046fae440d32cc6dec8148c7e06a8b4b987f8a2f (diff)
Merge tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull arm-soc driver specific updates from Olof Johansson: "These changes are specific to some driver that may be used by multiple boards or socs. The most significant change in here is the move of the samsung iommu code from a platform specific in-kernel interface to the generic iommu subsystem." Fix up trivial conflicts in arch/arm/mach-exynos/Kconfig * tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (28 commits) mmc: dt: Consolidate DT bindings iommu/exynos: Add iommu driver for EXYNOS Platforms ARM: davinci: optimize the DMA ISR ARM: davinci: implement DEBUG_LL port choice ARM: tegra: Add SMMU enabler in AHB ARM: tegra: Add Tegra AHB driver Input: pxa27x_keypad add choice to set direct_key_mask Input: pxa27x_keypad direct key may be low active Input: pxa27x_keypad bug fix for direct_key_mask Input: pxa27x_keypad keep clock on as wakeup source ARM: dt: tegra: pinmux changes for USB ULPI ARM: tegra: add USB ULPI PHY reset GPIO to device tree ARM: tegra: don't hard-code USB ULPI PHY reset_gpio ARM: tegra: change pll_p_out4's rate to 24MHz ARM: tegra: fix pclk rate ARM: tegra: reparent sclk to pll_c_out1 ARM: tegra: Add pllc clock init table ARM: dt: tegra cardhu: basic audio support ARM: dt: tegra30.dtsi: Add audio-related nodes ARM: tegra: add AUXDATA required for audio ...
Diffstat (limited to 'drivers/amba')
-rw-r--r--drivers/amba/Makefile4
-rw-r--r--drivers/amba/tegra-ahb.c293
2 files changed, 295 insertions, 2 deletions
diff --git a/drivers/amba/Makefile b/drivers/amba/Makefile
index 40fe74097be2..66e81c2f1e3c 100644
--- a/drivers/amba/Makefile
+++ b/drivers/amba/Makefile
@@ -1,2 +1,2 @@
1obj-y += bus.o 1obj-$(CONFIG_ARM_AMBA) += bus.o
2 2obj-$(CONFIG_TEGRA_AHB) += tegra-ahb.o
diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c
new file mode 100644
index 000000000000..aa0b1f160528
--- /dev/null
+++ b/drivers/amba/tegra-ahb.c
@@ -0,0 +1,293 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 * Copyright (C) 2011 Google, Inc.
4 *
5 * Author:
6 * Jay Cheng <jacheng@nvidia.com>
7 * James Wylder <james.wylder@motorola.com>
8 * Benoit Goby <benoit@android.com>
9 * Colin Cross <ccross@android.com>
10 * Hiroshi DOYU <hdoyu@nvidia.com>
11 *
12 * This software is licensed under the terms of the GNU General Public
13 * License version 2, as published by the Free Software Foundation, and
14 * may be copied, distributed, and modified under those terms.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 */
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/io.h>
27
28#define DRV_NAME "tegra-ahb"
29
30#define AHB_ARBITRATION_DISABLE 0x00
31#define AHB_ARBITRATION_PRIORITY_CTRL 0x04
32#define AHB_PRIORITY_WEIGHT(x) (((x) & 0x7) << 29)
33#define PRIORITY_SELECT_USB BIT(6)
34#define PRIORITY_SELECT_USB2 BIT(18)
35#define PRIORITY_SELECT_USB3 BIT(17)
36
37#define AHB_GIZMO_AHB_MEM 0x0c
38#define ENB_FAST_REARBITRATE BIT(2)
39#define DONT_SPLIT_AHB_WR BIT(7)
40
41#define AHB_GIZMO_APB_DMA 0x10
42#define AHB_GIZMO_IDE 0x18
43#define AHB_GIZMO_USB 0x1c
44#define AHB_GIZMO_AHB_XBAR_BRIDGE 0x20
45#define AHB_GIZMO_CPU_AHB_BRIDGE 0x24
46#define AHB_GIZMO_COP_AHB_BRIDGE 0x28
47#define AHB_GIZMO_XBAR_APB_CTLR 0x2c
48#define AHB_GIZMO_VCP_AHB_BRIDGE 0x30
49#define AHB_GIZMO_NAND 0x3c
50#define AHB_GIZMO_SDMMC4 0x44
51#define AHB_GIZMO_XIO 0x48
52#define AHB_GIZMO_BSEV 0x60
53#define AHB_GIZMO_BSEA 0x70
54#define AHB_GIZMO_NOR 0x74
55#define AHB_GIZMO_USB2 0x78
56#define AHB_GIZMO_USB3 0x7c
57#define IMMEDIATE BIT(18)
58
59#define AHB_GIZMO_SDMMC1 0x80
60#define AHB_GIZMO_SDMMC2 0x84
61#define AHB_GIZMO_SDMMC3 0x88
62#define AHB_MEM_PREFETCH_CFG_X 0xd8
63#define AHB_ARBITRATION_XBAR_CTRL 0xdc
64#define AHB_MEM_PREFETCH_CFG3 0xe0
65#define AHB_MEM_PREFETCH_CFG4 0xe4
66#define AHB_MEM_PREFETCH_CFG1 0xec
67#define AHB_MEM_PREFETCH_CFG2 0xf0
68#define PREFETCH_ENB BIT(31)
69#define MST_ID(x) (((x) & 0x1f) << 26)
70#define AHBDMA_MST_ID MST_ID(5)
71#define USB_MST_ID MST_ID(6)
72#define USB2_MST_ID MST_ID(18)
73#define USB3_MST_ID MST_ID(17)
74#define ADDR_BNDRY(x) (((x) & 0xf) << 21)
75#define INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0)
76
77#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xf8
78
79#define AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE BIT(17)
80
81static struct platform_driver tegra_ahb_driver;
82
83static const u32 tegra_ahb_gizmo[] = {
84 AHB_ARBITRATION_DISABLE,
85 AHB_ARBITRATION_PRIORITY_CTRL,
86 AHB_GIZMO_AHB_MEM,
87 AHB_GIZMO_APB_DMA,
88 AHB_GIZMO_IDE,
89 AHB_GIZMO_USB,
90 AHB_GIZMO_AHB_XBAR_BRIDGE,
91 AHB_GIZMO_CPU_AHB_BRIDGE,
92 AHB_GIZMO_COP_AHB_BRIDGE,
93 AHB_GIZMO_XBAR_APB_CTLR,
94 AHB_GIZMO_VCP_AHB_BRIDGE,
95 AHB_GIZMO_NAND,
96 AHB_GIZMO_SDMMC4,
97 AHB_GIZMO_XIO,
98 AHB_GIZMO_BSEV,
99 AHB_GIZMO_BSEA,
100 AHB_GIZMO_NOR,
101 AHB_GIZMO_USB2,
102 AHB_GIZMO_USB3,
103 AHB_GIZMO_SDMMC1,
104 AHB_GIZMO_SDMMC2,
105 AHB_GIZMO_SDMMC3,
106 AHB_MEM_PREFETCH_CFG_X,
107 AHB_ARBITRATION_XBAR_CTRL,
108 AHB_MEM_PREFETCH_CFG3,
109 AHB_MEM_PREFETCH_CFG4,
110 AHB_MEM_PREFETCH_CFG1,
111 AHB_MEM_PREFETCH_CFG2,
112 AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID,
113};
114
115struct tegra_ahb {
116 void __iomem *regs;
117 struct device *dev;
118 u32 ctx[0];
119};
120
121static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset)
122{
123 return readl(ahb->regs + offset);
124}
125
126static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset)
127{
128 writel(value, ahb->regs + offset);
129}
130
131#ifdef CONFIG_ARCH_TEGRA_3x_SOC
132static int tegra_ahb_match_by_smmu(struct device *dev, void *data)
133{
134 struct tegra_ahb *ahb = dev_get_drvdata(dev);
135 struct device_node *dn = data;
136
137 return (ahb->dev->of_node == dn) ? 1 : 0;
138}
139
140int tegra_ahb_enable_smmu(struct device_node *dn)
141{
142 struct device *dev;
143 u32 val;
144 struct tegra_ahb *ahb;
145
146 dev = driver_find_device(&tegra_ahb_driver.driver, NULL, dn,
147 tegra_ahb_match_by_smmu);
148 if (!dev)
149 return -EPROBE_DEFER;
150 ahb = dev_get_drvdata(dev);
151 val = gizmo_readl(ahb, AHB_ARBITRATION_XBAR_CTRL);
152 val |= AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE;
153 gizmo_writel(ahb, val, AHB_ARBITRATION_XBAR_CTRL);
154 return 0;
155}
156EXPORT_SYMBOL(tegra_ahb_enable_smmu);
157#endif
158
159static int tegra_ahb_suspend(struct device *dev)
160{
161 int i;
162 struct tegra_ahb *ahb = dev_get_drvdata(dev);
163
164 for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++)
165 ahb->ctx[i] = gizmo_readl(ahb, tegra_ahb_gizmo[i]);
166 return 0;
167}
168
169static int tegra_ahb_resume(struct device *dev)
170{
171 int i;
172 struct tegra_ahb *ahb = dev_get_drvdata(dev);
173
174 for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++)
175 gizmo_writel(ahb, ahb->ctx[i], tegra_ahb_gizmo[i]);
176 return 0;
177}
178
179static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm,
180 tegra_ahb_suspend,
181 tegra_ahb_resume, NULL);
182
183static void tegra_ahb_gizmo_init(struct tegra_ahb *ahb)
184{
185 u32 val;
186
187 val = gizmo_readl(ahb, AHB_GIZMO_AHB_MEM);
188 val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR;
189 gizmo_writel(ahb, val, AHB_GIZMO_AHB_MEM);
190
191 val = gizmo_readl(ahb, AHB_GIZMO_USB);
192 val |= IMMEDIATE;
193 gizmo_writel(ahb, val, AHB_GIZMO_USB);
194
195 val = gizmo_readl(ahb, AHB_GIZMO_USB2);
196 val |= IMMEDIATE;
197 gizmo_writel(ahb, val, AHB_GIZMO_USB2);
198
199 val = gizmo_readl(ahb, AHB_GIZMO_USB3);
200 val |= IMMEDIATE;
201 gizmo_writel(ahb, val, AHB_GIZMO_USB3);
202
203 val = gizmo_readl(ahb, AHB_ARBITRATION_PRIORITY_CTRL);
204 val |= PRIORITY_SELECT_USB |
205 PRIORITY_SELECT_USB2 |
206 PRIORITY_SELECT_USB3 |
207 AHB_PRIORITY_WEIGHT(7);
208 gizmo_writel(ahb, val, AHB_ARBITRATION_PRIORITY_CTRL);
209
210 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG1);
211 val &= ~MST_ID(~0);
212 val |= PREFETCH_ENB |
213 AHBDMA_MST_ID |
214 ADDR_BNDRY(0xc) |
215 INACTIVITY_TIMEOUT(0x1000);
216 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG1);
217
218 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG2);
219 val &= ~MST_ID(~0);
220 val |= PREFETCH_ENB |
221 USB_MST_ID |
222 ADDR_BNDRY(0xc) |
223 INACTIVITY_TIMEOUT(0x1000);
224 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG2);
225
226 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG3);
227 val &= ~MST_ID(~0);
228 val |= PREFETCH_ENB |
229 USB3_MST_ID |
230 ADDR_BNDRY(0xc) |
231 INACTIVITY_TIMEOUT(0x1000);
232 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG3);
233
234 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG4);
235 val &= ~MST_ID(~0);
236 val |= PREFETCH_ENB |
237 USB2_MST_ID |
238 ADDR_BNDRY(0xc) |
239 INACTIVITY_TIMEOUT(0x1000);
240 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG4);
241}
242
243static int __devinit tegra_ahb_probe(struct platform_device *pdev)
244{
245 struct resource *res;
246 struct tegra_ahb *ahb;
247 size_t bytes;
248
249 bytes = sizeof(*ahb) + sizeof(u32) * ARRAY_SIZE(tegra_ahb_gizmo);
250 ahb = devm_kzalloc(&pdev->dev, bytes, GFP_KERNEL);
251 if (!ahb)
252 return -ENOMEM;
253
254 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
255 if (!res)
256 return -ENODEV;
257 ahb->regs = devm_request_and_ioremap(&pdev->dev, res);
258 if (!ahb->regs)
259 return -EBUSY;
260
261 ahb->dev = &pdev->dev;
262 platform_set_drvdata(pdev, ahb);
263 tegra_ahb_gizmo_init(ahb);
264 return 0;
265}
266
267static int __devexit tegra_ahb_remove(struct platform_device *pdev)
268{
269 return 0;
270}
271
272static const struct of_device_id tegra_ahb_of_match[] __devinitconst = {
273 { .compatible = "nvidia,tegra30-ahb", },
274 { .compatible = "nvidia,tegra20-ahb", },
275 {},
276};
277
278static struct platform_driver tegra_ahb_driver = {
279 .probe = tegra_ahb_probe,
280 .remove = __devexit_p(tegra_ahb_remove),
281 .driver = {
282 .name = DRV_NAME,
283 .owner = THIS_MODULE,
284 .of_match_table = tegra_ahb_of_match,
285 .pm = &tegra_ahb_pm,
286 },
287};
288module_platform_driver(tegra_ahb_driver);
289
290MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
291MODULE_DESCRIPTION("Tegra AHB driver");
292MODULE_LICENSE("GPL v2");
293MODULE_ALIAS("platform:" DRV_NAME);