1*441a065aSBharat Gooty /* 2*441a065aSBharat Gooty * Copyright (c) 2016 - 2021, Broadcom 3*441a065aSBharat Gooty * 4*441a065aSBharat Gooty * SPDX-License-Identifier: BSD-3-Clause 5*441a065aSBharat Gooty */ 6*441a065aSBharat Gooty #include <string.h> 7*441a065aSBharat Gooty 8*441a065aSBharat Gooty #include <platform_def.h> 9*441a065aSBharat Gooty 10*441a065aSBharat Gooty #include <common/debug.h> 11*441a065aSBharat Gooty #include <drivers/delay_timer.h> 12*441a065aSBharat Gooty #include <lib/mmio.h> 13*441a065aSBharat Gooty #include <mdio.h> 14*441a065aSBharat Gooty 15*441a065aSBharat Gooty static int mdio_op_status(uint32_t result) 16*441a065aSBharat Gooty { 17*441a065aSBharat Gooty uint32_t timeout = 1000000U; /* loop for 1s */ 18*441a065aSBharat Gooty uint32_t val; 19*441a065aSBharat Gooty 20*441a065aSBharat Gooty do { 21*441a065aSBharat Gooty val = mmio_read_32(CMIC_MIIM_STAT); 22*441a065aSBharat Gooty if ((val & MDIO_STAT_DONE) == result) { 23*441a065aSBharat Gooty return 0; 24*441a065aSBharat Gooty } 25*441a065aSBharat Gooty 26*441a065aSBharat Gooty udelay(1U); 27*441a065aSBharat Gooty } while (timeout-- != 0U); 28*441a065aSBharat Gooty return -1; 29*441a065aSBharat Gooty } 30*441a065aSBharat Gooty 31*441a065aSBharat Gooty static int mdio_op(uint16_t busid, uint16_t phyid, uint32_t reg, 32*441a065aSBharat Gooty uint16_t val, uint8_t op) 33*441a065aSBharat Gooty { 34*441a065aSBharat Gooty uint32_t param; 35*441a065aSBharat Gooty int ret; 36*441a065aSBharat Gooty 37*441a065aSBharat Gooty mmio_write_32(CMIC_MIIM_CTRL, 0U); 38*441a065aSBharat Gooty ret = mdio_op_status(0U); 39*441a065aSBharat Gooty if (ret != 0) { 40*441a065aSBharat Gooty goto err; 41*441a065aSBharat Gooty } 42*441a065aSBharat Gooty 43*441a065aSBharat Gooty param = 0U; 44*441a065aSBharat Gooty param |= 1U << MDIO_PARAM_INTERNAL_SEL; 45*441a065aSBharat Gooty param |= (busid & MDIO_PARAM_BUSID_MASK) << MDIO_PARAM_BUSID; 46*441a065aSBharat Gooty param |= (phyid & MDIO_PARAM_PHYID_MASK) << MDIO_PARAM_PHYID; 47*441a065aSBharat Gooty param |= (val & MDIO_PARAM_DATA_MASK) << MDIO_PARAM_DATA; 48*441a065aSBharat Gooty 49*441a065aSBharat Gooty mmio_write_32(CMIC_MIIM_PARAM, param); 50*441a065aSBharat Gooty 51*441a065aSBharat Gooty mmio_write_32(CMIC_MIIM_ADDRESS, reg); 52*441a065aSBharat Gooty 53*441a065aSBharat Gooty mmio_write_32(CMIC_MIIM_CTRL, op); 54*441a065aSBharat Gooty 55*441a065aSBharat Gooty ret = mdio_op_status(1U); 56*441a065aSBharat Gooty if (ret != 0) { 57*441a065aSBharat Gooty goto err; 58*441a065aSBharat Gooty } 59*441a065aSBharat Gooty 60*441a065aSBharat Gooty if (op == MDIO_CTRL_READ_OP) { 61*441a065aSBharat Gooty ret = mmio_read_32(CMIC_MIIM_READ_DATA) & MDIO_READ_DATA_MASK; 62*441a065aSBharat Gooty } 63*441a065aSBharat Gooty err: 64*441a065aSBharat Gooty return ret; 65*441a065aSBharat Gooty } 66*441a065aSBharat Gooty 67*441a065aSBharat Gooty int mdio_write(uint16_t busid, uint16_t phyid, uint32_t reg, uint16_t val) 68*441a065aSBharat Gooty { 69*441a065aSBharat Gooty int ret; 70*441a065aSBharat Gooty 71*441a065aSBharat Gooty ret = mdio_op(busid, phyid, reg, val, MDIO_CTRL_WRITE_OP); 72*441a065aSBharat Gooty if (ret == -1) { 73*441a065aSBharat Gooty INFO("MDIO write fail\n"); 74*441a065aSBharat Gooty } 75*441a065aSBharat Gooty return ret; 76*441a065aSBharat Gooty } 77*441a065aSBharat Gooty 78*441a065aSBharat Gooty int mdio_read(uint16_t busid, uint16_t phyid, uint32_t reg) 79*441a065aSBharat Gooty { 80*441a065aSBharat Gooty int ret; 81*441a065aSBharat Gooty 82*441a065aSBharat Gooty ret = mdio_op(busid, phyid, reg, 0U, MDIO_CTRL_READ_OP); 83*441a065aSBharat Gooty if (ret == -1) { 84*441a065aSBharat Gooty INFO("MDIO read fail\n"); 85*441a065aSBharat Gooty } 86*441a065aSBharat Gooty return ret; 87*441a065aSBharat Gooty } 88