Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/amba/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  tegra-ahb.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
 * Copyright (C) 2011 Google, Inc.
 *
 * Author:
 * Jay Cheng <jacheng@nvidia.com>
 * James Wylder <james.wylder@motorola.com>
 * Benoit Goby <benoit@android.com>
 * Colin Cross <ccross@android.com>
 * Hiroshi DOYU <hdoyu@nvidia.com>
 */


#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/of.h>

#include <soc/tegra/ahb.h>

#define DRV_NAME "tegra-ahb"

#define AHB_ARBITRATION_DISABLE  0x04
#define AHB_ARBITRATION_PRIORITY_CTRL 0x08
#define   AHB_PRIORITY_WEIGHT(x) (((x) & 0x7) << 29)
#define   PRIORITY_SELECT_USB BIT(6)
#define   PRIORITY_SELECT_USB2 BIT(18)
#define   PRIORITY_SELECT_USB3 BIT(17)

#define AHB_GIZMO_AHB_MEM  0x10
#define   ENB_FAST_REARBITRATE BIT(2)
#define   DONT_SPLIT_AHB_WR     BIT(7)

#define AHB_GIZMO_APB_DMA  0x14
#define AHB_GIZMO_IDE   0x1c
#define AHB_GIZMO_USB   0x20
#define AHB_GIZMO_AHB_XBAR_BRIDGE 0x24
#define AHB_GIZMO_CPU_AHB_BRIDGE 0x28
#define AHB_GIZMO_COP_AHB_BRIDGE 0x2c
#define AHB_GIZMO_XBAR_APB_CTLR  0x30
#define AHB_GIZMO_VCP_AHB_BRIDGE 0x34
#define AHB_GIZMO_NAND   0x40
#define AHB_GIZMO_SDMMC4  0x48
#define AHB_GIZMO_XIO   0x4c
#define AHB_GIZMO_BSEV   0x64
#define AHB_GIZMO_BSEA   0x74
#define AHB_GIZMO_NOR   0x78
#define AHB_GIZMO_USB2   0x7c
#define AHB_GIZMO_USB3   0x80
#define   IMMEDIATE BIT(18)

#define AHB_GIZMO_SDMMC1  0x84
#define AHB_GIZMO_SDMMC2  0x88
#define AHB_GIZMO_SDMMC3  0x8c
#define AHB_MEM_PREFETCH_CFG_X  0xdc
#define AHB_ARBITRATION_XBAR_CTRL 0xe0
#define AHB_MEM_PREFETCH_CFG3  0xe4
#define AHB_MEM_PREFETCH_CFG4  0xe8
#define AHB_MEM_PREFETCH_CFG1  0xf0
#define AHB_MEM_PREFETCH_CFG2  0xf4
#define   PREFETCH_ENB BIT(31)
#define   MST_ID(x) (((x) & 0x1f) << 26)
#define   AHBDMA_MST_ID MST_ID(5)
#define   USB_MST_ID MST_ID(6)
#define   USB2_MST_ID MST_ID(18)
#define   USB3_MST_ID MST_ID(17)
#define   ADDR_BNDRY(x) (((x) & 0xf) << 21)
#define   INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0)

#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xfc

#define AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE BIT(17)

/*
 * INCORRECT_BASE_ADDR_LOW_BYTE: Legacy kernel DT files for Tegra SoCs
 * prior to Tegra124 generally use a physical base address ending in
 * 0x4 for the AHB IP block.  According to the TRM, the low byte
 * should be 0x0.  During device probing, this macro is used to detect
 * whether the passed-in physical address is incorrect, and if so, to
 * correct it.
 */

#define INCORRECT_BASE_ADDR_LOW_BYTE  0x4

static struct platform_driver tegra_ahb_driver;

static const u32 tegra_ahb_gizmo[] = {
 AHB_ARBITRATION_DISABLE,
 AHB_ARBITRATION_PRIORITY_CTRL,
 AHB_GIZMO_AHB_MEM,
 AHB_GIZMO_APB_DMA,
 AHB_GIZMO_IDE,
 AHB_GIZMO_USB,
 AHB_GIZMO_AHB_XBAR_BRIDGE,
 AHB_GIZMO_CPU_AHB_BRIDGE,
 AHB_GIZMO_COP_AHB_BRIDGE,
 AHB_GIZMO_XBAR_APB_CTLR,
 AHB_GIZMO_VCP_AHB_BRIDGE,
 AHB_GIZMO_NAND,
 AHB_GIZMO_SDMMC4,
 AHB_GIZMO_XIO,
 AHB_GIZMO_BSEV,
 AHB_GIZMO_BSEA,
 AHB_GIZMO_NOR,
 AHB_GIZMO_USB2,
 AHB_GIZMO_USB3,
 AHB_GIZMO_SDMMC1,
 AHB_GIZMO_SDMMC2,
 AHB_GIZMO_SDMMC3,
 AHB_MEM_PREFETCH_CFG_X,
 AHB_ARBITRATION_XBAR_CTRL,
 AHB_MEM_PREFETCH_CFG3,
 AHB_MEM_PREFETCH_CFG4,
 AHB_MEM_PREFETCH_CFG1,
 AHB_MEM_PREFETCH_CFG2,
 AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID,
};

struct tegra_ahb {
 void __iomem *regs;
 struct device *dev;
 u32  ctx[];
};

static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset)
{
 return readl(ahb->regs + offset);
}

static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset)
{
 writel(value, ahb->regs + offset);
}

