On Mon, 2019-01-21 at 11:31 -0800, Sean Wang wrote:
> From: g...@kernel.org [mailto:g...@kernel.org]
> Sent: Sunday, January 20, 2019 11:12 PM
> To: Sean Wang <sean.w...@mediatek.com>; bj...@mork.no; and...@lunn.ch; 
> vivien.dide...@savoirfairelinux.com; f.faine...@gmail.com; 
> netdev@vger.kernel.org
> Cc: r...@vdorst.com; j...@phrozen.org; n...@brown.name; Greg Ungerer 
> <g...@kernel.org>
> Subject: [PATCHv3 2/3] net: dsa: mt7530: support the 7530 switch on the 
> Mediatek MT7621 SoC
> 
> From: Greg Ungerer <g...@kernel.org>
> 
> The MediaTek MT7621 SoC device contains a 7530 switch, and the existing linux 
> kernel 7530 DSA switch driver can be used with it.
> 
> The bulk of the changes required stem from the 7621 having different 
> regulator and pad setup. The existing setup of these in the 7530 driver 
> appears to be very specific to its implemtation in the Mediatek
> 7623 SoC. (Not entirely surprising given the 7623 is a quad core ARM based 
> SoC, and the 7621 is a dual core, dual thread MIPS based SoC).
> 
> Create a new devicetree type, "mediatek,mt7621", to support the 7530 switch 
> in the 7621 SoC. There appears to be no usable ID register to distinguish it 
> from a 7530 in other hardware at runtime. This is used to carry out the 
> appropriate configuration and setup.
> 
> Signed-off-by: Greg Ungerer <g...@kernel.org>
> ---
>  drivers/net/dsa/mt7530.c | 97 ++++++++++++++++++++++++----------------
>  drivers/net/dsa/mt7530.h |  9 ++++
>  2 files changed, 67 insertions(+), 39 deletions(-)
> 
> v1: initial patch
> v2: use separate devicetree binding
> v3: rebase onto 5.0-rc3
> 
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index 
> a8a2c728afba..350ce4c4fd52 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -621,17 +621,19 @@ static void mt7530_adjust_link(struct dsa_switch *ds, 
> int port,
>       struct mt7530_priv *priv = ds->priv;
>  
>       if (phy_is_pseudo_fixed_link(phydev)) {
> -             dev_dbg(priv->dev, "phy-mode for master device = %x\n",
> -                     phydev->interface);
> -
> -             /* Setup TX circuit incluing relevant PAD and driving */
> -             mt7530_pad_clk_setup(ds, phydev->interface);
> -
> -             /* Setup RX circuit, relevant PAD and driving on the host
> -              * which must be placed after the setup on the device side is
> -              * all finished.
> -              */
> -             mt7623_pad_clk_setup(ds);
> +             if (priv->id == ID_MT7530) {
> +                     dev_dbg(priv->dev, "phy-mode for master device = %x\n",
> +                             phydev->interface);
> +
> +                     /* Setup TX circuit incluing relevant PAD and driving */
> +                     mt7530_pad_clk_setup(ds, phydev->interface);
> +
> +                     /* Setup RX circuit, relevant PAD and driving on the
> +                      * host which must be placed after the setup on the
> +                      * device side is all finished.
> +                      */
> +                     mt7623_pad_clk_setup(ds);
> +             }
>       } else {
>               u16 lcl_adv = 0, rmt_adv = 0;
>               u8 flowctrl;
> @@ -687,6 +689,10 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv,
>       /* Unknown unicast frame fordwarding to the cpu port */
>       mt7530_set(priv, MT7530_MFC, UNU_FFP(BIT(port)));
>  
> +     /* Set CPU port number */
> +     if (priv->id == ID_MT7621)
> +             mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
> +
>       /* CPU port gets connected to all user ports of
>        * the switch
>        */
> @@ -1219,24 +1225,27 @@ mt7530_setup(struct dsa_switch *ds)
>        * as two netdev instances.
>        */
>       dn = ds->ports[MT7530_CPU_PORT].master->dev.of_node->parent;
> -     priv->ethernet = syscon_node_to_regmap(dn);
> -     if (IS_ERR(priv->ethernet))
> -             return PTR_ERR(priv->ethernet);
>  
> -     regulator_set_voltage(priv->core_pwr, 1000000, 1000000);
> -     ret = regulator_enable(priv->core_pwr);
> -     if (ret < 0) {
> -             dev_err(priv->dev,
> -                     "Failed to enable core power: %d\n", ret);
> -             return ret;
> -     }
> +     if (priv->id == ID_MT7530) {
> +             priv->ethernet = syscon_node_to_regmap(dn);
> +             if (IS_ERR(priv->ethernet))
> +                     return PTR_ERR(priv->ethernet);
> +
> +             regulator_set_voltage(priv->core_pwr, 1000000, 1000000);
> +             ret = regulator_enable(priv->core_pwr);
> +             if (ret < 0) {
> +                     dev_err(priv->dev,
> +                             "Failed to enable core power: %d\n", ret);
> +                     return ret;
> +             }
>  
> -     regulator_set_voltage(priv->io_pwr, 3300000, 3300000);
> -     ret = regulator_enable(priv->io_pwr);
> -     if (ret < 0) {
> -             dev_err(priv->dev, "Failed to enable io pwr: %d\n",
> -                     ret);
> -             return ret;
> +             regulator_set_voltage(priv->io_pwr, 3300000, 3300000);
> +             ret = regulator_enable(priv->io_pwr);
> +             if (ret < 0) {
> +                     dev_err(priv->dev, "Failed to enable io pwr: %d\n",
> +                             ret);
> +                     return ret;
> +             }
>       }
>  
>       /* Reset whole chip through gpio pin or memory-mapped registers for @@ 
> -1326,9 +1335,17 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
>       .port_vlan_del          = mt7530_port_vlan_del,
>  };
>  
> +static const struct of_device_id mt7530_of_match[] = {
> +     { .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, },
> +     { .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, },
> +     { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, mt7530_of_match);
> +
>  static int
>  mt7530_probe(struct mdio_device *mdiodev)  {
> +     const struct of_device_id *of_id;
>       struct mt7530_priv *priv;
>       struct device_node *dn;
>  
> @@ -1356,13 +1373,21 @@ mt7530_probe(struct mdio_device *mdiodev)
>               }
>       }
>  
> -     priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
> -     if (IS_ERR(priv->core_pwr))
> -             return PTR_ERR(priv->core_pwr);
> +     /* Get the hardware identifier from the devicetree node.
> +      * We will need it for some of the clock and regulator setup.
> +      */
> +     of_id = of_match_node(mt7530_of_match, dn);
> +     priv->id = (unsigned int)of_id->data;
>  

We could use of_device_get_match_data instead of the above two lines.

and could you help Cc linux-media...@lists.infradead.org if you have the
next version for the series ?

> -     priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
> -     if (IS_ERR(priv->io_pwr))
> -             return PTR_ERR(priv->io_pwr);
> +     if (priv->id == ID_MT7530) {
> +             priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
> +             if (IS_ERR(priv->core_pwr))
> +                     return PTR_ERR(priv->core_pwr);
> +
> +             priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
> +             if (IS_ERR(priv->io_pwr))
> +                     return PTR_ERR(priv->io_pwr);
> +     }
>  
>       /* Not MCM that indicates switch works as the remote standalone
>        * integrated circuit so the GPIO pin would be used to complete @@ 
> -1408,12 +1433,6 @@ mt7530_remove(struct mdio_device *mdiodev)
>       mutex_destroy(&priv->reg_mutex);
>  }
>  
> -static const struct of_device_id mt7530_of_match[] = {
> -     { .compatible = "mediatek,mt7530" },
> -     { /* sentinel */ },
> -};
> -MODULE_DEVICE_TABLE(of, mt7530_of_match);
> -
>  static struct mdio_driver mt7530_mdio_driver = {
>       .probe  = mt7530_probe,
>       .remove = mt7530_remove,
> diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h index 
> d9b407a22a58..a95ed958df5b 100644
> --- a/drivers/net/dsa/mt7530.h
> +++ b/drivers/net/dsa/mt7530.h
> @@ -19,6 +19,11 @@
>  #define MT7530_NUM_FDB_RECORDS               2048
>  #define MT7530_ALL_MEMBERS           0xff
>  
> +enum {
> +     ID_MT7530 = 0,
> +     ID_MT7621 = 1,
> +};
> +
>  #define      NUM_TRGMII_CTRL                 5
>  
>  #define TRGMII_BASE(x)                       (0x10000 + (x))
> @@ -36,6 +41,9 @@
>  #define  UNM_FFP(x)                  (((x) & 0xff) << 16)
>  #define  UNU_FFP(x)                  (((x) & 0xff) << 8)
>  #define  UNU_FFP_MASK                        UNU_FFP(~0)
> +#define  CPU_EN                              BIT(7)
> +#define  CPU_PORT(x)                 ((x) << 4)
> +#define  CPU_MASK                    (0xf << 4)
>  
>  /* Registers for address table access */
>  #define MT7530_ATA1                  0x74
> @@ -430,6 +438,7 @@ struct mt7530_priv {
>       struct regulator        *core_pwr;
>       struct regulator        *io_pwr;
>       struct gpio_desc        *reset;
> +     unsigned int            id;
>       bool                    mcm;
>  
>       struct mt7530_port      ports[MT7530_NUM_PORTS];
> --
> 2.17.1
> 






Reply via email to