blob: 83d3e5bdd28f63e7ba9d9cb530f7d947f3f5790d [file] [log] [blame]
Lars Povlsen0ee16642018-12-20 09:56:02 +01001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2018 Microsemi Corporation
4 */
5
6#include <common.h>
Simon Glass0f2af882020-05-10 11:40:05 -06007#include <log.h>
Lars Povlsen0ee16642018-12-20 09:56:02 +01008#include <asm/io.h>
9
10int mscc_phy_rd_wr(u8 read,
11 u32 miimdev,
12 u8 miim_addr,
13 u8 addr,
14 u16 *value)
15{
16 u32 data;
17 int i;
18
19 /* Command part */
20 data = (read ? MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(2) : /* Read */
21 MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(1) | /* Write */
22 MSCC_F_MII_CMD_MIIM_CMD_WRDATA(*value)); /* value */
23
24 /* Addressing part */
25 data |=
26 MSCC_F_MII_CMD_MIIM_CMD_VLD(1) | /* Valid command */
27 MSCC_F_MII_CMD_MIIM_CMD_REGAD(addr) | /* Reg addr */
28 MSCC_F_MII_CMD_MIIM_CMD_PHYAD(miim_addr); /* Miim addr */
29
30 /* Enqueue MIIM operation to be executed */
31 writel(data, BASE_DEVCPU_GCB + MIIM_MII_CMD(miimdev));
32
33 /* Wait for MIIM operation to finish */
34 i = 0;
35 do {
36 if (i++ > 100) {
37 debug("Miim timeout");
38 return -1;
39 }
40 data = readl(BASE_DEVCPU_GCB + MIIM_MII_STATUS(miimdev));
41 debug("Read status miim(%d): 0x%08x\n", miimdev, data);
42 } while (data & MSCC_F_MII_STATUS_MIIM_STAT_BUSY(1));
43
44 if (read) {
45 data = readl(BASE_DEVCPU_GCB + MIIM_MII_DATA(miimdev));
46 if (data & MSCC_M_MII_DATA_MIIM_DATA_SUCCESS) {
47 debug("Read(%d, %d) returned 0x%08x\n",
48 miim_addr, addr, data);
49 return -1;
50 }
51 *value = MSCC_X_MII_DATA_MIIM_DATA_RDDATA(data);
52 }
53
54 return 0;
55}
56
57int mscc_phy_rd(u32 miimdev,
58 u8 miim_addr,
59 u8 addr,
60 u16 *value)
61{
62 if (mscc_phy_rd_wr(1, miimdev, miim_addr, addr, value) == 0)
63 return 0;
64 debug("Read(%d, %d) returned error\n", miim_addr, addr);
65 return -1;
66}
67
68int mscc_phy_wr(u32 miimdev,
69 u8 miim_addr,
70 u8 addr,
71 u16 value)
72{
73 return mscc_phy_rd_wr(0, miimdev, miim_addr, addr, &value);
74}