Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / mips / mach-mscc / phy.c
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Copyright (c) 2018 Microsemi Corporation
4  */
5
6 #include <common.h>
7 #include <log.h>
8 #include <asm/io.h>
9
10 int 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
57 int 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
68 int 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 }