1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2012 Freescale Semiconductor, Inc. 4 * Andy Fleming <afleming@gmail.com> 5 * Roy Zang <tie-fei.zang@freescale.com> 6 * Some part is taken from tsec.c 7 */ 8 #include <common.h> 9 #include <miiphy.h> 10 #include <phy.h> 11 #include <asm/io.h> 12 #include <fsl_memac.h> 13 #include <fm_eth.h> 14 15 #ifdef CONFIG_SYS_MEMAC_LITTLE_ENDIAN 16 #define memac_out_32(a, v) out_le32(a, v) 17 #define memac_clrbits_32(a, v) clrbits_le32(a, v) 18 #define memac_setbits_32(a, v) setbits_le32(a, v) 19 #else 20 #define memac_out_32(a, v) out_be32(a, v) 21 #define memac_clrbits_32(a, v) clrbits_be32(a, v) 22 #define memac_setbits_32(a, v) setbits_be32(a, v) 23 #endif 24 25 static u32 memac_in_32(u32 *reg) 26 { 27 #ifdef CONFIG_SYS_MEMAC_LITTLE_ENDIAN 28 return in_le32(reg); 29 #else 30 return in_be32(reg); 31 #endif 32 } 33 34 /* 35 * Write value to the PHY for this device to the register at regnum, waiting 36 * until the write is done before it returns. All PHY configuration has to be 37 * done through the TSEC1 MIIM regs 38 */ 39 int memac_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr, 40 int regnum, u16 value) 41 { 42 u32 mdio_ctl; 43 struct memac_mdio_controller *regs = bus->priv; 44 u32 c45 = 1; /* Default to 10G interface */ 45 46 if (dev_addr == MDIO_DEVAD_NONE) { 47 c45 = 0; /* clause 22 */ 48 dev_addr = regnum & 0x1f; 49 memac_clrbits_32(®s->mdio_stat, MDIO_STAT_ENC); 50 } else 51 memac_setbits_32(®s->mdio_stat, MDIO_STAT_ENC); 52 53 /* Wait till the bus is free */ 54 while ((memac_in_32(®s->mdio_stat)) & MDIO_STAT_BSY) 55 ; 56 57 /* Set the port and dev addr */ 58 mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); 59 memac_out_32(®s->mdio_ctl, mdio_ctl); 60 61 /* Set the register address */ 62 if (c45) 63 memac_out_32(®s->mdio_addr, regnum & 0xffff); 64 65 /* Wait till the bus is free */ 66 while ((memac_in_32(®s->mdio_stat)) & MDIO_STAT_BSY) 67 ; 68 69 /* Write the value to the register */ 70 memac_out_32(®s->mdio_data, MDIO_DATA(value)); 71 72 /* Wait till the MDIO write is complete */ 73 while ((memac_in_32(®s->mdio_data)) & MDIO_DATA_BSY) 74 ; 75 76 return 0; 77 } 78 79 /* 80 * Reads from register regnum in the PHY for device dev, returning the value. 81 * Clears miimcom first. All PHY configuration has to be done through the 82 * TSEC1 MIIM regs 83 */ 84 int memac_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr, 85 int regnum) 86 { 87 u32 mdio_ctl; 88 struct memac_mdio_controller *regs = bus->priv; 89 u32 c45 = 1; 90 91 if (dev_addr == MDIO_DEVAD_NONE) { 92 if (!strcmp(bus->name, DEFAULT_FM_TGEC_MDIO_NAME)) 93 return 0xffff; 94 c45 = 0; /* clause 22 */ 95 dev_addr = regnum & 0x1f; 96 memac_clrbits_32(®s->mdio_stat, MDIO_STAT_ENC); 97 } else 98 memac_setbits_32(®s->mdio_stat, MDIO_STAT_ENC); 99 100 /* Wait till the bus is free */ 101 while ((memac_in_32(®s->mdio_stat)) & MDIO_STAT_BSY) 102 ; 103 104 /* Set the Port and Device Addrs */ 105 mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); 106 memac_out_32(®s->mdio_ctl, mdio_ctl); 107 108 /* Set the register address */ 109 if (c45) 110 memac_out_32(®s->mdio_addr, regnum & 0xffff); 111 112 /* Wait till the bus is free */ 113 while ((memac_in_32(®s->mdio_stat)) & MDIO_STAT_BSY) 114 ; 115 116 /* Initiate the read */ 117 mdio_ctl |= MDIO_CTL_READ; 118 memac_out_32(®s->mdio_ctl, mdio_ctl); 119 120 /* Wait till the MDIO write is complete */ 121 while ((memac_in_32(®s->mdio_data)) & MDIO_DATA_BSY) 122 ; 123 124 /* Return all Fs if nothing was there */ 125 if (memac_in_32(®s->mdio_stat) & MDIO_STAT_RD_ER) 126 return 0xffff; 127 128 return memac_in_32(®s->mdio_data) & 0xffff; 129 } 130 131 int memac_mdio_reset(struct mii_dev *bus) 132 { 133 return 0; 134 } 135 136 int fm_memac_mdio_init(bd_t *bis, struct memac_mdio_info *info) 137 { 138 struct mii_dev *bus = mdio_alloc(); 139 140 if (!bus) { 141 printf("Failed to allocate FM TGEC MDIO bus\n"); 142 return -1; 143 } 144 145 bus->read = memac_mdio_read; 146 bus->write = memac_mdio_write; 147 bus->reset = memac_mdio_reset; 148 strcpy(bus->name, info->name); 149 150 bus->priv = info->regs; 151 152 /* 153 * On some platforms like B4860, default value of MDIO_CLK_DIV bits 154 * in mdio_stat(mdio_cfg) register generates MDIO clock too high 155 * (much higher than 2.5MHz), violating the IEEE specs. 156 * On other platforms like T1040, default value of MDIO_CLK_DIV bits 157 * is zero, so MDIO clock is disabled. 158 * So, for proper functioning of MDIO, MDIO_CLK_DIV bits needs to 159 * be properly initialized. 160 * NEG bit default should be '1' as per FMAN-v3 RM, but on platform 161 * like T2080QDS, this bit default is '0', which leads to MDIO failure 162 * on XAUI PHY, so set this bit definitely. 163 */ 164 memac_setbits_32( 165 &((struct memac_mdio_controller *)info->regs)->mdio_stat, 166 MDIO_STAT_CLKDIV(258) | MDIO_STAT_NEG); 167 168 return mdio_register(bus); 169 } 170