mt76: update to the latest version
[oweals/openwrt.git] / package / kernel / mac80211 / patches / 552-ahb_of.patch
1 Index: backports-2017-11-01/drivers/net/wireless/ath/ath9k/ahb.c
2 ===================================================================
3 --- backports-2017-11-01.orig/drivers/net/wireless/ath/ath9k/ahb.c
4 +++ backports-2017-11-01/drivers/net/wireless/ath/ath9k/ahb.c
5 @@ -19,7 +19,15 @@
6  #include <linux/nl80211.h>
7  #include <linux/platform_device.h>
8  #include <linux/module.h>
9 +#include <linux/of_device.h>
10  #include "ath9k.h"
11 +#include <linux/ath9k_platform.h>
12 +
13 +#ifdef CONFIG_OF
14 +#include <asm/mach-ath79/ath79.h>
15 +#include <asm/mach-ath79/ar71xx_regs.h>
16 +#include <linux/mtd/mtd.h>
17 +#endif
18  
19  static const struct platform_device_id ath9k_platform_id_table[] = {
20         {
21 @@ -68,6 +76,235 @@ static const struct ath_bus_ops ath_ahb_
22         .eeprom_read = ath_ahb_eeprom_read,
23  };
24  
25 +#ifdef CONFIG_OF
26 +
27 +#define QCA955X_DDR_CTL_CONFIG          0x108
28 +#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23)
29 +
30 +static int of_get_wifi_cal(struct device_node *np, struct ath9k_platform_data *pdata)
31 +{
32 +#ifdef CONFIG_MTD
33 +       struct device_node *mtd_np = NULL;
34 +       size_t retlen;
35 +       int size, ret;
36 +       struct mtd_info *mtd;
37 +       const char *part;
38 +       const __be32 *list;
39 +       phandle phandle;
40 +
41 +       list = of_get_property(np, "mtd-cal-data", &size);
42 +       if (!list)
43 +               return 0;
44 +
45 +       if (size != (2 * sizeof(*list)))
46 +               return 1;
47 +
48 +       phandle = be32_to_cpup(list++);
49 +       if (phandle)
50 +               mtd_np = of_find_node_by_phandle(phandle);
51 +
52 +       if (!mtd_np)
53 +               return 1;
54 +
55 +       part = of_get_property(mtd_np, "label", NULL);
56 +       if (!part)
57 +               part = mtd_np->name;
58 +
59 +       mtd = get_mtd_device_nm(part);
60 +       if (IS_ERR(mtd))
61 +               return 1;
62 +
63 +       ret = mtd_read(mtd, be32_to_cpup(list), sizeof(pdata->eeprom_data),
64 +                       &retlen, (u8*)pdata->eeprom_data);
65 +       put_mtd_device(mtd);
66 +
67 +#endif
68 +       return 0;
69 +}
70 +
71 +static int ar913x_wmac_reset(void)
72 +{
73 +       ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
74 +       mdelay(10);
75 +
76 +       ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
77 +       mdelay(10);
78 +
79 +       return 0;
80 +}
81 +
82 +static int ar933x_wmac_reset(void)
83 +{
84 +       int retries = 20;
85 +
86 +       ath79_device_reset_set(AR933X_RESET_WMAC);
87 +       ath79_device_reset_clear(AR933X_RESET_WMAC);
88 +
89 +       while (1) {
90 +               u32 bootstrap;
91 +
92 +               bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
93 +               if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0)
94 +                       return 0;
95 +
96 +               if (retries-- == 0)
97 +                       break;
98 +
99 +               udelay(10000);
100 +       }
101 +
102 +       pr_err("ar933x: WMAC reset timed out");
103 +       return -ETIMEDOUT;
104 +}
105 +
106 +static int qca955x_wmac_reset(void)
107 +{
108 +       int i;
109 +
110 +       /* Try to wait for WMAC DDR activity to stop */
111 +       for (i = 0; i < 10; i++) {
112 +               if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) &
113 +                   QCA955X_DDR_CTL_CONFIG_ACT_WMAC))
114 +                       break;
115 +
116 +               udelay(10);
117 +       }
118 +
119 +       ath79_device_reset_set(QCA955X_RESET_RTC);
120 +       udelay(10);
121 +       ath79_device_reset_clear(QCA955X_RESET_RTC);
122 +       udelay(10);
123 +
124 +       return 0;
125 +}
126 +
127 +enum {
128 +       AR913X_WMAC = 0,
129 +       AR933X_WMAC,
130 +       AR934X_WMAC,
131 +       QCA953X_WMAC,
132 +       QCA955X_WMAC,
133 +       QCA956X_WMAC,
134 +};
135 +
136 +static int ar9330_get_soc_revision(void)
137 +{
138 +       if (ath79_soc_rev == 1)
139 +               return ath79_soc_rev;
140 +
141 +       return 0;
142 +}
143 +
144 +static int ath79_get_soc_revision(void)
145 +{
146 +       return ath79_soc_rev;
147 +}
148 +
149 +static const struct of_ath_ahb_data {
150 +       u16 dev_id;
151 +       u32 bootstrap_reg;
152 +       u32 bootstrap_ref;
153 +
154 +       int (*soc_revision)(void);
155 +       int (*wmac_reset)(void);
156 +} of_ath_ahb_data[] = {
157 +       [AR913X_WMAC] = {
158 +               .dev_id = AR5416_AR9100_DEVID,
159 +               .wmac_reset = ar913x_wmac_reset,
160 +
161 +       },
162 +       [AR933X_WMAC] = {
163 +               .dev_id = AR9300_DEVID_AR9330,
164 +               .bootstrap_reg = AR933X_RESET_REG_BOOTSTRAP,
165 +               .bootstrap_ref = AR933X_BOOTSTRAP_REF_CLK_40,
166 +               .soc_revision = ar9330_get_soc_revision,
167 +               .wmac_reset = ar933x_wmac_reset,
168 +       },
169 +       [AR934X_WMAC] = {
170 +               .dev_id = AR9300_DEVID_AR9340,
171 +               .bootstrap_reg = AR934X_RESET_REG_BOOTSTRAP,
172 +               .bootstrap_ref = AR934X_BOOTSTRAP_REF_CLK_40,
173 +               .soc_revision = ath79_get_soc_revision,
174 +       },
175 +       [QCA953X_WMAC] = {
176 +               .dev_id = AR9300_DEVID_AR953X,
177 +               .bootstrap_reg = QCA953X_RESET_REG_BOOTSTRAP,
178 +               .bootstrap_ref = QCA953X_BOOTSTRAP_REF_CLK_40,
179 +               .soc_revision = ath79_get_soc_revision,
180 +       },
181 +       [QCA955X_WMAC] = {
182 +               .dev_id = AR9300_DEVID_QCA955X,
183 +               .bootstrap_reg = QCA955X_RESET_REG_BOOTSTRAP,
184 +               .bootstrap_ref = QCA955X_BOOTSTRAP_REF_CLK_40,
185 +               .wmac_reset = qca955x_wmac_reset,
186 +       },
187 +       [QCA956X_WMAC] = {
188 +               .dev_id = AR9300_DEVID_QCA956X,
189 +               .bootstrap_reg = QCA956X_RESET_REG_BOOTSTRAP,
190 +               .bootstrap_ref = QCA956X_BOOTSTRAP_REF_CLK_40,
191 +               .soc_revision = ath79_get_soc_revision,
192 +       },
193 +};
194 +
195 +const struct of_device_id of_ath_ahb_match[] = {
196 +       { .compatible = "qca,ar9130-wmac", .data = &of_ath_ahb_data[AR913X_WMAC] },
197 +       { .compatible = "qca,ar9330-wmac", .data = &of_ath_ahb_data[AR933X_WMAC] },
198 +       { .compatible = "qca,ar9340-wmac", .data = &of_ath_ahb_data[AR934X_WMAC] },
199 +       { .compatible = "qca,qca9530-wmac", .data = &of_ath_ahb_data[QCA953X_WMAC] },
200 +       { .compatible = "qca,qca9550-wmac", .data = &of_ath_ahb_data[QCA955X_WMAC] },
201 +       { .compatible = "qca,qca9560-wmac", .data = &of_ath_ahb_data[QCA956X_WMAC] },
202 +       {},
203 +};
204 +MODULE_DEVICE_TABLE(of, of_ath_ahb_match);
205 +
206 +static int of_ath_ahb_probe(struct platform_device *pdev)
207 +{
208 +       struct ath9k_platform_data *pdata;
209 +       const struct of_device_id *match;
210 +       const struct of_ath_ahb_data *data;
211 +       u8 led_pin;
212 +
213 +       match = of_match_device(of_ath_ahb_match, &pdev->dev);
214 +       data = (const struct of_ath_ahb_data *)match->data;
215 +
216 +       pdata = dev_get_platdata(&pdev->dev);
217 +
218 +       if (!of_property_read_u8(pdev->dev.of_node, "qca,led-pin", &led_pin))
219 +               pdata->led_pin = led_pin;
220 +       else
221 +               pdata->led_pin = -1;
222 +
223 +       if (of_property_read_bool(pdev->dev.of_node, "qca,disable-2ghz"))
224 +               pdata->disable_2ghz = true;
225 +
226 +       if (of_property_read_bool(pdev->dev.of_node, "qca,disable-5ghz"))
227 +               pdata->disable_5ghz = true;
228 +
229 +       if (of_property_read_bool(pdev->dev.of_node, "qca,tx-gain-buffalo"))
230 +               pdata->tx_gain_buffalo = true;
231 +
232 +       if (data->wmac_reset) {
233 +               data->wmac_reset();
234 +               pdata->external_reset = data->wmac_reset;
235 +       }
236 +
237 +       if (data->bootstrap_reg && data->bootstrap_ref) {
238 +               u32 t = ath79_reset_rr(data->bootstrap_reg);
239 +               if (t & data->bootstrap_ref)
240 +                       pdata->is_clk_25mhz = false;
241 +               else
242 +                       pdata->is_clk_25mhz = true;
243 +       }
244 +
245 +       pdata->get_mac_revision = data->soc_revision;
246 +
247 +       if (of_get_wifi_cal(pdev->dev.of_node, pdata))
248 +               dev_err(&pdev->dev, "failed to load calibration data from mtd device\n");
249 +
250 +       return data->dev_id;
251 +}
252 +#endif
253 +
254  static int ath_ahb_probe(struct platform_device *pdev)
255  {
256         void __iomem *mem;
257 @@ -79,6 +316,17 @@ static int ath_ahb_probe(struct platform
258         int ret = 0;
259         struct ath_hw *ah;
260         char hw_name[64];
261 +       u16 dev_id;
262 +
263 +       if (id)
264 +               dev_id = id->driver_data;
265 +
266 +#ifdef CONFIG_OF
267 +       if (pdev->dev.of_node)
268 +               pdev->dev.platform_data = devm_kzalloc(&pdev->dev,
269 +                                       sizeof(struct ath9k_platform_data),
270 +                                       GFP_KERNEL);
271 +#endif
272  
273         if (!dev_get_platdata(&pdev->dev)) {
274                 dev_err(&pdev->dev, "no platform data specified\n");
275 @@ -121,13 +369,16 @@ static int ath_ahb_probe(struct platform
276         sc->mem = mem;
277         sc->irq = irq;
278  
279 +#ifdef CONFIG_OF
280 +       dev_id = of_ath_ahb_probe(pdev);
281 +#endif
282         ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
283         if (ret) {
284                 dev_err(&pdev->dev, "request_irq failed\n");
285                 goto err_free_hw;
286         }
287  
288 -       ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops);
289 +       ret = ath9k_init_device(dev_id, sc, &ath_ahb_bus_ops);
290         if (ret) {
291                 dev_err(&pdev->dev, "failed to initialize device\n");
292                 goto err_irq;
293 @@ -158,6 +409,9 @@ static int ath_ahb_remove(struct platfor
294                 free_irq(sc->irq, sc);
295                 ieee80211_free_hw(sc->hw);
296         }
297 +#ifdef CONFIG_OF
298 +       pdev->dev.platform_data = NULL;
299 +#endif
300  
301         return 0;
302  }
303 @@ -167,6 +421,9 @@ static struct platform_driver ath_ahb_dr
304         .remove     = ath_ahb_remove,
305         .driver         = {
306                 .name   = "ath9k",
307 +#ifdef CONFIG_OF
308 +               .of_match_table = of_ath_ahb_match,
309 +#endif
310         },
311         .id_table    = ath9k_platform_id_table,
312  };
313 Index: backports-2017-11-01/drivers/net/wireless/ath/ath9k/ath9k.h
314 ===================================================================
315 --- backports-2017-11-01.orig/drivers/net/wireless/ath/ath9k/ath9k.h
316 +++ backports-2017-11-01/drivers/net/wireless/ath/ath9k/ath9k.h
317 @@ -25,6 +25,7 @@
318  #include <linux/time.h>
319  #include <linux/hw_random.h>
320  #include <linux/gpio/driver.h>
321 +#include <linux/reset.h>
322  
323  #include "common.h"
324  #include "debug.h"
325 @@ -1023,6 +1024,9 @@ struct ath_softc {
326         struct ath_hw *sc_ah;
327         void __iomem *mem;
328         int irq;
329 +#ifdef CONFIG_OF
330 +       struct reset_control *reset;
331 +#endif
332         spinlock_t sc_serial_rw;
333         spinlock_t sc_pm_lock;
334         spinlock_t sc_pcu_lock;