ff37b6706222bb9e79ff2bcc6bb6d13da19d8d7f
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / misc / samsung / scsc / platform_mif_9610.c
1 /****************************************************************************
2 *
3 * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
4 *
5 ****************************************************************************/
6
7 /* Implements interface */
8
9 #include "platform_mif.h"
10
11 /* Interfaces it Uses */
12
13 #include <linux/version.h>
14 #include <linux/module.h>
15 #include <linux/interrupt.h>
16 #include <linux/pm_qos.h>
17 #include <linux/platform_device.h>
18 #include <linux/moduleparam.h>
19 #include <linux/iommu.h>
20 #include <linux/slab.h>
21 #include <linux/io.h>
22 #include <linux/smc.h>
23 #ifdef CONFIG_OF
24 #include <linux/of.h>
25 #include <linux/of_address.h>
26 #include <linux/of_platform.h>
27 #endif
28 #include <linux/mfd/syscon.h>
29 #include <linux/regmap.h>
30 #include <linux/delay.h>
31 #include <scsc/scsc_logring.h>
32 #include "mif_reg_S5E9610.h"
33 #include "platform_mif_module.h"
34 #ifdef CONFIG_ARCH_EXYNOS
35 #include <linux/soc/samsung/exynos-soc.h>
36 #endif
37
38 #ifdef CONFIG_SCSC_SMAPPER
39 #include <linux/dma-mapping.h>
40 #include "mif_reg_smapper.h"
41 #endif
42 #ifdef CONFIG_SCSC_QOS
43 #include <linux/pm_qos.h>
44 #endif
45
46 #if !defined(CONFIG_SOC_EXYNOS9610)
47 #error Target processor CONFIG_SOC_EXYNOS9610 not selected
48 #endif
49
50 #ifdef CONFIG_SCSC_LOG_COLLECTION
51 #include <scsc/scsc_log_collector.h>
52 #endif
53 /* Time to wait for CFG_REQ IRQ on 9610 */
54 #define WLBT_BOOT_TIMEOUT (HZ)
55
56 #ifdef CONFIG_OF_RESERVED_MEM
57 #include <linux/of_reserved_mem.h>
58 #endif
59 static unsigned long sharedmem_base;
60 static size_t sharedmem_size;
61
62 #ifdef CONFIG_SCSC_CHV_SUPPORT
63 static bool chv_disable_irq;
64 module_param(chv_disable_irq, bool, S_IRUGO | S_IWUSR);
65 MODULE_PARM_DESC(chv_disable_irq, "Do not register for irq");
66 #endif
67
68 static bool enable_platform_mif_arm_reset = true;
69 module_param(enable_platform_mif_arm_reset, bool, S_IRUGO | S_IWUSR);
70 MODULE_PARM_DESC(enable_platform_mif_arm_reset, "Enables WIFIBT ARM cores reset");
71
72 #ifdef CONFIG_SCSC_QOS
73 struct qos_table {
74 unsigned int freq_mif;
75 unsigned int freq_int;
76 unsigned int freq_cl0;
77 unsigned int freq_cl1;
78 };
79 #endif
80
81 struct platform_mif {
82 struct scsc_mif_abs interface;
83 struct scsc_mbox_s *mbox;
84 struct platform_device *pdev;
85
86 struct device *dev;
87
88 struct {
89 int irq_num;
90 int flags;
91 atomic_t irq_disabled_cnt;
92 } wlbt_irq[PLATFORM_MIF_NUM_IRQS];
93
94 /* MIF registers preserved during suspend */
95 struct {
96 u32 irq_bit_mask;
97 } mif_preserve;
98
99 /* register MBOX memory space */
100 size_t reg_start;
101 size_t reg_size;
102 void __iomem *base;
103
104 /* register CMU memory space */
105 struct regmap *cmu_base;
106
107 void __iomem *con0_base;
108
109 /* pmu syscon regmap */
110 struct regmap *pmureg;
111 #if defined(CONFIG_SOC_EXYNOS9610)
112 struct regmap *baaw_p_wlbt;
113 struct regmap *dbus_baaw;
114 struct regmap *pbus_baaw;
115 struct regmap *wlbt_remap;
116 struct regmap *boot_cfg;
117
118 /* Signalled when CFG_REQ IRQ handled */
119 struct completion cfg_ack;
120
121 /* State of CFG_REQ handler */
122 enum wlbt_boot_state {
123 WLBT_BOOT_IN_RESET = 0,
124 WLBT_BOOT_WAIT_CFG_REQ,
125 WLBT_BOOT_CFG_DONE,
126 WLBT_BOOT_CFG_ERROR
127 } boot_state;
128
129 #endif
130 #ifdef CONFIG_SCSC_SMAPPER
131 /* SMAPPER */
132 void __iomem *smapper_base;
133 u8 smapper_banks;
134 struct {
135 u8 bank;
136 u32 ws;
137 bool large;
138 struct scsc_mif_smapper_info bank_info;
139 } *smapper;
140 #endif
141 /* Shared memory space - reserved memory */
142 unsigned long mem_start;
143 size_t mem_size;
144 void __iomem *mem;
145
146 /* Callback function and dev pointer mif_intr manager handler */
147 void (*r4_handler)(int irq, void *data);
148 void *irq_dev;
149 /* spinlock to serialize driver access */
150 spinlock_t mif_spinlock;
151 void (*reset_request_handler)(int irq, void *data);
152 void *irq_reset_request_dev;
153
154 #ifdef CONFIG_SCSC_QOS
155 /* QoS table */
156 struct qos_table *qos;
157 bool qos_enabled;
158 #endif
159 /* Suspend/resume handlers */
160 int (*suspend_handler)(struct scsc_mif_abs *abs, void *data);
161 void (*resume_handler)(struct scsc_mif_abs *abs, void *data);
162 void *suspendresume_data;
163 };
164
165 extern int mx140_log_dump(void);
166
167 #define platform_mif_from_mif_abs(MIF_ABS_PTR) container_of(MIF_ABS_PTR, struct platform_mif, interface)
168
169 inline void platform_mif_reg_write(struct platform_mif *platform, u16 offset, u32 value)
170 {
171 writel(value, platform->base + offset);
172 }
173
174 inline u32 platform_mif_reg_read(struct platform_mif *platform, u16 offset)
175 {
176 return readl(platform->base + offset);
177 }
178
179 #ifdef CONFIG_SCSC_SMAPPER
180 inline void platform_mif_reg_write_smapper(struct platform_mif *platform, u16 offset, u32 value)
181 {
182 writel(value, platform->smapper_base + offset);
183 }
184
185 inline u32 platform_mif_reg_read_smapper(struct platform_mif *platform, u16 offset)
186 {
187 return readl(platform->smapper_base + offset);
188 }
189
190 #define PLATFORM_MIF_SHIFT_SMAPPER_ADDR 11 /* From 36 bits addres to 25 bits */
191 #define PLATFORM_MIF_SHIFT_SMAPPER_END 4 /* End address aligment */
192
193 /* Platform is responsible to give the phys mapping of the SMAPPER maps */
194 static int platform_mif_smapper_get_mapping(struct scsc_mif_abs *interface, u8 *phy_map, u16 *align)
195 {
196 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
197 u8 i;
198
199 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Mapping %d banks\n", platform->smapper_banks);
200
201 if (!platform->smapper_banks)
202 return -EINVAL;
203
204 for (i = 0; i < platform->smapper_banks; i++) {
205 if (platform->smapper[i].large)
206 phy_map[i] = SCSC_MIF_ABS_LARGE_BANK;
207 else
208 phy_map[i] = SCSC_MIF_ABS_SMALL_BANK;
209 }
210
211 if (align)
212 *align = 1 << PLATFORM_MIF_SHIFT_SMAPPER_ADDR;
213
214 return 0;
215 }
216
217 static int platform_mif_smapper_get_bank_info(struct scsc_mif_abs *interface, u8 bank, struct scsc_mif_smapper_info *bank_info)
218 {
219 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
220
221 if (!platform->smapper_banks)
222 return -EINVAL;
223
224 bank_info->num_entries = platform->smapper[bank].bank_info.num_entries;
225 bank_info->mem_range_bytes = platform->smapper[bank].bank_info.mem_range_bytes;
226
227 return 0;
228 }
229
230 static u8 platform_mif_smapper_granularity_to_bits(u32 granularity)
231 {
232 if (granularity <= 2 * 1024)
233 return 0;
234 if (granularity <= 4 * 1024)
235 return 1;
236 if (granularity <= 8 * 1024)
237 return 2;
238 if (granularity <= 16 * 1024)
239 return 3;
240 if (granularity <= 32 * 1024)
241 return 4;
242 if (granularity <= 64 * 1024)
243 return 5;
244 if (granularity <= 128 * 1024)
245 return 6;
246 return 7;
247 }
248
249 static u32 platform_mif_smapper_get_bank_base_address(struct scsc_mif_abs *interface, u8 bank)
250 {
251 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
252
253 if (!platform->smapper)
254 return 0;
255
256 return platform->smapper[bank].ws;
257 }
258
259 /* Configure smapper according the memory map and range */
260 static void platform_mif_smapper_configure(struct scsc_mif_abs *interface, u32 granularity)
261 {
262 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
263 u8 i;
264 u8 gran;
265 u8 nb = platform->smapper_banks;
266
267 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Configure SMAPPER with granularity %d\n", granularity);
268
269 gran = platform_mif_smapper_granularity_to_bits(granularity);
270
271 platform_mif_reg_write_smapper(platform, SMAPPER_QCH_DISABLE, 1);
272 platform_mif_reg_write_smapper(platform, ORIGIN_ADDR_AR, 0);
273 platform_mif_reg_write_smapper(platform, ORIGIN_ADDR_AW, 0);
274 /* Program SMAPPER memmap */
275 for (i = 0; i < nb; i++) {
276 /* Set ADDR_MAP_EN to 1'b0*/
277 platform_mif_reg_write_smapper(platform, ADDR_MAP_EN(i), 0);
278 /* Set START_ADDR */
279 platform_mif_reg_write_smapper(platform, START_ADDR(i), platform->smapper[i].ws);
280 /* Set ADDR_GRANULARITY - FIXED AT 4KB */
281 platform_mif_reg_write_smapper(platform, ADDR_GRANULARITY(i), gran);
282 /* WLAN_ADDR_MAP operation is started */
283 }
284 /* Set access window control (MSB 32bits Start/End address) */
285 /* Remapped address should be ranged from AW_START_ADDR to AW_EN_ADDR */
286 platform_mif_reg_write_smapper(platform, AW_START_ADDR, 0);
287 platform_mif_reg_write_smapper(platform, AW_END_ADDR, dma_get_mask(platform->dev) >> PLATFORM_MIF_SHIFT_SMAPPER_END);
288 smp_mb();
289 }
290
291 /* Caller is responsible of validating the phys address (alignment) */
292 static int platform_mif_smapper_write_sram(struct scsc_mif_abs *interface, u8 bank, u8 num_entries, u8 first_entry, dma_addr_t *addr)
293 {
294 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
295 u8 i;
296 u32 rb;
297
298 if (!platform->smapper_banks)
299 return -EINVAL;
300
301 if (!platform->smapper_base) {
302 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "SMAPPER not enabled\n");
303 return -EINVAL;
304 }
305
306 /* Set ADDR_MAP_EN to 1'b0*/
307 platform_mif_reg_write_smapper(platform, ADDR_MAP_EN(bank), 0);
308 /* Write mapping table to SRAM. Each entry consists of 25 bits MSB address to remap */
309 for (i = 0; i < num_entries; i++) {
310 if (!addr[i]) {
311 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "ADDR IS NULL at bank %d entry %d/%d\n", bank, first_entry + i, num_entries);
312 return -EINVAL;
313 }
314 /* Set SRAM_WRITE_CTRL to 1'b1*/
315 platform_mif_reg_write_smapper(platform, SRAM_WRITE_CTRL(bank), 1);
316 platform_mif_reg_write_smapper(platform, SRAM_BANK_INDEX(bank, first_entry + i), addr[i] >> PLATFORM_MIF_SHIFT_SMAPPER_ADDR);
317 /* check incorrect writings */
318 platform_mif_reg_write_smapper(platform, SRAM_WRITE_CTRL(bank), 0);
319 rb = platform_mif_reg_read_smapper(platform, SRAM_BANK_INDEX(bank, first_entry + i));
320 if (rb != addr[i] >> PLATFORM_MIF_SHIFT_SMAPPER_ADDR) {
321 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "incorrect mapping detected rb 0x%x, addr 0x%x\n", rb, (u32)addr[i] >> PLATFORM_MIF_SHIFT_SMAPPER_ADDR);
322 return -EFAULT;
323 }
324 }
325 platform_mif_reg_write_smapper(platform, ADDR_MAP_EN(bank), 1);
326 smp_mb();
327 return 0;
328 }
329
330 static int platform_mif_parse_smapper(struct platform_mif *platform, struct device_node *np, u8 num_banks)
331 {
332 /* SMAPPER parsing */
333 struct device_node *np_banks;
334 char node_name[50];
335 u32 val[2];
336 u8 i;
337 u32 bank = 0, ws = 0, wsz = 0, ent = 0, large = 0;
338
339 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "banks found: %d szof %zu\n", num_banks, sizeof(*platform->smapper));
340
341 platform->smapper = kmalloc_array(num_banks, sizeof(*platform->smapper), GFP_KERNEL);
342
343 if (!platform->smapper)
344 return -ENOMEM;
345
346 for (i = 0; i < num_banks; i++) {
347 snprintf(node_name, sizeof(node_name), "smapper_bank_%d", i);
348 np_banks = of_find_node_by_name(np, node_name);
349 if (!np_banks) {
350 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "%s: could not find smapper_bank\n",
351 node_name);
352 kfree(platform->smapper);
353 platform->smapper = NULL;
354 return -ENOENT;
355 }
356 of_property_read_u32(np_banks, "bank_num", &bank);
357 of_property_read_u32(np_banks, "fw_window_start", &ws);
358 of_property_read_u32(np_banks, "fw_window_size", &wsz);
359 of_property_read_u32(np_banks, "num_entries", &ent);
360 of_property_read_u32(np_banks, "is_large", &large);
361 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev,
362 "bank %d fw_w_start 0x%x fw_w_sz 0x%x entries %d is_large %d\n",
363 bank, ws, wsz, ent, large);
364
365 platform->smapper[i].bank = (u8)bank;
366 platform->smapper[i].ws = ws;
367 platform->smapper[i].large = (bool)large;
368 platform->smapper[i].bank_info.num_entries = ent;
369 platform->smapper[i].bank_info.mem_range_bytes = wsz;
370 }
371
372 /* Update the number of banks before returning */
373 platform->smapper_banks = num_banks;
374
375 of_property_read_u32_array(np, "smapper_reg", val, 2);
376 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev,
377 "smapper reg address 0x%x size 0x%x\n", val[0], val[1]);
378 platform->smapper_base =
379 devm_ioremap_nocache(platform->dev, val[0], val[1]);
380
381 if (!platform->smapper_base) {
382 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
383 "Error mapping smapper register region\n");
384 kfree(platform->smapper);
385 platform->smapper = NULL;
386 return -ENOENT;
387 }
388
389 return 0;
390 }
391 #endif
392 #ifdef CONFIG_SCSC_QOS
393 static int platform_mif_parse_qos(struct platform_mif *platform, struct device_node *np)
394 {
395 int len, i;
396
397 platform->qos_enabled = false;
398
399 len = of_property_count_u32_elems(np, "qos_table");
400 if (!(len == 12)) {
401 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev,
402 "No qos table for wlbt, or incorrect size\n");
403 return -ENOENT;
404 }
405
406 platform->qos = devm_kzalloc(platform->dev, sizeof(struct qos_table) * len / 4, GFP_KERNEL);
407 if (!platform->qos)
408 return -ENOMEM;
409
410 of_property_read_u32_array(np, "qos_table", (unsigned int *)platform->qos, len);
411
412 for (i = 0; i < len / 4; i++) {
413 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "QoS Table[%d] mif : %u int : %u cl0 : %u cl1: %u\n", i,
414 platform->qos[i].freq_mif,
415 platform->qos[i].freq_int,
416 platform->qos[i].freq_cl0,
417 platform->qos[i].freq_cl1);
418 }
419
420 platform->qos_enabled = true;
421 return 0;
422 }
423
424 struct qos_table platform_mif_pm_qos_get_table(struct platform_mif *platform, enum scsc_qos_config config)
425 {
426 struct qos_table table;
427
428 switch (config) {
429 case SCSC_QOS_MIN:
430 table.freq_mif = platform->qos[0].freq_mif;
431 table.freq_int = platform->qos[0].freq_int;
432 table.freq_cl0 = platform->qos[0].freq_cl0;
433 table.freq_cl1 = platform->qos[0].freq_cl1;
434 break;
435
436 case SCSC_QOS_MED:
437 table.freq_mif = platform->qos[1].freq_mif;
438 table.freq_int = platform->qos[1].freq_int;
439 table.freq_cl0 = platform->qos[1].freq_cl0;
440 table.freq_cl1 = platform->qos[1].freq_cl1;
441 break;
442
443 case SCSC_QOS_MAX:
444 table.freq_mif = platform->qos[2].freq_mif;
445 table.freq_int = platform->qos[2].freq_int;
446 table.freq_cl0 = platform->qos[2].freq_cl0;
447 table.freq_cl1 = platform->qos[2].freq_cl1;
448 break;
449
450 default:
451 table.freq_mif = 0;
452 table.freq_int = 0;
453 table.freq_cl0 = 0;
454 table.freq_cl1 = 0;
455 }
456
457 return table;
458 }
459
460 static int platform_mif_pm_qos_add_request(struct scsc_mif_abs *interface, struct scsc_mifqos_request *qos_req, enum scsc_qos_config config)
461 {
462 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
463 struct qos_table table;
464
465 if (!platform)
466 return -ENODEV;
467
468 if (!platform->qos_enabled) {
469 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "PM QoS not configured\n");
470 return -EOPNOTSUPP;
471 }
472
473 table = platform_mif_pm_qos_get_table(platform, config);
474
475 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev,
476 "PM QoS add request: %u. MIF %u INT %u CL0 %u CL1 %u\n", config, table.freq_mif, table.freq_int, table.freq_cl0, table.freq_cl1);
477
478 pm_qos_add_request(&qos_req->pm_qos_req_mif, PM_QOS_BUS_THROUGHPUT, table.freq_mif);
479 pm_qos_add_request(&qos_req->pm_qos_req_int, PM_QOS_DEVICE_THROUGHPUT, table.freq_int);
480 pm_qos_add_request(&qos_req->pm_qos_req_cl0, PM_QOS_CLUSTER0_FREQ_MIN, table.freq_cl0);
481 pm_qos_add_request(&qos_req->pm_qos_req_cl1, PM_QOS_CLUSTER1_FREQ_MIN, table.freq_cl1);
482
483 return 0;
484 }
485
486 static int platform_mif_pm_qos_update_request(struct scsc_mif_abs *interface, struct scsc_mifqos_request *qos_req, enum scsc_qos_config config)
487 {
488 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
489 struct qos_table table;
490
491 if (!platform)
492 return -ENODEV;
493
494 if (!platform->qos_enabled) {
495 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "PM QoS not configured\n");
496 return -EOPNOTSUPP;
497 }
498
499 table = platform_mif_pm_qos_get_table(platform, config);
500
501 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev,
502 "PM QoS update request: %u. MIF %u INT %u CL0 %u CL1 %u\n", config, table.freq_mif, table.freq_int, table.freq_cl0, table.freq_cl1);
503
504 pm_qos_update_request(&qos_req->pm_qos_req_mif, table.freq_mif);
505 pm_qos_update_request(&qos_req->pm_qos_req_int, table.freq_int);
506 pm_qos_update_request(&qos_req->pm_qos_req_cl0, table.freq_cl0);
507 pm_qos_update_request(&qos_req->pm_qos_req_cl1, table.freq_cl1);
508
509 return 0;
510 }
511
512 static int platform_mif_pm_qos_remove_request(struct scsc_mif_abs *interface, struct scsc_mifqos_request *qos_req)
513 {
514 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
515
516 if (!platform)
517 return -ENODEV;
518
519
520 if (!platform->qos_enabled) {
521 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "PM QoS not configured\n");
522 return -EOPNOTSUPP;
523 }
524
525 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "PM QoS remove request\n");
526 pm_qos_remove_request(&qos_req->pm_qos_req_mif);
527 pm_qos_remove_request(&qos_req->pm_qos_req_int);
528 pm_qos_remove_request(&qos_req->pm_qos_req_cl0);
529 pm_qos_remove_request(&qos_req->pm_qos_req_cl1);
530
531 return 0;
532 }
533 #endif
534
535 static void platform_mif_irq_default_handler(int irq, void *data)
536 {
537 /* Avoid unused parameter error */
538 (void)irq;
539 (void)data;
540
541 /* int handler not registered */
542 SCSC_TAG_INFO_DEV(PLAT_MIF, NULL, "INT handler not registered\n");
543 }
544
545 static void platform_mif_irq_reset_request_default_handler(int irq, void *data)
546 {
547 /* Avoid unused parameter error */
548 (void)irq;
549 (void)data;
550
551 /* int handler not registered */
552 SCSC_TAG_INFO_DEV(PLAT_MIF, NULL, "INT reset_request handler not registered\n");
553 }
554
555 irqreturn_t platform_mif_isr(int irq, void *data)
556 {
557 struct platform_mif *platform = (struct platform_mif *)data;
558
559 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "INT %pS\n", platform->r4_handler);
560 if (platform->r4_handler != platform_mif_irq_default_handler)
561 platform->r4_handler(irq, platform->irq_dev);
562 else
563 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "MIF Interrupt Handler not registered\n");
564
565 return IRQ_HANDLED;
566 }
567
568 #ifdef CONFIG_SCSC_ENABLE_ALIVE_IRQ
569 irqreturn_t platform_alive_isr(int irq, void *data)
570 {
571 struct platform_mif *platform = (struct platform_mif *)data;
572
573 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INT received\n");
574
575 return IRQ_HANDLED;
576 }
577 #endif
578
579 irqreturn_t platform_wdog_isr(int irq, void *data)
580 {
581 int ret = 0;
582 struct platform_mif *platform = (struct platform_mif *)data;
583
584 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INT received\n");
585 if (platform->reset_request_handler != platform_mif_irq_reset_request_default_handler) {
586 disable_irq_nosync(platform->wlbt_irq[PLATFORM_MIF_WDOG].irq_num);
587 platform->reset_request_handler(irq, platform->irq_reset_request_dev);
588 } else {
589 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "WDOG Interrupt reset_request_handler not registered\n");
590 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Disabling unhandled WDOG IRQ.\n");
591 disable_irq_nosync(platform->wlbt_irq[PLATFORM_MIF_WDOG].irq_num);
592 atomic_inc(&platform->wlbt_irq[PLATFORM_MIF_WDOG].irq_disabled_cnt);
593 }
594 #ifdef CONFIG_SOC_EXYNOS9610
595 ret = regmap_update_bits(platform->pmureg, WLBT_CTRL_NS,
596 WLBT_RESET_REQ_CLR, WLBT_RESET_REQ_CLR);
597 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Clearing WLBT_RESET_REQ\n");
598 if (ret < 0)
599 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
600 "Failed to Set WLBT_CTRL_NS[WLBT_RESET_REQ_CLR]: %d\n", ret);
601 #endif
602 return IRQ_HANDLED;
603 }
604
605 #ifdef CONFIG_SOC_EXYNOS9610
606 /*
607 * Attached array contains the replacement PMU boot code which should
608 * be programmed using the CBUS during the config phase.
609 */
610 uint32_t ka_patch[] = {
611 /* Low temp fix 28/1
612 * Maxwell142 PMU+PROC combined boot ROM
613 * IP Version: 0xA3
614 * Major Version: 0xF, Minor Version: 0xF
615 * PMU ROM version: 0x4
616 * PROC ROM version: 0x0
617 */
618 0x90750002,
619 0x11a4c218,
620 0x75671191,
621 0x9075e090,
622 0x54b3e5e7,
623 0x30f76001,
624 0xb14315a2,
625 0xb4b2e503,
626 0xb153fb03,
627 0xa90185fc,
628 0xacf50774,
629 0x75fdadb5,
630 0xb47508a0,
631 0x54b3e501,
632 0x75fa7001,
633 0x907500b4,
634 0x78cb8018,
635 0x80837982,
636 0x07a075c5,
637 0xb0783779,
638 0xb40754e6,
639 0x0b800207,
640 0xc404f6d9,
641 0xaf7590f5,
642 0x75038000,
643 0x53229090,
644 0xce53eff7,
645 0xd90479fe,
646 0xfdce53fe,
647 0xfed90c79,
648 0x75fbce53,
649 0x91530b92,
650 0xf7ce53fd,
651 0x5308f943,
652 0xf922fef9,
653 0xfbd8fed9,
654 0x019e7522,
655 0x75cfc175,
656 0xc375a4c2,
657 0x47c4754a,
658 0x75a4c575,
659 0xc7756dc6,
660 0x03d27540,
661 0x7510d375,
662 0xca7500c9,
663 0x00cb75d0,
664 0x7500cc75,
665 0x9b75009a,
666 0x009c75c0,
667 0x78009d75,
668 0x12827402,
669 0xc6438b80,
670 0x74097802,
671 0x8b8012e7,
672 0x75d09075,
673 0x9e750291,
674 0x01a97502,
675 0x00000022,
676 };
677
678 extern bool reset_failed;
679
680 irqreturn_t platform_cfg_req_isr(int irq, void *data)
681 {
682 struct platform_mif *platform = (struct platform_mif *)data;
683 const u64 EXYNOS_WLBT = 0x1;
684 u64 ret64 = 0;
685 s32 ret = 0;
686 unsigned int ka_addr = 0x1000;
687 uint32_t *ka_patch_addr = ka_patch;
688 u32 id;
689
690 #define CHECK(x) do { \
691 int retval = (x); \
692 if (retval < 0) \
693 goto cfg_error; \
694 } while (0)
695
696 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INT received\n");
697 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "disable_irq\n");
698
699 /* mask the irq */
700 disable_irq_nosync(platform->wlbt_irq[PLATFORM_MIF_CFG_REQ].irq_num);
701
702 /* Was the CFG_REQ irq received from WLBT before we expected it?
703 * Typically this indicates an issue returning WLBT HW to reset.
704 */
705 if (platform->boot_state != WLBT_BOOT_WAIT_CFG_REQ) {
706 u32 val;
707 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
708 "Spurious CFG_REQ IRQ from WLBT!\n");
709
710 regmap_read(platform->pmureg, CENTRAL_SEQ_WLBT_STATUS, &val);
711 SCSC_TAG_INFO(PLAT_MIF, "CENTRAL_SEQ_WLBT_STATUS 0x%x\n", val);
712
713 regmap_read(platform->pmureg, WLBT_CTRL_NS, &val);
714 SCSC_TAG_INFO(PLAT_MIF, "WLBT_CTRL_NS 0x%x\n", val);
715
716 regmap_read(platform->pmureg, WLBT_CTRL_S, &val);
717 SCSC_TAG_INFO(PLAT_MIF, "WLBT_CTRL_S 0x%x\n", val);
718
719 regmap_read(platform->pmureg, WLBT_DEBUG, &val);
720 SCSC_TAG_INFO(PLAT_MIF, "WLBT_DEBUG 0x%x\n", val);
721
722 reset_failed = true; /* prevent further interaction with HW */
723
724 return IRQ_HANDLED;
725 }
726
727 /* CBUS should be ready before we get CFG_REQ, but we suspect
728 * CBUS is not ready yet. add some delay to see if that helps
729 */
730 udelay(100);
731
732 /* Set TZPC to non-secure mode */
733 ret64 = exynos_smc(SMC_CMD_CONN_IF, (EXYNOS_WLBT << 32) | EXYNOS_SET_CONN_TZPC, 0, 0);
734 if (ret64)
735 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
736 "Failed to set TZPC to non-secure mode: %llu\n", ret64);
737 else
738 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev,
739 "SMC_CMD_CONN_IF run successfully : %llu\n", ret64);
740
741 /* WLBT_REMAP */
742 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "WLBT_REMAP begin\n");
743 CHECK(regmap_write(platform->wlbt_remap, 0x0, WLBT_DBUS_BAAW_0_START >> 12));
744 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "WLBT_REMAP end\n");
745
746 /* CHIP_VERSION_ID - overload with EMA settings */
747 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "CHIP_VERSION_ID begin\n");
748 regmap_read(platform->wlbt_remap, 0x10, &id);
749 id &= ~CHIP_VERSION_ID_EMA_MASK;
750 id |= CHIP_VERSION_ID_EMA_VALUE;
751 CHECK(regmap_write(platform->wlbt_remap, 0x10, id));
752 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "CHIP_VERSION_ID 0x%x end\n", id);
753
754 /* DBUS_BAAW regions */
755 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "DBUS_BAAW begin\n");
756 CHECK(regmap_write(platform->dbus_baaw, 0x0, WLBT_DBUS_BAAW_0_START >> 12));
757 CHECK(regmap_write(platform->dbus_baaw, 0x4, WLBT_DBUS_BAAW_0_END >> 12));
758 CHECK(regmap_write(platform->dbus_baaw, 0x8, platform->mem_start >> 12));
759 CHECK(regmap_write(platform->dbus_baaw, 0xC, WLBT_BAAW_ACCESS_CTRL));
760 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "DBUS_BAAW end\n");
761
762 /* PBUS_BAAW regions */
763 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "PBUS_BAAW begin\n");
764 CHECK(regmap_write(platform->pbus_baaw, 0x0, WLBT_PBUS_BAAW_0_START >> 12));
765 CHECK(regmap_write(platform->pbus_baaw, 0x4, WLBT_PBUS_BAAW_0_END >> 12));
766 CHECK(regmap_write(platform->pbus_baaw, 0x8, WLBT_PBUS_MBOX_CP2WLBT_BASE >> 12));
767 CHECK(regmap_write(platform->pbus_baaw, 0xC, WLBT_BAAW_ACCESS_CTRL));
768
769 CHECK(regmap_write(platform->pbus_baaw, 0x10, WLBT_PBUS_BAAW_1_START >> 12));
770 CHECK(regmap_write(platform->pbus_baaw, 0x14, WLBT_PBUS_BAAW_1_END >> 12));
771 CHECK(regmap_write(platform->pbus_baaw, 0x18, WLBT_PBUS_MBOX_SHUB2WLBT_BASE >> 12));
772 CHECK(regmap_write(platform->pbus_baaw, 0x1C, WLBT_BAAW_ACCESS_CTRL));
773
774 CHECK(regmap_write(platform->pbus_baaw, 0x20, WLBT_PBUS_BAAW_2_START >> 12));
775 CHECK(regmap_write(platform->pbus_baaw, 0x24, WLBT_PBUS_BAAW_2_END >> 12));
776 CHECK(regmap_write(platform->pbus_baaw, 0x28, WLBT_PBUS_USI_CMG00_BASE >> 12));
777 CHECK(regmap_write(platform->pbus_baaw, 0x2C, WLBT_BAAW_ACCESS_CTRL));
778
779 CHECK(regmap_write(platform->pbus_baaw, 0x30, WLBT_PBUS_BAAW_3_START >> 12));
780 CHECK(regmap_write(platform->pbus_baaw, 0x34, WLBT_PBUS_BAAW_3_END >> 12));
781 CHECK(regmap_write(platform->pbus_baaw, 0x38, WLBT_PBUS_SYSREG_CMGP2WLBT_BASE >> 12));
782 CHECK(regmap_write(platform->pbus_baaw, 0x3C, WLBT_BAAW_ACCESS_CTRL));
783
784 CHECK(regmap_write(platform->pbus_baaw, 0x40, WLBT_PBUS_BAAW_4_START >> 12));
785 CHECK(regmap_write(platform->pbus_baaw, 0x44, WLBT_PBUS_BAAW_4_END >> 12));
786 CHECK(regmap_write(platform->pbus_baaw, 0x48, WLBT_PBUS_GPIO_CMGP_BASE >> 12));
787 CHECK(regmap_write(platform->pbus_baaw, 0x4C, WLBT_BAAW_ACCESS_CTRL));
788
789 CHECK(regmap_write(platform->pbus_baaw, 0x50, WLBT_PBUS_BAAW_5_START >> 12));
790 CHECK(regmap_write(platform->pbus_baaw, 0x54, WLBT_PBUS_BAAW_5_END >> 12));
791 CHECK(regmap_write(platform->pbus_baaw, 0x58, WLBT_PBUS_SHUB_BASE >> 12));
792 CHECK(regmap_write(platform->pbus_baaw, 0x5C, WLBT_BAAW_ACCESS_CTRL));
793 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "PBUS_BAAW end\n");
794
795 /* PMU boot bug workaround */
796 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "BOOT_WLBT begin\n");
797 CHECK(regmap_write(platform->boot_cfg, 0x0, 0x1));
798 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "BOOT_WLBT done\n");
799
800 while (ka_patch_addr < (ka_patch + ARRAY_SIZE(ka_patch))) {
801 CHECK(regmap_write(platform->boot_cfg, ka_addr, *ka_patch_addr));
802 ka_addr += sizeof(ka_patch[0]);
803 ka_patch_addr++;
804 }
805
806 /* Notify PMU of configuration done */
807 CHECK(regmap_write(platform->boot_cfg, 0x0, 0x0));
808
809 /* BOOT_CFG_ACK */
810 CHECK(regmap_write(platform->boot_cfg, 0x4, 0x1));
811 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "BOOT_CFG_ACK done\n");
812
813 /* Delay to allow HW to clear CFG_REQ and hence de-assert IRQ, which
814 * it does in response to CFG_ACK
815 */
816 udelay(100);
817
818 /* Release ownership of MASK_PWR_REQ */
819 /* See sequence in 9.6.6 */
820 ret = regmap_update_bits(platform->pmureg, WLBT_CTRL_NS,
821 MASK_PWR_REQ, 0);
822 if (ret < 0) {
823 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
824 "Failed to clear WLBT_CTRL_NS[MASK_PWR_REQ]: %d\n", ret);
825 goto cfg_error;
826 }
827
828 /* Mark as CFQ_REQ handled, so boot may continue */
829 platform->boot_state = WLBT_BOOT_CFG_DONE;
830
831 /* Signal triggering function that the IRQ arrived and CFG was done */
832 complete(&platform->cfg_ack);
833
834 /* Re-enable IRQ here to allow spurious interrupt to be tracked */
835 enable_irq(platform->wlbt_irq[PLATFORM_MIF_CFG_REQ].irq_num);
836
837 return IRQ_HANDLED;
838 cfg_error:
839 platform->boot_state = WLBT_BOOT_CFG_ERROR;
840 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "ERROR: WLBT Config failed. WLBT will not work\n");
841 complete(&platform->cfg_ack);
842 return IRQ_HANDLED;
843 }
844 #endif
845
846 static void platform_mif_unregister_irq(struct platform_mif *platform)
847 {
848 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Unregistering IRQs\n");
849
850 devm_free_irq(platform->dev, platform->wlbt_irq[PLATFORM_MIF_MBOX].irq_num, platform);
851 devm_free_irq(platform->dev, platform->wlbt_irq[PLATFORM_MIF_WDOG].irq_num, platform);
852 /* Reset irq_disabled_cnt for WDOG IRQ since the IRQ itself is here unregistered and disabled */
853 atomic_set(&platform->wlbt_irq[PLATFORM_MIF_WDOG].irq_disabled_cnt, 0);
854 #ifdef CONFIG_SCSC_ENABLE_ALIVE_IRQ
855 /* if ALIVE irq is required */
856 devm_free_irq(platform->dev, platform->wlbt_irq[PLATFORM_MIF_ALIVE].irq_num, platform);
857 #endif
858 #ifdef CONFIG_SOC_EXYNOS9610
859 devm_free_irq(platform->dev, platform->wlbt_irq[PLATFORM_MIF_CFG_REQ].irq_num, platform);
860 #endif
861 }
862
863 static int platform_mif_register_irq(struct platform_mif *platform)
864 {
865 int err;
866
867 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Registering IRQs\n");
868
869 /* Register MBOX irq */
870 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Registering MBOX irq: %d flag 0x%x\n",
871 platform->wlbt_irq[PLATFORM_MIF_MBOX].irq_num, platform->wlbt_irq[PLATFORM_MIF_MBOX].flags);
872
873 err = devm_request_irq(platform->dev, platform->wlbt_irq[PLATFORM_MIF_MBOX].irq_num, platform_mif_isr,
874 platform->wlbt_irq[PLATFORM_MIF_MBOX].flags, DRV_NAME, platform);
875 if (IS_ERR_VALUE((unsigned long)err)) {
876 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
877 "Failed to register MBOX handler: %d. Aborting.\n", err);
878 err = -ENODEV;
879 return err;
880 }
881
882 /* Register WDOG irq */
883 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Registering WDOG irq: %d flag 0x%x\n",
884 platform->wlbt_irq[PLATFORM_MIF_WDOG].irq_num, platform->wlbt_irq[PLATFORM_MIF_WDOG].flags);
885
886 err = devm_request_irq(platform->dev, platform->wlbt_irq[PLATFORM_MIF_WDOG].irq_num, platform_wdog_isr,
887 platform->wlbt_irq[PLATFORM_MIF_WDOG].flags, DRV_NAME, platform);
888 if (IS_ERR_VALUE((unsigned long)err)) {
889 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
890 "Failed to register WDOG handler: %d. Aborting.\n", err);
891 err = -ENODEV;
892 return err;
893 }
894
895 #ifdef CONFIG_SCSC_ENABLE_ALIVE_IRQ
896 /* Register ALIVE irq */
897 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Registering ALIVE irq: %d flag 0x%x\n",
898 platform->wlbt_irq[PLATFORM_MIF_ALIVE].irq_num, platform->wlbt_irq[PLATFORM_MIF_ALIVE].flags);
899
900 err = devm_request_irq(platform->dev, platform->wlbt_irq[PLATFORM_MIF_ALIVE].irq_num, platform_alive_isr,
901 platform->wlbt_irq[PLATFORM_MIF_ALIVE].flags, DRV_NAME, platform);
902 if (IS_ERR_VALUE(err)) {
903 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
904 "Failed to register ALIVE handler: %d. Aborting.\n", err);
905 err = -ENODEV;
906 return err;
907 }
908 #endif
909
910 #ifdef CONFIG_SOC_EXYNOS9610
911 /* Mark as WLBT in reset before enabling IRQ to guard against spurious IRQ */
912 platform->boot_state = WLBT_BOOT_IN_RESET;
913 smp_wmb(); /* commit before irq */
914
915 /* Register WB2AP_CFG_REQ irq */
916 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Registering CFG_REQ irq: %d flag 0x%x\n",
917 platform->wlbt_irq[PLATFORM_MIF_CFG_REQ].irq_num, platform->wlbt_irq[PLATFORM_MIF_CFG_REQ].flags);
918
919 err = devm_request_irq(platform->dev, platform->wlbt_irq[PLATFORM_MIF_CFG_REQ].irq_num, platform_cfg_req_isr,
920 platform->wlbt_irq[PLATFORM_MIF_CFG_REQ].flags, DRV_NAME, platform);
921 if (IS_ERR_VALUE((unsigned long)err)) {
922 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
923 "Failed to register CFG_REQ handler: %d. Aborting.\n", err);
924 err = -ENODEV;
925 return err;
926 }
927 #endif
928 return 0;
929 }
930
931 static void platform_mif_destroy(struct scsc_mif_abs *interface)
932 {
933 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
934
935 platform_mif_unregister_irq(platform);
936 }
937
938 static char *platform_mif_get_uid(struct scsc_mif_abs *interface)
939 {
940 /* Avoid unused parameter error */
941 (void)interface;
942 return "0";
943 }
944
945 /* WLBT Power domain */
946 static int platform_mif_power(struct scsc_mif_abs *interface, bool power)
947 {
948 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
949 u32 val = 0;
950 s32 ret = 0;
951 #ifdef CONFIG_SOC_EXYNOS9610
952 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "power %d\n", power);
953
954 if (power)
955 val = MASK_PWR_REQ;
956
957 /* See sequence in 9.6.6 */
958 ret = regmap_update_bits(platform->pmureg, WLBT_CTRL_NS,
959 MASK_PWR_REQ, val);
960 if (ret < 0) {
961 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
962 "Failed to update WLBT_CTRL_NS[MASK_PWR_REQ]: %d\n", ret);
963 return ret;
964 }
965 #endif
966 return 0;
967 }
968
969 /* WLBT RESET */
970 static int platform_mif_hold_reset(struct scsc_mif_abs *interface, bool reset)
971 {
972 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
973 u32 val = 0;
974 s32 ret = 0;
975 #ifdef CONFIG_SOC_EXYNOS9610
976 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "reset %d\n", reset);
977 if (reset)
978 val = WLBT_RESET_SET;
979 /* See sequence in 9.6.6 */
980 ret = regmap_update_bits(platform->pmureg, WLBT_CTRL_NS,
981 WLBT_RESET_SET, val);
982 if (ret < 0) {
983 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
984 "Failed to update WLBT_CTRL_NS[WLBT_RESET_SET]: %d\n", ret);
985 return ret;
986 }
987 #endif
988 return 0;
989 }
990
991 /* WLBT START */
992 static int platform_mif_start(struct scsc_mif_abs *interface, bool start)
993 {
994 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
995 u32 val = 0;
996 s32 ret = 0;
997
998 #ifdef CONFIG_SOC_EXYNOS9610
999 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "start %d\n", start);
1000 if (start)
1001 val = WLBT_START;
1002
1003 /* See sequence in 9.6.6 */
1004 ret = regmap_update_bits(platform->pmureg, WLBT_CTRL_S,
1005 WLBT_START, val);
1006 if (ret < 0) {
1007 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1008 "Failed to update WLBT_CTRL_S[WLBT_START]: %d\n", ret);
1009 return ret;
1010 }
1011 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1012 "update WIFI_CTRL_S[WIFI_START]: %d\n", ret);
1013
1014 /* At this point WLBT should assert the CFG_REQ IRQ, so wait for it */
1015 if (start &&
1016 wait_for_completion_timeout(&platform->cfg_ack, WLBT_BOOT_TIMEOUT) == 0) {
1017 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "Timeout waiting for CFG_REQ IRQ\n");
1018 regmap_read(platform->pmureg, CENTRAL_SEQ_WLBT_STATUS, &val);
1019 SCSC_TAG_INFO(PLAT_MIF, "CENTRAL_SEQ_WLBT_STATUS 0x%x\n", val);
1020 regmap_read(platform->pmureg, WLBT_DEBUG, &val);
1021 SCSC_TAG_INFO(PLAT_MIF, "WLBT_DEBUG 0x%x\n", val);
1022 return -ETIMEDOUT;
1023 }
1024 /* only continue if CFG_REQ IRQ configured WLBT/PMU correctly */
1025 if (platform->boot_state == WLBT_BOOT_CFG_ERROR) {
1026 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "CFG_REQ failed to configure WLBT.\n");
1027 return -EIO;
1028 }
1029 #endif
1030 return 0;
1031 }
1032
1033 static int platform_mif_pmu_reset_release(struct scsc_mif_abs *interface)
1034 {
1035 int ret = 0;
1036 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1037
1038 #ifdef CONFIG_SOC_EXYNOS9610
1039 /* We're now ready for the IRQ */
1040 platform->boot_state = WLBT_BOOT_WAIT_CFG_REQ;
1041 smp_wmb(); /* commit before irq */
1042 #endif
1043 ret = platform_mif_power(interface, true);
1044 if (ret)
1045 return ret;
1046 ret = platform_mif_hold_reset(interface, false);
1047 if (ret)
1048 return ret;
1049 ret = platform_mif_start(interface, true);
1050 if (ret)
1051 return ret;
1052
1053 return ret;
1054 }
1055
1056 static int platform_mif_pmu_reset(struct scsc_mif_abs *interface, u8 rst_case)
1057 {
1058 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1059 unsigned long timeout;
1060 int ret;
1061 u32 val;
1062
1063 if (rst_case == 0 || rst_case > 2) {
1064 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1065 "Incorrect pmu reset case %d\n", rst_case);
1066 return -EIO;
1067 }
1068
1069 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "rst_case %d\n", rst_case);
1070
1071 /* Revert power control ownership to AP, as WLBT is going down (S9.6.6). */
1072 ret = regmap_update_bits(platform->pmureg, WLBT_CTRL_NS,
1073 MASK_PWR_REQ, MASK_PWR_REQ);
1074 if (ret < 0) {
1075 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1076 "Failed to update WLBT_CTRL_NS[MASK_PWR_REQ]: %d\n", ret);
1077 return ret;
1078 }
1079
1080 /* reset sequence as per excite implementation for Leman */
1081 ret = regmap_update_bits(platform->pmureg, CENTRAL_SEQ_WLBT_CONFIGURATION,
1082 SYS_PWR_CFG_16, 0);
1083 if (ret < 0) {
1084 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1085 "Failed to update CENTRAL_SEQ_WLBT_CONFIGURATION %d\n", ret);
1086 return ret;
1087 }
1088
1089 ret = regmap_update_bits(platform->pmureg, RESET_AHEAD_WLBT_SYS_PWR_REG,
1090 SYS_PWR_CFG_2, 0);
1091 if (ret < 0) {
1092 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1093 "Failed to update RESET_AHEAD_WLBT_SYS_PWR_REG %d\n", ret);
1094 return ret;
1095 }
1096
1097 ret = regmap_update_bits(platform->pmureg, CLEANY_BUS_WLBT_SYS_PWR_REG,
1098 SYS_PWR_CFG, 0);
1099 if (ret < 0) {
1100 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1101 "Failed to update CLEANY_BUS_WLBT_SYS_PWR_REG%d\n", ret);
1102 return ret;
1103 }
1104
1105 ret = regmap_update_bits(platform->pmureg, LOGIC_RESET_WLBT_SYS_PWR_REG,
1106 SYS_PWR_CFG_2, 0);
1107 if (ret < 0) {
1108 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1109 "Failed to update LOGIC_RESET_WLBT_SYS_PWR_REG %d\n", ret);
1110 return ret;
1111 }
1112
1113 ret = regmap_update_bits(platform->pmureg, TCXO_GATE_WLBT_SYS_PWR_REG,
1114 SYS_PWR_CFG, 0);
1115 if (ret < 0) {
1116 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1117 "Failed to update TCXO_GATE_WLBT_SYS_PWR_REG %d\n", ret);
1118 return ret;
1119 }
1120
1121 ret = regmap_update_bits(platform->pmureg, WLBT_DISABLE_ISO_SYS_PWR_REG,
1122 SYS_PWR_CFG, 1);
1123 if (ret < 0) {
1124 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1125 "Failed to update WLBT_DISABLE_ISO_SYS_PWR_REG %d\n", ret);
1126 return ret;
1127 }
1128
1129 ret = regmap_update_bits(platform->pmureg, WLBT_RESET_ISO_SYS_PWR_REG,
1130 SYS_PWR_CFG, 0);
1131 if (ret < 0) {
1132 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1133 "Failed to update WLBT_RESET_ISO_SYS_PWR_REG %d\n", ret);
1134 return ret;
1135 }
1136
1137 /* rst_case is always 2 on 9610 */
1138 ret = platform_mif_hold_reset(interface, true);
1139
1140 if (ret)
1141 return ret;
1142
1143 timeout = jiffies + msecs_to_jiffies(500);
1144 do {
1145 regmap_read(platform->pmureg, CENTRAL_SEQ_WLBT_STATUS, &val);
1146 val &= STATES;
1147 val >>= 16;
1148 if (val == 0x80) {
1149 /* OK. Switch CTRL_NS[MASK_PWR_REQ] ownership to FW following
1150 * reset. WLBT PWR_REQ is cleared when it's put in reset.
1151 * The SW PWR_REQ remains asserted, but as ownership is now FW,
1152 * it'll be ignored. This leaves it as we found it.
1153 */
1154 platform_mif_power(interface, false);
1155
1156 return 0; /* OK - return */
1157 }
1158 } while (time_before(jiffies, timeout));
1159
1160 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1161 "Timeout waiting for CENTRAL_SEQ_WLBT_STATUS SM status\n");
1162 regmap_read(platform->pmureg, CENTRAL_SEQ_WLBT_STATUS, &val);
1163 SCSC_TAG_INFO(PLAT_MIF, "CENTRAL_SEQ_WLBT_STATUS 0x%x\n", val);
1164 regmap_read(platform->pmureg, WLBT_DEBUG, &val);
1165 SCSC_TAG_INFO(PLAT_MIF, "WLBT_DEBUG 0x%x\n", val);
1166
1167 return -ETIME;
1168 }
1169
1170 /* reset=0 - release from reset */
1171 /* reset=1 - hold reset */
1172 static int platform_mif_reset(struct scsc_mif_abs *interface, bool reset)
1173 {
1174 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1175 u32 ret = 0;
1176
1177 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "\n");
1178
1179 if (enable_platform_mif_arm_reset || !reset) {
1180 if (!reset) { /* Release from reset */
1181 #ifdef CONFIG_ARCH_EXYNOS
1182 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev,
1183 "SOC_VERSION: product_id 0x%x, rev 0x%x\n",
1184 exynos_soc_info.product_id, exynos_soc_info.revision);
1185 #endif
1186 ret = platform_mif_pmu_reset_release(interface);
1187 } else {
1188 /* Put back into reset */
1189 ret = platform_mif_pmu_reset(interface, 2);
1190 }
1191 } else
1192 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Not resetting ARM Cores - enable_platform_mif_arm_reset: %d\n",
1193 enable_platform_mif_arm_reset);
1194 return ret;
1195 }
1196
1197 static void __iomem *platform_mif_map_region(unsigned long phys_addr, size_t size)
1198 {
1199 int i;
1200 struct page **pages;
1201 void *vmem;
1202
1203 size = PAGE_ALIGN(size);
1204
1205 pages = kmalloc((size >> PAGE_SHIFT) * sizeof(*pages), GFP_KERNEL);
1206 if (!pages)
1207 return NULL;
1208
1209 /* Map NORMAL_NC pages with kernel virtual space */
1210 for (i = 0; i < (size >> PAGE_SHIFT); i++) {
1211 pages[i] = phys_to_page(phys_addr);
1212 phys_addr += PAGE_SIZE;
1213 }
1214
1215 vmem = vmap(pages, size >> PAGE_SHIFT, VM_MAP, pgprot_writecombine(PAGE_KERNEL));
1216
1217 kfree(pages);
1218 return (void __iomem *)vmem;
1219 }
1220
1221 static void platform_mif_unmap_region(void *vmem)
1222 {
1223 vunmap(vmem);
1224 }
1225
1226 static void *platform_mif_map(struct scsc_mif_abs *interface, size_t *allocated)
1227 {
1228 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1229 u8 i;
1230
1231 if (allocated)
1232 *allocated = 0;
1233
1234 platform->mem =
1235 platform_mif_map_region(platform->mem_start, platform->mem_size);
1236
1237 if (!platform->mem) {
1238 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "Error remaping shared memory\n");
1239 return NULL;
1240 }
1241
1242 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Map: virt %p phys %lx\n", platform->mem, (uintptr_t)platform->mem_start);
1243
1244 /* Initialise MIF registers with documented defaults */
1245 /* MBOXes */
1246 for (i = 0; i < NUM_MBOX_PLAT; i++)
1247 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(ISSR(i)), 0x00000000);
1248
1249 /* MRs */ /*1's - set all as Masked */
1250 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTMR0), 0xffff0000);
1251 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTMR1), 0x0000ffff);
1252 /* CRs */ /* 1's - clear all the interrupts */
1253 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTCR0), 0xffff0000);
1254 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTCR1), 0x0000ffff);
1255
1256 #ifdef CONFIG_SCSC_CHV_SUPPORT
1257 if (chv_disable_irq == true) {
1258 if (allocated)
1259 *allocated = platform->mem_size;
1260 return platform->mem;
1261 }
1262 #endif
1263 /* register interrupts */
1264 if (platform_mif_register_irq(platform)) {
1265 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Unmap: virt %p phys %lx\n", platform->mem, (uintptr_t)platform->mem_start);
1266 platform_mif_unmap_region(platform->mem);
1267 return NULL;
1268 }
1269
1270 if (allocated)
1271 *allocated = platform->mem_size;
1272 /* Set the CR4 base address in Mailbox??*/
1273 return platform->mem;
1274 }
1275
1276 /* HERE: Not sure why mem is passed in - its stored in platform - as it should be */
1277 static void platform_mif_unmap(struct scsc_mif_abs *interface, void *mem)
1278 {
1279 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1280
1281 /* Avoid unused parameter error */
1282 (void)mem;
1283
1284 /* MRs */ /*1's - set all as Masked */
1285 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTMR0), 0xffff0000);
1286 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTMR1), 0x0000ffff);
1287
1288 #ifdef CONFIG_SCSC_CHV_SUPPORT
1289 /* Restore PIO changed by Maxwell subsystem */
1290 if (chv_disable_irq == false)
1291 /* Unregister IRQs */
1292 platform_mif_unregister_irq(platform);
1293 #else
1294 platform_mif_unregister_irq(platform);
1295 #endif
1296 /* CRs */ /* 1's - clear all the interrupts */
1297 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTCR0), 0xffff0000);
1298 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTCR1), 0x0000ffff);
1299 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Unmap: virt %p phys %lx\n", platform->mem, (uintptr_t)platform->mem_start);
1300 platform_mif_unmap_region(platform->mem);
1301 platform->mem = NULL;
1302 }
1303
1304 static u32 platform_mif_irq_bit_mask_status_get(struct scsc_mif_abs *interface)
1305 {
1306 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1307 u32 val;
1308
1309 val = platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTMR0)) >> 16;
1310 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "Getting INTMR0: 0x%x\n", val);
1311 return val;
1312 }
1313
1314 static u32 platform_mif_irq_get(struct scsc_mif_abs *interface)
1315 {
1316 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1317 u32 val;
1318
1319 /* Function has to return the interrupts that are enabled *AND* not masked */
1320 val = platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTMSR0)) >> 16;
1321 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "Getting INT-INTMSR0: 0x%x\n", val);
1322
1323 return val;
1324 }
1325
1326 static void platform_mif_irq_bit_set(struct scsc_mif_abs *interface, int bit_num, enum scsc_mif_abs_target target)
1327 {
1328 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1329 u32 reg;
1330
1331 if (bit_num >= 16) {
1332 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "Incorrect INT number: %d\n", bit_num);
1333 return;
1334 }
1335
1336 #ifdef CONFIG_SOC_EXYNOS9610
1337 reg = INTGR1;
1338 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(reg), (1 << bit_num));
1339 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "Setting INTGR1: bit %d on target %d\n", bit_num, target);
1340 #endif
1341 }
1342
1343 static void platform_mif_irq_bit_clear(struct scsc_mif_abs *interface, int bit_num)
1344 {
1345 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1346
1347 if (bit_num >= 16) {
1348 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "Incorrect INT number: %d\n", bit_num);
1349 return;
1350 }
1351 /* WRITE : 1 = Clears Interrupt */
1352 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTCR0), ((1 << bit_num) << 16));
1353 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "Setting INTCR0: bit %d\n", bit_num);
1354 }
1355
1356 static void platform_mif_irq_bit_mask(struct scsc_mif_abs *interface, int bit_num)
1357 {
1358 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1359 u32 val;
1360 unsigned long flags;
1361
1362 if (bit_num >= 16) {
1363 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "Incorrect INT number: %d\n", bit_num);
1364 return;
1365 }
1366 spin_lock_irqsave(&platform->mif_spinlock, flags);
1367 val = platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTMR0));
1368 /* WRITE : 1 = Mask Interrupt */
1369 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTMR0), val | ((1 << bit_num) << 16));
1370 spin_unlock_irqrestore(&platform->mif_spinlock, flags);
1371 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "Setting INTMR0: 0x%x bit %d\n", val | (1 << bit_num), bit_num);
1372 }
1373
1374 static void platform_mif_irq_bit_unmask(struct scsc_mif_abs *interface, int bit_num)
1375 {
1376 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1377 u32 val;
1378 unsigned long flags;
1379
1380 if (bit_num >= 16) {
1381 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "Incorrect INT number: %d\n", bit_num);
1382 return;
1383 }
1384 spin_lock_irqsave(&platform->mif_spinlock, flags);
1385 val = platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTMR0));
1386 /* WRITE : 0 = Unmask Interrupt */
1387 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTMR0), val & ~((1 << bit_num) << 16));
1388 spin_unlock_irqrestore(&platform->mif_spinlock, flags);
1389 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "UNMASK Setting INTMR0: 0x%x bit %d\n", val & ~((1 << bit_num) << 16), bit_num);
1390 }
1391
1392 /* Return the contents of the mask register */
1393 static u32 __platform_mif_irq_bit_mask_read(struct platform_mif *platform)
1394 {
1395 u32 val;
1396 unsigned long flags;
1397
1398 spin_lock_irqsave(&platform->mif_spinlock, flags);
1399 val = platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTMR0));
1400 spin_unlock_irqrestore(&platform->mif_spinlock, flags);
1401 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "Read INTMR0: 0x%x\n", val);
1402
1403 return val;
1404 }
1405
1406 /* Write the mask register, destroying previous contents */
1407 static void __platform_mif_irq_bit_mask_write(struct platform_mif *platform, u32 val)
1408 {
1409 unsigned long flags;
1410
1411 spin_lock_irqsave(&platform->mif_spinlock, flags);
1412 platform_mif_reg_write(platform, MAILBOX_WLBT_REG(INTMR0), val);
1413 spin_unlock_irqrestore(&platform->mif_spinlock, flags);
1414 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "Write INTMR0: 0x%x\n", val);
1415 }
1416
1417 static void platform_mif_irq_reg_handler(struct scsc_mif_abs *interface, void (*handler)(int irq, void *data), void *dev)
1418 {
1419 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1420 unsigned long flags;
1421
1422 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Registering mif int handler %pS in %p %p\n", handler, platform, interface);
1423 spin_lock_irqsave(&platform->mif_spinlock, flags);
1424 platform->r4_handler = handler;
1425 platform->irq_dev = dev;
1426 spin_unlock_irqrestore(&platform->mif_spinlock, flags);
1427 }
1428
1429 static void platform_mif_irq_unreg_handler(struct scsc_mif_abs *interface)
1430 {
1431 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1432 unsigned long flags;
1433
1434 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Unregistering mif int handler %pS\n", interface);
1435 spin_lock_irqsave(&platform->mif_spinlock, flags);
1436 platform->r4_handler = platform_mif_irq_default_handler;
1437 platform->irq_dev = NULL;
1438 spin_unlock_irqrestore(&platform->mif_spinlock, flags);
1439 }
1440
1441 static void platform_mif_irq_reg_reset_request_handler(struct scsc_mif_abs *interface, void (*handler)(int irq, void *data), void *dev)
1442 {
1443 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1444
1445 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Registering mif reset_request int handler %pS in %p %p\n", handler, platform, interface);
1446 platform->reset_request_handler = handler;
1447 platform->irq_reset_request_dev = dev;
1448 if (atomic_read(&platform->wlbt_irq[PLATFORM_MIF_WDOG].irq_disabled_cnt)) {
1449 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev,
1450 "Default WDOG handler disabled by spurios IRQ...re-enabling.\n");
1451 enable_irq(platform->wlbt_irq[PLATFORM_MIF_WDOG].irq_num);
1452 atomic_set(&platform->wlbt_irq[PLATFORM_MIF_WDOG].irq_disabled_cnt, 0);
1453 }
1454 }
1455
1456 static void platform_mif_irq_unreg_reset_request_handler(struct scsc_mif_abs *interface)
1457 {
1458 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1459
1460 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "UnRegistering mif reset_request int handler %pS\n", interface);
1461 platform->reset_request_handler = platform_mif_irq_reset_request_default_handler;
1462 platform->irq_reset_request_dev = NULL;
1463 }
1464
1465 static void platform_mif_suspend_reg_handler(struct scsc_mif_abs *interface,
1466 int (*suspend)(struct scsc_mif_abs *abs, void *data),
1467 void (*resume)(struct scsc_mif_abs *abs, void *data),
1468 void *data)
1469 {
1470 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1471
1472 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Registering mif suspend/resume handlers in %p %p\n", platform, interface);
1473 platform->suspend_handler = suspend;
1474 platform->resume_handler = resume;
1475 platform->suspendresume_data = data;
1476 }
1477
1478 static void platform_mif_suspend_unreg_handler(struct scsc_mif_abs *interface)
1479 {
1480 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1481
1482 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Unregistering mif suspend/resume handlers in %p %p\n", platform, interface);
1483 platform->suspend_handler = NULL;
1484 platform->resume_handler = NULL;
1485 platform->suspendresume_data = NULL;
1486 }
1487
1488 static u32 *platform_mif_get_mbox_ptr(struct scsc_mif_abs *interface, u32 mbox_index)
1489 {
1490 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1491 u32 *addr;
1492
1493 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "mbox_index 0x%x\n", mbox_index);
1494 addr = platform->base + MAILBOX_WLBT_REG(ISSR(mbox_index));
1495 return addr;
1496 }
1497
1498 static int platform_mif_get_mifram_ref(struct scsc_mif_abs *interface, void *ptr, scsc_mifram_ref *ref)
1499 {
1500 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1501
1502 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "\n");
1503
1504 if (!platform->mem) {
1505 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "Memory unmmaped\n");
1506 return -ENOMEM;
1507 }
1508
1509 /* Check limits! */
1510 if (ptr >= (platform->mem + platform->mem_size)) {
1511 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "Unable to get pointer reference\n");
1512 return -ENOMEM;
1513 }
1514
1515 *ref = (scsc_mifram_ref)((uintptr_t)ptr - (uintptr_t)platform->mem);
1516
1517 return 0;
1518 }
1519
1520 static void *platform_mif_get_mifram_ptr(struct scsc_mif_abs *interface, scsc_mifram_ref ref)
1521 {
1522 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1523
1524 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "\n");
1525
1526 if (!platform->mem) {
1527 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "Memory unmmaped\n");
1528 return NULL;
1529 }
1530
1531 /* Check limits */
1532 if (ref >= 0 && ref < platform->mem_size)
1533 return (void *)((uintptr_t)platform->mem + (uintptr_t)ref);
1534 else
1535 return NULL;
1536 }
1537
1538 static void *platform_mif_get_mifram_phy_ptr(struct scsc_mif_abs *interface, scsc_mifram_ref ref)
1539 {
1540 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1541
1542 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "\n");
1543
1544 if (!platform->mem_start) {
1545 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "Memory unmmaped\n");
1546 return NULL;
1547 }
1548
1549 return (void *)((uintptr_t)platform->mem_start + (uintptr_t)ref);
1550 }
1551
1552 static uintptr_t platform_mif_get_mif_pfn(struct scsc_mif_abs *interface)
1553 {
1554 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1555
1556 return vmalloc_to_pfn(platform->mem);
1557 }
1558
1559 static struct device *platform_mif_get_mif_device(struct scsc_mif_abs *interface)
1560 {
1561 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1562
1563 SCSC_TAG_DEBUG_DEV(PLAT_MIF, platform->dev, "\n");
1564
1565 return platform->dev;
1566 }
1567
1568 static void platform_mif_irq_clear(void)
1569 {
1570 /* Implement if required */
1571 }
1572
1573 static int platform_mif_read_register(struct scsc_mif_abs *interface, u64 id, u32 *val)
1574 {
1575 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1576
1577 if (id == SCSC_REG_READ_WLBT_STAT) {
1578 regmap_read(platform->pmureg, WLBT_STAT, val);
1579 return 0;
1580 }
1581
1582 return -EIO;
1583 }
1584
1585 static void platform_mif_dump_register(struct scsc_mif_abs *interface)
1586 {
1587 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1588 unsigned long flags;
1589
1590 spin_lock_irqsave(&platform->mif_spinlock, flags);
1591
1592 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INTGR0 0x%08x\n", platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTGR0)));
1593 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INTGR1 0x%08x\n", platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTGR1)));
1594 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INTCR0 0x%08x\n", platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTCR0)));
1595 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INTCR1 0x%08x\n", platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTCR1)));
1596 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INTMR0 0x%08x\n", platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTMR0)));
1597 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INTMR1 0x%08x\n", platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTMR1)));
1598 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INTSR0 0x%08x\n", platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTSR0)));
1599 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INTSR1 0x%08x\n", platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTSR1)));
1600 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INTMSR0 0x%08x\n", platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTMSR0)));
1601 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "INTMSR1 0x%08x\n", platform_mif_reg_read(platform, MAILBOX_WLBT_REG(INTMSR1)));
1602
1603 spin_unlock_irqrestore(&platform->mif_spinlock, flags);
1604 }
1605
1606 static void platform_mif_cleanup(struct scsc_mif_abs *interface)
1607 {
1608 }
1609
1610 static void platform_mif_restart(struct scsc_mif_abs *interface)
1611 {
1612 }
1613
1614 #ifdef CONFIG_OF_RESERVED_MEM
1615 static int __init platform_mif_wifibt_if_reserved_mem_setup(struct reserved_mem *remem)
1616 {
1617 SCSC_TAG_DEBUG(PLAT_MIF, "memory reserved: mem_base=%#lx, mem_size=%zd\n",
1618 (unsigned long)remem->base, (size_t)remem->size);
1619
1620 sharedmem_base = remem->base;
1621 sharedmem_size = remem->size;
1622 return 0;
1623 }
1624 RESERVEDMEM_OF_DECLARE(wifibt_if, "exynos,wifibt_if", platform_mif_wifibt_if_reserved_mem_setup);
1625 #endif
1626
1627 struct scsc_mif_abs *platform_mif_create(struct platform_device *pdev)
1628 {
1629 struct scsc_mif_abs *platform_if;
1630 struct platform_mif *platform =
1631 (struct platform_mif *)devm_kzalloc(&pdev->dev, sizeof(struct platform_mif), GFP_KERNEL);
1632 int err = 0;
1633 u8 i = 0;
1634 struct resource *reg_res;
1635
1636 #ifdef CONFIG_SCSC_SMAPPER
1637 u32 smapper_banks = 0;
1638 #endif
1639
1640 if (!platform)
1641 return NULL;
1642
1643 SCSC_TAG_INFO_DEV(PLAT_MIF, &pdev->dev, "Creating MIF platform device\n");
1644
1645 platform_if = &platform->interface;
1646
1647 /* initialise interface structure */
1648 platform_if->destroy = platform_mif_destroy;
1649 platform_if->get_uid = platform_mif_get_uid;
1650 platform_if->reset = platform_mif_reset;
1651 platform_if->map = platform_mif_map;
1652 platform_if->unmap = platform_mif_unmap;
1653 platform_if->irq_bit_set = platform_mif_irq_bit_set;
1654 platform_if->irq_get = platform_mif_irq_get;
1655 platform_if->irq_bit_mask_status_get = platform_mif_irq_bit_mask_status_get;
1656 platform_if->irq_bit_clear = platform_mif_irq_bit_clear;
1657 platform_if->irq_bit_mask = platform_mif_irq_bit_mask;
1658 platform_if->irq_bit_unmask = platform_mif_irq_bit_unmask;
1659 platform_if->irq_reg_handler = platform_mif_irq_reg_handler;
1660 platform_if->irq_unreg_handler = platform_mif_irq_unreg_handler;
1661 platform_if->irq_reg_reset_request_handler = platform_mif_irq_reg_reset_request_handler;
1662 platform_if->irq_unreg_reset_request_handler = platform_mif_irq_unreg_reset_request_handler;
1663 platform_if->suspend_reg_handler = platform_mif_suspend_reg_handler;
1664 platform_if->suspend_unreg_handler = platform_mif_suspend_unreg_handler;
1665 platform_if->get_mbox_ptr = platform_mif_get_mbox_ptr;
1666 platform_if->get_mifram_ptr = platform_mif_get_mifram_ptr;
1667 platform_if->get_mifram_ref = platform_mif_get_mifram_ref;
1668 platform_if->get_mifram_pfn = platform_mif_get_mif_pfn;
1669 platform_if->get_mifram_phy_ptr = platform_mif_get_mifram_phy_ptr;
1670 platform_if->get_mif_device = platform_mif_get_mif_device;
1671 platform_if->irq_clear = platform_mif_irq_clear;
1672 platform_if->mif_dump_registers = platform_mif_dump_register;
1673 platform_if->mif_read_register = platform_mif_read_register;
1674 platform_if->mif_cleanup = platform_mif_cleanup;
1675 platform_if->mif_restart = platform_mif_restart;
1676 #ifdef CONFIG_SCSC_SMAPPER
1677 platform_if->mif_smapper_get_mapping = platform_mif_smapper_get_mapping;
1678 platform_if->mif_smapper_get_bank_info = platform_mif_smapper_get_bank_info;
1679 platform_if->mif_smapper_write_sram = platform_mif_smapper_write_sram;
1680 platform_if->mif_smapper_configure = platform_mif_smapper_configure;
1681 platform_if->mif_smapper_get_bank_base_address = platform_mif_smapper_get_bank_base_address;
1682 #endif
1683 #ifdef CONFIG_SCSC_QOS
1684 platform_if->mif_pm_qos_add_request = platform_mif_pm_qos_add_request;
1685 platform_if->mif_pm_qos_update_request = platform_mif_pm_qos_update_request;
1686 platform_if->mif_pm_qos_remove_request = platform_mif_pm_qos_remove_request;
1687 #endif
1688 /* Update state */
1689 platform->pdev = pdev;
1690 platform->dev = &pdev->dev;
1691
1692 platform->r4_handler = platform_mif_irq_default_handler;
1693 platform->irq_dev = NULL;
1694 platform->reset_request_handler = platform_mif_irq_reset_request_default_handler;
1695 platform->irq_reset_request_dev = NULL;
1696 platform->suspend_handler = NULL;
1697 platform->resume_handler = NULL;
1698 platform->suspendresume_data = NULL;
1699
1700 #ifdef CONFIG_OF_RESERVED_MEM
1701 platform->mem_start = sharedmem_base;
1702 platform->mem_size = sharedmem_size;
1703 #else
1704 /* If CONFIG_OF_RESERVED_MEM is not defined, sharedmem values should be
1705 * parsed from the scsc_wifibt binding
1706 */
1707 if (of_property_read_u32(pdev->dev.of_node, "sharedmem-base", &sharedmem_base)) {
1708 err = -EINVAL;
1709 goto error_exit;
1710 }
1711 platform->mem_start = sharedmem_base;
1712
1713 if (of_property_read_u32(pdev->dev.of_node, "sharedmem-size", &sharedmem_size)) {
1714 err = -EINVAL;
1715 goto error_exit;
1716 }
1717 platform->mem_size = sharedmem_size;
1718 #endif
1719 #ifdef CONFIG_SCSC_SMAPPER
1720 platform->smapper = NULL;
1721 #endif
1722
1723 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "platform->mem_start 0x%x platform->mem_size 0x%x\n",
1724 (u32)platform->mem_start, (u32)platform->mem_size);
1725 if (platform->mem_start == 0)
1726 SCSC_TAG_WARNING_DEV(PLAT_MIF, platform->dev, "platform->mem_start is 0");
1727
1728 if (platform->mem_size == 0) {
1729 /* We return return if mem_size is 0 as it does not make any sense.
1730 * This may be an indication of an incorrect platform device binding.
1731 */
1732 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "platform->mem_size is 0");
1733 err = -EINVAL;
1734 goto error_exit;
1735 }
1736
1737 /* Memory resource - Phys Address of MAILBOX_WLBT register map */
1738 reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1739 if (!reg_res) {
1740 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1741 "Error getting mem resource for MAILBOX_WLBT\n");
1742 err = -ENOENT;
1743 goto error_exit;
1744 }
1745
1746 platform->reg_start = reg_res->start;
1747 platform->reg_size = resource_size(reg_res);
1748
1749 platform->base =
1750 devm_ioremap_nocache(platform->dev, reg_res->start, resource_size(reg_res));
1751
1752 if (!platform->base) {
1753 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1754 "Error mapping register region\n");
1755 err = -EBUSY;
1756 goto error_exit;
1757 }
1758 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "platform->reg_start %lx size %x base %p\n",
1759 (uintptr_t)platform->reg_start, (u32)platform->reg_size, platform->base);
1760
1761 /* Get the 4 IRQ resources */
1762 for (i = 0; i < 4; i++) {
1763 struct resource *irq_res;
1764 int irqtag;
1765
1766 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
1767 if (!irq_res) {
1768 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev, "No IRQ resource at index %d\n", i);
1769 err = -ENOENT;
1770 goto error_exit;
1771 }
1772
1773 if (!strcmp(irq_res->name, "MBOX")) {
1774 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "MBOX irq %d flag 0x%x\n", (u32)irq_res->start, (u32)irq_res->flags);
1775 irqtag = PLATFORM_MIF_MBOX;
1776 } else if (!strcmp(irq_res->name, "ALIVE")) {
1777 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "ALIVE irq %d flag 0x%x\n", (u32)irq_res->start, (u32)irq_res->flags);
1778 irqtag = PLATFORM_MIF_ALIVE;
1779 } else if (!strcmp(irq_res->name, "WDOG")) {
1780 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "WDOG irq %d flag 0x%x\n", (u32)irq_res->start, (u32)irq_res->flags);
1781 irqtag = PLATFORM_MIF_WDOG;
1782 } else if (!strcmp(irq_res->name, "CFG_REQ")) {
1783 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "CFG_REQ irq %d flag 0x%x\n", (u32)irq_res->start, (u32)irq_res->flags);
1784 irqtag = PLATFORM_MIF_CFG_REQ;
1785 } else {
1786 SCSC_TAG_ERR_DEV(PLAT_MIF, &pdev->dev, "Invalid irq res name: %s\n",
1787 irq_res->name);
1788 err = -EINVAL;
1789 goto error_exit;
1790 }
1791 platform->wlbt_irq[irqtag].irq_num = irq_res->start;
1792 platform->wlbt_irq[irqtag].flags = (irq_res->flags & IRQF_TRIGGER_MASK);
1793 atomic_set(&platform->wlbt_irq[irqtag].irq_disabled_cnt, 0);
1794 }
1795
1796 /* PMU reg map - syscon */
1797 platform->pmureg = syscon_regmap_lookup_by_phandle(platform->dev->of_node,
1798 "samsung,syscon-phandle");
1799 if (IS_ERR(platform->pmureg)) {
1800 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1801 "syscon regmap lookup failed. Aborting. %ld\n", PTR_ERR(platform->pmureg));
1802 err = -EINVAL;
1803 goto error_exit;
1804 }
1805
1806 #ifdef CONFIG_SOC_EXYNOS9610
1807 /* Completion event and state used to indicate CFG_REQ IRQ occurred */
1808 init_completion(&platform->cfg_ack);
1809 platform->boot_state = WLBT_BOOT_IN_RESET;
1810
1811 /* BAAW_P_WLBT */
1812 platform->baaw_p_wlbt = syscon_regmap_lookup_by_phandle(platform->dev->of_node,
1813 "samsung,baaw_p_wlbt-syscon-phandle");
1814 if (IS_ERR(platform->baaw_p_wlbt)) {
1815 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1816 "baaw_p_wlbt regmap lookup failed. Aborting. %ld\n", PTR_ERR(platform->baaw_p_wlbt));
1817 err = -EINVAL;
1818 goto error_exit;
1819 }
1820
1821 /* DBUS_BAAW */
1822 platform->dbus_baaw = syscon_regmap_lookup_by_phandle(platform->dev->of_node,
1823 "samsung,dbus_baaw-syscon-phandle");
1824 if (IS_ERR(platform->dbus_baaw)) {
1825 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1826 "dbus_baaw regmap lookup failed. Aborting. %ld\n", PTR_ERR(platform->dbus_baaw));
1827 err = -EINVAL;
1828 goto error_exit;
1829 }
1830
1831 /* PBUS_BAAW */
1832 platform->pbus_baaw = syscon_regmap_lookup_by_phandle(platform->dev->of_node,
1833 "samsung,pbus_baaw-syscon-phandle");
1834 if (IS_ERR(platform->pbus_baaw)) {
1835 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1836 "pbus_baaw regmap lookup failed. Aborting. %ld\n", PTR_ERR(platform->pbus_baaw));
1837 err = -EINVAL;
1838 goto error_exit;
1839 }
1840
1841 /* WLBT_REMAP */
1842 platform->wlbt_remap = syscon_regmap_lookup_by_phandle(platform->dev->of_node,
1843 "samsung,wlbt_remap-syscon-phandle");
1844 if (IS_ERR(platform->wlbt_remap)) {
1845 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1846 "wlbt_remap regmap lookup failed. Aborting. %ld\n", PTR_ERR(platform->wlbt_remap));
1847 err = -EINVAL;
1848 goto error_exit;
1849 }
1850
1851 /* BOOT_CFG */
1852 platform->boot_cfg = syscon_regmap_lookup_by_phandle(platform->dev->of_node,
1853 "samsung,boot_cfg-syscon-phandle");
1854 if (IS_ERR(platform->boot_cfg)) {
1855 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1856 "boot_cfg regmap lookup failed. Aborting. %ld\n", PTR_ERR(platform->boot_cfg));
1857 err = -EINVAL;
1858 goto error_exit;
1859 }
1860 #endif
1861 #ifdef CONFIG_SCSC_SMAPPER
1862 /* SMAPPER parsing */
1863 if (!of_property_read_u32(pdev->dev.of_node, "smapper_num_banks", &smapper_banks))
1864 platform_mif_parse_smapper(platform, platform->dev->of_node, smapper_banks);
1865
1866 #endif
1867 #ifdef CONFIG_SCSC_QOS
1868 platform_mif_parse_qos(platform, platform->dev->of_node);
1869 #endif
1870 /* Initialize spinlock */
1871 spin_lock_init(&platform->mif_spinlock);
1872
1873 return platform_if;
1874
1875 error_exit:
1876 devm_kfree(&pdev->dev, platform);
1877 return NULL;
1878 }
1879
1880 void platform_mif_destroy_platform(struct platform_device *pdev, struct scsc_mif_abs *interface)
1881 {
1882 }
1883
1884 struct platform_device *platform_mif_get_platform_dev(struct scsc_mif_abs *interface)
1885 {
1886 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1887
1888 BUG_ON(!interface || !platform);
1889
1890 return platform->pdev;
1891 }
1892
1893 struct device *platform_mif_get_dev(struct scsc_mif_abs *interface)
1894 {
1895 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1896
1897 BUG_ON(!interface || !platform);
1898
1899 return platform->dev;
1900 }
1901
1902 /* Preserve MIF registers during suspend.
1903 * If all users of the MIF (AP, mx140, CP, etc) release it, the registers
1904 * will lose their values. Save the useful subset here.
1905 *
1906 * Assumption: the AP will not change the register values between the suspend
1907 * and resume handlers being called!
1908 */
1909 static void platform_mif_reg_save(struct platform_mif *platform)
1910 {
1911 platform->mif_preserve.irq_bit_mask = __platform_mif_irq_bit_mask_read(platform);
1912 }
1913
1914 /* Restore MIF registers that may have been lost during suspend */
1915 static void platform_mif_reg_restore(struct platform_mif *platform)
1916 {
1917 __platform_mif_irq_bit_mask_write(platform, platform->mif_preserve.irq_bit_mask);
1918 }
1919
1920 int platform_mif_suspend(struct scsc_mif_abs *interface)
1921 {
1922 int r = 0;
1923 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1924
1925 if (platform->suspend_handler)
1926 r = platform->suspend_handler(interface, platform->suspendresume_data);
1927
1928 /* Save the MIF registers.
1929 * This must be done last as the suspend_handler may use the MIF
1930 */
1931 platform_mif_reg_save(platform);
1932
1933 return r;
1934 }
1935
1936 void platform_mif_resume(struct scsc_mif_abs *interface)
1937 {
1938 struct platform_mif *platform = platform_mif_from_mif_abs(interface);
1939 s32 ret;
1940
1941 /* Restore the MIF registers.
1942 * This must be done first as the resume_handler may use the MIF.
1943 */
1944 platform_mif_reg_restore(platform);
1945 #ifdef CONFIG_SOC_EXYNOS9610
1946 SCSC_TAG_INFO_DEV(PLAT_MIF, platform->dev, "Clear WLBT_ACTIVE_CLR flag\n");
1947 /* Clear WLBT_ACTIVE_CLR flag in WLBT_CTRL_NS */
1948 ret = regmap_update_bits(platform->pmureg, WLBT_CTRL_NS, WLBT_ACTIVE_CLR, 1);
1949 if (ret < 0) {
1950 SCSC_TAG_ERR_DEV(PLAT_MIF, platform->dev,
1951 "Failed to Set WLBT_CTRL_NS[WLBT_ACTIVE_CLR]: %d\n", ret);
1952 }
1953 #endif
1954 if (platform->resume_handler)
1955 platform->resume_handler(interface, platform->suspendresume_data);
1956 }