All of lore.kernel.org
 help / color / mirror / Atom feed
From: Biao Huang <biao.huang@mediatek.com>
To: AngeloGioacchino Del Regno 
	<angelogioacchino.delregno@somainline.org>, <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	Rob Herring <robh+dt@kernel.org>
Cc: Matthias Brugger <matthias.bgg@gmail.com>,
	Giuseppe Cavallaro <peppe.cavallaro@st.com>,
	Alexandre Torgue <alexandre.torgue@foss.st.com>,
	Jose Abreu <joabreu@synopsys.com>,
	Maxime Coquelin <mcoquelin.stm32@gmail.com>,
	<netdev@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-mediatek@lists.infradead.org>,
	<linux-stm32@st-md-mailman.stormreply.com>,
	<srv_heupstream@mediatek.com>, <macpaul.lin@mediatek.com>
Subject: Re: [PATCH v2 3/5] net: stmmac: dwmac-mediatek: add support for mt8195
Date: Fri, 12 Nov 2021 10:40:07 +0800	[thread overview]
Message-ID: <d66c18f41bcbc502a0e7f0f7345412ca888d6a49.camel@mediatek.com> (raw)
In-Reply-To: <6f894146-692b-63c7-cef6-2b26a171f006@somainline.org>

Dear Angelo,
	Thanks for your comments~

