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