Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.16 289 lines 7.6 kB view raw
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/err.h> 24#include <linux/kernel.h> 25#include <linux/module.h> 26#include <linux/platform_device.h> 27#include <linux/io.h> 28#include <linux/tegra-ahb.h> 29 30#define DRV_NAME "tegra-ahb" 31 32#define AHB_ARBITRATION_DISABLE 0x00 33#define AHB_ARBITRATION_PRIORITY_CTRL 0x04 34#define AHB_PRIORITY_WEIGHT(x) (((x) & 0x7) << 29) 35#define PRIORITY_SELECT_USB BIT(6) 36#define PRIORITY_SELECT_USB2 BIT(18) 37#define PRIORITY_SELECT_USB3 BIT(17) 38 39#define AHB_GIZMO_AHB_MEM 0x0c 40#define ENB_FAST_REARBITRATE BIT(2) 41#define DONT_SPLIT_AHB_WR BIT(7) 42 43#define AHB_GIZMO_APB_DMA 0x10 44#define AHB_GIZMO_IDE 0x18 45#define AHB_GIZMO_USB 0x1c 46#define AHB_GIZMO_AHB_XBAR_BRIDGE 0x20 47#define AHB_GIZMO_CPU_AHB_BRIDGE 0x24 48#define AHB_GIZMO_COP_AHB_BRIDGE 0x28 49#define AHB_GIZMO_XBAR_APB_CTLR 0x2c 50#define AHB_GIZMO_VCP_AHB_BRIDGE 0x30 51#define AHB_GIZMO_NAND 0x3c 52#define AHB_GIZMO_SDMMC4 0x44 53#define AHB_GIZMO_XIO 0x48 54#define AHB_GIZMO_BSEV 0x60 55#define AHB_GIZMO_BSEA 0x70 56#define AHB_GIZMO_NOR 0x74 57#define AHB_GIZMO_USB2 0x78 58#define AHB_GIZMO_USB3 0x7c 59#define IMMEDIATE BIT(18) 60 61#define AHB_GIZMO_SDMMC1 0x80 62#define AHB_GIZMO_SDMMC2 0x84 63#define AHB_GIZMO_SDMMC3 0x88 64#define AHB_MEM_PREFETCH_CFG_X 0xd8 65#define AHB_ARBITRATION_XBAR_CTRL 0xdc 66#define AHB_MEM_PREFETCH_CFG3 0xe0 67#define AHB_MEM_PREFETCH_CFG4 0xe4 68#define AHB_MEM_PREFETCH_CFG1 0xec 69#define AHB_MEM_PREFETCH_CFG2 0xf0 70#define PREFETCH_ENB BIT(31) 71#define MST_ID(x) (((x) & 0x1f) << 26) 72#define AHBDMA_MST_ID MST_ID(5) 73#define USB_MST_ID MST_ID(6) 74#define USB2_MST_ID MST_ID(18) 75#define USB3_MST_ID MST_ID(17) 76#define ADDR_BNDRY(x) (((x) & 0xf) << 21) 77#define INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0) 78 79#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xf8 80 81#define AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE BIT(17) 82 83static struct platform_driver tegra_ahb_driver; 84 85static const u32 tegra_ahb_gizmo[] = { 86 AHB_ARBITRATION_DISABLE, 87 AHB_ARBITRATION_PRIORITY_CTRL, 88 AHB_GIZMO_AHB_MEM, 89 AHB_GIZMO_APB_DMA, 90 AHB_GIZMO_IDE, 91 AHB_GIZMO_USB, 92 AHB_GIZMO_AHB_XBAR_BRIDGE, 93 AHB_GIZMO_CPU_AHB_BRIDGE, 94 AHB_GIZMO_COP_AHB_BRIDGE, 95 AHB_GIZMO_XBAR_APB_CTLR, 96 AHB_GIZMO_VCP_AHB_BRIDGE, 97 AHB_GIZMO_NAND, 98 AHB_GIZMO_SDMMC4, 99 AHB_GIZMO_XIO, 100 AHB_GIZMO_BSEV, 101 AHB_GIZMO_BSEA, 102 AHB_GIZMO_NOR, 103 AHB_GIZMO_USB2, 104 AHB_GIZMO_USB3, 105 AHB_GIZMO_SDMMC1, 106 AHB_GIZMO_SDMMC2, 107 AHB_GIZMO_SDMMC3, 108 AHB_MEM_PREFETCH_CFG_X, 109 AHB_ARBITRATION_XBAR_CTRL, 110 AHB_MEM_PREFETCH_CFG3, 111 AHB_MEM_PREFETCH_CFG4, 112 AHB_MEM_PREFETCH_CFG1, 113 AHB_MEM_PREFETCH_CFG2, 114 AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID, 115}; 116 117struct tegra_ahb { 118 void __iomem *regs; 119 struct device *dev; 120 u32 ctx[0]; 121}; 122 123static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset) 124{ 125 return readl(ahb->regs + offset); 126} 127 128static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset) 129{ 130 writel(value, ahb->regs + offset); 131} 132 133#ifdef CONFIG_TEGRA_IOMMU_SMMU 134static int tegra_ahb_match_by_smmu(struct device *dev, void *data) 135{ 136 struct tegra_ahb *ahb = dev_get_drvdata(dev); 137 struct device_node *dn = data; 138 139 return (ahb->dev->of_node == dn) ? 1 : 0; 140} 141 142int tegra_ahb_enable_smmu(struct device_node *dn) 143{ 144 struct device *dev; 145 u32 val; 146 struct tegra_ahb *ahb; 147 148 dev = driver_find_device(&tegra_ahb_driver.driver, NULL, dn, 149 tegra_ahb_match_by_smmu); 150 if (!dev) 151 return -EPROBE_DEFER; 152 ahb = dev_get_drvdata(dev); 153 val = gizmo_readl(ahb, AHB_ARBITRATION_XBAR_CTRL); 154 val |= AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE; 155 gizmo_writel(ahb, val, AHB_ARBITRATION_XBAR_CTRL); 156 return 0; 157} 158EXPORT_SYMBOL(tegra_ahb_enable_smmu); 159#endif 160 161#ifdef CONFIG_PM 162static int tegra_ahb_suspend(struct device *dev) 163{ 164 int i; 165 struct tegra_ahb *ahb = dev_get_drvdata(dev); 166 167 for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++) 168 ahb->ctx[i] = gizmo_readl(ahb, tegra_ahb_gizmo[i]); 169 return 0; 170} 171 172static int tegra_ahb_resume(struct device *dev) 173{ 174 int i; 175 struct tegra_ahb *ahb = dev_get_drvdata(dev); 176 177 for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++) 178 gizmo_writel(ahb, ahb->ctx[i], tegra_ahb_gizmo[i]); 179 return 0; 180} 181#endif 182 183static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm, 184 tegra_ahb_suspend, 185 tegra_ahb_resume, NULL); 186 187static void tegra_ahb_gizmo_init(struct tegra_ahb *ahb) 188{ 189 u32 val; 190 191 val = gizmo_readl(ahb, AHB_GIZMO_AHB_MEM); 192 val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR; 193 gizmo_writel(ahb, val, AHB_GIZMO_AHB_MEM); 194 195 val = gizmo_readl(ahb, AHB_GIZMO_USB); 196 val |= IMMEDIATE; 197 gizmo_writel(ahb, val, AHB_GIZMO_USB); 198 199 val = gizmo_readl(ahb, AHB_GIZMO_USB2); 200 val |= IMMEDIATE; 201 gizmo_writel(ahb, val, AHB_GIZMO_USB2); 202 203 val = gizmo_readl(ahb, AHB_GIZMO_USB3); 204 val |= IMMEDIATE; 205 gizmo_writel(ahb, val, AHB_GIZMO_USB3); 206 207 val = gizmo_readl(ahb, AHB_ARBITRATION_PRIORITY_CTRL); 208 val |= PRIORITY_SELECT_USB | 209 PRIORITY_SELECT_USB2 | 210 PRIORITY_SELECT_USB3 | 211 AHB_PRIORITY_WEIGHT(7); 212 gizmo_writel(ahb, val, AHB_ARBITRATION_PRIORITY_CTRL); 213 214 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG1); 215 val &= ~MST_ID(~0); 216 val |= PREFETCH_ENB | 217 AHBDMA_MST_ID | 218 ADDR_BNDRY(0xc) | 219 INACTIVITY_TIMEOUT(0x1000); 220 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG1); 221 222 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG2); 223 val &= ~MST_ID(~0); 224 val |= PREFETCH_ENB | 225 USB_MST_ID | 226 ADDR_BNDRY(0xc) | 227 INACTIVITY_TIMEOUT(0x1000); 228 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG2); 229 230 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG3); 231 val &= ~MST_ID(~0); 232 val |= PREFETCH_ENB | 233 USB3_MST_ID | 234 ADDR_BNDRY(0xc) | 235 INACTIVITY_TIMEOUT(0x1000); 236 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG3); 237 238 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG4); 239 val &= ~MST_ID(~0); 240 val |= PREFETCH_ENB | 241 USB2_MST_ID | 242 ADDR_BNDRY(0xc) | 243 INACTIVITY_TIMEOUT(0x1000); 244 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG4); 245} 246 247static int tegra_ahb_probe(struct platform_device *pdev) 248{ 249 struct resource *res; 250 struct tegra_ahb *ahb; 251 size_t bytes; 252 253 bytes = sizeof(*ahb) + sizeof(u32) * ARRAY_SIZE(tegra_ahb_gizmo); 254 ahb = devm_kzalloc(&pdev->dev, bytes, GFP_KERNEL); 255 if (!ahb) 256 return -ENOMEM; 257 258 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 259 ahb->regs = devm_ioremap_resource(&pdev->dev, res); 260 if (IS_ERR(ahb->regs)) 261 return PTR_ERR(ahb->regs); 262 263 ahb->dev = &pdev->dev; 264 platform_set_drvdata(pdev, ahb); 265 tegra_ahb_gizmo_init(ahb); 266 return 0; 267} 268 269static const struct of_device_id tegra_ahb_of_match[] = { 270 { .compatible = "nvidia,tegra30-ahb", }, 271 { .compatible = "nvidia,tegra20-ahb", }, 272 {}, 273}; 274 275static struct platform_driver tegra_ahb_driver = { 276 .probe = tegra_ahb_probe, 277 .driver = { 278 .name = DRV_NAME, 279 .owner = THIS_MODULE, 280 .of_match_table = tegra_ahb_of_match, 281 .pm = &tegra_ahb_pm, 282 }, 283}; 284module_platform_driver(tegra_ahb_driver); 285 286MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); 287MODULE_DESCRIPTION("Tegra AHB driver"); 288MODULE_LICENSE("GPL v2"); 289MODULE_ALIAS("platform:" DRV_NAME);