On Thu, 2021-11-11 at 14:26 +0100, AngeloGioacchino Del Regno wrote:
> Il 11/11/21 08:12, Biao Huang ha scritto:
> > Add Ethernet support for MediaTek SoCs from the mt8195 family.
> > 
> > Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> > ---
> >   .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 261
> > +++++++++++++++++-
> >   1 file changed, 260 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > index 6ea972e96665..b1266b68e21f 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > @@ -40,6 +40,33 @@
> >   #define ETH_FINE_DLY_GTXC	BIT(1)
> >   #define ETH_FINE_DLY_RXC	BIT(0)
> >   
> > +/* Peri Configuration register for mt8195 */
> > +#define MT8195_PERI_ETH_CTRL0		0xFD0
> > +#define MT8195_RMII_CLK_SRC_INTERNAL	BIT(28)
> > +#define MT8195_RMII_CLK_SRC_RXC		BIT(27)
> > +#define MT8195_ETH_INTF_SEL		GENMASK(26, 24)
> > +#define MT8195_RGMII_TXC_PHASE_CTRL	BIT(22)
> > +#define MT8195_EXT_PHY_MODE		BIT(21)
> > +#define MT8195_DLY_GTXC_INV		BIT(12)
> > +#define MT8195_DLY_GTXC_ENABLE		BIT(5)
> > +#define MT8195_DLY_GTXC_STAGES		GENMASK(4, 0)
> > +
> > +#define MT8195_PERI_ETH_CTRL1		0xFD4
> > +#define MT8195_DLY_RXC_INV		BIT(25)
> > +#define MT8195_DLY_RXC_ENABLE		BIT(18)
> > +#define MT8195_DLY_RXC_STAGES		GENMASK(17, 13)
> > +#define MT8195_DLY_TXC_INV		BIT(12)
> > +#define MT8195_DLY_TXC_ENABLE		BIT(5)
> > +#define MT8195_DLY_TXC_STAGES		GENMASK(4, 0)
> > +
> > +#define MT8195_PERI_ETH_CTRL2		0xFD8
> > +#define MT8195_DLY_RMII_RXC_INV		BIT(25)
> > +#define MT8195_DLY_RMII_RXC_ENABLE	BIT(18)
> > +#define MT8195_DLY_RMII_RXC_STAGES	GENMASK(17, 13)
> > +#define MT8195_DLY_RMII_TXC_INV		BIT(12)
> > +#define MT8195_DLY_RMII_TXC_ENABLE	BIT(5)
> > +#define MT8195_DLY_RMII_TXC_STAGES	GENMASK(4, 0)
> > +
> >   struct mac_delay_struct {
> >   	u32 tx_delay;
> >   	u32 rx_delay;
> > @@ -58,11 +85,13 @@ struct mediatek_dwmac_plat_data {
> >   	int num_clks_to_config;
> >   	bool rmii_clk_from_mac;
> >   	bool rmii_rxc;
> > +	bool mac_wol;
> >   };
> >   
> >   struct mediatek_dwmac_variant {
> >   	int (*dwmac_set_phy_interface)(struct mediatek_dwmac_plat_data
> > *plat);
> >   	int (*dwmac_set_delay)(struct mediatek_dwmac_plat_data *plat);
> > +	void (*dwmac_fix_mac_speed)(void *priv, unsigned int speed);
> >   
> >   	/* clock ids to be requested */
> >   	const char * const *clk_list;
> > @@ -78,6 +107,10 @@ static const char * const mt2712_dwmac_clk_l[]
> > = {
> >   	"axi", "apb", "mac_main", "ptp_ref", "rmii_internal"
> >   };
> >   
> > +static const char * const mt8195_dwmac_clk_l[] = {
> > +	"axi", "apb", "mac_cg", "mac_main", "ptp_ref", "rmii_internal"
> > +};
> > +
> >   static int mt2712_set_interface(struct mediatek_dwmac_plat_data
> > *plat)
> >   {
> >   	int rmii_clk_from_mac = plat->rmii_clk_from_mac ?
> > RMII_CLK_SRC_INTERNAL : 0;
> > @@ -268,6 +301,204 @@ static const struct mediatek_dwmac_variant
> > mt2712_gmac_variant = {
> >   		.tx_delay_max = 17600,
> >   };
> >   
> > +static int mt8195_set_interface(struct mediatek_dwmac_plat_data
> > *plat)
> > +{
> > +	int rmii_clk_from_mac = plat->rmii_clk_from_mac ?
> > MT8195_RMII_CLK_SRC_INTERNAL : 0;
> > +	int rmii_rxc = plat->rmii_rxc ? MT8195_RMII_CLK_SRC_RXC : 0;
> > +	u32 intf_val = 0;
> > +
> > +	/* The clock labeled as "rmii_internal" in mt8195_dwmac_clk_l
> > is needed
> > +	 * only in RMII(when MAC provides the reference clock), and
> > useless for
> > +	 * RGMII/MII/RMII(when PHY provides the reference clock).
> > +	 * num_clks_to_config indicates the real number of clocks
> > should be
> > +	 * configured, equals to (plat->variant->num_clks - 1) in
> > default for all the case,
> > +	 * then +1 for rmii_clk_from_mac case.
> > +	 */
> > +	plat->num_clks_to_config = plat->variant->num_clks - 1;
> > +
> > +	/* select phy interface in top control domain */
> > +	switch (plat->phy_mode) {
> > +	case PHY_INTERFACE_MODE_MII:
> > +		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL,
> > PHY_INTF_MII);
> > +		break;
> > +	case PHY_INTERFACE_MODE_RMII:
> > +		if (plat->rmii_clk_from_mac)
> > +			plat->num_clks_to_config++;
> > +		intf_val |= (rmii_rxc | rmii_clk_from_mac);
> > +		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL,
> > PHY_INTF_RMII);
> > +		break;
> > +	case PHY_INTERFACE_MODE_RGMII:
> > +	case PHY_INTERFACE_MODE_RGMII_TXID:
> > +	case PHY_INTERFACE_MODE_RGMII_RXID:
> > +	case PHY_INTERFACE_MODE_RGMII_ID:
> > +		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL,
> > PHY_INTF_RGMII);
> > +		break;
> > +	default:
> > +		dev_err(plat->dev, "phy interface not supported\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* MT8195 only support external PHY */
> > +	intf_val |= MT8195_EXT_PHY_MODE;
> > +
> > +	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL0,
> > intf_val);
> > +
> > +	return 0;
> > +}
> > +
> > +static void mt8195_delay_ps2stage(struct mediatek_dwmac_plat_data
> > *plat)
> > +{
> > +	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > +
> > +	/* 290ps per stage */
> > +	mac_delay->tx_delay /= 290;
> > +	mac_delay->rx_delay /= 290;
> > +}
> > +
> > +static void mt8195_delay_stage2ps(struct mediatek_dwmac_plat_data
> > *plat)
> > +{
> > +	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > +
> > +	/* 290ps per stage */
> > +	mac_delay->tx_delay *= 290;
> > +	mac_delay->rx_delay *= 290;
> > +}
> > +
> > +static int mt8195_set_delay(struct mediatek_dwmac_plat_data *plat)
> > +{
> > +	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > +	u32 gtxc_delay_val, delay_val = 0, rmii_delay_val = 0;
> > +
> > +	mt8195_delay_ps2stage(plat);
> > +
> > +	switch (plat->phy_mode) {
> > +	case PHY_INTERFACE_MODE_MII:
> > +		delay_val |= FIELD_PREP(MT8195_DLY_TXC_ENABLE,
> > !!mac_delay->tx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_TXC_STAGES,
> > mac_delay->tx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_TXC_INV, mac_delay-
> > >tx_inv);
> > +
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE,
> > !!mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES,
> > mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV, mac_delay-
> > >rx_inv);
> > +		break;
> > +	case PHY_INTERFACE_MODE_RMII:
> > +		if (plat->rmii_clk_from_mac) {
> > +			/* case 1: mac provides the rmii reference
> > clock,
> > +			 * and the clock output to TXC pin.
> > +			 * The egress timing can be adjusted by
> > RMII_TXC delay macro circuit.
> > +			 * The ingress timing can be adjusted by
> > RMII_RXC delay macro circuit.
> > +			 */
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_TXC_ENABLE,
> > +						     !!mac_delay-
> > >tx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_TXC_STAGES,
> > +						     mac_delay-
> > >tx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_TXC_INV,
> > +						     mac_delay-
> > >tx_inv);
> > +
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_RXC_ENABLE,
> > +						     !!mac_delay-
> > >rx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_RXC_STAGES,
> > +						     mac_delay-
> > >rx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_RXC_INV,
> > +						     mac_delay-
> > >rx_inv);
> > +		} else {
> > +			/* case 2: the rmii reference clock is from
> > external phy,
> > +			 * and the property "rmii_rxc" indicates which
> > pin(TXC/RXC)
> > +			 * the reference clk is connected to. The
> > reference clock is a
> > +			 * received signal, so rx_delay/rx_inv are used
> > to indicate
> > +			 * the reference clock timing adjustment
> > +			 */
> > +			if (plat->rmii_rxc) {
> > +				/* the rmii reference clock from
> > outside is connected
> > +				 * to RXC pin, the reference clock will
> > be adjusted
> > +				 * by RXC delay macro circuit.
> > +				 */
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_RXC_ENABLE,
> > +							!!mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_RXC_STAGES,
> > +							mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_RXC_INV,
> > +							mac_delay-
> > >rx_inv);
> > +			} else {
> > +				/* the rmii reference clock from
> > outside is connected
> > +				 * to TXC pin, the reference clock will
> > be adjusted
> > +				 * by TXC delay macro circuit.
> > +				 */
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_TXC_ENABLE,
> > +							!!mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_TXC_STAGES,
> > +							mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_TXC_INV,
> > +							mac_delay-
> > >rx_inv);
> > +			}
> > +		}
> > +		break;
> > +	case PHY_INTERFACE_MODE_RGMII:
> > +	case PHY_INTERFACE_MODE_RGMII_TXID:
> > +	case PHY_INTERFACE_MODE_RGMII_RXID:
> > +	case PHY_INTERFACE_MODE_RGMII_ID:
> > +		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_ENABLE,
> > !!mac_delay->tx_delay);
> > +		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_STAGES,
> > mac_delay->tx_delay);
> > +		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_INV,
> > mac_delay->tx_inv);
> > +
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE,
> > !!mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES,
> > mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV, mac_delay-
> > >rx_inv);
> > +
> > +		break;
> > +	default:
> > +		dev_err(plat->dev, "phy interface not supported\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	regmap_update_bits(plat->peri_regmap,
> > +			   MT8195_PERI_ETH_CTRL0,
> > +			   MT8195_RGMII_TXC_PHASE_CTRL |
> > +			   MT8195_DLY_GTXC_INV |
> > +			   MT8195_DLY_GTXC_ENABLE |
> > +			   MT8195_DLY_GTXC_STAGES,
> > +			   gtxc_delay_val);
> > +	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL1,
> > delay_val);
> > +	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL2,
> > rmii_delay_val);
> > +
> > +	mt8195_delay_stage2ps(plat);
> > +
> > +	return 0;
> > +}
> > +
> > +static void mt8195_fix_mac_speed(void *priv, unsigned int speed)
> > +{
> > +	struct mediatek_dwmac_plat_data *priv_plat = priv;
> > +
> > +	if ((phy_interface_mode_is_rgmii(priv_plat->phy_mode))) {
> > +		/* prefer 2ns fixed delay which is controlled by
> > TXC_PHASE_CTRL,
> > +		 * when link speed is 1Gbps with RGMII interface,
> > +		 * Fall back to delay macro circuit for 10/100Mbps link
> > speed.
> > +		 */
> > +		if (speed == SPEED_1000)
> > +			regmap_update_bits(priv_plat->peri_regmap,
> > +					   MT8195_PERI_ETH_CTRL0,
> > +					   MT8195_RGMII_TXC_PHASE_CTRL
> > |
> > +					   MT8195_DLY_GTXC_ENABLE |
> > +					   MT8195_DLY_GTXC_INV |
> > +					   MT8195_DLY_GTXC_STAGES,
> > +					   MT8195_RGMII_TXC_PHASE_CTRL)
> > ;
> > +		else
> > +			mt8195_set_delay(priv_plat);
> > +	}
> > +}
> > +
> > +static const struct mediatek_dwmac_variant mt8195_gmac_variant = {
> > +	.dwmac_set_phy_interface = mt8195_set_interface,
> > +	.dwmac_set_delay = mt8195_set_delay,
> > +	.dwmac_fix_mac_speed = mt8195_fix_mac_speed,
> > +	.clk_list = mt8195_dwmac_clk_l,
> > +	.num_clks = ARRAY_SIZE(mt8195_dwmac_clk_l),
> > +	.dma_bit_mask = 35,
> > +	.rx_delay_max = 9280,
> > +	.tx_delay_max = 9280,
> > +};
> > +
> >   static int mediatek_dwmac_config_dt(struct
> > mediatek_dwmac_plat_data *plat)
> >   {
> >   	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > @@ -308,6 +539,7 @@ static int mediatek_dwmac_config_dt(struct
> > mediatek_dwmac_plat_data *plat)
> >   	mac_delay->rx_inv = of_property_read_bool(plat->np,
> > "mediatek,rxc-inverse");
> >   	plat->rmii_rxc = of_property_read_bool(plat->np,
> > "mediatek,rmii-rxc");
> >   	plat->rmii_clk_from_mac = of_property_read_bool(plat->np,
> > "mediatek,rmii-clk-from-mac");
> > +	plat->mac_wol = of_property_read_bool(plat->np, "mediatek,mac-
> > wol");
> >   
> >   	return 0;
> >   }
> > @@ -384,6 +616,16 @@ static int mediatek_dwmac_clks_config(void
> > *priv, bool enabled)
> >   
> >   	return ret;
> >   }
> > +
> > +static void mediatek_fix_mac_speed(void *priv, unsigned int speed)
> > +{
> > +	struct mediatek_dwmac_plat_data *plat = priv;
> > +	const struct mediatek_dwmac_variant *variant = plat->variant;
> > +
> > +	if (variant->dwmac_fix_mac_speed)
> > +		variant->dwmac_fix_mac_speed(priv, speed);
> > +}
> > +
> >   static int mediatek_dwmac_probe(struct platform_device *pdev)
> >   {
> >   	struct mediatek_dwmac_plat_data *priv_plat;
> > @@ -421,7 +663,7 @@ static int mediatek_dwmac_probe(struct
> > platform_device *pdev)
> >   		return PTR_ERR(plat_dat);
> >   
> >   	plat_dat->interface = priv_plat->phy_mode;
> > -	plat_dat->use_phy_wol = 1;
> > +	plat_dat->use_phy_wol = priv_plat->mac_wol ? 0 : 1;
> >   	plat_dat->riwt_off = 1;
> >   	plat_dat->maxmtu = ETH_DATA_LEN;
> >   	plat_dat->addr64 = priv_plat->variant->dma_bit_mask;
> > @@ -429,7 +671,22 @@ static int mediatek_dwmac_probe(struct
> > platform_device *pdev)
> >   	plat_dat->init = mediatek_dwmac_init;
> >   	plat_dat->exit = mediatek_dwmac_exit;
> >   	plat_dat->clks_config = mediatek_dwmac_clks_config;
> > +	plat_dat->fix_mac_speed = mediatek_fix_mac_speed;
> 
> 
> 
> So, since that function serves as a wrapper only....
> 
> 
> 
> 	if (priv_plat->variant->dwmac_fix_mac_speed)
> 
> 		lat_dat->fix_mac_speed = priv_plat->variant-
> >dwmac_fix_mac_speed;
> 
> 
> 
> seems to be a good option :)
> 
Yes, that makes sense, will fix it in next send.
> 
> 
> 
> 
> Regards,
> 
> - Angelo
> 

