/** * struct modctrl_match - Matching table entry for convctrl configuration * See section 8.2.1 of manual. * @mode_cfg: Configuration value for convctrl * @conv: Configuration of ethernet port muxes. First index is SWITCH_PORTIN, * then index 1 - 5 are CONV1 - CONV5.
*/ struct modctrl_match {
u32 mode_cfg;
u8 conv[MIIC_MODCTRL_CONF_CONV_NUM];
};
/** * struct miic - MII converter structure * @base: base address of the MII converter * @dev: Device associated to the MII converter * @lock: Lock used for read-modify-write access
*/ struct miic { void __iomem *base; struct device *dev;
spinlock_t lock;
};
/** * struct miic_port - Per port MII converter struct * @miic: backiling to MII converter structure * @pcs: PCS structure associated to the port * @port: port number * @interface: interface mode of the port
*/ struct miic_port { struct miic *miic; struct phylink_pcs pcs; int port;
phy_interface_t interface;
};
switch (interface) { case PHY_INTERFACE_MODE_RMII:
conv_mode = CONV_MODE_RMII;
speed = CONV_MODE_100MBPS; break; case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_TXID: case PHY_INTERFACE_MODE_RGMII_RXID:
conv_mode = CONV_MODE_RGMII;
speed = CONV_MODE_1000MBPS; break; case PHY_INTERFACE_MODE_MII:
conv_mode = CONV_MODE_MII; /* When in MII mode, speed should be set to 0 (which is actually * CONV_MODE_10MBPS)
*/
speed = CONV_MODE_10MBPS; break; default: return -EOPNOTSUPP;
}
val = FIELD_PREP(MIIC_CONVCTRL_CONV_MODE, conv_mode);
mask = MIIC_CONVCTRL_CONV_MODE;
/* Update speed only if we are going to change the interface because * the link might already be up and it would break it if the speed is * changed.
*/ if (interface != miic_port->interface) {
val |= FIELD_PREP(MIIC_CONVCTRL_CONV_SPEED, speed);
mask |= MIIC_CONVCTRL_CONV_SPEED;
miic_port->interface = interface;
}
/* 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;
staticint miic_init_hw(struct miic *miic, u32 cfg_mode)
{ int port;
/* Unlock write access to accessory registers (cf datasheet). If this * is going to be used in conjunction with the Cortex-M3, this sequence * will have to be moved in register write
*/
miic_reg_writel(miic, MIIC_PRCMD, 0x00A5);
miic_reg_writel(miic, MIIC_PRCMD, 0x0001);
miic_reg_writel(miic, MIIC_PRCMD, 0xFFFE);
miic_reg_writel(miic, MIIC_PRCMD, 0x0001);
for (port = 0; port < MIIC_MAX_NR_PORTS; port++) {
miic_converter_enable(miic, port, 0); /* Disable speed/duplex control from these registers, datasheet * says switch registers should be used to setup switch port * speed and duplex.
*/
miic_reg_writel(miic, MIIC_SWCTRL, 0x0);
miic_reg_writel(miic, MIIC_SWDUPC, 0x0);
}
return 0;
}
staticbool miic_modctrl_match(s8 table_val[MIIC_MODCTRL_CONF_CONV_NUM],
s8 dt_val[MIIC_MODCTRL_CONF_CONV_NUM])
{ int i;
for (i = 0; i < MIIC_MODCTRL_CONF_CONV_NUM; i++) { if (dt_val[i] == MIIC_MODCTRL_CONF_NONE) continue;
for (i = 0; i < MIIC_MODCTRL_CONF_CONV_NUM; i++) { if (conf[i] != MIIC_MODCTRL_CONF_NONE)
conf_name = conf_to_string[conf[i]]; else
conf_name = "NONE";
ret = devm_pm_runtime_enable(dev); if (ret < 0) return ret;
ret = pm_runtime_resume_and_get(dev); if (ret < 0) return ret;
ret = miic_init_hw(miic, mode_cfg); if (ret) goto disable_runtime_pm;
/* miic_create() relies on that fact that data are attached to the * platform device to determine if the driver is ready so this needs to * be the last thing to be done after everything is initialized * properly.
*/
platform_set_drvdata(pdev, miic);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.