Merge tag 'rpi-next-2019.10' of https://github.com/mbgg/u-boot
[oweals/u-boot.git] / drivers / net / fsl_enetc_mdio.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * ENETC ethernet controller driver
4  * Copyright 2019 NXP
5  */
6
7 #include <common.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <pci.h>
11 #include <miiphy.h>
12 #include <asm/io.h>
13 #include <asm/processor.h>
14 #include <miiphy.h>
15
16 #include "fsl_enetc.h"
17
18 static void enetc_mdio_wait_bsy(struct enetc_mdio_priv *priv)
19 {
20         while (enetc_read(priv, ENETC_MDIO_CFG) & ENETC_EMDIO_CFG_BSY)
21                 cpu_relax();
22 }
23
24 int enetc_mdio_read_priv(struct enetc_mdio_priv *priv, int addr, int devad,
25                          int reg)
26 {
27         if (devad == MDIO_DEVAD_NONE)
28                 enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C22);
29         else
30                 enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C45);
31         enetc_mdio_wait_bsy(priv);
32
33         if (devad == MDIO_DEVAD_NONE) {
34                 enetc_write(priv, ENETC_MDIO_CTL, ENETC_MDIO_CTL_READ |
35                             (addr << 5) | reg);
36         } else {
37                 enetc_write(priv, ENETC_MDIO_CTL, (addr << 5) + devad);
38                 enetc_mdio_wait_bsy(priv);
39
40                 enetc_write(priv, ENETC_MDIO_STAT, reg);
41                 enetc_mdio_wait_bsy(priv);
42
43                 enetc_write(priv, ENETC_MDIO_CTL, ENETC_MDIO_CTL_READ |
44                             (addr << 5) | devad);
45         }
46
47         enetc_mdio_wait_bsy(priv);
48         if (enetc_read(priv, ENETC_MDIO_CFG) & ENETC_EMDIO_CFG_RD_ER)
49                 return ENETC_MDIO_READ_ERR;
50
51         return enetc_read(priv, ENETC_MDIO_DATA);
52 }
53
54 int enetc_mdio_write_priv(struct enetc_mdio_priv *priv, int addr, int devad,
55                           int reg, u16 val)
56 {
57         if (devad == MDIO_DEVAD_NONE)
58                 enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C22);
59         else
60                 enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C45);
61         enetc_mdio_wait_bsy(priv);
62
63         if (devad != MDIO_DEVAD_NONE) {
64                 enetc_write(priv, ENETC_MDIO_CTL, (addr << 5) + devad);
65                 enetc_write(priv, ENETC_MDIO_STAT, reg);
66         } else {
67                 enetc_write(priv, ENETC_MDIO_CTL, (addr << 5) + reg);
68         }
69         enetc_mdio_wait_bsy(priv);
70
71         enetc_write(priv, ENETC_MDIO_DATA, val);
72         enetc_mdio_wait_bsy(priv);
73
74         return 0;
75 }
76
77 /* DM wrappers */
78 static int dm_enetc_mdio_read(struct udevice *dev, int addr, int devad, int reg)
79 {
80         struct enetc_mdio_priv *priv = dev_get_priv(dev);
81
82         return enetc_mdio_read_priv(priv, addr, devad, reg);
83 }
84
85 static int dm_enetc_mdio_write(struct udevice *dev, int addr, int devad,
86                                int reg, u16 val)
87 {
88         struct enetc_mdio_priv *priv = dev_get_priv(dev);
89
90         return enetc_mdio_write_priv(priv, addr, devad, reg, val);
91 }
92
93 static const struct mdio_ops enetc_mdio_ops = {
94         .read = dm_enetc_mdio_read,
95         .write = dm_enetc_mdio_write,
96 };
97
98 static int enetc_mdio_bind(struct udevice *dev)
99 {
100         char name[16];
101         static int eth_num_devices;
102
103         /*
104          * prefer using PCI function numbers to number interfaces, but these
105          * are only available if dts nodes are present.  For PCI they are
106          * optional, handle that case too.  Just in case some nodes are present
107          * and some are not, use different naming scheme - enetc-N based on
108          * PCI function # and enetc#N based on interface count
109          */
110         if (ofnode_valid(dev->node))
111                 sprintf(name, "emdio-%u", PCI_FUNC(pci_get_devfn(dev)));
112         else
113                 sprintf(name, "emdio#%u", eth_num_devices++);
114         device_set_name(dev, name);
115
116         return 0;
117 }
118
119 static int enetc_mdio_probe(struct udevice *dev)
120 {
121         struct enetc_mdio_priv *priv = dev_get_priv(dev);
122
123         priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0);
124         if (!priv->regs_base) {
125                 enetc_dbg(dev, "failed to map BAR0\n");
126                 return -EINVAL;
127         }
128
129         priv->regs_base += ENETC_MDIO_BASE;
130
131         dm_pci_clrset_config16(dev, PCI_COMMAND, 0, PCI_COMMAND_MEMORY);
132
133         return 0;
134 }
135
136 U_BOOT_DRIVER(enetc_mdio) = {
137         .name   = "enetc_mdio",
138         .id     = UCLASS_MDIO,
139         .bind   = enetc_mdio_bind,
140         .probe  = enetc_mdio_probe,
141         .ops    = &enetc_mdio_ops,
142         .priv_auto_alloc_size = sizeof(struct enetc_mdio_priv),
143 };
144
145 static struct pci_device_id enetc_mdio_ids[] = {
146         { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_ENETC_MDIO) },
147         { }
148 };
149
150 U_BOOT_PCI_DEVICE(enetc_mdio, enetc_mdio_ids);