// SPDX-License-Identifier: GPL-2.0+ /* Copyright (c) 2016 Broadcom Corporation All Rights Reserved */ /* * Created on: June 2017 * Author: dima.mamut@broadcom.com */ /* * MDIO driver for BCM96846 6856 and 6878 */ #include "os_dep.h" #include "mdio_drv_impl5.h" #include "dt_access.h" static uintptr_t mdio_base; static uintptr_t pMdioMasterSelect; static int mdio_probe(dt_device_t *pdev) { int ret; mdio_base = dt_dev_remap_resource(pdev, 0); if (IS_ERR(mdio_base)) { ret = PTR_ERR(mdio_base); mdio_base = NULL; dev_err(&pdev->dev, "Missing mdio_base entry\n"); goto Exit; } pMdioMasterSelect = dt_dev_remap_resource(pdev, 1); if (IS_ERR(pMdioMasterSelect)) { ret = PTR_ERR(pMdioMasterSelect); pMdioMasterSelect = NULL; dev_err(&pdev->dev, "Missing MdioMasterSelect entry\n"); goto Exit; } dev_dbg(&pdev->dev, "mdio_base=0x%lx\n", mdio_base); dev_dbg(&pdev->dev, "pMdioMasterSelect=0x%lx\n", pMdioMasterSelect); dev_info(&pdev->dev, "registered\n"); return 0; Exit: return ret; } #ifdef __UBOOT__ static const struct udevice_id mdio_ids[] = { #if defined(CONFIG_BCM63146) || defined(CONFIG_BCM4912) { .compatible = "brcm,mdio-sf2" }, //FIXME! redirect mdio-sf2 to mdio5 for now #else { .compatible = "brcm,mdio5" }, #endif { /* end of list */ }, }; U_BOOT_DRIVER(brcm_mdio) = { .name = "brcm-mdio", .id = UCLASS_MISC, .of_match = mdio_ids, .probe = mdio_probe, }; #else static const struct of_device_id of_platform_table[] = { { .compatible = "brcm,mdio5" }, { /* end of list */ }, }; static struct platform_driver of_platform_driver = { .driver = { .name = "brcm-mdio", .of_match_table = of_platform_table, }, .probe = mdio_probe, }; module_platform_driver(of_platform_driver); #endif #define MDIO_CMD (void *)mdio_base static DEFINE_SPINLOCK(mdio_access); static void mdio_cfg_type(mdio_type_t type) { #if defined(CONFIG_BCM63146) || defined(CONFIG_BCM4912) if (type != MDIO_INT) #else if (type == MDIO_INT) #endif *(uint32_t *)pMdioMasterSelect = 0; else *(uint32_t *)pMdioMasterSelect = 1; } int32_t mdio_read_c22_register(mdio_type_t type, uint32_t addr, uint32_t reg, uint16_t *val) { int ret = MDIO_OK; spin_lock_bh(&mdio_access); mdio_cfg_type(type); ret = mdio_cmd_read_22(MDIO_CMD, addr, reg, val); spin_unlock_bh(&mdio_access); return ret; } EXPORT_SYMBOL(mdio_read_c22_register); int32_t mdio_write_c22_register(mdio_type_t type, uint32_t addr, uint32_t reg, uint16_t val) { int ret = MDIO_OK; spin_lock_bh(&mdio_access); mdio_cfg_type(type); ret = mdio_cmd_write_22(MDIO_CMD, addr, reg, val); spin_unlock_bh(&mdio_access); return ret; } EXPORT_SYMBOL(mdio_write_c22_register); int32_t mdio_read_c45_register(mdio_type_t type, uint32_t addr, uint32_t dev, uint16_t reg, uint16_t *val) { int ret = MDIO_OK; spin_lock_bh(&mdio_access); mdio_cfg_type(type); ret = mdio_cmd_read_45(MDIO_CMD, addr, dev, reg, val); spin_unlock_bh(&mdio_access); return ret; } EXPORT_SYMBOL(mdio_read_c45_register); int32_t mdio_write_c45_register(mdio_type_t type, uint32_t addr, uint32_t dev, uint16_t reg, uint16_t val) { int ret = MDIO_OK; spin_lock_bh(&mdio_access); mdio_cfg_type(type); ret = mdio_cmd_write_45(MDIO_CMD, addr, dev, reg, val); spin_unlock_bh(&mdio_access); return ret; } EXPORT_SYMBOL(mdio_write_c45_register);