Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/net/ethernet/stmicro/stmmac/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 5 kB image not shown  

Quelle  dwmac-loongson1.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Loongson-1 DWMAC glue layer
 *
 * Copyright (C) 2011-2023 Keguang Zhang <keguang.zhang@gmail.com>
 */


#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#include "stmmac.h"
#include "stmmac_platform.h"

#define LS1B_GMAC0_BASE  (0x1fe10000)
#define LS1B_GMAC1_BASE  (0x1fe20000)

/* Loongson-1 SYSCON Registers */
#define LS1X_SYSCON0  (0x0)
#define LS1X_SYSCON1  (0x4)

/* Loongson-1B SYSCON Register Bits */
#define GMAC1_USE_UART1  BIT(4)
#define GMAC1_USE_UART0  BIT(3)

#define GMAC1_SHUT  BIT(13)
#define GMAC0_SHUT  BIT(12)

#define GMAC1_USE_TXCLK  BIT(3)
#define GMAC0_USE_TXCLK  BIT(2)
#define GMAC1_USE_PWM23  BIT(1)
#define GMAC0_USE_PWM01  BIT(0)

/* Loongson-1C SYSCON Register Bits */
#define GMAC_SHUT  BIT(6)

#define PHY_INTF_SELI  GENMASK(30, 28)
#define PHY_INTF_MII  FIELD_PREP(PHY_INTF_SELI, 0)
#define PHY_INTF_RMII  FIELD_PREP(PHY_INTF_SELI, 4)

struct ls1x_dwmac {
 struct plat_stmmacenet_data *plat_dat;
 struct regmap *regmap;
 unsigned int id;
};

struct ls1x_data {
 int (*setup)(struct platform_device *pdev,
       struct plat_stmmacenet_data *plat_dat);
 int (*init)(struct platform_device *pdev, void *bsp_priv);
};

static int ls1b_dwmac_setup(struct platform_device *pdev,
       struct plat_stmmacenet_data *plat_dat)
{
 struct ls1x_dwmac *dwmac = plat_dat->bsp_priv;
 struct resource *res;

 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 if (!res) {
  /* This shouldn't fail - stmmac_get_platform_resources()
 * already mapped this resource.
 */

  dev_err(&pdev->dev, "Could not get IO_MEM resources\n");
  return -EINVAL;
 }

 if (res->start == LS1B_GMAC0_BASE) {
  dwmac->id = 0;
 } else if (res->start == LS1B_GMAC1_BASE) {
  dwmac->id = 1;
 } else {
  dev_err(&pdev->dev, "Invalid Ethernet MAC base address %pR",
   res);
  return -EINVAL;
 }

 return 0;
}

