diff options
Diffstat (limited to 'drivers/net/pcs/pcs-rzn1-miic.c')
-rw-r--r-- | drivers/net/pcs/pcs-rzn1-miic.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c index d93f84fbb1fd..d79bb9b06cd2 100644 --- a/drivers/net/pcs/pcs-rzn1-miic.c +++ b/drivers/net/pcs/pcs-rzn1-miic.c @@ -183,7 +183,7 @@ static void miic_converter_enable(struct miic *miic, int port, int enable) miic_reg_rmw(miic, MIIC_CONVRST, MIIC_CONVRST_PHYIF_RST(port), val); } -static int miic_config(struct phylink_pcs *pcs, unsigned int mode, +static int miic_config(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, const unsigned long *advertising, bool permit) { @@ -234,7 +234,7 @@ static int miic_config(struct phylink_pcs *pcs, unsigned int mode, return 0; } -static void miic_link_up(struct phylink_pcs *pcs, unsigned int mode, +static void miic_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, int speed, int duplex) { struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs); @@ -268,21 +268,37 @@ static void miic_link_up(struct phylink_pcs *pcs, unsigned int mode, (MIIC_CONVCTRL_CONV_SPEED | MIIC_CONVCTRL_FULLD), val); } -static int miic_validate(struct phylink_pcs *pcs, unsigned long *supported, - const struct phylink_link_state *state) +static int miic_pre_init(struct phylink_pcs *pcs) { - if (phy_interface_mode_is_rgmii(state->interface) || - state->interface == PHY_INTERFACE_MODE_RMII || - state->interface == PHY_INTERFACE_MODE_MII) - return 1; + struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs); + struct miic *miic = miic_port->miic; + u32 val, mask; + + /* Start RX clock if required */ + if (pcs->rxc_always_on) { + /* In MII through mode, the clock signals will be driven by the + * external PHY, which might not be initialized yet. Set RMII + * as default mode to ensure that a reference clock signal is + * generated. + */ + miic_port->interface = PHY_INTERFACE_MODE_RMII; - return -EINVAL; + val = FIELD_PREP(MIIC_CONVCTRL_CONV_MODE, CONV_MODE_RMII) | + FIELD_PREP(MIIC_CONVCTRL_CONV_SPEED, CONV_MODE_100MBPS); + mask = MIIC_CONVCTRL_CONV_MODE | MIIC_CONVCTRL_CONV_SPEED; + + miic_reg_rmw(miic, MIIC_CONVCTRL(miic_port->port), mask, val); + + miic_converter_enable(miic, miic_port->port, 1); + } + + return 0; } static const struct phylink_pcs_ops miic_phylink_ops = { - .pcs_validate = miic_validate, .pcs_config = miic_config, .pcs_link_up = miic_link_up, + .pcs_pre_init = miic_pre_init, }; struct phylink_pcs *miic_create(struct device *dev, struct device_node *np) @@ -334,6 +350,10 @@ struct phylink_pcs *miic_create(struct device *dev, struct device_node *np) miic_port->port = port - 1; miic_port->pcs.ops = &miic_phylink_ops; + phy_interface_set_rgmii(miic_port->pcs.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_RMII, miic_port->pcs.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_MII, miic_port->pcs.supported_interfaces); + return &miic_port->pcs; } EXPORT_SYMBOL(miic_create); @@ -443,13 +463,10 @@ static int miic_parse_dt(struct device *dev, u32 *mode_cfg) if (of_property_read_u32(np, "renesas,miic-switch-portin", &conf) == 0) dt_val[0] = conf; - for_each_child_of_node(np, conv) { + for_each_available_child_of_node(np, conv) { if (of_property_read_u32(conv, "reg", &port)) continue; - if (!of_device_is_available(conv)) - continue; - if (of_property_read_u32(conv, "renesas,miic-input", &conf) == 0) dt_val[port] = conf; } @@ -523,7 +540,7 @@ static struct platform_driver miic_driver = { .of_match_table = miic_of_mtable, }, .probe = miic_probe, - .remove_new = miic_remove, + .remove = miic_remove, }; module_platform_driver(miic_driver); |