aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt11
-rw-r--r--arch/arm/mach-tegra/Kconfig8
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/amba/Makefile4
-rw-r--r--drivers/amba/tegra-ahb.c261
5 files changed, 283 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt
new file mode 100644
index 000000000000..234406d41c12
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt
@@ -0,0 +1,11 @@
1NVIDIA Tegra AHB
2
3Required properties:
4- compatible : "nvidia,tegra20-ahb" or "nvidia,tegra30-ahb"
5- reg : Should contain 1 register ranges(address and length)
6
7Example:
8 ahb: ahb@6000c004 {
9 compatible = "nvidia,tegra20-ahb";
10 reg = <0x6000c004 0x10c>; /* AHB Arbitration + Gizmo Controller */
11 };
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index d0f2546706ca..8bf27b54288e 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -50,6 +50,14 @@ config TEGRA_PCI
50 depends on ARCH_TEGRA_2x_SOC 50 depends on ARCH_TEGRA_2x_SOC
51 select PCI 51 select PCI
52 52
53config TEGRA_AHB
54 bool "Enable AHB driver for NVIDIA Tegra SoCs"
55 default y
56 help
57 Adds AHB configuration functionality for NVIDIA Tegra SoCs,
58 which controls AHB bus master arbitration and some
59 perfomance parameters(priority, prefech size).
60
53comment "Tegra board type" 61comment "Tegra board type"
54 62
55config MACH_HARMONY 63config MACH_HARMONY
diff --git a/drivers/Makefile b/drivers/Makefile
index 95952c82bf16..fd7176390168 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -18,7 +18,7 @@ obj-$(CONFIG_SFI) += sfi/
18# PnP must come after ACPI since it will eventually need to check if acpi 18# PnP must come after ACPI since it will eventually need to check if acpi
19# was used and do nothing if so 19# was used and do nothing if so
20obj-$(CONFIG_PNP) += pnp/ 20obj-$(CONFIG_PNP) += pnp/
21obj-$(CONFIG_ARM_AMBA) += amba/ 21obj-y += amba/
22# Many drivers will want to use DMA so this has to be made available 22# Many drivers will want to use DMA so this has to be made available
23# really early. 23# really early.
24obj-$(CONFIG_DMA_ENGINE) += dma/ 24obj-$(CONFIG_DMA_ENGINE) += dma/
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..106a780d29a0
--- /dev/null
+++ b/drivers/amba/tegra-ahb.c
@@ -0,0 +1,261 @@
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
79static const u32 tegra_ahb_gizmo[] = {
80 AHB_ARBITRATION_DISABLE,
81 AHB_ARBITRATION_PRIORITY_CTRL,
82 AHB_GIZMO_AHB_MEM,
83 AHB_GIZMO_APB_DMA,
84 AHB_GIZMO_IDE,
85 AHB_GIZMO_USB,
86 AHB_GIZMO_AHB_XBAR_BRIDGE,
87 AHB_GIZMO_CPU_AHB_BRIDGE,
88 AHB_GIZMO_COP_AHB_BRIDGE,
89 AHB_GIZMO_XBAR_APB_CTLR,
90 AHB_GIZMO_VCP_AHB_BRIDGE,
91 AHB_GIZMO_NAND,
92 AHB_GIZMO_SDMMC4,
93 AHB_GIZMO_XIO,
94 AHB_GIZMO_BSEV,
95 AHB_GIZMO_BSEA,
96 AHB_GIZMO_NOR,
97 AHB_GIZMO_USB2,
98 AHB_GIZMO_USB3,
99 AHB_GIZMO_SDMMC1,
100 AHB_GIZMO_SDMMC2,
101 AHB_GIZMO_SDMMC3,
102 AHB_MEM_PREFETCH_CFG_X,
103 AHB_ARBITRATION_XBAR_CTRL,
104 AHB_MEM_PREFETCH_CFG3,
105 AHB_MEM_PREFETCH_CFG4,
106 AHB_MEM_PREFETCH_CFG1,
107 AHB_MEM_PREFETCH_CFG2,
108 AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID,
109};
110
111struct tegra_ahb {
112 void __iomem *regs;
113 struct device *dev;
114 u32 ctx[0];
115};
116
117static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset)
118{
119 return readl(ahb->regs + offset);
120}
121
122static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset)
123{
124 writel(value, ahb->regs + offset);
125}
126
127static int tegra_ahb_suspend(struct device *dev)
128{
129 int i;
130 struct tegra_ahb *ahb = dev_get_drvdata(dev);
131
132 for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++)
133 ahb->ctx[i] = gizmo_readl(ahb, tegra_ahb_gizmo[i]);
134 return 0;
135}
136
137static int tegra_ahb_resume(struct device *dev)
138{
139 int i;
140 struct tegra_ahb *ahb = dev_get_drvdata(dev);
141
142 for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++)
143 gizmo_writel(ahb, ahb->ctx[i], tegra_ahb_gizmo[i]);
144 return 0;
145}
146
147static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm,
148 tegra_ahb_suspend,
149 tegra_ahb_resume, NULL);
150
151static void tegra_ahb_gizmo_init(struct tegra_ahb *ahb)
152{
153 u32 val;
154
155 val = gizmo_readl(ahb, AHB_GIZMO_AHB_MEM);
156 val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR;
157 gizmo_writel(ahb, val, AHB_GIZMO_AHB_MEM);
158
159 val = gizmo_readl(ahb, AHB_GIZMO_USB);
160 val |= IMMEDIATE;
161 gizmo_writel(ahb, val, AHB_GIZMO_USB);
162
163 val = gizmo_readl(ahb, AHB_GIZMO_USB2);
164 val |= IMMEDIATE;
165 gizmo_writel(ahb, val, AHB_GIZMO_USB2);
166
167 val = gizmo_readl(ahb, AHB_GIZMO_USB3);
168 val |= IMMEDIATE;
169 gizmo_writel(ahb, val, AHB_GIZMO_USB3);
170
171 val = gizmo_readl(ahb, AHB_ARBITRATION_PRIORITY_CTRL);
172 val |= PRIORITY_SELECT_USB |
173 PRIORITY_SELECT_USB2 |
174 PRIORITY_SELECT_USB3 |
175 AHB_PRIORITY_WEIGHT(7);
176 gizmo_writel(ahb, val, AHB_ARBITRATION_PRIORITY_CTRL);
177
178 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG1);
179 val &= ~MST_ID(~0);
180 val |= PREFETCH_ENB |
181 AHBDMA_MST_ID |
182 ADDR_BNDRY(0xc) |
183 INACTIVITY_TIMEOUT(0x1000);
184 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG1);
185
186 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG2);
187 val &= ~MST_ID(~0);
188 val |= PREFETCH_ENB |
189 USB_MST_ID |
190 ADDR_BNDRY(0xc) |
191 INACTIVITY_TIMEOUT(0x1000);
192 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG2);
193
194 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG3);
195 val &= ~MST_ID(~0);
196 val |= PREFETCH_ENB |
197 USB3_MST_ID |
198 ADDR_BNDRY(0xc) |
199 INACTIVITY_TIMEOUT(0x1000);
200 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG3);
201
202 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG4);
203 val &= ~MST_ID(~0);
204 val |= PREFETCH_ENB |
205 USB2_MST_ID |
206 ADDR_BNDRY(0xc) |
207 INACTIVITY_TIMEOUT(0x1000);
208 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG4);
209}
210
211static int __devinit tegra_ahb_probe(struct platform_device *pdev)
212{
213 struct resource *res;
214 struct tegra_ahb *ahb;
215 size_t bytes;
216
217 bytes = sizeof(*ahb) + sizeof(u32) * ARRAY_SIZE(tegra_ahb_gizmo);
218 ahb = devm_kzalloc(&pdev->dev, bytes, GFP_KERNEL);
219 if (!ahb)
220 return -ENOMEM;
221
222 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
223 if (!res)
224 return -ENODEV;
225 ahb->regs = devm_request_and_ioremap(&pdev->dev, res);
226 if (!ahb->regs)
227 return -EBUSY;
228
229 ahb->dev = &pdev->dev;
230 platform_set_drvdata(pdev, ahb);
231 tegra_ahb_gizmo_init(ahb);
232 return 0;
233}
234
235static int __devexit tegra_ahb_remove(struct platform_device *pdev)
236{
237 return 0;
238}
239
240static const struct of_device_id tegra_ahb_of_match[] __devinitconst = {
241 { .compatible = "nvidia,tegra30-ahb", },
242 { .compatible = "nvidia,tegra20-ahb", },
243 {},
244};
245
246static struct platform_driver tegra_ahb_driver = {
247 .probe = tegra_ahb_probe,
248 .remove = __devexit_p(tegra_ahb_remove),
249 .driver = {
250 .name = DRV_NAME,
251 .owner = THIS_MODULE,
252 .of_match_table = tegra_ahb_of_match,
253 .pm = &tegra_ahb_pm,
254 },
255};
256module_platform_driver(tegra_ahb_driver);
257
258MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
259MODULE_DESCRIPTION("Tegra AHB driver");
260MODULE_LICENSE("GPL v2");
261MODULE_ALIAS("platform:" DRV_NAME);