/* select phy interface in top control domain */ switch (plat->phy_mode) { case PHY_INTERFACE_MODE_MII:
intf_val |= PHY_INTF_MII; break; case PHY_INTERFACE_MODE_RMII:
intf_val |= (PHY_INTF_RMII | rmii_rxc | rmii_clk_from_mac); 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 |= PHY_INTF_RGMII; break; default:
dev_err(plat->dev, "phy interface not supported\n"); return -EINVAL;
}
switch (plat->phy_mode) { case PHY_INTERFACE_MODE_MII: case PHY_INTERFACE_MODE_RMII: /* 550ps per stage for MII/RMII */
mac_delay->tx_delay /= 550;
mac_delay->rx_delay /= 550; break; case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_TXID: case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_ID: /* 170ps per stage for RGMII */
mac_delay->tx_delay /= 170;
mac_delay->rx_delay /= 170; break; default:
dev_err(plat->dev, "phy interface not supported\n"); break;
}
}
switch (plat->phy_mode) { case PHY_INTERFACE_MODE_MII: case PHY_INTERFACE_MODE_RMII: /* 550ps per stage for MII/RMII */
mac_delay->tx_delay *= 550;
mac_delay->rx_delay *= 550; break; case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_TXID: case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_ID: /* 170ps per stage for RGMII */
mac_delay->tx_delay *= 170;
mac_delay->rx_delay *= 170; break; default:
dev_err(plat->dev, "phy interface not supported\n"); break;
}
}
delay_val |= FIELD_PREP(ETH_DLY_RXC_ENABLE, !!mac_delay->rx_delay);
delay_val |= FIELD_PREP(ETH_DLY_RXC_STAGES, mac_delay->rx_delay);
delay_val |= FIELD_PREP(ETH_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 GTXC delay macro circuit. * The ingress timing can be adjusted by TXC delay macro circuit.
*/
delay_val |= FIELD_PREP(ETH_DLY_TXC_ENABLE, !!mac_delay->rx_delay);
delay_val |= FIELD_PREP(ETH_DLY_TXC_STAGES, mac_delay->rx_delay);
delay_val |= FIELD_PREP(ETH_DLY_TXC_INV, mac_delay->rx_inv);
delay_val |= FIELD_PREP(ETH_DLY_GTXC_ENABLE, !!mac_delay->tx_delay);
delay_val |= FIELD_PREP(ETH_DLY_GTXC_STAGES, mac_delay->tx_delay);
delay_val |= FIELD_PREP(ETH_DLY_GTXC_INV, mac_delay->tx_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(ETH_DLY_RXC_ENABLE, !!mac_delay->rx_delay);
delay_val |= FIELD_PREP(ETH_DLY_RXC_STAGES, mac_delay->rx_delay);
delay_val |= FIELD_PREP(ETH_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(ETH_DLY_TXC_ENABLE, !!mac_delay->rx_delay);
delay_val |= FIELD_PREP(ETH_DLY_TXC_STAGES, mac_delay->rx_delay);
delay_val |= FIELD_PREP(ETH_DLY_TXC_INV, mac_delay->rx_inv);
} /* tx_inv will inverse the tx clock inside mac relateive to * reference clock from external phy, * and this bit is located in the same register with fine-tune
*/ if (mac_delay->tx_inv)
fine_val = ETH_RMII_DLY_TX_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:
fine_val = ETH_FINE_DLY_GTXC | ETH_FINE_DLY_RXC;
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);
staticint mediatek_dwmac_clk_init(struct mediatek_dwmac_plat_data *plat)
{ conststruct mediatek_dwmac_variant *variant = plat->variant; int i, ret;
plat->clks = devm_kcalloc(plat->dev, variant->num_clks, sizeof(*plat->clks), GFP_KERNEL); if (!plat->clks) return -ENOMEM;
for (i = 0; i < variant->num_clks; i++)
plat->clks[i].id = variant->clk_list[i];
ret = devm_clk_bulk_get(plat->dev, variant->num_clks, plat->clks); if (ret) return ret;
/* The clock labeled as "rmii_internal" is needed only in RMII(when * MAC provides the reference clock), and useless for RGMII/MII or * RMII(when PHY provides the reference clock). * So, "rmii_internal" clock is got and configured only when * reference clock of RMII is from MAC.
*/ if (plat->rmii_clk_from_mac) {
plat->rmii_internal_clk = devm_clk_get(plat->dev, "rmii_internal"); if (IS_ERR(plat->rmii_internal_clk))
ret = PTR_ERR(plat->rmii_internal_clk);
} else {
plat->rmii_internal_clk = NULL;
}
if (variant->dwmac_set_phy_interface) {
ret = variant->dwmac_set_phy_interface(plat); if (ret) {
dev_err(plat->dev, "failed to set phy interface, err = %d\n", ret); return ret;
}
}
if (variant->dwmac_set_delay) {
ret = variant->dwmac_set_delay(plat); if (ret) {
dev_err(plat->dev, "failed to set delay value, err = %d\n", ret); return ret;
}
}
return 0;
}
staticint mediatek_dwmac_clks_config(void *priv, bool enabled)
{ struct mediatek_dwmac_plat_data *plat = priv; conststruct mediatek_dwmac_variant *variant = plat->variant; int ret = 0;
if (enabled) {
ret = clk_bulk_prepare_enable(variant->num_clks, plat->clks); if (ret) {
dev_err(plat->dev, "failed to enable clks, err = %d\n", ret); return ret;
}
ret = clk_prepare_enable(plat->rmii_internal_clk); if (ret) {
dev_err(plat->dev, "failed to enable rmii internal clk, err = %d\n", ret); return ret;
}
} else {
clk_disable_unprepare(plat->rmii_internal_clk);
clk_bulk_disable_unprepare(variant->num_clks, plat->clks);
}
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.