static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv)
{
 struct ls1x_dwmac *dwmac = priv;
 struct plat_stmmacenet_data *plat = dwmac->plat_dat;
 struct regmap *regmap = dwmac->regmap;

 if (dwmac->id == 0) {
  switch (plat->phy_interface) {
  case PHY_INTERFACE_MODE_RGMII_ID:
   regmap_update_bits(regmap, LS1X_SYSCON0,
        GMAC0_USE_TXCLK | GMAC0_USE_PWM01,
        0);
   break;
  case PHY_INTERFACE_MODE_MII:
   regmap_update_bits(regmap, LS1X_SYSCON0,
        GMAC0_USE_TXCLK | GMAC0_USE_PWM01,
        GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
   break;
  default:
   dev_err(&pdev->dev, "Unsupported PHY mode %u\n",
    plat->phy_interface);
   return -EOPNOTSUPP;
  }

  regmap_update_bits(regmap, LS1X_SYSCON0, GMAC0_SHUT, 0);
 } else if (dwmac->id == 1) {
  regmap_update_bits(regmap, LS1X_SYSCON0,
       GMAC1_USE_UART1 | GMAC1_USE_UART0,
       GMAC1_USE_UART1 | GMAC1_USE_UART0);

  switch (plat->phy_interface) {
  case PHY_INTERFACE_MODE_RGMII_ID:
   regmap_update_bits(regmap, LS1X_SYSCON1,
        GMAC1_USE_TXCLK | GMAC1_USE_PWM23,
        0);

   break;
  case PHY_INTERFACE_MODE_MII:
   regmap_update_bits(regmap, LS1X_SYSCON1,
        GMAC1_USE_TXCLK | GMAC1_USE_PWM23,
        GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
   break;
  default:
   dev_err(&pdev->dev, "Unsupported PHY mode %u\n",
    plat->phy_interface);
   return -EOPNOTSUPP;
  }

  regmap_update_bits(regmap, LS1X_SYSCON1, GMAC1_SHUT, 0);
 }

 return 0;
}

static int ls1c_dwmac_syscon_init(struct platform_device *pdev, void *priv)
{
 struct ls1x_dwmac *dwmac = priv;
 struct plat_stmmacenet_data *plat = dwmac->plat_dat;
 struct regmap *regmap = dwmac->regmap;

 switch (plat->phy_interface) {
 case PHY_INTERFACE_MODE_MII:
  regmap_update_bits(regmap, LS1X_SYSCON1, PHY_INTF_SELI,
       PHY_INTF_MII);
  break;
 case PHY_INTERFACE_MODE_RMII:
  regmap_update_bits(regmap, LS1X_SYSCON1, PHY_INTF_SELI,
       PHY_INTF_RMII);
  break;
 default:
  dev_err(&pdev->dev, "Unsupported PHY-mode %u\n",
   plat->phy_interface);
  return -EOPNOTSUPP;
 }

 regmap_update_bits(regmap, LS1X_SYSCON0, GMAC0_SHUT, 0);

 return 0;
}

static int ls1x_dwmac_probe(struct platform_device *pdev)
{
 struct plat_stmmacenet_data *plat_dat;
 struct stmmac_resources stmmac_res;
 const struct ls1x_data *data;
 struct regmap *regmap;
 struct ls1x_dwmac *dwmac;
 int ret;

 ret = stmmac_get_platform_resources(pdev, &stmmac_res);
 if (ret)
  return ret;

 /* Probe syscon */
 regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
       "loongson,ls1-syscon");
 if (IS_ERR(regmap))
  return dev_err_probe(&pdev->dev, PTR_ERR(regmap),
         "Unable to find syscon\n");

 data = of_device_get_match_data(&pdev->dev);
 if (!data) {
  dev_err(&pdev->dev, "No of match data provided\n");
  return -EINVAL;
 }

 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
 if (!dwmac)
  return -ENOMEM;

 plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
 if (IS_ERR(plat_dat))
  return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
         "dt configuration failed\n");

 plat_dat->bsp_priv = dwmac;
 plat_dat->init = data->init;
 dwmac->plat_dat = plat_dat;
 dwmac->regmap = regmap;

 if (data->setup) {
  ret = data->setup(pdev, plat_dat);
  if (ret)
   return ret;
 }

 return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
}

static const struct ls1x_data ls1b_dwmac_data = {
 .setup = ls1b_dwmac_setup,
 .init = ls1b_dwmac_syscon_init,
};

static const struct ls1x_data ls1c_dwmac_data = {
 .init = ls1c_dwmac_syscon_init,
};

static const struct of_device_id ls1x_dwmac_match[] = {
 {
  .compatible = "loongson,ls1b-gmac",
  .data = &ls1b_dwmac_data,
 },
 {
  .compatible = "loongson,ls1c-emac",
  .data = &ls1c_dwmac_data,
 },
 { }
};
MODULE_DEVICE_TABLE(of, ls1x_dwmac_match);

static struct platform_driver ls1x_dwmac_driver = {
 .probe = ls1x_dwmac_probe,
 .driver = {
  .name = "loongson1-dwmac",
  .of_match_table = ls1x_dwmac_match,
 },
};
module_platform_driver(ls1x_dwmac_driver);

MODULE_AUTHOR("Keguang Zhang ");
MODULE_DESCRIPTION("Loongson-1 DWMAC glue layer");
MODULE_LICENSE("GPL");

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

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© 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.