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

SSL mtk_eth_path.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018-2019 MediaTek Inc.

/* A library for configuring path from GMAC/GDM to target PHY
 *
 * Author: Sean Wang <sean.wang@mediatek.com>
 *
 */


#include <linux/phy.h>
#include <linux/regmap.h>

#include "mtk_eth_soc.h"

struct mtk_eth_muxc {
 const char *name;
 u64  cap_bit;
 int  (*set_path)(struct mtk_eth *eth, u64 path);
};

static const char *mtk_eth_path_name(u64 path)
{
 switch (path) {
 case MTK_ETH_PATH_GMAC1_RGMII:
  return "gmac1_rgmii";
 case MTK_ETH_PATH_GMAC1_TRGMII:
  return "gmac1_trgmii";
 case MTK_ETH_PATH_GMAC1_SGMII:
  return "gmac1_sgmii";
 case MTK_ETH_PATH_GMAC2_RGMII:
  return "gmac2_rgmii";
 case MTK_ETH_PATH_GMAC2_SGMII:
  return "gmac2_sgmii";
 case MTK_ETH_PATH_GMAC2_2P5GPHY:
  return "gmac2_2p5gphy";
 case MTK_ETH_PATH_GMAC2_GEPHY:
  return "gmac2_gephy";
 case MTK_ETH_PATH_GDM1_ESW:
  return "gdm1_esw";
 default:
  return "unknown path";
 }
}

static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
{
 bool updated = true;
 u32 mask, set, reg;

 switch (path) {
 case MTK_ETH_PATH_GMAC1_SGMII:
  mask = ~(u32)MTK_MUX_TO_ESW;
  set = 0;
  break;
 case MTK_ETH_PATH_GDM1_ESW:
  mask = ~(u32)MTK_MUX_TO_ESW;
  set = MTK_MUX_TO_ESW;
  break;
 default:
  updated = false;
  break;
 }

 if (mtk_is_netsys_v3_or_greater(eth))
  reg = MTK_MAC_MISC_V3;
 else
  reg = MTK_MAC_MISC;

 if (updated)
  mtk_m32(eth, mask, set, reg);

 dev_dbg(eth->dev, "path %s in %s updated = %d\n",
  mtk_eth_path_name(path), __func__, updated);

 return 0;
}

static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path)
{
 unsigned int val = 0;
 bool updated = true;

 switch (path) {
 case MTK_ETH_PATH_GMAC2_GEPHY:
  val = ~(u32)GEPHY_MAC_SEL;
  break;
 default:
  updated = false;
  break;
 }

 if (updated)
  regmap_update_bits(eth->infra, INFRA_MISC2, GEPHY_MAC_SEL, val);

 dev_dbg(eth->dev, "path %s in %s updated = %d\n",
  mtk_eth_path_name(path), __func__, updated);

 return 0;
}

static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
{
 unsigned int val = 0, mask = 0, reg = 0;
 bool updated = true;

 switch (path) {
 case MTK_ETH_PATH_GMAC2_SGMII:
  if (MTK_HAS_CAPS(eth->soc->caps, MTK_U3_COPHY_V2)) {
   reg = USB_PHY_SWITCH_REG;
   val = SGMII_QPHY_SEL;
   mask = QPHY_SEL_MASK;
  } else {
   reg = INFRA_MISC2;
   val = CO_QPHY_SEL;
   mask = val;
  }
  break;
 default:
  updated = false;
  break;
 }

 if (updated)
  regmap_update_bits(eth->infra, reg, mask, val);

 dev_dbg(eth->dev, "path %s in %s updated = %d\n",
  mtk_eth_path_name(path), __func__, updated);

 return 0;
}

static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path)
{
 int ret;

 if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) {
  ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0,
     SYSCFG0_SGMII_GMAC2_V2);
  if (ret)
   return ret;

  /* Setup mux to 2p5g PHY */
  ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX,
     MUX_G2_USXGMII_SEL);
  if (ret)
   return ret;

  dev_dbg(eth->dev, "path %s in %s updated\n",
   mtk_eth_path_name(path), __func__);
 }

 return 0;
}

