summaryrefslogtreecommitdiff
path: root/drivers/net/pcs/pcs-rzn1-miic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcs/pcs-rzn1-miic.c')
-rw-r--r--drivers/net/pcs/pcs-rzn1-miic.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c
index 4bd66fdde367..d79bb9b06cd2 100644
--- a/drivers/net/pcs/pcs-rzn1-miic.c
+++ b/drivers/net/pcs/pcs-rzn1-miic.c
@@ -268,21 +268,37 @@ static void miic_link_up(struct phylink_pcs *pcs, unsigned int neg_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)
@@ -333,7 +349,10 @@ struct phylink_pcs *miic_create(struct device *dev, struct device_node *np)
miic_port->miic = miic;
miic_port->port = port - 1;
miic_port->pcs.ops = &miic_phylink_ops;
- miic_port->pcs.neg_mode = true;
+
+ 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;
}
@@ -444,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;
}
@@ -524,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);