// SPDX-License-Identifier: GPL-2.0-or-later /* * MediaTek 10GE SerDes XFI T-PHY driver * * Copyright (c) 2024 Daniel Golle <[email protected]> * Bc-bocun Chen <[email protected]> * based on mtk_usxgmii.c and mtk_sgmii.c found in MediaTek's SDK (GPL-2.0) * Copyright (c) 2022 MediaTek Inc. * Author: Henry Yen <[email protected]> */ #include <linux/module.h> #include <linux/device.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/io.h> #include <linux/clk.h> #include <linux/reset.h> #include <linux/phy.h> #include <linux/phy/phy.h> #include "phy-mtk-io.h" #define MTK_XFI_TPHY_NUM_CLOCKS … #define REG_DIG_GLB_70 … #define XTP_PCS_RX_EQ_IN_PROGRESS(x) … #define XTP_PCS_MODE_MASK … #define XTP_PCS_MODE(x) … #define XTP_PCS_RST_B … #define XTP_FRC_PCS_RST_B … #define XTP_PCS_PWD_SYNC_MASK … #define XTP_PCS_PWD_SYNC(x) … #define XTP_PCS_PWD_ASYNC_MASK … #define XTP_PCS_PWD_ASYNC(x) … #define XTP_FRC_PCS_PWD_ASYNC … #define XTP_PCS_UPDT … #define XTP_PCS_IN_FR_RG … #define REG_DIG_GLB_F4 … #define XFI_DPHY_PCS_SEL … #define XFI_DPHY_PCS_SEL_SGMII … #define XFI_DPHY_PCS_SEL_USXGMII … #define XFI_DPHY_AD_SGDT_FRC_EN … #define REG_DIG_LN_TRX_40 … #define XTP_LN_FRC_TX_DATA_EN … #define XTP_LN_TX_DATA_EN … #define REG_DIG_LN_TRX_B0 … #define XTP_LN_FRC_TX_MACCK_EN … #define XTP_LN_TX_MACCK_EN … #define REG_ANA_GLB_D0 … #define XTP_GLB_USXGMII_SEL_MASK … #define XTP_GLB_USXGMII_SEL(x) … #define XTP_GLB_USXGMII_EN … /** * struct mtk_xfi_tphy - run-time data of the XFI phy instance * @base: IO memory area to access phy registers. * @dev: Kernel device used to output prefixed debug info. * @reset: Reset control corresponding to the phy instance. * @clocks: All clocks required for the phy to operate. * @da_war: Enables work-around for 10GBase-R mode. */ struct mtk_xfi_tphy { … }; /** * mtk_xfi_tphy_setup() - Setup phy for specified interface mode. * @xfi_tphy: XFI phy instance. * @interface: Ethernet interface mode * * The setup function is the condensed result of combining the 5 functions which * setup the phy in MediaTek's GPL licensed public SDK sources. They can be found * in mtk_sgmii.c[1] as well as mtk_usxgmii.c[2]. * * Many magic values have been replaced by register and bit definitions, however, * that has not been possible in all cases. While the vendor driver uses a * sequence of 32-bit writes, here we try to only modify the actually required * bits. * * [1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/b72d6cba92bf9e29fb035c03052fa1e86664a25b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c * * [2]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/dec96a1d9b82cdcda4a56453fd0b453d4cab4b85/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c */ static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy, phy_interface_t interface) { … } /** * mtk_xfi_tphy_set_mode() - Setup phy for specified interface mode. * * @phy: Phy instance. * @mode: Only PHY_MODE_ETHERNET is supported. * @submode: An Ethernet interface mode. * * Validate selected mode and call function mtk_xfi_tphy_setup(). * * Return: * * %0 - OK * * %-EINVAL - invalid mode */ static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int submode) { … } /** * mtk_xfi_tphy_reset() - Reset the phy. * * @phy: Phy instance. * * Reset the phy using the external reset controller. * * Return: * %0 - OK */ static int mtk_xfi_tphy_reset(struct phy *phy) { … } /** * mtk_xfi_tphy_power_on() - Power-on the phy. * * @phy: Phy instance. * * Prepare and enable all clocks required for the phy to operate. * * Return: * See clk_bulk_prepare_enable(). */ static int mtk_xfi_tphy_power_on(struct phy *phy) { … } /** * mtk_xfi_tphy_power_off() - Power-off the phy. * * @phy: Phy instance. * * Disable and unprepare all clocks previously enabled. * * Return: * See clk_bulk_prepare_disable(). */ static int mtk_xfi_tphy_power_off(struct phy *phy) { … } static const struct phy_ops mtk_xfi_tphy_ops = …; /** * mtk_xfi_tphy_probe() - Probe phy instance from Device Tree. * @pdev: Matching platform device. * * The probe function gets IO resource, clocks, reset controller and * whether the DA work-around for 10GBase-R is required from Device Tree and * allocates memory for holding that information in a struct mtk_xfi_tphy. * * Return: * * %0 - OK * * %-ENODEV - Missing associated Device Tree node (should never happen). * * %-ENOMEM - Out of memory. * * Any error value which devm_platform_ioremap_resource(), * devm_clk_bulk_get(), devm_reset_control_get_exclusive(), * devm_phy_create() or devm_of_phy_provider_register() may return. */ static int mtk_xfi_tphy_probe(struct platform_device *pdev) { … } static const struct of_device_id mtk_xfi_tphy_match[] = …; MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match); static struct platform_driver mtk_xfi_tphy_driver = …; module_platform_driver(…) …; MODULE_DESCRIPTION(…) …; MODULE_AUTHOR(…) …; MODULE_AUTHOR(…) …; MODULE_LICENSE(…) …;