static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
{
 unsigned int val = 0;
 bool updated = true;

 switch (path) {
 case MTK_ETH_PATH_GMAC1_SGMII:
  val = SYSCFG0_SGMII_GMAC1;
  break;
 case MTK_ETH_PATH_GMAC2_SGMII:
  val = SYSCFG0_SGMII_GMAC2;
  break;
 case MTK_ETH_PATH_GMAC1_RGMII:
 case MTK_ETH_PATH_GMAC2_RGMII:
  regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
  val &= SYSCFG0_SGMII_MASK;

  if ((path == MTK_GMAC1_RGMII && val == SYSCFG0_SGMII_GMAC1) ||
      (path == MTK_GMAC2_RGMII && val == SYSCFG0_SGMII_GMAC2))
   val = 0;
  else
   updated = false;
  break;
 default:
  updated = false;
  break;
 }

 if (updated)
  regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
       SYSCFG0_SGMII_MASK, val);

 dev_dbg(eth->dev, "path %s in %s updated = %d\n",
  mtk_eth_path_name(path), __func__, updated);

 return 0;
}

static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
{
 unsigned int val = 0;
 bool updated = true;

 regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);

 switch (path) {
 case MTK_ETH_PATH_GMAC1_SGMII:
  val |= SYSCFG0_SGMII_GMAC1_V2;
  break;
 case MTK_ETH_PATH_GMAC2_GEPHY:
  val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
  break;
 case MTK_ETH_PATH_GMAC2_SGMII:
  val |= SYSCFG0_SGMII_GMAC2_V2;
  break;
 default:
  updated = false;
 }

 if (updated)
  regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
       SYSCFG0_SGMII_MASK, val);

 dev_dbg(eth->dev, "path %s in %s updated = %d\n",
  mtk_eth_path_name(path), __func__, updated);

 return 0;
}

static const struct mtk_eth_muxc mtk_eth_muxc[] = {
 {
  .name = "mux_gdm1_to_gmac1_esw",
  .cap_bit = MTK_ETH_MUX_GDM1_TO_GMAC1_ESW,
  .set_path = set_mux_gdm1_to_gmac1_esw,
 }, {
  .name = "mux_gmac2_gmac0_to_gephy",
  .cap_bit = MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY,
  .set_path = set_mux_gmac2_gmac0_to_gephy,
 }, {
  .name = "mux_u3_gmac2_to_qphy",
  .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
  .set_path = set_mux_u3_gmac2_to_qphy,
 }, {
  .name = "mux_gmac2_to_2p5gphy",
  .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
  .set_path = set_mux_gmac2_to_2p5gphy,
 }, {
  .name = "mux_gmac1_gmac2_to_sgmii_rgmii",
  .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
  .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii,
 }, {
  .name = "mux_gmac12_to_gephy_sgmii",
  .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
  .set_path = set_mux_gmac12_to_gephy_sgmii,
 },
};

static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
{
 int i, err = 0;

 if (!MTK_HAS_CAPS(eth->soc->caps, path)) {
  dev_err(eth->dev, "path %s isn't support on the SoC\n",
   mtk_eth_path_name(path));
  return -EINVAL;
 }

 if (!MTK_HAS_CAPS(eth->soc->caps, MTK_MUX))
  return 0;

 /* Setup MUX in path fabric */
 for (i = 0; i < ARRAY_SIZE(mtk_eth_muxc); i++) {
  if (MTK_HAS_CAPS(eth->soc->caps, mtk_eth_muxc[i].cap_bit)) {
   err = mtk_eth_muxc[i].set_path(eth, path);
   if (err)
    goto out;
  } else {
   dev_dbg(eth->dev, "mux %s isn't present on the SoC\n",
    mtk_eth_muxc[i].name);
  }
 }

out:
 return err;
}

int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
{
 u64 path;

 path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
    MTK_ETH_PATH_GMAC2_SGMII;

 /* Setup proper MUXes along the path */
 return mtk_eth_mux_setup(eth, path);
}

int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id)
{
 u64 path = 0;

 if (mac_id == MTK_GMAC2_ID)
  path = MTK_ETH_PATH_GMAC2_2P5GPHY;

 if (!path)
  return -EINVAL;

 /* Setup proper MUXes along the path */
 return mtk_eth_mux_setup(eth, path);
}

int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
{
 u64 path = 0;

 if (mac_id == 1)
  path = MTK_ETH_PATH_GMAC2_GEPHY;

 if (!path)
  return -EINVAL;

 /* Setup proper MUXes along the path */
 return mtk_eth_mux_setup(eth, path);
}

int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
{
 u64 path;

 path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_RGMII :
    MTK_ETH_PATH_GMAC2_RGMII;

 /* Setup proper MUXes along the path */
 return mtk_eth_mux_setup(eth, path);
}


Messung V0.5
C=98 H=98 G=97

¤ 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.