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