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/etherdevice.h>
18 #include <linux/of_address.h>
19 #include <linux/of_net.h>
22 static u32
platform_bgmac_read(struct bgmac
*bgmac
, u16 offset
)
24 return readl(bgmac
->plat
.base
+ offset
);
27 static void platform_bgmac_write(struct bgmac
*bgmac
, u16 offset
, u32 value
)
29 writel(value
, bgmac
->plat
.base
+ offset
);
32 static u32
platform_bgmac_idm_read(struct bgmac
*bgmac
, u16 offset
)
34 return readl(bgmac
->plat
.idm_base
+ offset
);
37 static void platform_bgmac_idm_write(struct bgmac
*bgmac
, u16 offset
, u32 value
)
39 return writel(value
, bgmac
->plat
.idm_base
+ offset
);
42 static bool platform_bgmac_clk_enabled(struct bgmac
*bgmac
)
44 if ((bgmac_idm_read(bgmac
, BCMA_IOCTL
) &
45 (BCMA_IOCTL_CLK
| BCMA_IOCTL_FGC
)) != BCMA_IOCTL_CLK
)
47 if (bgmac_idm_read(bgmac
, BCMA_RESET_CTL
) & BCMA_RESET_CTL_RESET
)
52 static void platform_bgmac_clk_enable(struct bgmac
*bgmac
, u32 flags
)
54 bgmac_idm_write(bgmac
, BCMA_IOCTL
,
55 (BCMA_IOCTL_CLK
| BCMA_IOCTL_FGC
| flags
));
56 bgmac_idm_read(bgmac
, BCMA_IOCTL
);
58 bgmac_idm_write(bgmac
, BCMA_RESET_CTL
, 0);
59 bgmac_idm_read(bgmac
, BCMA_RESET_CTL
);
62 bgmac_idm_write(bgmac
, BCMA_IOCTL
, (BCMA_IOCTL_CLK
| flags
));
63 bgmac_idm_read(bgmac
, BCMA_IOCTL
);
67 static void platform_bgmac_cco_ctl_maskset(struct bgmac
*bgmac
, u32 offset
,
70 /* This shouldn't be encountered */
74 static u32
platform_bgmac_get_bus_clock(struct bgmac
*bgmac
)
76 /* This shouldn't be encountered */
82 static void platform_bgmac_cmn_maskset32(struct bgmac
*bgmac
, u16 offset
,
85 /* This shouldn't be encountered */
89 static int bgmac_probe(struct platform_device
*pdev
)
91 struct device_node
*np
= pdev
->dev
.of_node
;
93 struct resource
*regs
;
96 bgmac
= devm_kzalloc(&pdev
->dev
, sizeof(*bgmac
), GFP_KERNEL
);
100 platform_set_drvdata(pdev
, bgmac
);
102 /* Set the features of the 4707 family */
103 bgmac
->feature_flags
|= BGMAC_FEAT_CLKCTLST
;
104 bgmac
->feature_flags
|= BGMAC_FEAT_NO_RESET
;
105 bgmac
->feature_flags
|= BGMAC_FEAT_FORCE_SPEED_2500
;
106 bgmac
->feature_flags
|= BGMAC_FEAT_CMDCFG_SR_REV4
;
107 bgmac
->feature_flags
|= BGMAC_FEAT_TX_MASK_SETUP
;
108 bgmac
->feature_flags
|= BGMAC_FEAT_RX_MASK_SETUP
;
110 bgmac
->dev
= &pdev
->dev
;
111 bgmac
->dma_dev
= &pdev
->dev
;
113 mac_addr
= of_get_mac_address(np
);
115 ether_addr_copy(bgmac
->mac_addr
, mac_addr
);
117 dev_warn(&pdev
->dev
, "MAC address not present in device tree\n");
119 bgmac
->irq
= platform_get_irq(pdev
, 0);
120 if (bgmac
->irq
< 0) {
121 dev_err(&pdev
->dev
, "Unable to obtain IRQ\n");
125 regs
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "amac_base");
127 dev_err(&pdev
->dev
, "Unable to obtain base resource\n");
131 bgmac
->plat
.base
= devm_ioremap_resource(&pdev
->dev
, regs
);
132 if (IS_ERR(bgmac
->plat
.base
))
133 return PTR_ERR(bgmac
->plat
.base
);
135 regs
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "idm_base");
137 dev_err(&pdev
->dev
, "Unable to obtain idm resource\n");
141 bgmac
->plat
.idm_base
= devm_ioremap_resource(&pdev
->dev
, regs
);
142 if (IS_ERR(bgmac
->plat
.idm_base
))
143 return PTR_ERR(bgmac
->plat
.idm_base
);
145 bgmac
->read
= platform_bgmac_read
;
146 bgmac
->write
= platform_bgmac_write
;
147 bgmac
->idm_read
= platform_bgmac_idm_read
;
148 bgmac
->idm_write
= platform_bgmac_idm_write
;
149 bgmac
->clk_enabled
= platform_bgmac_clk_enabled
;
150 bgmac
->clk_enable
= platform_bgmac_clk_enable
;
151 bgmac
->cco_ctl_maskset
= platform_bgmac_cco_ctl_maskset
;
152 bgmac
->get_bus_clock
= platform_bgmac_get_bus_clock
;
153 bgmac
->cmn_maskset32
= platform_bgmac_cmn_maskset32
;
155 return bgmac_enet_probe(bgmac
);
158 static int bgmac_remove(struct platform_device
*pdev
)
160 struct bgmac
*bgmac
= platform_get_drvdata(pdev
);
162 bgmac_enet_remove(bgmac
);
167 static const struct of_device_id bgmac_of_enet_match
[] = {
168 {.compatible
= "brcm,amac",},
169 {.compatible
= "brcm,nsp-amac",},
173 MODULE_DEVICE_TABLE(of
, bgmac_of_enet_match
);
175 static struct platform_driver bgmac_enet_driver
= {
177 .name
= "bgmac-enet",
178 .of_match_table
= bgmac_of_enet_match
,
180 .probe
= bgmac_probe
,
181 .remove
= bgmac_remove
,
184 module_platform_driver(bgmac_enet_driver
);
185 MODULE_LICENSE("GPL");