procd: update to latest git HEAD
[oweals/openwrt.git] / target / linux / ath79 / files-4.19 / drivers / net / ethernet / atheros / ag71xx / ag71xx_gmac.c
1 /*
2  *  Atheros AR71xx built-in ethernet mac driver
3  *
4  *  This program is free software; you can redistribute it and/or modify it
5  *  under the terms of the GNU General Public License version 2 as published
6  *  by the Free Software Foundation.
7  */
8
9 #include <linux/sizes.h>
10 #include <linux/of_address.h>
11 #include "ag71xx.h"
12
13 static void ag71xx_of_set(struct device_node *np, const char *prop,
14                           u32 *reg, u32 shift, u32 mask)
15 {
16         u32 val;
17
18         if (of_property_read_u32(np, prop, &val))
19                 return;
20
21         *reg &= ~(mask << shift);
22         *reg |= ((val & mask) << shift);
23 }
24
25 static void ag71xx_of_bit(struct device_node *np, const char *prop,
26                           u32 *reg, u32 mask)
27 {
28         u32 val;
29
30         if (of_property_read_u32(np, prop, &val))
31                 return;
32
33         if (val)
34                 *reg |= mask;
35         else
36                 *reg &= ~mask;
37 }
38
39 static void ag71xx_setup_gmac_933x(struct device_node *np, void __iomem *base)
40 {
41         u32 val = __raw_readl(base + AR933X_GMAC_REG_ETH_CFG);
42
43         ag71xx_of_bit(np, "switch-phy-swap", &val, AR933X_ETH_CFG_SW_PHY_SWAP);
44         ag71xx_of_bit(np, "switch-phy-addr-swap", &val,
45                 AR933X_ETH_CFG_SW_PHY_ADDR_SWAP);
46
47         __raw_writel(val, base + AR933X_GMAC_REG_ETH_CFG);
48 }
49
50 static void ag71xx_setup_gmac_934x(struct device_node *np, void __iomem *base)
51 {
52         u32 val = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG);
53
54         ag71xx_of_bit(np, "rgmii-gmac0", &val, AR934X_ETH_CFG_RGMII_GMAC0);
55         ag71xx_of_bit(np, "mii-gmac0", &val, AR934X_ETH_CFG_MII_GMAC0);
56         ag71xx_of_bit(np, "mii-gmac0-slave", &val, AR934X_ETH_CFG_MII_GMAC0_SLAVE);
57         ag71xx_of_bit(np, "gmii-gmac0", &val, AR934X_ETH_CFG_GMII_GMAC0);
58         ag71xx_of_bit(np, "switch-phy-swap", &val, AR934X_ETH_CFG_SW_PHY_SWAP);
59         ag71xx_of_bit(np, "switch-only-mode", &val,
60                 AR934X_ETH_CFG_SW_ONLY_MODE);
61         ag71xx_of_set(np, "rxdv-delay", &val,
62                       AR934X_ETH_CFG_RDV_DELAY_SHIFT, 0x3);
63         ag71xx_of_set(np, "rxd-delay", &val,
64                       AR934X_ETH_CFG_RXD_DELAY_SHIFT, 0x3);
65         ag71xx_of_set(np, "txd-delay", &val,
66                       AR934X_ETH_CFG_TXD_DELAY_SHIFT, 0x3);
67         ag71xx_of_set(np, "txen-delay", &val,
68                       AR934X_ETH_CFG_TXE_DELAY_SHIFT, 0x3);
69
70         __raw_writel(val, base + AR934X_GMAC_REG_ETH_CFG);
71 }
72
73 static void ag71xx_setup_gmac_955x(struct device_node *np, void __iomem *base)
74 {
75         u32 val = __raw_readl(base + QCA955X_GMAC_REG_ETH_CFG);
76
77         ag71xx_of_bit(np, "rgmii-enabled", &val, QCA955X_ETH_CFG_RGMII_EN);
78         ag71xx_of_bit(np, "ge0-sgmii", &val, QCA955X_ETH_CFG_GE0_SGMII);
79         ag71xx_of_set(np, "txen-delay", &val, QCA955X_ETH_CFG_TXE_DELAY_SHIFT, 0x3);
80         ag71xx_of_set(np, "txd-delay", &val, QCA955X_ETH_CFG_TXD_DELAY_SHIFT, 0x3);
81         ag71xx_of_set(np, "rxdv-delay", &val, QCA955X_ETH_CFG_RDV_DELAY_SHIFT, 0x3);
82         ag71xx_of_set(np, "rxd-delay", &val, QCA955X_ETH_CFG_RXD_DELAY_SHIFT, 0x3);
83
84         __raw_writel(val, base + QCA955X_GMAC_REG_ETH_CFG);
85 }
86
87 static void ag71xx_setup_gmac_956x(struct device_node *np, void __iomem *base)
88 {
89         u32 val = __raw_readl(base + QCA956X_GMAC_REG_ETH_CFG);
90
91         ag71xx_of_bit(np, "switch-phy-swap", &val, QCA956X_ETH_CFG_SW_PHY_SWAP);
92         ag71xx_of_bit(np, "switch-phy-addr-swap", &val,
93                 QCA956X_ETH_CFG_SW_PHY_ADDR_SWAP);
94
95         __raw_writel(val, base + QCA956X_GMAC_REG_ETH_CFG);
96 }
97
98 int ag71xx_setup_gmac(struct device_node *np)
99 {
100         struct device_node *np_dev;
101         void __iomem *base;
102         int err = 0;
103
104         np = of_get_child_by_name(np, "gmac-config");
105         if (!np)
106                 return 0;
107
108         np_dev = of_parse_phandle(np, "device", 0);
109         if (!np_dev)
110                 goto out;
111
112         base = of_iomap(np_dev, 0);
113         if (!base) {
114                 pr_err("%pOF: can't map GMAC registers\n", np_dev);
115                 err = -ENOMEM;
116                 goto err_iomap;
117         }
118
119         if (of_device_is_compatible(np_dev, "qca,ar9330-gmac"))
120                 ag71xx_setup_gmac_933x(np, base);
121         else if (of_device_is_compatible(np_dev, "qca,ar9340-gmac"))
122                 ag71xx_setup_gmac_934x(np, base);
123         else if (of_device_is_compatible(np_dev, "qca,qca9550-gmac"))
124                 ag71xx_setup_gmac_955x(np, base);
125         else if (of_device_is_compatible(np_dev, "qca,qca9560-gmac"))
126                 ag71xx_setup_gmac_956x(np, base);
127
128         iounmap(base);
129
130 err_iomap:
131         of_node_put(np_dev);
132 out:
133         of_node_put(np);
134         return err;
135 }