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 81 static struct platform_driver tegra_ahb_driver; 82 83 static 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 115 struct tegra_ahb { 116 void __iomem *regs; 117 struct device *dev; 118 u32 ctx[0]; 119 }; 120 121 static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset) 122 { 123 return readl(ahb->regs + offset); 124 } 125 126 static 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 132 static 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 140 int 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 } 156 EXPORT_SYMBOL(tegra_ahb_enable_smmu); 157 #endif 158 159 static 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 169 static 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 179 static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm, 180 tegra_ahb_suspend, 181 tegra_ahb_resume, NULL); 182 183 static 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 243 static 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 267 static const struct of_device_id tegra_ahb_of_match[] __devinitconst = { 268 { .compatible = "nvidia,tegra30-ahb", }, 269 { .compatible = "nvidia,tegra20-ahb", }, 270 {}, 271 }; 272 273 static struct platform_driver tegra_ahb_driver = { 274 .probe = tegra_ahb_probe, 275 .driver = { 276 .name = DRV_NAME, 277 .owner = THIS_MODULE, 278 .of_match_table = tegra_ahb_of_match, 279 .pm = &tegra_ahb_pm, 280 }, 281 }; 282 module_platform_driver(tegra_ahb_driver); 283 284 MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); 285 MODULE_DESCRIPTION("Tegra AHB driver"); 286 MODULE_LICENSE("GPL v2"); 287 MODULE_ALIAS("platform:" DRV_NAME); 288