2 * Copyright (C) 2016 Broadcom
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16 #include <linux/bcma/bcma.h>
17 #include <linux/brcmphy.h>
18 #include <linux/etherdevice.h>
19 #include <linux/of_address.h>
20 #include <linux/of_mdio.h>
21 #include <linux/of_net.h>
24 #define NICPM_PADRING_CFG 0x00000004
25 #define NICPM_IOMUX_CTRL 0x00000008
27 #define NICPM_PADRING_CFG_INIT_VAL 0x74000000
28 #define NICPM_IOMUX_CTRL_INIT_VAL_AX 0x21880000
30 #define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000
31 #define NICPM_IOMUX_CTRL_SPD_SHIFT 10
32 #define NICPM_IOMUX_CTRL_SPD_10M 0
33 #define NICPM_IOMUX_CTRL_SPD_100M 1
34 #define NICPM_IOMUX_CTRL_SPD_1000M 2
36 static u32
platform_bgmac_read(struct bgmac
*bgmac
, u16 offset
)
38 return readl(bgmac
->plat
.base
+ offset
);
41 static void platform_bgmac_write(struct bgmac
*bgmac
, u16 offset
, u32 value
)
43 writel(value
, bgmac
->plat
.base
+ offset
);
46 static u32
platform_bgmac_idm_read(struct bgmac
*bgmac
, u16 offset
)
48 return readl(bgmac
->plat
.idm_base
+ offset
);
51 static void platform_bgmac_idm_write(struct bgmac
*bgmac
, u16 offset
, u32 value
)
53 return writel(value
, bgmac
->plat
.idm_base
+ offset
);
56 static bool platform_bgmac_clk_enabled(struct bgmac
*bgmac
)
58 if ((bgmac_idm_read(bgmac
, BCMA_IOCTL
) & BGMAC_CLK_EN
) != BGMAC_CLK_EN
)
60 if (bgmac_idm_read(bgmac
, BCMA_RESET_CTL
) & BCMA_RESET_CTL_RESET
)
65 static void platform_bgmac_clk_enable(struct bgmac
*bgmac
, u32 flags
)
69 /* The Reset Control register only contains a single bit to show if the
70 * controller is currently in reset. Do a sanity check here, just in
71 * case the bootloader happened to leave the device in reset.
73 val
= bgmac_idm_read(bgmac
, BCMA_RESET_CTL
);
75 bgmac_idm_write(bgmac
, BCMA_RESET_CTL
, 0);
76 bgmac_idm_read(bgmac
, BCMA_RESET_CTL
);
80 val
= bgmac_idm_read(bgmac
, BCMA_IOCTL
);
81 /* Some bits of BCMA_IOCTL set by HW/ATF and should not change */
82 val
|= flags
& ~(BGMAC_AWCACHE
| BGMAC_ARCACHE
| BGMAC_AWUSER
|
85 bgmac_idm_write(bgmac
, BCMA_IOCTL
, val
);
86 bgmac_idm_read(bgmac
, BCMA_IOCTL
);
90 static void platform_bgmac_cco_ctl_maskset(struct bgmac
*bgmac
, u32 offset
,
93 /* This shouldn't be encountered */
97 static u32
platform_bgmac_get_bus_clock(struct bgmac
*bgmac
)
99 /* This shouldn't be encountered */
105 static void platform_bgmac_cmn_maskset32(struct bgmac
*bgmac
, u16 offset
,
108 /* This shouldn't be encountered */
112 static void bgmac_nicpm_speed_set(struct net_device
*net_dev
)
114 struct bgmac
*bgmac
= netdev_priv(net_dev
);
117 if (!bgmac
->plat
.nicpm_base
)
120 /* SET RGMII IO CONFIG */
121 writel(NICPM_PADRING_CFG_INIT_VAL
,
122 bgmac
->plat
.nicpm_base
+ NICPM_PADRING_CFG
);
124 val
= NICPM_IOMUX_CTRL_INIT_VAL
;
125 switch (bgmac
->net_dev
->phydev
->speed
) {
127 netdev_err(net_dev
, "Unsupported speed. Defaulting to 1000Mb\n");
129 val
|= NICPM_IOMUX_CTRL_SPD_1000M
<< NICPM_IOMUX_CTRL_SPD_SHIFT
;
132 val
|= NICPM_IOMUX_CTRL_SPD_100M
<< NICPM_IOMUX_CTRL_SPD_SHIFT
;
135 val
|= NICPM_IOMUX_CTRL_SPD_10M
<< NICPM_IOMUX_CTRL_SPD_SHIFT
;
139 writel(val
, bgmac
->plat
.nicpm_base
+ NICPM_IOMUX_CTRL
);
141 bgmac_adjust_link(bgmac
->net_dev
);
144 static int platform_phy_connect(struct bgmac
*bgmac
)
146 struct phy_device
*phy_dev
;
148 if (bgmac
->plat
.nicpm_base
)
149 phy_dev
= of_phy_get_and_connect(bgmac
->net_dev
,
151 bgmac_nicpm_speed_set
);
153 phy_dev
= of_phy_get_and_connect(bgmac
->net_dev
,
157 dev_err(bgmac
->dev
, "PHY connection failed\n");
164 static int bgmac_probe(struct platform_device
*pdev
)
166 struct device_node
*np
= pdev
->dev
.of_node
;
168 struct resource
*regs
;
171 bgmac
= bgmac_alloc(&pdev
->dev
);
175 platform_set_drvdata(pdev
, bgmac
);
177 /* Set the features of the 4707 family */
178 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
179 bgmac
->feature_flags
|= BGMAC_FEAT_NO_RESET
;
180 bgmac
->feature_flags
|= BGMAC_FEAT_CMDCFG_SR_REV4
;
181 bgmac
->feature_flags
|= BGMAC_FEAT_TX_MASK_SETUP
;
182 bgmac
->feature_flags
|= BGMAC_FEAT_RX_MASK_SETUP
;
184 bgmac
->dev
= &pdev
->dev
;
185 bgmac
->dma_dev
= &pdev
->dev
;
187 mac_addr
= of_get_mac_address(np
);
189 ether_addr_copy(bgmac
->net_dev
->dev_addr
, mac_addr
);
191 dev_warn(&pdev
->dev
, "MAC address not present in device tree\n");
193 bgmac
->irq
= platform_get_irq(pdev
, 0);
194 if (bgmac
->irq
< 0) {
195 dev_err(&pdev
->dev
, "Unable to obtain IRQ\n");
199 regs
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "amac_base");
201 dev_err(&pdev
->dev
, "Unable to obtain base resource\n");
205 bgmac
->plat
.base
= devm_ioremap_resource(&pdev
->dev
, regs
);
206 if (IS_ERR(bgmac
->plat
.base
))
207 return PTR_ERR(bgmac
->plat
.base
);
209 regs
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "idm_base");
211 dev_err(&pdev
->dev
, "Unable to obtain idm resource\n");
215 bgmac
->plat
.idm_base
= devm_ioremap_resource(&pdev
->dev
, regs
);
216 if (IS_ERR(bgmac
->plat
.idm_base
))
217 return PTR_ERR(bgmac
->plat
.idm_base
);
219 regs
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "nicpm_base");
221 bgmac
->plat
.nicpm_base
= devm_ioremap_resource(&pdev
->dev
,
223 if (IS_ERR(bgmac
->plat
.nicpm_base
))
224 return PTR_ERR(bgmac
->plat
.nicpm_base
);
227 bgmac
->read
= platform_bgmac_read
;
228 bgmac
->write
= platform_bgmac_write
;
229 bgmac
->idm_read
= platform_bgmac_idm_read
;
230 bgmac
->idm_write
= platform_bgmac_idm_write
;
231 bgmac
->clk_enabled
= platform_bgmac_clk_enabled
;
232 bgmac
->clk_enable
= platform_bgmac_clk_enable
;
233 bgmac
->cco_ctl_maskset
= platform_bgmac_cco_ctl_maskset
;
234 bgmac
->get_bus_clock
= platform_bgmac_get_bus_clock
;
235 bgmac
->cmn_maskset32
= platform_bgmac_cmn_maskset32
;
236 if (of_parse_phandle(np
, "phy-handle", 0)) {
237 bgmac
->phy_connect
= platform_phy_connect
;
239 bgmac
->phy_connect
= bgmac_phy_connect_direct
;
240 bgmac
->feature_flags
|= BGMAC_FEAT_FORCE_SPEED_2500
;
243 return bgmac_enet_probe(bgmac
);
246 static int bgmac_remove(struct platform_device
*pdev
)
248 struct bgmac
*bgmac
= platform_get_drvdata(pdev
);
250 bgmac_enet_remove(bgmac
);
256 static int bgmac_suspend(struct device
*dev
)
258 struct bgmac
*bgmac
= dev_get_drvdata(dev
);
260 return bgmac_enet_suspend(bgmac
);
263 static int bgmac_resume(struct device
*dev
)
265 struct bgmac
*bgmac
= dev_get_drvdata(dev
);
267 return bgmac_enet_resume(bgmac
);
270 static const struct dev_pm_ops bgmac_pm_ops
= {
271 .suspend
= bgmac_suspend
,
272 .resume
= bgmac_resume
275 #define BGMAC_PM_OPS (&bgmac_pm_ops)
277 #define BGMAC_PM_OPS NULL
278 #endif /* CONFIG_PM */
280 static const struct of_device_id bgmac_of_enet_match
[] = {
281 {.compatible
= "brcm,amac",},
282 {.compatible
= "brcm,nsp-amac",},
283 {.compatible
= "brcm,ns2-amac",},
287 MODULE_DEVICE_TABLE(of
, bgmac_of_enet_match
);
289 static struct platform_driver bgmac_enet_driver
= {
291 .name
= "bgmac-enet",
292 .of_match_table
= bgmac_of_enet_match
,
295 .probe
= bgmac_probe
,
296 .remove
= bgmac_remove
,
299 module_platform_driver(bgmac_enet_driver
);
300 MODULE_LICENSE("GPL");