WARNING: multiple messages have this Message-ID (diff)
From: Biao Huang <biao.huang@mediatek.com>
To: AngeloGioacchino Del Regno
	<angelogioacchino.delregno@somainline.org>, <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	Rob Herring <robh+dt@kernel.org>
Cc: Matthias Brugger <matthias.bgg@gmail.com>,
	Giuseppe Cavallaro <peppe.cavallaro@st.com>,
	Alexandre Torgue <alexandre.torgue@foss.st.com>,
	Jose Abreu <joabreu@synopsys.com>,
	Maxime Coquelin <mcoquelin.stm32@gmail.com>,
	<netdev@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-mediatek@lists.infradead.org>,
	 <linux-stm32@st-md-mailman.stormreply.com>,
	<srv_heupstream@mediatek.com>, <macpaul.lin@mediatek.com>
Subject: Re: [PATCH v2 3/5] net: stmmac: dwmac-mediatek: add support for mt8195
Date: Fri, 12 Nov 2021 10:40:07 +0800	[thread overview]
Message-ID: <d66c18f41bcbc502a0e7f0f7345412ca888d6a49.camel@mediatek.com> (raw)
In-Reply-To: <6f894146-692b-63c7-cef6-2b26a171f006@somainline.org>

Dear Angelo,
	Thanks for your comments~

