82d3fe4d6d197688698e908d591efd5c24ff1d21
[librecmc/librecmc.git] /
1 From 1cb94db3d1bfe0075bde78fb2989f17e0a8a3936 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
3 Date: Wed, 17 Aug 2016 23:00:30 +0200
4 Subject: [PATCH] net: bgmac: support Ethernet core on BCM53573 SoCs
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 BCM53573 is a new series of Broadcom's SoCs. It's based on ARM and can
10 be found in two packages (versions): BCM53573 and BCM47189. It shares
11 some code with the Northstar family, but also requires some new quirks.
12
13 First of all there can be up to 2 Ethernet cores on this SoC. If that is
14 the case, they are connected to two different switch ports allowing some
15 more complex/optimized setups. It seems the second unit doesn't come
16 fully configured and requires some IRQ quirk.
17
18 Other than that only the first core is connected to the PHY. For the
19 second one we have to register fixed PHY (similarly to the Northstar),
20 otherwise generic PHY driver would get some invalid info.
21
22 This has been successfully tested on Tenda AC9 (BCM47189B0).
23
24 Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
25 Signed-off-by: David S. Miller <davem@davemloft.net>
26 ---
27  drivers/net/ethernet/broadcom/bgmac-bcma.c | 19 ++++++++++++++++++-
28  drivers/net/ethernet/broadcom/bgmac.c      | 25 +++++++++++++++++++++++++
29  drivers/net/ethernet/broadcom/bgmac.h      | 19 +++++++++++++++++++
30  include/linux/bcma/bcma.h                  |  3 +++
31  include/linux/bcma/bcma_regs.h             |  1 +
32  5 files changed, 66 insertions(+), 1 deletion(-)
33
34 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
35 +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
36 @@ -92,6 +92,7 @@ MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl
37  /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
38  static int bgmac_probe(struct bcma_device *core)
39  {
40 +       struct bcma_chipinfo *ci = &core->bus->chipinfo;
41         struct ssb_sprom *sprom = &core->bus->sprom;
42         struct mii_bus *mii_bus;
43         struct bgmac *bgmac;
44 @@ -157,7 +158,8 @@ static int bgmac_probe(struct bcma_devic
45         dev_info(bgmac->dev, "Found PHY addr: %d%s\n", bgmac->phyaddr,
46                  bgmac->phyaddr == BGMAC_PHY_NOREGS ? " (NOREGS)" : "");
47  
48 -       if (!bgmac_is_bcm4707_family(core)) {
49 +       if (!bgmac_is_bcm4707_family(core) &&
50 +           !(ci->id == BCMA_CHIP_ID_BCM53573 && core->core_unit == 1)) {
51                 mii_bus = bcma_mdio_mii_register(core, bgmac->phyaddr);
52                 if (IS_ERR(mii_bus)) {
53                         err = PTR_ERR(mii_bus);
54 @@ -230,6 +232,21 @@ static int bgmac_probe(struct bcma_devic
55                 bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
56                 bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
57                 break;
58 +       case BCMA_CHIP_ID_BCM53573:
59 +               bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
60 +               bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
61 +               if (ci->pkg == BCMA_PKG_ID_BCM47189)
62 +                       bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED;
63 +               if (core->core_unit == 0) {
64 +                       bgmac->feature_flags |= BGMAC_FEAT_CC4_IF_SW_TYPE;
65 +                       if (ci->pkg == BCMA_PKG_ID_BCM47189)
66 +                               bgmac->feature_flags |=
67 +                                       BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII;
68 +               } else if (core->core_unit == 1) {
69 +                       bgmac->feature_flags |= BGMAC_FEAT_IRQ_ID_OOB_6;
70 +                       bgmac->feature_flags |= BGMAC_FEAT_CC7_IF_TYPE_RGMII;
71 +               }
72 +               break;
73         default:
74                 bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
75                 bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
76 --- a/drivers/net/ethernet/broadcom/bgmac.c
77 +++ b/drivers/net/ethernet/broadcom/bgmac.c
78 @@ -943,6 +943,27 @@ static void bgmac_chip_reset(struct bgma
79                 bgmac_cco_ctl_maskset(bgmac, 1, ~(BGMAC_CHIPCTL_1_IF_TYPE_MASK |
80                                                   BGMAC_CHIPCTL_1_SW_TYPE_MASK),
81                                       sw_type);
82 +       } else if (bgmac->feature_flags & BGMAC_FEAT_CC4_IF_SW_TYPE) {
83 +               u32 sw_type = BGMAC_CHIPCTL_4_IF_TYPE_MII |
84 +                             BGMAC_CHIPCTL_4_SW_TYPE_EPHY;
85 +               u8 et_swtype = 0;
86 +               char buf[4];
87 +
88 +               if (bcm47xx_nvram_getenv("et_swtype", buf, sizeof(buf)) > 0) {
89 +                       if (kstrtou8(buf, 0, &et_swtype))
90 +                               dev_err(bgmac->dev, "Failed to parse et_swtype (%s)\n",
91 +                                       buf);
92 +                       sw_type = (et_swtype & 0x0f) << 12;
93 +               } else if (bgmac->feature_flags & BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII) {
94 +                       sw_type = BGMAC_CHIPCTL_4_IF_TYPE_RGMII |
95 +                                 BGMAC_CHIPCTL_4_SW_TYPE_RGMII;
96 +               }
97 +               bgmac_cco_ctl_maskset(bgmac, 4, ~(BGMAC_CHIPCTL_4_IF_TYPE_MASK |
98 +                                                 BGMAC_CHIPCTL_4_SW_TYPE_MASK),
99 +                                     sw_type);
100 +       } else if (bgmac->feature_flags & BGMAC_FEAT_CC7_IF_TYPE_RGMII) {
101 +               bgmac_cco_ctl_maskset(bgmac, 7, ~BGMAC_CHIPCTL_7_IF_TYPE_MASK,
102 +                                     BGMAC_CHIPCTL_7_IF_TYPE_RGMII);
103         }
104  
105         if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
106 @@ -1486,6 +1507,10 @@ int bgmac_enet_probe(struct bgmac *info)
107          */
108         bgmac_clk_enable(bgmac, 0);
109  
110 +       /* This seems to be fixing IRQ by assigning OOB #6 to the core */
111 +       if (bgmac->feature_flags & BGMAC_FEAT_IRQ_ID_OOB_6)
112 +               bgmac_idm_write(bgmac, BCMA_OOB_SEL_OUT_A30, 0x86);
113 +
114         bgmac_chip_reset(bgmac);
115  
116         err = bgmac_dma_alloc(bgmac);
117 --- a/drivers/net/ethernet/broadcom/bgmac.h
118 +++ b/drivers/net/ethernet/broadcom/bgmac.h
119 @@ -369,6 +369,21 @@
120  #define BGMAC_CHIPCTL_1_SW_TYPE_RGMII          0x000000C0
121  #define BGMAC_CHIPCTL_1_RXC_DLL_BYPASS         0x00010000
122  
123 +#define BGMAC_CHIPCTL_4_IF_TYPE_MASK           0x00003000
124 +#define BGMAC_CHIPCTL_4_IF_TYPE_RMII           0x00000000
125 +#define BGMAC_CHIPCTL_4_IF_TYPE_MII            0x00001000
126 +#define BGMAC_CHIPCTL_4_IF_TYPE_RGMII          0x00002000
127 +#define BGMAC_CHIPCTL_4_SW_TYPE_MASK           0x0000C000
128 +#define BGMAC_CHIPCTL_4_SW_TYPE_EPHY           0x00000000
129 +#define BGMAC_CHIPCTL_4_SW_TYPE_EPHYMII                0x00004000
130 +#define BGMAC_CHIPCTL_4_SW_TYPE_EPHYRMII       0x00008000
131 +#define BGMAC_CHIPCTL_4_SW_TYPE_RGMII          0x0000C000
132 +
133 +#define BGMAC_CHIPCTL_7_IF_TYPE_MASK           0x000000C0
134 +#define BGMAC_CHIPCTL_7_IF_TYPE_RMII           0x00000000
135 +#define BGMAC_CHIPCTL_7_IF_TYPE_MII            0x00000040
136 +#define BGMAC_CHIPCTL_7_IF_TYPE_RGMII          0x00000080
137 +
138  #define BGMAC_WEIGHT   64
139  
140  #define ETHER_MAX_LEN   1518
141 @@ -390,6 +405,10 @@
142  #define BGMAC_FEAT_NO_CLR_MIB          BIT(13)
143  #define BGMAC_FEAT_FORCE_SPEED_2500    BIT(14)
144  #define BGMAC_FEAT_CMDCFG_SR_REV4      BIT(15)
145 +#define BGMAC_FEAT_IRQ_ID_OOB_6                BIT(16)
146 +#define BGMAC_FEAT_CC4_IF_SW_TYPE      BIT(17)
147 +#define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII        BIT(18)
148 +#define BGMAC_FEAT_CC7_IF_TYPE_RGMII   BIT(19)
149  
150  struct bgmac_slot_info {
151         union {
152 --- a/include/linux/bcma/bcma_regs.h
153 +++ b/include/linux/bcma/bcma_regs.h
154 @@ -23,6 +23,7 @@
155  #define  BCMA_CLKCTLST_4328A0_HAVEALP  0x00020000 /* 4328a0 has reversed bits */
156  
157  /* Agent registers (common for every core) */
158 +#define BCMA_OOB_SEL_OUT_A30           0x0100
159  #define BCMA_IOCTL                     0x0408 /* IO control */
160  #define  BCMA_IOCTL_CLK                        0x0001
161  #define  BCMA_IOCTL_FGC                        0x0002