aboutsummaryrefslogtreecommitdiff
path: root/drivers/brcm/mdio/mdio.c
blob: 1cf9d668aa7ff83b91dc4a44fc080e431ff23f51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
 * Copyright (c) 2016 - 2021, Broadcom
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#include <string.h>

#include <platform_def.h>

#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <mdio.h>

static int mdio_op_status(uint32_t result)
{
	uint32_t timeout = 1000000U; /* loop for 1s */
	uint32_t val;

	do {
		val = mmio_read_32(CMIC_MIIM_STAT);
		if ((val & MDIO_STAT_DONE) == result) {
			return 0;
		}

		udelay(1U);
	} while (timeout-- != 0U);
	return -1;
}

static int mdio_op(uint16_t busid, uint16_t phyid, uint32_t reg,
	       uint16_t val, uint8_t op)
{
	uint32_t param;
	int ret;

	mmio_write_32(CMIC_MIIM_CTRL, 0U);
	ret = mdio_op_status(0U);
	if (ret != 0) {
		goto err;
	}

	param = 0U;
	param |= 1U << MDIO_PARAM_INTERNAL_SEL;
	param |= (busid & MDIO_PARAM_BUSID_MASK) << MDIO_PARAM_BUSID;
	param |= (phyid & MDIO_PARAM_PHYID_MASK) << MDIO_PARAM_PHYID;
	param |= (val & MDIO_PARAM_DATA_MASK) << MDIO_PARAM_DATA;

	mmio_write_32(CMIC_MIIM_PARAM, param);

	mmio_write_32(CMIC_MIIM_ADDRESS, reg);

	mmio_write_32(CMIC_MIIM_CTRL, op);

	ret = mdio_op_status(1U);
	if (ret != 0) {
		goto err;
	}

	if (op == MDIO_CTRL_READ_OP) {
		ret = mmio_read_32(CMIC_MIIM_READ_DATA) & MDIO_READ_DATA_MASK;
	}
err:
	return ret;
}

int mdio_write(uint16_t busid, uint16_t phyid, uint32_t reg, uint16_t val)
{
	int ret;

	ret = mdio_op(busid, phyid, reg, val, MDIO_CTRL_WRITE_OP);
	if (ret == -1) {
		INFO("MDIO write fail\n");
	}
	return ret;
}

int mdio_read(uint16_t busid, uint16_t phyid, uint32_t reg)
{
	int ret;

	ret = mdio_op(busid, phyid, reg, 0U, MDIO_CTRL_READ_OP);
	if (ret == -1) {
		INFO("MDIO read fail\n");
	}
	return ret;
}