On Thu, 2021-11-11 at 14:26 +0100, AngeloGioacchino Del Regno wrote:
> Il 11/11/21 08:12, Biao Huang ha scritto:
> > Add Ethernet support for MediaTek SoCs from the mt8195 family.
> > 
> > Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> > ---
> >   .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 261
> > +++++++++++++++++-
> >   1 file changed, 260 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > index 6ea972e96665..b1266b68e21f 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > @@ -40,6 +40,33 @@
> >   #define ETH_FINE_DLY_GTXC	BIT(1)
> >   #define ETH_FINE_DLY_RXC	BIT(0)
> >   
> > +/* Peri Configuration register for mt8195 */
> > +#define MT8195_PERI_ETH_CTRL0		0xFD0
> > +#define MT8195_RMII_CLK_SRC_INTERNAL	BIT(28)
> > +#define MT8195_RMII_CLK_SRC_RXC		BIT(27)
> > +#define MT8195_ETH_INTF_SEL		GENMASK(26, 24)
> > +#define MT8195_RGMII_TXC_PHASE_CTRL	BIT(22)
> > +#define MT8195_EXT_PHY_MODE		BIT(21)
> > +#define MT8195_DLY_GTXC_INV		BIT(12)
> > +#define MT8195_DLY_GTXC_ENABLE		BIT(5)
> > +#define MT8195_DLY_GTXC_STAGES		GENMASK(4, 0)
> > +
> > +#define MT8195_PERI_ETH_CTRL1		0xFD4
> > +#define MT8195_DLY_RXC_INV		BIT(25)
> > +#define MT8195_DLY_RXC_ENABLE		BIT(18)
> > +#define MT8195_DLY_RXC_STAGES		GENMASK(17, 13)
> > +#define MT8195_DLY_TXC_INV		BIT(12)
> > +#define MT8195_DLY_TXC_ENABLE		BIT(5)
> > +#define MT8195_DLY_TXC_STAGES		GENMASK(4, 0)
> > +
> > +#define MT8195_PERI_ETH_CTRL2		0xFD8
> > +#define MT8195_DLY_RMII_RXC_INV		BIT(25)
> > +#define MT8195_DLY_RMII_RXC_ENABLE	BIT(18)
> > +#define MT8195_DLY_RMII_RXC_STAGES	GENMASK(17, 13)
> > +#define MT8195_DLY_RMII_TXC_INV		BIT(12)
> > +#define MT8195_DLY_RMII_TXC_ENABLE	BIT(5)
> > +#define MT8195_DLY_RMII_TXC_STAGES	GENMASK(4, 0)
> > +
> >   struct mac_delay_struct {
> >   	u32 tx_delay;
> >   	u32 rx_delay;
> > @@ -58,11 +85,13 @@ struct mediatek_dwmac_plat_data {
> >   	int num_clks_to_config;
> >   	bool rmii_clk_from_mac;
> >   	bool rmii_rxc;
> > +	bool mac_wol;
> >   };
> >   
> >   struct mediatek_dwmac_variant {
> >   	int (*dwmac_set_phy_interface)(struct mediatek_dwmac_plat_data
> > *plat);
> >   	int (*dwmac_set_delay)(struct mediatek_dwmac_plat_data *plat);
> > +	void (*dwmac_fix_mac_speed)(void *priv, unsigned int speed);
> >   
> >   	/* clock ids to be requested */
> >   	const char * const *clk_list;
> > @@ -78,6 +107,10 @@ static const char * const mt2712_dwmac_clk_l[]
> > = {
> >   	"axi", "apb", "mac_main", "ptp_ref", "rmii_internal"
> >   };
> >   
> > +static const char * const mt8195_dwmac_clk_l[] = {
> > +	"axi", "apb", "mac_cg", "mac_main", "ptp_ref", "rmii_internal"
> > +};
> > +
> >   static int mt2712_set_interface(struct mediatek_dwmac_plat_data
> > *plat)
> >   {
> >   	int rmii_clk_from_mac = plat->rmii_clk_from_mac ?
> > RMII_CLK_SRC_INTERNAL : 0;
> > @@ -268,6 +301,204 @@ static const struct mediatek_dwmac_variant
> > mt2712_gmac_variant = {
> >   		.tx_delay_max = 17600,
> >   };
> >   
> > +static int mt8195_set_interface(struct mediatek_dwmac_plat_data
> > *plat)
> > +{
> > +	int rmii_clk_from_mac = plat->rmii_clk_from_mac ?
> > MT8195_RMII_CLK_SRC_INTERNAL : 0;
> > +	int rmii_rxc = plat->rmii_rxc ? MT8195_RMII_CLK_SRC_RXC : 0;
> > +	u32 intf_val = 0;
> > +
> > +	/* The clock labeled as "rmii_internal" in mt8195_dwmac_clk_l
> > is needed
> > +	 * only in RMII(when MAC provides the reference clock), and
> > useless for
> > +	 * RGMII/MII/RMII(when PHY provides the reference clock).
> > +	 * num_clks_to_config indicates the real number of clocks
> > should be
> > +	 * configured, equals to (plat->variant->num_clks - 1) in
> > default for all the case,
> > +	 * then +1 for rmii_clk_from_mac case.
> > +	 */
> > +	plat->num_clks_to_config = plat->variant->num_clks - 1;
> > +
> > +	/* select phy interface in top control domain */
> > +	switch (plat->phy_mode) {
> > +	case PHY_INTERFACE_MODE_MII:
> > +		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL,
> > PHY_INTF_MII);
> > +		break;
> > +	case PHY_INTERFACE_MODE_RMII:
> > +		if (plat->rmii_clk_from_mac)
> > +			plat->num_clks_to_config++;
> > +		intf_val |= (rmii_rxc | rmii_clk_from_mac);
> > +		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL,
> > PHY_INTF_RMII);
> > +		break;
> > +	case PHY_INTERFACE_MODE_RGMII:
> > +	case PHY_INTERFACE_MODE_RGMII_TXID:
> > +	case PHY_INTERFACE_MODE_RGMII_RXID:
> > +	case PHY_INTERFACE_MODE_RGMII_ID:
> > +		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL,
> > PHY_INTF_RGMII);
> > +		break;
> > +	default:
> > +		dev_err(plat->dev, "phy interface not supported\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* MT8195 only support external PHY */
> > +	intf_val |= MT8195_EXT_PHY_MODE;
> > +
> > +	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL0,
> > intf_val);
> > +
> > +	return 0;
> > +}
> > +
> > +static void mt8195_delay_ps2stage(struct mediatek_dwmac_plat_data
> > *plat)
> > +{
> > +	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > +
> > +	/* 290ps per stage */
> > +	mac_delay->tx_delay /= 290;
> > +	mac_delay->rx_delay /= 290;
> > +}
> > +
> > +static void mt8195_delay_stage2ps(struct mediatek_dwmac_plat_data
> > *plat)
> > +{
> > +	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > +
> > +	/* 290ps per stage */
> > +	mac_delay->tx_delay *= 290;
> > +	mac_delay->rx_delay *= 290;
> > +}
> > +
> > +static int mt8195_set_delay(struct mediatek_dwmac_plat_data *plat)
> > +{
> > +	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > +	u32 gtxc_delay_val, delay_val = 0, rmii_delay_val = 0;
> > +
> > +	mt8195_delay_ps2stage(plat);
> > +
> > +	switch (plat->phy_mode) {
> > +	case PHY_INTERFACE_MODE_MII:
> > +		delay_val |= FIELD_PREP(MT8195_DLY_TXC_ENABLE,
> > !!mac_delay->tx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_TXC_STAGES,
> > mac_delay->tx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_TXC_INV, mac_delay-
> > >tx_inv);
> > +
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE,
> > !!mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES,
> > mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV, mac_delay-
> > >rx_inv);
> > +		break;
> > +	case PHY_INTERFACE_MODE_RMII:
> > +		if (plat->rmii_clk_from_mac) {
> > +			/* case 1: mac provides the rmii reference
> > clock,
> > +			 * and the clock output to TXC pin.
> > +			 * The egress timing can be adjusted by
> > RMII_TXC delay macro circuit.
> > +			 * The ingress timing can be adjusted by
> > RMII_RXC delay macro circuit.
> > +			 */
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_TXC_ENABLE,
> > +						     !!mac_delay-
> > >tx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_TXC_STAGES,
> > +						     mac_delay-
> > >tx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_TXC_INV,
> > +						     mac_delay-
> > >tx_inv);
> > +
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_RXC_ENABLE,
> > +						     !!mac_delay-
> > >rx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_RXC_STAGES,
> > +						     mac_delay-
> > >rx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_RXC_INV,
> > +						     mac_delay-
> > >rx_inv);
> > +		} else {
> > +			/* case 2: the rmii reference clock is from
> > external phy,
> > +			 * and the property "rmii_rxc" indicates which
> > pin(TXC/RXC)
> > +			 * the reference clk is connected to. The
> > reference clock is a
> > +			 * received signal, so rx_delay/rx_inv are used
> > to indicate
> > +			 * the reference clock timing adjustment
> > +			 */
> > +			if (plat->rmii_rxc) {
> > +				/* the rmii reference clock from
> > outside is connected
> > +				 * to RXC pin, the reference clock will
> > be adjusted
> > +				 * by RXC delay macro circuit.
> > +				 */
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_RXC_ENABLE,
> > +							!!mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_RXC_STAGES,
> > +							mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_RXC_INV,
> > +							mac_delay-
> > >rx_inv);
> > +			} else {
> > +				/* the rmii reference clock from
> > outside is connected
> > +				 * to TXC pin, the reference clock will
> > be adjusted
> > +				 * by TXC delay macro circuit.
> > +				 */
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_TXC_ENABLE,
> > +							!!mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_TXC_STAGES,
> > +							mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_TXC_INV,
> > +							mac_delay-
> > >rx_inv);
> > +			}
> > +		}
> > +		break;
> > +	case PHY_INTERFACE_MODE_RGMII:
> > +	case PHY_INTERFACE_MODE_RGMII_TXID:
> > +	case PHY_INTERFACE_MODE_RGMII_RXID:
> > +	case PHY_INTERFACE_MODE_RGMII_ID:
> > +		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_ENABLE,
> > !!mac_delay->tx_delay);
> > +		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_STAGES,
> > mac_delay->tx_delay);
> > +		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_INV,
> > mac_delay->tx_inv);
> > +
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE,
> > !!mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES,
> > mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV, mac_delay-
> > >rx_inv);
> > +
> > +		break;
> > +	default:
> > +		dev_err(plat->dev, "phy interface not supported\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	regmap_update_bits(plat->peri_regmap,
> > +			   MT8195_PERI_ETH_CTRL0,
> > +			   MT8195_RGMII_TXC_PHASE_CTRL |
> > +			   MT8195_DLY_GTXC_INV |
> > +			   MT8195_DLY_GTXC_ENABLE |
> > +			   MT8195_DLY_GTXC_STAGES,
> > +			   gtxc_delay_val);
> > +	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL1,
> > delay_val);
> > +	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL2,
> > rmii_delay_val);
> > +
> > +	mt8195_delay_stage2ps(plat);
> > +
> > +	return 0;
> > +}
> > +
> > +static void mt8195_fix_mac_speed(void *priv, unsigned int speed)
> > +{
> > +	struct mediatek_dwmac_plat_data *priv_plat = priv;
> > +
> > +	if ((phy_interface_mode_is_rgmii(priv_plat->phy_mode))) {
> > +		/* prefer 2ns fixed delay which is controlled by
> > TXC_PHASE_CTRL,
> > +		 * when link speed is 1Gbps with RGMII interface,
> > +		 * Fall back to delay macro circuit for 10/100Mbps link
> > speed.
> > +		 */
> > +		if (speed == SPEED_1000)
> > +			regmap_update_bits(priv_plat->peri_regmap,
> > +					   MT8195_PERI_ETH_CTRL0,
> > +					   MT8195_RGMII_TXC_PHASE_CTRL
> > |
> > +					   MT8195_DLY_GTXC_ENABLE |
> > +					   MT8195_DLY_GTXC_INV |
> > +					   MT8195_DLY_GTXC_STAGES,
> > +					   MT8195_RGMII_TXC_PHASE_CTRL)
> > ;
> > +		else
> > +			mt8195_set_delay(priv_plat);
> > +	}
> > +}
> > +
> > +static const struct mediatek_dwmac_variant mt8195_gmac_variant = {
> > +	.dwmac_set_phy_interface = mt8195_set_interface,
> > +	.dwmac_set_delay = mt8195_set_delay,
> > +	.dwmac_fix_mac_speed = mt8195_fix_mac_speed,
> > +	.clk_list = mt8195_dwmac_clk_l,
> > +	.num_clks = ARRAY_SIZE(mt8195_dwmac_clk_l),
> > +	.dma_bit_mask = 35,
> > +	.rx_delay_max = 9280,
> > +	.tx_delay_max = 9280,
> > +};
> > +
> >   static int mediatek_dwmac_config_dt(struct
> > mediatek_dwmac_plat_data *plat)
> >   {
> >   	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > @@ -308,6 +539,7 @@ static int mediatek_dwmac_config_dt(struct
> > mediatek_dwmac_plat_data *plat)
> >   	mac_delay->rx_inv = of_property_read_bool(plat->np,
> > "mediatek,rxc-inverse");
> >   	plat->rmii_rxc = of_property_read_bool(plat->np,
> > "mediatek,rmii-rxc");
> >   	plat->rmii_clk_from_mac = of_property_read_bool(plat->np,
> > "mediatek,rmii-clk-from-mac");
> > +	plat->mac_wol = of_property_read_bool(plat->np, "mediatek,mac-
> > wol");
> >   
> >   	return 0;
> >   }
> > @@ -384,6 +616,16 @@ static int mediatek_dwmac_clks_config(void
> > *priv, bool enabled)
> >   
> >   	return ret;
> >   }
> > +
> > +static void mediatek_fix_mac_speed(void *priv, unsigned int speed)
> > +{
> > +	struct mediatek_dwmac_plat_data *plat = priv;
> > +	const struct mediatek_dwmac_variant *variant = plat->variant;
> > +
> > +	if (variant->dwmac_fix_mac_speed)
> > +		variant->dwmac_fix_mac_speed(priv, speed);
> > +}
> > +
> >   static int mediatek_dwmac_probe(struct platform_device *pdev)
> >   {
> >   	struct mediatek_dwmac_plat_data *priv_plat;
> > @@ -421,7 +663,7 @@ static int mediatek_dwmac_probe(struct
> > platform_device *pdev)
> >   		return PTR_ERR(plat_dat);
> >   
> >   	plat_dat->interface = priv_plat->phy_mode;
> > -	plat_dat->use_phy_wol = 1;
> > +	plat_dat->use_phy_wol = priv_plat->mac_wol ? 0 : 1;
> >   	plat_dat->riwt_off = 1;
> >   	plat_dat->maxmtu = ETH_DATA_LEN;
> >   	plat_dat->addr64 = priv_plat->variant->dma_bit_mask;
> > @@ -429,7 +671,22 @@ static int mediatek_dwmac_probe(struct
> > platform_device *pdev)
> >   	plat_dat->init = mediatek_dwmac_init;
> >   	plat_dat->exit = mediatek_dwmac_exit;
> >   	plat_dat->clks_config = mediatek_dwmac_clks_config;
> > +	plat_dat->fix_mac_speed = mediatek_fix_mac_speed;
> 
> 
> 
> So, since that function serves as a wrapper only....
> 
> 
> 
> 	if (priv_plat->variant->dwmac_fix_mac_speed)
> 
> 		lat_dat->fix_mac_speed = priv_plat->variant-
> >dwmac_fix_mac_speed;
> 
> 
> 
> seems to be a good option :)
> 
Yes, that makes sense, will fix it in next send.
> 
> 
> 
> 
> Regards,
> 
> - Angelo
> 
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

