Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  t7xx_pcie_mac.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2021, MediaTek Inc.
 * Copyright (c) 2021-2022, Intel Corporation.
 *
 * Authors:
 *  Haijun Liu <haijun.liu@mediatek.com>
 *  Moises Veleta <moises.veleta@intel.com>
 *  Sreehari Kancharla <sreehari.kancharla@intel.com>
 *
 * Contributors:
 *  Amir Hanania <amir.hanania@intel.com>
 *  Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com>
 *  Ricardo Martinez <ricardo.martinez@linux.intel.com>
 */


#include <linux/bits.h>
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/types.h>

#include "t7xx_pci.h"
#include "t7xx_pcie_mac.h"
#include "t7xx_reg.h"

#define T7XX_PCIE_REG_BAR  2
#define T7XX_PCIE_REG_PORT  ATR_SRC_PCI_WIN0
#define T7XX_PCIE_REG_TABLE_NUM  0
#define T7XX_PCIE_REG_TRSL_PORT  ATR_DST_AXIM_0

#define T7XX_PCIE_DEV_DMA_PORT_START ATR_SRC_AXIS_0
#define T7XX_PCIE_DEV_DMA_PORT_END ATR_SRC_AXIS_2
#define T7XX_PCIE_DEV_DMA_TABLE_NUM 0
#define T7XX_PCIE_DEV_DMA_TRSL_ADDR 0
#define T7XX_PCIE_DEV_DMA_SRC_ADDR 0
#define T7XX_PCIE_DEV_DMA_TRANSPARENT 1
#define T7XX_PCIE_DEV_DMA_SIZE  0

enum t7xx_atr_src_port {
 ATR_SRC_PCI_WIN0,
 ATR_SRC_PCI_WIN1,
 ATR_SRC_AXIS_0,
 ATR_SRC_AXIS_1,
 ATR_SRC_AXIS_2,
 ATR_SRC_AXIS_3,
};

enum t7xx_atr_dst_port {
 ATR_DST_PCI_TRX,
 ATR_DST_PCI_CONFIG,
 ATR_DST_AXIM_0 = 4,
 ATR_DST_AXIM_1,
 ATR_DST_AXIM_2,
 ATR_DST_AXIM_3,
};

struct t7xx_atr_config {
 u64   src_addr;
 u64   trsl_addr;
 u64   size;
 u32   port;
 u32   table;
 enum t7xx_atr_dst_port trsl_id;
 u32   transparent;
};

static void t7xx_pcie_mac_atr_tables_dis(void __iomem *pbase, enum t7xx_atr_src_port port)
{
 void __iomem *reg;
 int i, offset;

 for (i = 0; i < ATR_TABLE_NUM_PER_ATR; i++) {
  offset = ATR_PORT_OFFSET * port + ATR_TABLE_OFFSET * i;
  reg = pbase + ATR_PCIE_WIN0_T0_ATR_PARAM_SRC_ADDR + offset;
  iowrite64_lo_hi(0, reg);
 }
}

static int t7xx_pcie_mac_atr_cfg(struct t7xx_pci_dev *t7xx_dev, struct t7xx_atr_config *cfg)
{
 struct device *dev = &t7xx_dev->pdev->dev;
 void __iomem *pbase = IREG_BASE(t7xx_dev);
 int atr_size, pos, offset;
 void __iomem *reg;
 u64 value;

 if (cfg->transparent) {
  /* No address conversion is performed */
  atr_size = ATR_TRANSPARENT_SIZE;
 } else {
  if (cfg->src_addr & (cfg->size - 1)) {
   dev_err(dev, "Source address is not aligned to size\n");
   return -EINVAL;
  }

  if (cfg->trsl_addr & (cfg->size - 1)) {
   dev_err(dev, "Translation address %llx is not aligned to size %llx\n",
    cfg->trsl_addr, cfg->size - 1);
   return -EINVAL;
  }

  pos = __ffs64(cfg->size);

  /* HW calculates the address translation space as 2^(atr_size + 1) */
  atr_size = pos - 1;
 }

 offset = ATR_PORT_OFFSET * cfg->port + ATR_TABLE_OFFSET * cfg->table;

 reg = pbase + ATR_PCIE_WIN0_T0_TRSL_ADDR + offset;
 value = cfg->trsl_addr & ATR_PCIE_WIN0_ADDR_ALGMT;
 iowrite64_lo_hi(value, reg);

 reg = pbase + ATR_PCIE_WIN0_T0_TRSL_PARAM + offset;
 iowrite32(cfg->trsl_id, reg);

 reg = pbase + ATR_PCIE_WIN0_T0_ATR_PARAM_SRC_ADDR + offset;
 value = (cfg->src_addr & ATR_PCIE_WIN0_ADDR_ALGMT) | (atr_size << 1) | BIT(0);
 iowrite64_lo_hi(value, reg);

 /* Ensure ATR is set */
 ioread64_lo_hi(reg);
 return 0;
}

/**
 * t7xx_pcie_mac_atr_init() - Initialize address translation.
 * @t7xx_dev: MTK device.
 *
 * Setup ATR for ports & device.
 */

