1126596Sbms// SPDX-License-Identifier: GPL-2.0+ 2127655Sbms/* 3127655Sbms * Copyright 2018, 2020 NXP 4127655Sbms * 5126596Sbms */ 6126596Sbms 7126596Sbms#include <common.h> 8126596Sbms#include <netdev.h> 9126596Sbms#include <exports.h> 10126596Sbms#include <fsl-mc/fsl_mc.h> 11126596Sbms#include "lx2160a.h" 12126596Sbms 13126596SbmsDECLARE_GLOBAL_DATA_PTR; 14126596Sbms 15126596Sbmsint board_eth_init(struct bd_info *bis) 16126596Sbms{ 17126596Sbms#ifdef CONFIG_PHY_AQUANTIA 18126596Sbms /* 19126596Sbms * Export functions to be used by AQ firmware 20126596Sbms * upload application 21126596Sbms */ 22126596Sbms gd->jt->strcpy = strcpy; 23126596Sbms gd->jt->mdelay = mdelay; 24126596Sbms gd->jt->mdio_get_current_dev = mdio_get_current_dev; 25126596Sbms gd->jt->phy_find_by_mask = phy_find_by_mask; 26126596Sbms gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname; 27126596Sbms gd->jt->miiphy_set_current_dev = miiphy_set_current_dev; 28126596Sbms#endif 29126596Sbms return pci_eth_init(bis); 30196155Ssam} 31131738Sru 32126596Sbms#if defined(CONFIG_RESET_PHY_R) 33126596Sbmsvoid reset_phy(void) 34126596Sbms{ 35196155Ssam#if defined(CONFIG_FSL_MC_ENET) 36126596Sbms mc_env_boot(); 37126596Sbms#endif 38126596Sbms} 39196155Ssam#endif /* CONFIG_RESET_PHY_R */ 40196155Ssam 41196155Ssamstatic int fdt_get_dpmac_node(void *fdt, int dpmac_id) 42196155Ssam{ 43196155Ssam char dpmac_str[11] = "dpmacs@00"; 44196155Ssam int offset, dpmacs_offset; 45196155Ssam 46196155Ssam /* get the dpmac offset */ 47196155Ssam dpmacs_offset = fdt_path_offset(fdt, "/soc/fsl-mc/dpmacs"); 48196155Ssam if (dpmacs_offset < 0) 49196155Ssam dpmacs_offset = fdt_path_offset(fdt, "/fsl-mc/dpmacs"); 50196155Ssam 51196155Ssam if (dpmacs_offset < 0) { 52196155Ssam printf("dpmacs node not found in device tree\n"); 53196155Ssam return dpmacs_offset; 54196155Ssam } 55196155Ssam 56196155Ssam sprintf(dpmac_str, "dpmac@%x", dpmac_id); 57196155Ssam offset = fdt_subnode_offset(fdt, dpmacs_offset, dpmac_str); 58196155Ssam if (offset < 0) { 59126596Sbms sprintf(dpmac_str, "ethernet@%x", dpmac_id); 60126596Sbms offset = fdt_subnode_offset(fdt, dpmacs_offset, dpmac_str); 61196155Ssam if (offset < 0) { 62196155Ssam printf("dpmac@%x/ethernet@%x node not found in device tree\n", 63196155Ssam dpmac_id, dpmac_id); 64237216Seadler return offset; 65196155Ssam } 66196155Ssam } 67196155Ssam 68196155Ssam return offset; 69126596Sbms} 70196155Ssam 71196155Ssamstatic int fdt_update_phy_addr(void *fdt, int dpmac_id, int phy_addr) 72196155Ssam{ 73196155Ssam char dpmac_str[] = "dpmacs@00"; 74127655Sbms const u32 *phyhandle; 75127655Sbms int offset; 76196155Ssam int err; 77196155Ssam 78196155Ssam /* get the dpmac offset */ 79196155Ssam offset = fdt_get_dpmac_node(fdt, dpmac_id); 80196155Ssam if (offset < 0) 81196155Ssam return offset; 82196155Ssam 83196155Ssam /* get dpmac phy-handle */ 84196155Ssam sprintf(dpmac_str, "dpmac@%x", dpmac_id); 85196155Ssam phyhandle = (u32 *)fdt_getprop(fdt, offset, "phy-handle", NULL); 86196155Ssam if (!phyhandle) { 87196155Ssam printf("%s node not found in device tree\n", dpmac_str); 88196155Ssam return offset; 89196155Ssam } 90196155Ssam 91196155Ssam offset = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*phyhandle)); 92196155Ssam if (offset < 0) { 93196155Ssam printf("Could not get the ph node offset for dpmac %d\n", 94127655Sbms dpmac_id); 95196155Ssam return offset; 96196155Ssam } 97196155Ssam 98196155Ssam phy_addr = cpu_to_fdt32(phy_addr); 99196155Ssam err = fdt_setprop(fdt, offset, "reg", &phy_addr, sizeof(phy_addr)); 100196155Ssam if (err < 0) { 101196155Ssam printf("Could not set phy node's reg for dpmac %d: %s.\n", 102196155Ssam dpmac_id, fdt_strerror(err)); 103196155Ssam return err; 104196155Ssam } 105196155Ssam 106196155Ssam return 0; 107126596Sbms} 108196155Ssam 109196155Ssamstatic int fdt_delete_phy_handle(void *fdt, int dpmac_id) 110196155Ssam{ 111196155Ssam const u32 *phyhandle; 112126596Sbms int offset; 113126596Sbms 114196155Ssam /* get the dpmac offset */ 115196155Ssam offset = fdt_get_dpmac_node(fdt, dpmac_id); 116196155Ssam if (offset < 0) 117196155Ssam return offset; 118196155Ssam 119196155Ssam /* verify if the node has a phy-handle */ 120196155Ssam phyhandle = (u32 *)fdt_getprop(fdt, offset, "phy-handle", NULL); 121196155Ssam if (!phyhandle) 122196155Ssam return 0; 123196155Ssam 124126596Sbms return fdt_delprop(fdt, offset, "phy-handle"); 125126596Sbms} 126196155Ssam 127126596Sbmsint fdt_fixup_board_phy_revc(void *fdt) 128196155Ssam{ 129196155Ssam int ret; 130196155Ssam 131131738Sru if (get_board_rev() < 'C') 132126596Sbms return 0; 133126596Sbms 134196155Ssam /* DPMACs 3,4 have their Aquantia PHYs at new addresses */ 135196155Ssam ret = fdt_update_phy_addr(fdt, 3, AQR113C_PHY_ADDR1); 136126596Sbms if (ret) 137196155Ssam return ret; 138196155Ssam 139126596Sbms ret = fdt_update_phy_addr(fdt, 4, AQR113C_PHY_ADDR2); 140196155Ssam if (ret) 141196155Ssam return ret; 142196155Ssam 143196155Ssam /* There is no PHY for the DPMAC2, so remove the phy-handle */ 144196155Ssam return fdt_delete_phy_handle(fdt, 2); 145196155Ssam} 146196155Ssam