WARNING: multiple messages have this Message-ID (diff)
From: Biao Huang <biao.huang@mediatek.com>
To: AngeloGioacchino Del Regno
	<angelogioacchino.delregno@somainline.org>, <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	Rob Herring <robh+dt@kernel.org>
Cc: Matthias Brugger <matthias.bgg@gmail.com>,
	Giuseppe Cavallaro <peppe.cavallaro@st.com>,
	Alexandre Torgue <alexandre.torgue@foss.st.com>,
	Jose Abreu <joabreu@synopsys.com>,
	Maxime Coquelin <mcoquelin.stm32@gmail.com>,
	<netdev@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-mediatek@lists.infradead.org>,
	 <linux-stm32@st-md-mailman.stormreply.com>,
	<srv_heupstream@mediatek.com>, <macpaul.lin@mediatek.com>
Subject: Re: [PATCH v2 3/5] net: stmmac: dwmac-mediatek: add support for mt8195
Date: Fri, 12 Nov 2021 10:40:07 +0800	[thread overview]
Message-ID: <d66c18f41bcbc502a0e7f0f7345412ca888d6a49.camel@mediatek.com> (raw)
In-Reply-To: <6f894146-692b-63c7-cef6-2b26a171f006@somainline.org>

Dear Angelo,
	Thanks for your comments~