void t7xx_pcie_mac_atr_init(struct t7xx_pci_dev *t7xx_dev)
{
 struct t7xx_atr_config cfg;
 u32 i;

 /* Disable for all ports */
 for (i = ATR_SRC_PCI_WIN0; i <= ATR_SRC_AXIS_3; i++)
  t7xx_pcie_mac_atr_tables_dis(IREG_BASE(t7xx_dev), i);

 memset(&cfg, 0, sizeof(cfg));
 /* Config ATR for RC to access device's register */
 cfg.src_addr = pci_resource_start(t7xx_dev->pdev, T7XX_PCIE_REG_BAR);
 cfg.size = T7XX_PCIE_REG_SIZE_CHIP;
 cfg.trsl_addr = T7XX_PCIE_REG_TRSL_ADDR_CHIP;
 cfg.port = T7XX_PCIE_REG_PORT;
 cfg.table = T7XX_PCIE_REG_TABLE_NUM;
 cfg.trsl_id = T7XX_PCIE_REG_TRSL_PORT;
 t7xx_pcie_mac_atr_tables_dis(IREG_BASE(t7xx_dev), cfg.port);
 t7xx_pcie_mac_atr_cfg(t7xx_dev, &cfg);

 t7xx_dev->base_addr.pcie_dev_reg_trsl_addr = T7XX_PCIE_REG_TRSL_ADDR_CHIP;

 /* Config ATR for EP to access RC's memory */
 for (i = T7XX_PCIE_DEV_DMA_PORT_START; i <= T7XX_PCIE_DEV_DMA_PORT_END; i++) {
  cfg.src_addr = T7XX_PCIE_DEV_DMA_SRC_ADDR;
  cfg.size = T7XX_PCIE_DEV_DMA_SIZE;
  cfg.trsl_addr = T7XX_PCIE_DEV_DMA_TRSL_ADDR;
  cfg.port = i;
  cfg.table = T7XX_PCIE_DEV_DMA_TABLE_NUM;
  cfg.trsl_id = ATR_DST_PCI_TRX;
  cfg.transparent = T7XX_PCIE_DEV_DMA_TRANSPARENT;
  t7xx_pcie_mac_atr_tables_dis(IREG_BASE(t7xx_dev), cfg.port);
  t7xx_pcie_mac_atr_cfg(t7xx_dev, &cfg);
 }
}

/**
 * t7xx_pcie_mac_enable_disable_int() - Enable/disable interrupts.
 * @t7xx_dev: MTK device.
 * @enable: Enable/disable.
 *
 * Enable or disable device interrupts.
 */

static void t7xx_pcie_mac_enable_disable_int(struct t7xx_pci_dev *t7xx_dev, bool enable)
{
 u32 value;

 value = ioread32(IREG_BASE(t7xx_dev) + ISTAT_HST_CTRL);

 if (enable)
  value &= ~ISTAT_HST_CTRL_DIS;
 else
  value |= ISTAT_HST_CTRL_DIS;

 iowrite32(value, IREG_BASE(t7xx_dev) + ISTAT_HST_CTRL);
}

void t7xx_pcie_mac_interrupts_en(struct t7xx_pci_dev *t7xx_dev)
{
 t7xx_pcie_mac_enable_disable_int(t7xx_dev, true);
}

void t7xx_pcie_mac_interrupts_dis(struct t7xx_pci_dev *t7xx_dev)
{
 t7xx_pcie_mac_enable_disable_int(t7xx_dev, false);
}

/**
 * t7xx_pcie_mac_clear_set_int() - Clear/set interrupt by type.
 * @t7xx_dev: MTK device.
 * @int_type: Interrupt type.
 * @clear: Clear/set.
 *
 * Clear or set device interrupt by type.
 */

static void t7xx_pcie_mac_clear_set_int(struct t7xx_pci_dev *t7xx_dev,
     enum t7xx_int int_type, bool clear)
{
 void __iomem *reg;
 u32 val;

 if (clear)
  reg = IREG_BASE(t7xx_dev) + IMASK_HOST_MSIX_CLR_GRP0_0;
 else
  reg = IREG_BASE(t7xx_dev) + IMASK_HOST_MSIX_SET_GRP0_0;

 val = BIT(EXT_INT_START + int_type);
 iowrite32(val, reg);
}

void t7xx_pcie_mac_clear_int(struct t7xx_pci_dev *t7xx_dev, enum t7xx_int int_type)
{
 t7xx_pcie_mac_clear_set_int(t7xx_dev, int_type, true);
}

void t7xx_pcie_mac_set_int(struct t7xx_pci_dev *t7xx_dev, enum t7xx_int int_type)
{
 t7xx_pcie_mac_clear_set_int(t7xx_dev, int_type, false);
}

/**
 * t7xx_pcie_mac_clear_int_status() - Clear interrupt status by type.
 * @t7xx_dev: MTK device.
 * @int_type: Interrupt type.
 *
 * Enable or disable device interrupts' status by type.
 */

void t7xx_pcie_mac_clear_int_status(struct t7xx_pci_dev *t7xx_dev, enum t7xx_int int_type)
{
 void __iomem *reg = IREG_BASE(t7xx_dev) + MSIX_ISTAT_HST_GRP0_0;
 u32 val = BIT(EXT_INT_START + int_type);

 iowrite32(val, reg);
}

/**
 * t7xx_pcie_set_mac_msix_cfg() - Write MSIX control configuration.
 * @t7xx_dev: MTK device.
 * @irq_count: Number of MSIX IRQ vectors.
 *
 * Write IRQ count to device.
 */

void t7xx_pcie_set_mac_msix_cfg(struct t7xx_pci_dev *t7xx_dev, unsigned int irq_count)
{
 u32 val = ffs(irq_count) * 2 - 1;

 iowrite32(val, IREG_BASE(t7xx_dev) + T7XX_PCIE_CFG_MSIX);
}

Messung V0.5
C=98 H=93 G=95

¤ Dauer der Verarbeitung: 0.1 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge