0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/err.h>
0015 #include <linux/kernel.h>
0016 #include <linux/module.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/io.h>
0019 #include <linux/of.h>
0020
0021 #include <soc/tegra/ahb.h>
0022
0023 #define DRV_NAME "tegra-ahb"
0024
0025 #define AHB_ARBITRATION_DISABLE 0x04
0026 #define AHB_ARBITRATION_PRIORITY_CTRL 0x08
0027 #define AHB_PRIORITY_WEIGHT(x) (((x) & 0x7) << 29)
0028 #define PRIORITY_SELECT_USB BIT(6)
0029 #define PRIORITY_SELECT_USB2 BIT(18)
0030 #define PRIORITY_SELECT_USB3 BIT(17)
0031
0032 #define AHB_GIZMO_AHB_MEM 0x10
0033 #define ENB_FAST_REARBITRATE BIT(2)
0034 #define DONT_SPLIT_AHB_WR BIT(7)
0035
0036 #define AHB_GIZMO_APB_DMA 0x14
0037 #define AHB_GIZMO_IDE 0x1c
0038 #define AHB_GIZMO_USB 0x20
0039 #define AHB_GIZMO_AHB_XBAR_BRIDGE 0x24
0040 #define AHB_GIZMO_CPU_AHB_BRIDGE 0x28
0041 #define AHB_GIZMO_COP_AHB_BRIDGE 0x2c
0042 #define AHB_GIZMO_XBAR_APB_CTLR 0x30
0043 #define AHB_GIZMO_VCP_AHB_BRIDGE 0x34
0044 #define AHB_GIZMO_NAND 0x40
0045 #define AHB_GIZMO_SDMMC4 0x48
0046 #define AHB_GIZMO_XIO 0x4c
0047 #define AHB_GIZMO_BSEV 0x64
0048 #define AHB_GIZMO_BSEA 0x74
0049 #define AHB_GIZMO_NOR 0x78
0050 #define AHB_GIZMO_USB2 0x7c
0051 #define AHB_GIZMO_USB3 0x80
0052 #define IMMEDIATE BIT(18)
0053
0054 #define AHB_GIZMO_SDMMC1 0x84
0055 #define AHB_GIZMO_SDMMC2 0x88
0056 #define AHB_GIZMO_SDMMC3 0x8c
0057 #define AHB_MEM_PREFETCH_CFG_X 0xdc
0058 #define AHB_ARBITRATION_XBAR_CTRL 0xe0
0059 #define AHB_MEM_PREFETCH_CFG3 0xe4
0060 #define AHB_MEM_PREFETCH_CFG4 0xe8
0061 #define AHB_MEM_PREFETCH_CFG1 0xf0
0062 #define AHB_MEM_PREFETCH_CFG2 0xf4
0063 #define PREFETCH_ENB BIT(31)
0064 #define MST_ID(x) (((x) & 0x1f) << 26)
0065 #define AHBDMA_MST_ID MST_ID(5)
0066 #define USB_MST_ID MST_ID(6)
0067 #define USB2_MST_ID MST_ID(18)
0068 #define USB3_MST_ID MST_ID(17)
0069 #define ADDR_BNDRY(x) (((x) & 0xf) << 21)
0070 #define INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0)
0071
0072 #define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xfc
0073
0074 #define AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE BIT(17)
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 #define INCORRECT_BASE_ADDR_LOW_BYTE 0x4
0085
0086 static struct platform_driver tegra_ahb_driver;
0087
0088 static const u32 tegra_ahb_gizmo[] = {
0089 AHB_ARBITRATION_DISABLE,
0090 AHB_ARBITRATION_PRIORITY_CTRL,
0091 AHB_GIZMO_AHB_MEM,
0092 AHB_GIZMO_APB_DMA,
0093 AHB_GIZMO_IDE,
0094 AHB_GIZMO_USB,
0095 AHB_GIZMO_AHB_XBAR_BRIDGE,
0096 AHB_GIZMO_CPU_AHB_BRIDGE,
0097 AHB_GIZMO_COP_AHB_BRIDGE,
0098 AHB_GIZMO_XBAR_APB_CTLR,
0099 AHB_GIZMO_VCP_AHB_BRIDGE,
0100 AHB_GIZMO_NAND,
0101 AHB_GIZMO_SDMMC4,
0102 AHB_GIZMO_XIO,
0103 AHB_GIZMO_BSEV,
0104 AHB_GIZMO_BSEA,
0105 AHB_GIZMO_NOR,
0106 AHB_GIZMO_USB2,
0107 AHB_GIZMO_USB3,
0108 AHB_GIZMO_SDMMC1,
0109 AHB_GIZMO_SDMMC2,
0110 AHB_GIZMO_SDMMC3,
0111 AHB_MEM_PREFETCH_CFG_X,
0112 AHB_ARBITRATION_XBAR_CTRL,
0113 AHB_MEM_PREFETCH_CFG3,
0114 AHB_MEM_PREFETCH_CFG4,
0115 AHB_MEM_PREFETCH_CFG1,
0116 AHB_MEM_PREFETCH_CFG2,
0117 AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID,
0118 };
0119
0120 struct tegra_ahb {
0121 void __iomem *regs;
0122 struct device *dev;
0123 u32 ctx[];
0124 };
0125
0126 static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset)
0127 {
0128 return readl(ahb->regs + offset);
0129 }
0130
0131 static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset)
0132 {
0133 writel(value, ahb->regs + offset);
0134 }
0135
0136 #ifdef CONFIG_TEGRA_IOMMU_SMMU
0137 int tegra_ahb_enable_smmu(struct device_node *dn)
0138 {
0139 struct device *dev;
0140 u32 val;
0141 struct tegra_ahb *ahb;
0142
0143 dev = driver_find_device_by_of_node(&tegra_ahb_driver.driver, dn);
0144 if (!dev)
0145 return -EPROBE_DEFER;
0146 ahb = dev_get_drvdata(dev);
0147 val = gizmo_readl(ahb, AHB_ARBITRATION_XBAR_CTRL);
0148 val |= AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE;
0149 gizmo_writel(ahb, val, AHB_ARBITRATION_XBAR_CTRL);
0150 return 0;
0151 }
0152 EXPORT_SYMBOL(tegra_ahb_enable_smmu);
0153 #endif
0154
0155 static int __maybe_unused tegra_ahb_suspend(struct device *dev)
0156 {
0157 int i;
0158 struct tegra_ahb *ahb = dev_get_drvdata(dev);
0159
0160 for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++)
0161 ahb->ctx[i] = gizmo_readl(ahb, tegra_ahb_gizmo[i]);
0162 return 0;
0163 }
0164
0165 static int __maybe_unused tegra_ahb_resume(struct device *dev)
0166 {
0167 int i;
0168 struct tegra_ahb *ahb = dev_get_drvdata(dev);
0169
0170 for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++)
0171 gizmo_writel(ahb, ahb->ctx[i], tegra_ahb_gizmo[i]);
0172 return 0;
0173 }
0174
0175 static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm,
0176 tegra_ahb_suspend,
0177 tegra_ahb_resume, NULL);
0178
0179 static void tegra_ahb_gizmo_init(struct tegra_ahb *ahb)
0180 {
0181 u32 val;
0182
0183 val = gizmo_readl(ahb, AHB_GIZMO_AHB_MEM);
0184 val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR;
0185 gizmo_writel(ahb, val, AHB_GIZMO_AHB_MEM);
0186
0187 val = gizmo_readl(ahb, AHB_GIZMO_USB);
0188 val |= IMMEDIATE;
0189 gizmo_writel(ahb, val, AHB_GIZMO_USB);
0190
0191 val = gizmo_readl(ahb, AHB_GIZMO_USB2);
0192 val |= IMMEDIATE;
0193 gizmo_writel(ahb, val, AHB_GIZMO_USB2);
0194
0195 val = gizmo_readl(ahb, AHB_GIZMO_USB3);
0196 val |= IMMEDIATE;
0197 gizmo_writel(ahb, val, AHB_GIZMO_USB3);
0198
0199 val = gizmo_readl(ahb, AHB_ARBITRATION_PRIORITY_CTRL);
0200 val |= PRIORITY_SELECT_USB |
0201 PRIORITY_SELECT_USB2 |
0202 PRIORITY_SELECT_USB3 |
0203 AHB_PRIORITY_WEIGHT(7);
0204 gizmo_writel(ahb, val, AHB_ARBITRATION_PRIORITY_CTRL);
0205
0206 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG1);
0207 val &= ~MST_ID(~0);
0208 val |= PREFETCH_ENB |
0209 AHBDMA_MST_ID |
0210 ADDR_BNDRY(0xc) |
0211 INACTIVITY_TIMEOUT(0x1000);
0212 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG1);
0213
0214 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG2);
0215 val &= ~MST_ID(~0);
0216 val |= PREFETCH_ENB |
0217 USB_MST_ID |
0218 ADDR_BNDRY(0xc) |
0219 INACTIVITY_TIMEOUT(0x1000);
0220 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG2);
0221
0222 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG3);
0223 val &= ~MST_ID(~0);
0224 val |= PREFETCH_ENB |
0225 USB3_MST_ID |
0226 ADDR_BNDRY(0xc) |
0227 INACTIVITY_TIMEOUT(0x1000);
0228 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG3);
0229
0230 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG4);
0231 val &= ~MST_ID(~0);
0232 val |= PREFETCH_ENB |
0233 USB2_MST_ID |
0234 ADDR_BNDRY(0xc) |
0235 INACTIVITY_TIMEOUT(0x1000);
0236 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG4);
0237 }
0238
0239 static int tegra_ahb_probe(struct platform_device *pdev)
0240 {
0241 struct resource *res;
0242 struct tegra_ahb *ahb;
0243 size_t bytes;
0244
0245 bytes = sizeof(*ahb) + sizeof(u32) * ARRAY_SIZE(tegra_ahb_gizmo);
0246 ahb = devm_kzalloc(&pdev->dev, bytes, GFP_KERNEL);
0247 if (!ahb)
0248 return -ENOMEM;
0249
0250 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0251
0252
0253 if (res &&
0254 (res->start & INCORRECT_BASE_ADDR_LOW_BYTE) ==
0255 INCORRECT_BASE_ADDR_LOW_BYTE) {
0256 dev_warn(&pdev->dev, "incorrect AHB base address in DT data - enabling workaround\n");
0257 res->start -= INCORRECT_BASE_ADDR_LOW_BYTE;
0258 }
0259
0260 ahb->regs = devm_ioremap_resource(&pdev->dev, res);
0261 if (IS_ERR(ahb->regs))
0262 return PTR_ERR(ahb->regs);
0263
0264 ahb->dev = &pdev->dev;
0265 platform_set_drvdata(pdev, ahb);
0266 tegra_ahb_gizmo_init(ahb);
0267 return 0;
0268 }
0269
0270 static const struct of_device_id tegra_ahb_of_match[] = {
0271 { .compatible = "nvidia,tegra30-ahb", },
0272 { .compatible = "nvidia,tegra20-ahb", },
0273 {},
0274 };
0275
0276 static struct platform_driver tegra_ahb_driver = {
0277 .probe = tegra_ahb_probe,
0278 .driver = {
0279 .name = DRV_NAME,
0280 .of_match_table = tegra_ahb_of_match,
0281 .pm = &tegra_ahb_pm,
0282 },
0283 };
0284 module_platform_driver(tegra_ahb_driver);
0285
0286 MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
0287 MODULE_DESCRIPTION("Tegra AHB driver");
0288 MODULE_LICENSE("GPL v2");
0289 MODULE_ALIAS("platform:" DRV_NAME);