On Thu, 2021-11-11 at 14:26 +0100, AngeloGioacchino Del Regno wrote:
> Il 11/11/21 08:12, Biao Huang ha scritto:
> > Add Ethernet support for MediaTek SoCs from the mt8195 family.
> > 
> > Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> > ---
> >   .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 261
> > +++++++++++++++++-
> >   1 file changed, 260 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > index 6ea972e96665..b1266b68e21f 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > @@ -40,6 +40,33 @@
> >   #define ETH_FINE_DLY_GTXC	BIT(1)
> >   #define ETH_FINE_DLY_RXC	BIT(0)
> >   
> > +/* Peri Configuration register for mt8195 */
> > +#define MT8195_PERI_ETH_CTRL0		0xFD0
> > +#define MT8195_RMII_CLK_SRC_INTERNAL	BIT(28)
> > +#define MT8195_RMII_CLK_SRC_RXC		BIT(27)
> > +#define MT8195_ETH_INTF_SEL		GENMASK(26, 24)
> > +#define MT8195_RGMII_TXC_PHASE_CTRL	BIT(22)
> > +#define MT8195_EXT_PHY_MODE		BIT(21)
> > +#define MT8195_DLY_GTXC_INV		BIT(12)
> > +#define MT8195_DLY_GTXC_ENABLE		BIT(5)
> > +#define MT8195_DLY_GTXC_STAGES		GENMASK(4, 0)
> > +
> > +#define MT8195_PERI_ETH_CTRL1		0xFD4
> > +#define MT8195_DLY_RXC_INV		BIT(25)
> > +#define MT8195_DLY_RXC_ENABLE		BIT(18)
> > +#define MT8195_DLY_RXC_STAGES		GENMASK(17, 13)
> > +#define MT8195_DLY_TXC_INV		BIT(12)
> > +#define MT8195_DLY_TXC_ENABLE		BIT(5)
> > +#define MT8195_DLY_TXC_STAGES		GENMASK(4, 0)
> > +
> > +#define MT8195_PERI_ETH_CTRL2		0xFD8
> > +#define MT8195_DLY_RMII_RXC_INV		BIT(25)
> > +#define MT8195_DLY_RMII_RXC_ENABLE	BIT(18)
> > +#define MT8195_DLY_RMII_RXC_STAGES	GENMASK(17, 13)
> > +#define MT8195_DLY_RMII_TXC_INV		BIT(12)
> > +#define MT8195_DLY_RMII_TXC_ENABLE	BIT(5)
> > +#define MT8195_DLY_RMII_TXC_STAGES	GENMASK(4, 0)
> > +
> >   struct mac_delay_struct {
> >   	u32 tx_delay;
> >   	u32 rx_delay;
> > @@ -58,11 +85,13 @@ struct mediatek_dwmac_plat_data {
> >   	int num_clks_to_config;
> >   	bool rmii_clk_from_mac;
> >   	bool rmii_rxc;
> > +	bool mac_wol;
> >   };
> >   
> >   struct mediatek_dwmac_variant {
> >   	int (*dwmac_set_phy_interface)(struct mediatek_dwmac_plat_data
> > *plat);
> >   	int (*dwmac_set_delay)(struct mediatek_dwmac_plat_data *plat);
> > +	void (*dwmac_fix_mac_speed)(void *priv, unsigned int speed);
> >   
> >   	/* clock ids to be requested */
> >   	const char * const *clk_list;
> > @@ -78,6 +107,10 @@ static const char * const mt2712_dwmac_clk_l[]
> > = {
> >   	"axi", "apb", "mac_main", "ptp_ref", "rmii_internal"
> >   };
> >   
> > +static const char * const mt8195_dwmac_clk_l[] = {
> > +	"axi", "apb", "mac_cg", "mac_main", "ptp_ref", "rmii_internal"
> > +};
> > +
> >   static int mt2712_set_interface(struct mediatek_dwmac_plat_data
> > *plat)
> >   {
> >   	int rmii_clk_from_mac = plat->rmii_clk_from_mac ?
> > RMII_CLK_SRC_INTERNAL : 0;
> > @@ -268,6 +301,204 @@ static const struct mediatek_dwmac_variant
> > mt2712_gmac_variant = {
> >   		.tx_delay_max = 17600,
> >   };
> >   
> > +static int mt8195_set_interface(struct mediatek_dwmac_plat_data
> > *plat)
> > +{
> > +	int rmii_clk_from_mac = plat->rmii_clk_from_mac ?
> > MT8195_RMII_CLK_SRC_INTERNAL : 0;
> > +	int rmii_rxc = plat->rmii_rxc ? MT8195_RMII_CLK_SRC_RXC : 0;
> > +	u32 intf_val = 0;
> > +
> > +	/* The clock labeled as "rmii_internal" in mt8195_dwmac_clk_l
> > is needed
> > +	 * only in RMII(when MAC provides the reference clock), and
> > useless for
> > +	 * RGMII/MII/RMII(when PHY provides the reference clock).
> > +	 * num_clks_to_config indicates the real number of clocks
> > should be
> > +	 * configured, equals to (plat->variant->num_clks - 1) in
> > default for all the case,
> > +	 * then +1 for rmii_clk_from_mac case.
> > +	 */
> > +	plat->num_clks_to_config = plat->variant->num_clks - 1;
> > +
> > +	/* select phy interface in top control domain */
> > +	switch (plat->phy_mode) {
> > +	case PHY_INTERFACE_MODE_MII:
> > +		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL,
> > PHY_INTF_MII);
> > +		break;
> > +	case PHY_INTERFACE_MODE_RMII:
> > +		if (plat->rmii_clk_from_mac)
> > +			plat->num_clks_to_config++;
> > +		intf_val |= (rmii_rxc | rmii_clk_from_mac);
> > +		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL,
> > PHY_INTF_RMII);
> > +		break;
> > +	case PHY_INTERFACE_MODE_RGMII:
> > +	case PHY_INTERFACE_MODE_RGMII_TXID:
> > +	case PHY_INTERFACE_MODE_RGMII_RXID:
> > +	case PHY_INTERFACE_MODE_RGMII_ID:
> > +		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL,
> > PHY_INTF_RGMII);
> > +		break;
> > +	default:
> > +		dev_err(plat->dev, "phy interface not supported\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* MT8195 only support external PHY */
> > +	intf_val |= MT8195_EXT_PHY_MODE;
> > +
> > +	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL0,
> > intf_val);
> > +
> > +	return 0;
> > +}
> > +
> > +static void mt8195_delay_ps2stage(struct mediatek_dwmac_plat_data
> > *plat)
> > +{
> > +	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > +
> > +	/* 290ps per stage */
> > +	mac_delay->tx_delay /= 290;
> > +	mac_delay->rx_delay /= 290;
> > +}
> > +
> > +static void mt8195_delay_stage2ps(struct mediatek_dwmac_plat_data
> > *plat)
> > +{
> > +	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > +
> > +	/* 290ps per stage */
> > +	mac_delay->tx_delay *= 290;
> > +	mac_delay->rx_delay *= 290;
> > +}
> > +
> > +static int mt8195_set_delay(struct mediatek_dwmac_plat_data *plat)
> > +{
> > +	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > +	u32 gtxc_delay_val, delay_val = 0, rmii_delay_val = 0;
> > +
> > +	mt8195_delay_ps2stage(plat);
> > +
> > +	switch (plat->phy_mode) {
> > +	case PHY_INTERFACE_MODE_MII:
> > +		delay_val |= FIELD_PREP(MT8195_DLY_TXC_ENABLE,
> > !!mac_delay->tx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_TXC_STAGES,
> > mac_delay->tx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_TXC_INV, mac_delay-
> > >tx_inv);
> > +
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE,
> > !!mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES,
> > mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV, mac_delay-
> > >rx_inv);
> > +		break;
> > +	case PHY_INTERFACE_MODE_RMII:
> > +		if (plat->rmii_clk_from_mac) {
> > +			/* case 1: mac provides the rmii reference
> > clock,
> > +			 * and the clock output to TXC pin.
> > +			 * The egress timing can be adjusted by
> > RMII_TXC delay macro circuit.
> > +			 * The ingress timing can be adjusted by
> > RMII_RXC delay macro circuit.
> > +			 */
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_TXC_ENABLE,
> > +						     !!mac_delay-
> > >tx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_TXC_STAGES,
> > +						     mac_delay-
> > >tx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_TXC_INV,
> > +						     mac_delay-
> > >tx_inv);
> > +
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_RXC_ENABLE,
> > +						     !!mac_delay-
> > >rx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_RXC_STAGES,
> > +						     mac_delay-
> > >rx_delay);
> > +			rmii_delay_val |=
> > FIELD_PREP(MT8195_DLY_RMII_RXC_INV,
> > +						     mac_delay-
> > >rx_inv);
> > +		} else {
> > +			/* case 2: the rmii reference clock is from
> > external phy,
> > +			 * and the property "rmii_rxc" indicates which
> > pin(TXC/RXC)
> > +			 * the reference clk is connected to. The
> > reference clock is a
> > +			 * received signal, so rx_delay/rx_inv are used
> > to indicate
> > +			 * the reference clock timing adjustment
> > +			 */
> > +			if (plat->rmii_rxc) {
> > +				/* the rmii reference clock from
> > outside is connected
> > +				 * to RXC pin, the reference clock will
> > be adjusted
> > +				 * by RXC delay macro circuit.
> > +				 */
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_RXC_ENABLE,
> > +							!!mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_RXC_STAGES,
> > +							mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_RXC_INV,
> > +							mac_delay-
> > >rx_inv);
> > +			} else {
> > +				/* the rmii reference clock from
> > outside is connected
> > +				 * to TXC pin, the reference clock will
> > be adjusted
> > +				 * by TXC delay macro circuit.
> > +				 */
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_TXC_ENABLE,
> > +							!!mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_TXC_STAGES,
> > +							mac_delay-
> > >rx_delay);
> > +				delay_val |=
> > FIELD_PREP(MT8195_DLY_TXC_INV,
> > +							mac_delay-
> > >rx_inv);
> > +			}
> > +		}
> > +		break;
> > +	case PHY_INTERFACE_MODE_RGMII:
> > +	case PHY_INTERFACE_MODE_RGMII_TXID:
> > +	case PHY_INTERFACE_MODE_RGMII_RXID:
> > +	case PHY_INTERFACE_MODE_RGMII_ID:
> > +		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_ENABLE,
> > !!mac_delay->tx_delay);
> > +		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_STAGES,
> > mac_delay->tx_delay);
> > +		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_INV,
> > mac_delay->tx_inv);
> > +
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE,
> > !!mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES,
> > mac_delay->rx_delay);
> > +		delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV, mac_delay-
> > >rx_inv);
> > +
> > +		break;
> > +	default:
> > +		dev_err(plat->dev, "phy interface not supported\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	regmap_update_bits(plat->peri_regmap,
> > +			   MT8195_PERI_ETH_CTRL0,
> > +			   MT8195_RGMII_TXC_PHASE_CTRL |
> > +			   MT8195_DLY_GTXC_INV |
> > +			   MT8195_DLY_GTXC_ENABLE |
> > +			   MT8195_DLY_GTXC_STAGES,
> > +			   gtxc_delay_val);
> > +	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL1,
> > delay_val);
> > +	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL2,
> > rmii_delay_val);
> > +
> > +	mt8195_delay_stage2ps(plat);
> > +
> > +	return 0;
> > +}
> > +
> > +static void mt8195_fix_mac_speed(void *priv, unsigned int speed)
> > +{
> > +	struct mediatek_dwmac_plat_data *priv_plat = priv;
> > +
> > +	if ((phy_interface_mode_is_rgmii(priv_plat->phy_mode))) {
> > +		/* prefer 2ns fixed delay which is controlled by
> > TXC_PHASE_CTRL,
> > +		 * when link speed is 1Gbps with RGMII interface,
> > +		 * Fall back to delay macro circuit for 10/100Mbps link
> > speed.
> > +		 */
> > +		if (speed == SPEED_1000)
> > +			regmap_update_bits(priv_plat->peri_regmap,
> > +					   MT8195_PERI_ETH_CTRL0,
> > +					   MT8195_RGMII_TXC_PHASE_CTRL
> > |
> > +					   MT8195_DLY_GTXC_ENABLE |
> > +					   MT8195_DLY_GTXC_INV |
> > +					   MT8195_DLY_GTXC_STAGES,
> > +					   MT8195_RGMII_TXC_PHASE_CTRL)
> > ;
> > +		else
> > +			mt8195_set_delay(priv_plat);
> > +	}
> > +}
> > +
> > +static const struct mediatek_dwmac_variant mt8195_gmac_variant = {
> > +	.dwmac_set_phy_interface = mt8195_set_interface,
> > +	.dwmac_set_delay = mt8195_set_delay,
> > +	.dwmac_fix_mac_speed = mt8195_fix_mac_speed,
> > +	.clk_list = mt8195_dwmac_clk_l,
> > +	.num_clks = ARRAY_SIZE(mt8195_dwmac_clk_l),
> > +	.dma_bit_mask = 35,
> > +	.rx_delay_max = 9280,
> > +	.tx_delay_max = 9280,
> > +};
> > +
> >   static int mediatek_dwmac_config_dt(struct
> > mediatek_dwmac_plat_data *plat)
> >   {
> >   	struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > @@ -308,6 +539,7 @@ static int mediatek_dwmac_config_dt(struct
> > mediatek_dwmac_plat_data *plat)
> >   	mac_delay->rx_inv = of_property_read_bool(plat->np,
> > "mediatek,rxc-inverse");
> >   	plat->rmii_rxc = of_property_read_bool(plat->np,
> > "mediatek,rmii-rxc");
> >   	plat->rmii_clk_from_mac = of_property_read_bool(plat->np,
> > "mediatek,rmii-clk-from-mac");
> > +	plat->mac_wol = of_property_read_bool(plat->np, "mediatek,mac-
> > wol");
> >   
> >   	return 0;
> >   }
> > @@ -384,6 +616,16 @@ static int mediatek_dwmac_clks_config(void
> > *priv, bool enabled)
> >   
> >   	return ret;
> >   }
> > +
> > +static void mediatek_fix_mac_speed(void *priv, unsigned int speed)
> > +{
> > +	struct mediatek_dwmac_plat_data *plat = priv;
> > +	const struct mediatek_dwmac_variant *variant = plat->variant;
> > +
> > +	if (variant->dwmac_fix_mac_speed)
> > +		variant->dwmac_fix_mac_speed(priv, speed);
> > +}
> > +
> >   static int mediatek_dwmac_probe(struct platform_device *pdev)
> >   {
> >   	struct mediatek_dwmac_plat_data *priv_plat;
> > @@ -421,7 +663,7 @@ static int mediatek_dwmac_probe(struct
> > platform_device *pdev)
> >   		return PTR_ERR(plat_dat);
> >   
> >   	plat_dat->interface = priv_plat->phy_mode;
> > -	plat_dat->use_phy_wol = 1;
> > +	plat_dat->use_phy_wol = priv_plat->mac_wol ? 0 : 1;
> >   	plat_dat->riwt_off = 1;
> >   	plat_dat->maxmtu = ETH_DATA_LEN;
> >   	plat_dat->addr64 = priv_plat->variant->dma_bit_mask;
> > @@ -429,7 +671,22 @@ static int mediatek_dwmac_probe(struct
> > platform_device *pdev)
> >   	plat_dat->init = mediatek_dwmac_init;
> >   	plat_dat->exit = mediatek_dwmac_exit;
> >   	plat_dat->clks_config = mediatek_dwmac_clks_config;
> > +	plat_dat->fix_mac_speed = mediatek_fix_mac_speed;
> 
> 
> 
> So, since that function serves as a wrapper only....
> 
> 
> 
> 	if (priv_plat->variant->dwmac_fix_mac_speed)
> 
> 		lat_dat->fix_mac_speed = priv_plat->variant-
> >dwmac_fix_mac_speed;
> 
> 
> 
> seems to be a good option :)
> 
Yes, that makes sense, will fix it in next send.
> 
> 
> 
> 
> Regards,
> 
> - Angelo
> 
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2021-11-12  2:40 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-11  7:12 [PATCH v2 0/5] MediaTek Ethernet Patches on MT8195 Biao Huang
2021-11-11  7:12 ` Biao Huang
2021-11-11  7:12 ` Biao Huang
2021-11-11  7:12 ` [PATCH v2 1/5] net: stmmac: dwmac-mediatek: add platform level clocks management Biao Huang
2021-11-11  7:12   ` Biao Huang
2021-11-11  7:12   ` Biao Huang
2021-11-11  7:12 ` [PATCH v2 2/5] net: stmmac: dwmac-mediatek: Reuse more common features Biao Huang
2021-11-11  7:12   ` Biao Huang
2021-11-11  7:12   ` Biao Huang
2021-11-11 13:28   ` AngeloGioacchino Del Regno
2021-11-11 13:28     ` AngeloGioacchino Del Regno
2021-11-11 13:28     ` AngeloGioacchino Del Regno
2021-11-12  3:01     ` Biao Huang
2021-11-12  3:01       ` Biao Huang
2021-11-12  3:01       ` Biao Huang
2021-11-11  7:12 ` [PATCH v2 3/5] net: stmmac: dwmac-mediatek: add support for mt8195 Biao Huang
2021-11-11  7:12   ` Biao Huang
2021-11-11  7:12   ` Biao Huang
2021-11-11 13:26   ` AngeloGioacchino Del Regno
2021-11-11 13:26     ` AngeloGioacchino Del Regno
2021-11-11 13:26     ` AngeloGioacchino Del Regno
2021-11-12  2:40     ` Biao Huang [this message]
2021-11-12  2:40       ` Biao Huang
2021-11-12  2:40       ` Biao Huang
2021-11-11 13:27   ` AngeloGioacchino Del Regno
2021-11-11 13:27     ` AngeloGioacchino Del Regno
2021-11-11 13:27     ` AngeloGioacchino Del Regno
2021-11-11  7:12 ` [PATCH v2 4/5] dt-bindings: net: dwmac: Convert mediatek-dwmac to DT schema Biao Huang
2021-11-11  7:12   ` Biao Huang
2021-11-11  7:12   ` Biao Huang
2021-11-11 13:30   ` AngeloGioacchino Del Regno
2021-11-11 13:30     ` AngeloGioacchino Del Regno
2021-11-11 13:30     ` AngeloGioacchino Del Regno
2021-11-12  1:47     ` Biao Huang
2021-11-12  1:47       ` Biao Huang
2021-11-12  1:47       ` Biao Huang
2021-11-11 14:57   ` Rob Herring
2021-11-11 14:57     ` Rob Herring
2021-11-11 14:57     ` Rob Herring
2021-11-12  2:11     ` Biao Huang
2021-11-12  2:11       ` Biao Huang
2021-11-12  2:11       ` Biao Huang
2021-11-11  7:12 ` [PATCH v2 5/5] arm64: dts: mt8195: add ethernet device node Biao Huang
2021-11-11  7:12   ` Biao Huang
2021-11-11  7:12   ` Biao Huang
2021-11-11 11:35 ` [PATCH v2 0/5] MediaTek Ethernet Patches on MT8195 Denis Kirjanov
2021-11-11 11:35   ` Denis Kirjanov
2021-11-11 11:35   ` Denis Kirjanov
2021-11-12  1:22   ` Biao Huang
2021-11-12  1:22     ` Biao Huang
2021-11-12  1:22     ` Biao Huang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d66c18f41bcbc502a0e7f0f7345412ca888d6a49.camel@mediatek.com \
    --to=biao.huang@mediatek.com \
    --cc=alexandre.torgue@foss.st.com \
    --cc=angelogioacchino.delregno@somainline.org \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=joabreu@synopsys.com \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-stm32@st-md-mailman.stormreply.com \
    --cc=macpaul.lin@mediatek.com \
    --cc=matthias.bgg@gmail.com \
    --cc=mcoquelin.stm32@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=peppe.cavallaro@st.com \
    --cc=robh+dt@kernel.org \
    --cc=srv_heupstream@mediatek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.