#ifdef CONFIG_TEGRA_IOMMU_SMMU
int tegra_ahb_enable_smmu(struct device_node *dn)
{
 struct device *dev;
 u32 val;
 struct tegra_ahb *ahb;

 dev = driver_find_device_by_of_node(&tegra_ahb_driver.driver, dn);
 if (!dev)
  return -EPROBE_DEFER;
 ahb = dev_get_drvdata(dev);
 val = gizmo_readl(ahb, AHB_ARBITRATION_XBAR_CTRL);
 val |= AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE;
 gizmo_writel(ahb, val, AHB_ARBITRATION_XBAR_CTRL);
 return 0;
}
EXPORT_SYMBOL(tegra_ahb_enable_smmu);
#endif

static int __maybe_unused tegra_ahb_suspend(struct device *dev)
{
 int i;
 struct tegra_ahb *ahb = dev_get_drvdata(dev);

 for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++)
  ahb->ctx[i] = gizmo_readl(ahb, tegra_ahb_gizmo[i]);
 return 0;
}

static int __maybe_unused tegra_ahb_resume(struct device *dev)
{
 int i;
 struct tegra_ahb *ahb = dev_get_drvdata(dev);

 for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++)
  gizmo_writel(ahb, ahb->ctx[i], tegra_ahb_gizmo[i]);
 return 0;
}

static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm,
       tegra_ahb_suspend,
       tegra_ahb_resume, NULL);

static void tegra_ahb_gizmo_init(struct tegra_ahb *ahb)
{
 u32 val;

 val = gizmo_readl(ahb, AHB_GIZMO_AHB_MEM);
 val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR;
 gizmo_writel(ahb, val, AHB_GIZMO_AHB_MEM);

 val = gizmo_readl(ahb, AHB_GIZMO_USB);
 val |= IMMEDIATE;
 gizmo_writel(ahb, val, AHB_GIZMO_USB);

 val = gizmo_readl(ahb, AHB_GIZMO_USB2);
 val |= IMMEDIATE;
 gizmo_writel(ahb, val, AHB_GIZMO_USB2);

 val = gizmo_readl(ahb, AHB_GIZMO_USB3);
 val |= IMMEDIATE;
 gizmo_writel(ahb, val, AHB_GIZMO_USB3);

 val = gizmo_readl(ahb, AHB_ARBITRATION_PRIORITY_CTRL);
 val |= PRIORITY_SELECT_USB |
  PRIORITY_SELECT_USB2 |
  PRIORITY_SELECT_USB3 |
  AHB_PRIORITY_WEIGHT(7);
 gizmo_writel(ahb, val, AHB_ARBITRATION_PRIORITY_CTRL);

 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG1);
 val &= ~MST_ID(~0);
 val |= PREFETCH_ENB |
  AHBDMA_MST_ID |
  ADDR_BNDRY(0xc) |
  INACTIVITY_TIMEOUT(0x1000);
 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG1);

 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG2);
 val &= ~MST_ID(~0);
 val |= PREFETCH_ENB |
  USB_MST_ID |
  ADDR_BNDRY(0xc) |
  INACTIVITY_TIMEOUT(0x1000);
 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG2);

 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG3);
 val &= ~MST_ID(~0);
 val |= PREFETCH_ENB |
  USB3_MST_ID |
  ADDR_BNDRY(0xc) |
  INACTIVITY_TIMEOUT(0x1000);
 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG3);

 val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG4);
 val &= ~MST_ID(~0);
 val |= PREFETCH_ENB |
  USB2_MST_ID |
  ADDR_BNDRY(0xc) |
  INACTIVITY_TIMEOUT(0x1000);
 gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG4);
}

static int tegra_ahb_probe(struct platform_device *pdev)
{
 struct resource *res;
 struct tegra_ahb *ahb;
 size_t bytes;

 bytes = sizeof(*ahb) + sizeof(u32) * ARRAY_SIZE(tegra_ahb_gizmo);
 ahb = devm_kzalloc(&pdev->dev, bytes, GFP_KERNEL);
 if (!ahb)
  return -ENOMEM;

 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

 /* Correct the IP block base address if necessary */
 if (res &&
     (res->start & INCORRECT_BASE_ADDR_LOW_BYTE) ==
     INCORRECT_BASE_ADDR_LOW_BYTE) {
  dev_warn(&pdev->dev, "incorrect AHB base address in DT data - enabling workaround\n");
  res->start -= INCORRECT_BASE_ADDR_LOW_BYTE;
 }

 ahb->regs = devm_ioremap_resource(&pdev->dev, res);
 if (IS_ERR(ahb->regs))
  return PTR_ERR(ahb->regs);

 ahb->dev = &pdev->dev;
 platform_set_drvdata(pdev, ahb);
 tegra_ahb_gizmo_init(ahb);
 return 0;
}

static const struct of_device_id tegra_ahb_of_match[] = {
 { .compatible = "nvidia,tegra30-ahb", },
 { .compatible = "nvidia,tegra20-ahb", },
 {},
};

static struct platform_driver tegra_ahb_driver = {
 .probe = tegra_ahb_probe,
 .driver = {
  .name = DRV_NAME,
  .of_match_table = tegra_ahb_of_match,
  .pm = &tegra_ahb_pm,
 },
};
module_platform_driver(tegra_ahb_driver);

MODULE_AUTHOR("Hiroshi DOYU ");
MODULE_DESCRIPTION("Tegra AHB driver");
MODULE_ALIAS("platform:" DRV_NAME);

Messung V0.5
C=95 H=94 G=94

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.