2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
6 * Copyright (C) 2012 John Crispin <blogic@phrozen.org>
7 * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
8 * Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de>
11 #include <linux/clk.h>
12 #include <linux/delay.h>
13 #include <linux/dma-mapping.h>
14 #include <linux/firmware.h>
15 #include <linux/mfd/syscon.h>
16 #include <linux/module.h>
17 #include <linux/reboot.h>
18 #include <linux/regmap.h>
19 #include <linux/reset.h>
20 #include <linux/of_device.h>
21 #include <linux/of_platform.h>
22 #include <linux/property.h>
23 #include <dt-bindings/mips/lantiq_rcu_gphy.h>
25 #include <lantiq_soc.h>
27 #define XRX200_GPHY_FW_ALIGN (16 * 1024)
29 struct xway_gphy_priv
{
30 struct clk
*gphy_clk_gate
;
31 struct reset_control
*gphy_reset
;
32 struct reset_control
*gphy_reset2
;
33 void __iomem
*membase
;
37 struct xway_gphy_match_data
{
38 char *fe_firmware_name
;
39 char *ge_firmware_name
;
42 static const struct xway_gphy_match_data xrx200a1x_gphy_data
= {
43 .fe_firmware_name
= "lantiq/xrx200_phy22f_a14.bin",
44 .ge_firmware_name
= "lantiq/xrx200_phy11g_a14.bin",
47 static const struct xway_gphy_match_data xrx200a2x_gphy_data
= {
48 .fe_firmware_name
= "lantiq/xrx200_phy22f_a22.bin",
49 .ge_firmware_name
= "lantiq/xrx200_phy11g_a22.bin",
52 static const struct xway_gphy_match_data xrx300_gphy_data
= {
53 .fe_firmware_name
= "lantiq/xrx300_phy22f_a21.bin",
54 .ge_firmware_name
= "lantiq/xrx300_phy11g_a21.bin",
57 static const struct of_device_id xway_gphy_match
[] = {
58 { .compatible
= "lantiq,xrx200a1x-gphy", .data
= &xrx200a1x_gphy_data
},
59 { .compatible
= "lantiq,xrx200a2x-gphy", .data
= &xrx200a2x_gphy_data
},
60 { .compatible
= "lantiq,xrx300-gphy", .data
= &xrx300_gphy_data
},
61 { .compatible
= "lantiq,xrx330-gphy", .data
= &xrx300_gphy_data
},
64 MODULE_DEVICE_TABLE(of
, xway_gphy_match
);
66 static int xway_gphy_load(struct device
*dev
, struct xway_gphy_priv
*priv
,
69 const struct firmware
*fw
;
75 ret
= request_firmware(&fw
, priv
->fw_name
, dev
);
77 dev_err(dev
, "failed to load firmware: %s, error: %i\n",
83 * GPHY cores need the firmware code in a persistent and contiguous
84 * memory area with a 16 kB boundary aligned start address.
86 size
= fw
->size
+ XRX200_GPHY_FW_ALIGN
;
88 fw_addr
= dmam_alloc_coherent(dev
, size
, &dma_addr
, GFP_KERNEL
);
90 fw_addr
= PTR_ALIGN(fw_addr
, XRX200_GPHY_FW_ALIGN
);
91 *dev_addr
= ALIGN(dma_addr
, XRX200_GPHY_FW_ALIGN
);
92 memcpy(fw_addr
, fw
->data
, fw
->size
);
94 dev_err(dev
, "failed to alloc firmware memory\n");
103 static int xway_gphy_of_probe(struct platform_device
*pdev
,
104 struct xway_gphy_priv
*priv
)
106 struct device
*dev
= &pdev
->dev
;
107 const struct xway_gphy_match_data
*gphy_fw_name_cfg
;
110 struct resource
*res_gphy
;
112 gphy_fw_name_cfg
= of_device_get_match_data(dev
);
114 priv
->gphy_clk_gate
= devm_clk_get(dev
, NULL
);
115 if (IS_ERR(priv
->gphy_clk_gate
)) {
116 dev_err(dev
, "Failed to lookup gate clock\n");
117 return PTR_ERR(priv
->gphy_clk_gate
);
120 res_gphy
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
121 priv
->membase
= devm_ioremap_resource(dev
, res_gphy
);
122 if (IS_ERR(priv
->membase
))
123 return PTR_ERR(priv
->membase
);
125 priv
->gphy_reset
= devm_reset_control_get(dev
, "gphy");
126 if (IS_ERR(priv
->gphy_reset
)) {
127 if (PTR_ERR(priv
->gphy_reset
) != -EPROBE_DEFER
)
128 dev_err(dev
, "Failed to lookup gphy reset\n");
129 return PTR_ERR(priv
->gphy_reset
);
132 priv
->gphy_reset2
= devm_reset_control_get_optional(dev
, "gphy2");
133 if (IS_ERR(priv
->gphy_reset2
))
134 return PTR_ERR(priv
->gphy_reset2
);
136 ret
= device_property_read_u32(dev
, "lantiq,gphy-mode", &gphy_mode
);
137 /* Default to GE mode */
139 gphy_mode
= GPHY_MODE_GE
;
143 priv
->fw_name
= gphy_fw_name_cfg
->fe_firmware_name
;
146 priv
->fw_name
= gphy_fw_name_cfg
->ge_firmware_name
;
149 dev_err(dev
, "Unknown GPHY mode %d\n", gphy_mode
);
156 static int xway_gphy_probe(struct platform_device
*pdev
)
158 struct device
*dev
= &pdev
->dev
;
159 struct xway_gphy_priv
*priv
;
160 dma_addr_t fw_addr
= 0;
163 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
167 ret
= xway_gphy_of_probe(pdev
, priv
);
171 ret
= clk_prepare_enable(priv
->gphy_clk_gate
);
175 ret
= xway_gphy_load(dev
, priv
, &fw_addr
);
177 clk_disable_unprepare(priv
->gphy_clk_gate
);
181 reset_control_assert(priv
->gphy_reset
);
182 reset_control_assert(priv
->gphy_reset2
);
184 iowrite32be(fw_addr
, priv
->membase
);
186 reset_control_deassert(priv
->gphy_reset
);
187 reset_control_deassert(priv
->gphy_reset2
);
189 platform_set_drvdata(pdev
, priv
);
194 static int xway_gphy_remove(struct platform_device
*pdev
)
196 struct xway_gphy_priv
*priv
= platform_get_drvdata(pdev
);
198 iowrite32be(0, priv
->membase
);
200 clk_disable_unprepare(priv
->gphy_clk_gate
);
205 static struct platform_driver xway_gphy_driver
= {
206 .probe
= xway_gphy_probe
,
207 .remove
= xway_gphy_remove
,
209 .name
= "xway-rcu-gphy",
210 .of_match_table
= xway_gphy_match
,
214 module_platform_driver(xway_gphy_driver
);
216 MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin");
217 MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin");
218 MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin");
219 MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin");
220 MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin");
221 MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin");
222 MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
223 MODULE_DESCRIPTION("Lantiq XWAY GPHY Firmware Loader");
224 MODULE_LICENSE("GPL");