cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mtk_eth_path.c (5942B)


      1// SPDX-License-Identifier: GPL-2.0
      2// Copyright (c) 2018-2019 MediaTek Inc.
      3
      4/* A library for configuring path from GMAC/GDM to target PHY
      5 *
      6 * Author: Sean Wang <sean.wang@mediatek.com>
      7 *
      8 */
      9
     10#include <linux/phy.h>
     11#include <linux/regmap.h>
     12
     13#include "mtk_eth_soc.h"
     14
     15struct mtk_eth_muxc {
     16	const char	*name;
     17	int		cap_bit;
     18	int		(*set_path)(struct mtk_eth *eth, int path);
     19};
     20
     21static const char *mtk_eth_path_name(int path)
     22{
     23	switch (path) {
     24	case MTK_ETH_PATH_GMAC1_RGMII:
     25		return "gmac1_rgmii";
     26	case MTK_ETH_PATH_GMAC1_TRGMII:
     27		return "gmac1_trgmii";
     28	case MTK_ETH_PATH_GMAC1_SGMII:
     29		return "gmac1_sgmii";
     30	case MTK_ETH_PATH_GMAC2_RGMII:
     31		return "gmac2_rgmii";
     32	case MTK_ETH_PATH_GMAC2_SGMII:
     33		return "gmac2_sgmii";
     34	case MTK_ETH_PATH_GMAC2_GEPHY:
     35		return "gmac2_gephy";
     36	case MTK_ETH_PATH_GDM1_ESW:
     37		return "gdm1_esw";
     38	default:
     39		return "unknown path";
     40	}
     41}
     42
     43static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
     44{
     45	bool updated = true;
     46	u32 val, mask, set;
     47
     48	switch (path) {
     49	case MTK_ETH_PATH_GMAC1_SGMII:
     50		mask = ~(u32)MTK_MUX_TO_ESW;
     51		set = 0;
     52		break;
     53	case MTK_ETH_PATH_GDM1_ESW:
     54		mask = ~(u32)MTK_MUX_TO_ESW;
     55		set = MTK_MUX_TO_ESW;
     56		break;
     57	default:
     58		updated = false;
     59		break;
     60	}
     61
     62	if (updated) {
     63		val = mtk_r32(eth, MTK_MAC_MISC);
     64		val = (val & mask) | set;
     65		mtk_w32(eth, val, MTK_MAC_MISC);
     66	}
     67
     68	dev_dbg(eth->dev, "path %s in %s updated = %d\n",
     69		mtk_eth_path_name(path), __func__, updated);
     70
     71	return 0;
     72}
     73
     74static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
     75{
     76	unsigned int val = 0;
     77	bool updated = true;
     78
     79	switch (path) {
     80	case MTK_ETH_PATH_GMAC2_GEPHY:
     81		val = ~(u32)GEPHY_MAC_SEL;
     82		break;
     83	default:
     84		updated = false;
     85		break;
     86	}
     87
     88	if (updated)
     89		regmap_update_bits(eth->infra, INFRA_MISC2, GEPHY_MAC_SEL, val);
     90
     91	dev_dbg(eth->dev, "path %s in %s updated = %d\n",
     92		mtk_eth_path_name(path), __func__, updated);
     93
     94	return 0;
     95}
     96
     97static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
     98{
     99	unsigned int val = 0;
    100	bool updated = true;
    101
    102	switch (path) {
    103	case MTK_ETH_PATH_GMAC2_SGMII:
    104		val = CO_QPHY_SEL;
    105		break;
    106	default:
    107		updated = false;
    108		break;
    109	}
    110
    111	if (updated)
    112		regmap_update_bits(eth->infra, INFRA_MISC2, CO_QPHY_SEL, val);
    113
    114	dev_dbg(eth->dev, "path %s in %s updated = %d\n",
    115		mtk_eth_path_name(path), __func__, updated);
    116
    117	return 0;
    118}
    119
    120static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
    121{
    122	unsigned int val = 0;
    123	bool updated = true;
    124
    125	switch (path) {
    126	case MTK_ETH_PATH_GMAC1_SGMII:
    127		val = SYSCFG0_SGMII_GMAC1;
    128		break;
    129	case MTK_ETH_PATH_GMAC2_SGMII:
    130		val = SYSCFG0_SGMII_GMAC2;
    131		break;
    132	case MTK_ETH_PATH_GMAC1_RGMII:
    133	case MTK_ETH_PATH_GMAC2_RGMII:
    134		regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
    135		val &= SYSCFG0_SGMII_MASK;
    136
    137		if ((path == MTK_GMAC1_RGMII && val == SYSCFG0_SGMII_GMAC1) ||
    138		    (path == MTK_GMAC2_RGMII && val == SYSCFG0_SGMII_GMAC2))
    139			val = 0;
    140		else
    141			updated = false;
    142		break;
    143	default:
    144		updated = false;
    145		break;
    146	}
    147
    148	if (updated)
    149		regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
    150				   SYSCFG0_SGMII_MASK, val);
    151
    152	dev_dbg(eth->dev, "path %s in %s updated = %d\n",
    153		mtk_eth_path_name(path), __func__, updated);
    154
    155	return 0;
    156}
    157
    158static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
    159{
    160	unsigned int val = 0;
    161	bool updated = true;
    162
    163	regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
    164
    165	switch (path) {
    166	case MTK_ETH_PATH_GMAC1_SGMII:
    167		val |= SYSCFG0_SGMII_GMAC1_V2;
    168		break;
    169	case MTK_ETH_PATH_GMAC2_GEPHY:
    170		val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
    171		break;
    172	case MTK_ETH_PATH_GMAC2_SGMII:
    173		val |= SYSCFG0_SGMII_GMAC2_V2;
    174		break;
    175	default:
    176		updated = false;
    177	}
    178
    179	if (updated)
    180		regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
    181				   SYSCFG0_SGMII_MASK, val);
    182
    183	dev_dbg(eth->dev, "path %s in %s updated = %d\n",
    184		mtk_eth_path_name(path), __func__, updated);
    185
    186	return 0;
    187}
    188
    189static const struct mtk_eth_muxc mtk_eth_muxc[] = {
    190	{
    191		.name = "mux_gdm1_to_gmac1_esw",
    192		.cap_bit = MTK_ETH_MUX_GDM1_TO_GMAC1_ESW,
    193		.set_path = set_mux_gdm1_to_gmac1_esw,
    194	}, {
    195		.name = "mux_gmac2_gmac0_to_gephy",
    196		.cap_bit = MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY,
    197		.set_path = set_mux_gmac2_gmac0_to_gephy,
    198	}, {
    199		.name = "mux_u3_gmac2_to_qphy",
    200		.cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
    201		.set_path = set_mux_u3_gmac2_to_qphy,
    202	}, {
    203		.name = "mux_gmac1_gmac2_to_sgmii_rgmii",
    204		.cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
    205		.set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii,
    206	}, {
    207		.name = "mux_gmac12_to_gephy_sgmii",
    208		.cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
    209		.set_path = set_mux_gmac12_to_gephy_sgmii,
    210	},
    211};
    212
    213static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
    214{
    215	int i, err = 0;
    216
    217	if (!MTK_HAS_CAPS(eth->soc->caps, path)) {
    218		dev_err(eth->dev, "path %s isn't support on the SoC\n",
    219			mtk_eth_path_name(path));
    220		return -EINVAL;
    221	}
    222
    223	if (!MTK_HAS_CAPS(eth->soc->caps, MTK_MUX))
    224		return 0;
    225
    226	/* Setup MUX in path fabric */
    227	for (i = 0; i < ARRAY_SIZE(mtk_eth_muxc); i++) {
    228		if (MTK_HAS_CAPS(eth->soc->caps, mtk_eth_muxc[i].cap_bit)) {
    229			err = mtk_eth_muxc[i].set_path(eth, path);
    230			if (err)
    231				goto out;
    232		} else {
    233			dev_dbg(eth->dev, "mux %s isn't present on the SoC\n",
    234				mtk_eth_muxc[i].name);
    235		}
    236	}
    237
    238out:
    239	return err;
    240}
    241
    242int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
    243{
    244	int path;
    245
    246	path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
    247				MTK_ETH_PATH_GMAC2_SGMII;
    248
    249	/* Setup proper MUXes along the path */
    250	return mtk_eth_mux_setup(eth, path);
    251}
    252
    253int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
    254{
    255	int path = 0;
    256
    257	if (mac_id == 1)
    258		path = MTK_ETH_PATH_GMAC2_GEPHY;
    259
    260	if (!path)
    261		return -EINVAL;
    262
    263	/* Setup proper MUXes along the path */
    264	return mtk_eth_mux_setup(eth, path);
    265}
    266
    267int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
    268{
    269	int path;
    270
    271	path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_RGMII :
    272				MTK_ETH_PATH_GMAC2_RGMII;
    273
    274	/* Setup proper MUXes along the path */
    275	return mtk_eth_mux_setup(eth, path);
    276}
    277