1 /****************************************************************************
3 * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
5 ****************************************************************************/
7 /* Implements interface */
9 #include "platform_mif.h"
11 /* Interfaces it Uses */
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>
22 #include <linux/smc.h>
25 #include <linux/of_address.h>
26 #include <linux/of_platform.h>
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>
38 #ifdef CONFIG_SCSC_SMAPPER
39 #include <linux/dma-mapping.h>
40 #include "mif_reg_smapper.h"
42 #ifdef CONFIG_SCSC_QOS
43 #include <linux/pm_qos.h>
46 #if !defined(CONFIG_SOC_EXYNOS9610)
47 #error Target processor CONFIG_SOC_EXYNOS9610 not selected
50 #ifdef CONFIG_SCSC_LOG_COLLECTION
51 #include <scsc/scsc_log_collector.h>
53 /* Time to wait for CFG_REQ IRQ on 9610 */
54 #define WLBT_BOOT_TIMEOUT (HZ)
56 #ifdef CONFIG_OF_RESERVED_MEM
57 #include <linux/of_reserved_mem.h>
59 static unsigned long sharedmem_base
;
60 static size_t sharedmem_size
;
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");
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");
72 #ifdef CONFIG_SCSC_QOS
74 unsigned int freq_mif
;
75 unsigned int freq_int
;
76 unsigned int freq_cl0
;
77 unsigned int freq_cl1
;
82 struct scsc_mif_abs interface
;
83 struct scsc_mbox_s
*mbox
;
84 struct platform_device
*pdev
;
91 atomic_t irq_disabled_cnt
;
92 } wlbt_irq
[PLATFORM_MIF_NUM_IRQS
];
94 /* MIF registers preserved during suspend */
99 /* register MBOX memory space */
104 /* register CMU memory space */
105 struct regmap
*cmu_base
;
107 void __iomem
*con0_base
;
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
;
118 /* Signalled when CFG_REQ IRQ handled */
119 struct completion cfg_ack
;
121 /* State of CFG_REQ handler */
122 enum wlbt_boot_state
{
123 WLBT_BOOT_IN_RESET
= 0,
124 WLBT_BOOT_WAIT_CFG_REQ
,
130 #ifdef CONFIG_SCSC_SMAPPER
132 void __iomem
*smapper_base
;
138 struct scsc_mif_smapper_info bank_info
;
141 /* Shared memory space - reserved memory */
142 unsigned long mem_start
;
146 /* Callback function and dev pointer mif_intr manager handler */
147 void (*r4_handler
)(int irq
, void *data
);
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
;
154 #ifdef CONFIG_SCSC_QOS
156 struct qos_table
*qos
;
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
;
165 extern int mx140_log_dump(void);
167 #define platform_mif_from_mif_abs(MIF_ABS_PTR) container_of(MIF_ABS_PTR, struct platform_mif, interface)
169 inline void platform_mif_reg_write(struct platform_mif
*platform
, u16 offset
, u32 value
)
171 writel(value
, platform
->base
+ offset
);
174 inline u32
platform_mif_reg_read(struct platform_mif
*platform
, u16 offset
)
176 return readl(platform
->base
+ offset
);
179 #ifdef CONFIG_SCSC_SMAPPER
180 inline void platform_mif_reg_write_smapper(struct platform_mif
*platform
, u16 offset
, u32 value
)
182 writel(value
, platform
->smapper_base
+ offset
);
185 inline u32
platform_mif_reg_read_smapper(struct platform_mif
*platform
, u16 offset
)
187 return readl(platform
->smapper_base
+ offset
);
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 */
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
)
196 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
199 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "Mapping %d banks\n", platform
->smapper_banks
);
201 if (!platform
->smapper_banks
)
204 for (i
= 0; i
< platform
->smapper_banks
; i
++) {
205 if (platform
->smapper
[i
].large
)
206 phy_map
[i
] = SCSC_MIF_ABS_LARGE_BANK
;
208 phy_map
[i
] = SCSC_MIF_ABS_SMALL_BANK
;
212 *align
= 1 << PLATFORM_MIF_SHIFT_SMAPPER_ADDR
;
217 static int platform_mif_smapper_get_bank_info(struct scsc_mif_abs
*interface
, u8 bank
, struct scsc_mif_smapper_info
*bank_info
)
219 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
221 if (!platform
->smapper_banks
)
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
;
230 static u8
platform_mif_smapper_granularity_to_bits(u32 granularity
)
232 if (granularity
<= 2 * 1024)
234 if (granularity
<= 4 * 1024)
236 if (granularity
<= 8 * 1024)
238 if (granularity
<= 16 * 1024)
240 if (granularity
<= 32 * 1024)
242 if (granularity
<= 64 * 1024)
244 if (granularity
<= 128 * 1024)
249 static u32
platform_mif_smapper_get_bank_base_address(struct scsc_mif_abs
*interface
, u8 bank
)
251 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
253 if (!platform
->smapper
)
256 return platform
->smapper
[bank
].ws
;
259 /* Configure smapper according the memory map and range */
260 static void platform_mif_smapper_configure(struct scsc_mif_abs
*interface
, u32 granularity
)
262 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
265 u8 nb
= platform
->smapper_banks
;
267 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "Configure SMAPPER with granularity %d\n", granularity
);
269 gran
= platform_mif_smapper_granularity_to_bits(granularity
);
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);
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 */
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
);
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
)
294 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
298 if (!platform
->smapper_banks
)
301 if (!platform
->smapper_base
) {
302 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "SMAPPER not enabled\n");
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
++) {
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
);
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
);
325 platform_mif_reg_write_smapper(platform
, ADDR_MAP_EN(bank
), 1);
330 static int platform_mif_parse_smapper(struct platform_mif
*platform
, struct device_node
*np
, u8 num_banks
)
332 /* SMAPPER parsing */
333 struct device_node
*np_banks
;
337 u32 bank
= 0, ws
= 0, wsz
= 0, ent
= 0, large
= 0;
339 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "banks found: %d szof %zu\n", num_banks
, sizeof(*platform
->smapper
));
341 platform
->smapper
= kmalloc_array(num_banks
, sizeof(*platform
->smapper
), GFP_KERNEL
);
343 if (!platform
->smapper
)
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
);
350 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "%s: could not find smapper_bank\n",
352 kfree(platform
->smapper
);
353 platform
->smapper
= NULL
;
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
);
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
;
372 /* Update the number of banks before returning */
373 platform
->smapper_banks
= num_banks
;
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]);
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
;
392 #ifdef CONFIG_SCSC_QOS
393 static int platform_mif_parse_qos(struct platform_mif
*platform
, struct device_node
*np
)
397 platform
->qos_enabled
= false;
399 len
= of_property_count_u32_elems(np
, "qos_table");
401 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
,
402 "No qos table for wlbt, or incorrect size\n");
406 platform
->qos
= devm_kzalloc(platform
->dev
, sizeof(struct qos_table
) * len
/ 4, GFP_KERNEL
);
410 of_property_read_u32_array(np
, "qos_table", (unsigned int *)platform
->qos
, len
);
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
);
420 platform
->qos_enabled
= true;
424 struct qos_table
platform_mif_pm_qos_get_table(struct platform_mif
*platform
, enum scsc_qos_config config
)
426 struct qos_table table
;
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
;
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
;
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
;
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
)
462 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
463 struct qos_table table
;
468 if (!platform
->qos_enabled
) {
469 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "PM QoS not configured\n");
473 table
= platform_mif_pm_qos_get_table(platform
, config
);
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
);
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
);
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
)
488 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
489 struct qos_table table
;
494 if (!platform
->qos_enabled
) {
495 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "PM QoS not configured\n");
499 table
= platform_mif_pm_qos_get_table(platform
, config
);
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
);
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
);
512 static int platform_mif_pm_qos_remove_request(struct scsc_mif_abs
*interface
, struct scsc_mifqos_request
*qos_req
)
514 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
520 if (!platform
->qos_enabled
) {
521 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "PM QoS not configured\n");
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
);
535 static void platform_mif_irq_default_handler(int irq
, void *data
)
537 /* Avoid unused parameter error */
541 /* int handler not registered */
542 SCSC_TAG_INFO_DEV(PLAT_MIF
, NULL
, "INT handler not registered\n");
545 static void platform_mif_irq_reset_request_default_handler(int irq
, void *data
)
547 /* Avoid unused parameter error */
551 /* int handler not registered */
552 SCSC_TAG_INFO_DEV(PLAT_MIF
, NULL
, "INT reset_request handler not registered\n");
555 irqreturn_t
platform_mif_isr(int irq
, void *data
)
557 struct platform_mif
*platform
= (struct platform_mif
*)data
;
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
);
563 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "MIF Interrupt Handler not registered\n");
568 #ifdef CONFIG_SCSC_ENABLE_ALIVE_IRQ
569 irqreturn_t
platform_alive_isr(int irq
, void *data
)
571 struct platform_mif
*platform
= (struct platform_mif
*)data
;
573 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "INT received\n");
579 irqreturn_t
platform_wdog_isr(int irq
, void *data
)
582 struct platform_mif
*platform
= (struct platform_mif
*)data
;
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
);
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
);
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");
599 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
600 "Failed to Set WLBT_CTRL_NS[WLBT_RESET_REQ_CLR]: %d\n", ret
);
605 #ifdef CONFIG_SOC_EXYNOS9610
607 * Attached array contains the replacement PMU boot code which should
608 * be programmed using the CBUS during the config phase.
610 uint32_t ka_patch
[] = {
612 * Maxwell142 PMU+PROC combined boot ROM
614 * Major Version: 0xF, Minor Version: 0xF
615 * PMU ROM version: 0x4
616 * PROC ROM version: 0x0
678 extern bool reset_failed
;
680 irqreturn_t
platform_cfg_req_isr(int irq
, void *data
)
682 struct platform_mif
*platform
= (struct platform_mif
*)data
;
683 const u64 EXYNOS_WLBT
= 0x1;
686 unsigned int ka_addr
= 0x1000;
687 uint32_t *ka_patch_addr
= ka_patch
;
690 #define CHECK(x) do { \
696 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "INT received\n");
697 SCSC_TAG_DEBUG_DEV(PLAT_MIF
, platform
->dev
, "disable_irq\n");
700 disable_irq_nosync(platform
->wlbt_irq
[PLATFORM_MIF_CFG_REQ
].irq_num
);
702 /* Was the CFG_REQ irq received from WLBT before we expected it?
703 * Typically this indicates an issue returning WLBT HW to reset.
705 if (platform
->boot_state
!= WLBT_BOOT_WAIT_CFG_REQ
) {
707 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
708 "Spurious CFG_REQ IRQ from WLBT!\n");
710 regmap_read(platform
->pmureg
, CENTRAL_SEQ_WLBT_STATUS
, &val
);
711 SCSC_TAG_INFO(PLAT_MIF
, "CENTRAL_SEQ_WLBT_STATUS 0x%x\n", val
);
713 regmap_read(platform
->pmureg
, WLBT_CTRL_NS
, &val
);
714 SCSC_TAG_INFO(PLAT_MIF
, "WLBT_CTRL_NS 0x%x\n", val
);
716 regmap_read(platform
->pmureg
, WLBT_CTRL_S
, &val
);
717 SCSC_TAG_INFO(PLAT_MIF
, "WLBT_CTRL_S 0x%x\n", val
);
719 regmap_read(platform
->pmureg
, WLBT_DEBUG
, &val
);
720 SCSC_TAG_INFO(PLAT_MIF
, "WLBT_DEBUG 0x%x\n", val
);
722 reset_failed
= true; /* prevent further interaction with HW */
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
732 /* Set TZPC to non-secure mode */
733 ret64
= exynos_smc(SMC_CMD_CONN_IF
, (EXYNOS_WLBT
<< 32) | EXYNOS_SET_CONN_TZPC
, 0, 0);
735 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
736 "Failed to set TZPC to non-secure mode: %llu\n", ret64
);
738 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
,
739 "SMC_CMD_CONN_IF run successfully : %llu\n", ret64
);
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");
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
);
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");
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
));
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
));
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
));
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
));
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
));
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");
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");
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]);
806 /* Notify PMU of configuration done */
807 CHECK(regmap_write(platform
->boot_cfg
, 0x0, 0x0));
810 CHECK(regmap_write(platform
->boot_cfg
, 0x4, 0x1));
811 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "BOOT_CFG_ACK done\n");
813 /* Delay to allow HW to clear CFG_REQ and hence de-assert IRQ, which
814 * it does in response to CFG_ACK
818 /* Release ownership of MASK_PWR_REQ */
819 /* See sequence in 9.6.6 */
820 ret
= regmap_update_bits(platform
->pmureg
, WLBT_CTRL_NS
,
823 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
824 "Failed to clear WLBT_CTRL_NS[MASK_PWR_REQ]: %d\n", ret
);
828 /* Mark as CFQ_REQ handled, so boot may continue */
829 platform
->boot_state
= WLBT_BOOT_CFG_DONE
;
831 /* Signal triggering function that the IRQ arrived and CFG was done */
832 complete(&platform
->cfg_ack
);
834 /* Re-enable IRQ here to allow spurious interrupt to be tracked */
835 enable_irq(platform
->wlbt_irq
[PLATFORM_MIF_CFG_REQ
].irq_num
);
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
);
846 static void platform_mif_unregister_irq(struct platform_mif
*platform
)
848 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "Unregistering IRQs\n");
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
);
858 #ifdef CONFIG_SOC_EXYNOS9610
859 devm_free_irq(platform
->dev
, platform
->wlbt_irq
[PLATFORM_MIF_CFG_REQ
].irq_num
, platform
);
863 static int platform_mif_register_irq(struct platform_mif
*platform
)
867 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "Registering IRQs\n");
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
);
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
);
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
);
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
);
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
);
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
);
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 */
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
);
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
);
931 static void platform_mif_destroy(struct scsc_mif_abs
*interface
)
933 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
935 platform_mif_unregister_irq(platform
);
938 static char *platform_mif_get_uid(struct scsc_mif_abs
*interface
)
940 /* Avoid unused parameter error */
945 /* WLBT Power domain */
946 static int platform_mif_power(struct scsc_mif_abs
*interface
, bool power
)
948 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
951 #ifdef CONFIG_SOC_EXYNOS9610
952 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "power %d\n", power
);
957 /* See sequence in 9.6.6 */
958 ret
= regmap_update_bits(platform
->pmureg
, WLBT_CTRL_NS
,
961 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
962 "Failed to update WLBT_CTRL_NS[MASK_PWR_REQ]: %d\n", ret
);
970 static int platform_mif_hold_reset(struct scsc_mif_abs
*interface
, bool reset
)
972 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
975 #ifdef CONFIG_SOC_EXYNOS9610
976 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "reset %d\n", 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
);
983 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
984 "Failed to update WLBT_CTRL_NS[WLBT_RESET_SET]: %d\n", ret
);
992 static int platform_mif_start(struct scsc_mif_abs
*interface
, bool start
)
994 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
998 #ifdef CONFIG_SOC_EXYNOS9610
999 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "start %d\n", start
);
1003 /* See sequence in 9.6.6 */
1004 ret
= regmap_update_bits(platform
->pmureg
, WLBT_CTRL_S
,
1007 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1008 "Failed to update WLBT_CTRL_S[WLBT_START]: %d\n", ret
);
1011 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1012 "update WIFI_CTRL_S[WIFI_START]: %d\n", ret
);
1014 /* At this point WLBT should assert the CFG_REQ IRQ, so wait for it */
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
);
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");
1033 static int platform_mif_pmu_reset_release(struct scsc_mif_abs
*interface
)
1036 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
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 */
1043 ret
= platform_mif_power(interface
, true);
1046 ret
= platform_mif_hold_reset(interface
, false);
1049 ret
= platform_mif_start(interface
, true);
1056 static int platform_mif_pmu_reset(struct scsc_mif_abs
*interface
, u8 rst_case
)
1058 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1059 unsigned long timeout
;
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
);
1069 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "rst_case %d\n", rst_case
);
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
);
1075 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1076 "Failed to update WLBT_CTRL_NS[MASK_PWR_REQ]: %d\n", ret
);
1080 /* reset sequence as per excite implementation for Leman */
1081 ret
= regmap_update_bits(platform
->pmureg
, CENTRAL_SEQ_WLBT_CONFIGURATION
,
1084 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1085 "Failed to update CENTRAL_SEQ_WLBT_CONFIGURATION %d\n", ret
);
1089 ret
= regmap_update_bits(platform
->pmureg
, RESET_AHEAD_WLBT_SYS_PWR_REG
,
1092 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1093 "Failed to update RESET_AHEAD_WLBT_SYS_PWR_REG %d\n", ret
);
1097 ret
= regmap_update_bits(platform
->pmureg
, CLEANY_BUS_WLBT_SYS_PWR_REG
,
1100 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1101 "Failed to update CLEANY_BUS_WLBT_SYS_PWR_REG%d\n", ret
);
1105 ret
= regmap_update_bits(platform
->pmureg
, LOGIC_RESET_WLBT_SYS_PWR_REG
,
1108 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1109 "Failed to update LOGIC_RESET_WLBT_SYS_PWR_REG %d\n", ret
);
1113 ret
= regmap_update_bits(platform
->pmureg
, TCXO_GATE_WLBT_SYS_PWR_REG
,
1116 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1117 "Failed to update TCXO_GATE_WLBT_SYS_PWR_REG %d\n", ret
);
1121 ret
= regmap_update_bits(platform
->pmureg
, WLBT_DISABLE_ISO_SYS_PWR_REG
,
1124 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1125 "Failed to update WLBT_DISABLE_ISO_SYS_PWR_REG %d\n", ret
);
1129 ret
= regmap_update_bits(platform
->pmureg
, WLBT_RESET_ISO_SYS_PWR_REG
,
1132 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1133 "Failed to update WLBT_RESET_ISO_SYS_PWR_REG %d\n", ret
);
1137 /* rst_case is always 2 on 9610 */
1138 ret
= platform_mif_hold_reset(interface
, true);
1143 timeout
= jiffies
+ msecs_to_jiffies(500);
1145 regmap_read(platform
->pmureg
, CENTRAL_SEQ_WLBT_STATUS
, &val
);
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.
1154 platform_mif_power(interface
, false);
1156 return 0; /* OK - return */
1158 } while (time_before(jiffies
, timeout
));
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
);
1170 /* reset=0 - release from reset */
1171 /* reset=1 - hold reset */
1172 static int platform_mif_reset(struct scsc_mif_abs
*interface
, bool reset
)
1174 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1177 SCSC_TAG_DEBUG_DEV(PLAT_MIF
, platform
->dev
, "\n");
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
);
1186 ret
= platform_mif_pmu_reset_release(interface
);
1188 /* Put back into reset */
1189 ret
= platform_mif_pmu_reset(interface
, 2);
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
);
1197 static void __iomem
*platform_mif_map_region(unsigned long phys_addr
, size_t size
)
1200 struct page
**pages
;
1203 size
= PAGE_ALIGN(size
);
1205 pages
= kmalloc((size
>> PAGE_SHIFT
) * sizeof(*pages
), GFP_KERNEL
);
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
;
1215 vmem
= vmap(pages
, size
>> PAGE_SHIFT
, VM_MAP
, pgprot_writecombine(PAGE_KERNEL
));
1218 return (void __iomem
*)vmem
;
1221 static void platform_mif_unmap_region(void *vmem
)
1226 static void *platform_mif_map(struct scsc_mif_abs
*interface
, size_t *allocated
)
1228 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1235 platform_mif_map_region(platform
->mem_start
, platform
->mem_size
);
1237 if (!platform
->mem
) {
1238 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "Error remaping shared memory\n");
1242 SCSC_TAG_INFO_DEV(PLAT_MIF
, platform
->dev
, "Map: virt %p phys %lx\n", platform
->mem
, (uintptr_t)platform
->mem_start
);
1244 /* Initialise MIF registers with documented defaults */
1246 for (i
= 0; i
< NUM_MBOX_PLAT
; i
++)
1247 platform_mif_reg_write(platform
, MAILBOX_WLBT_REG(ISSR(i
)), 0x00000000);
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);
1256 #ifdef CONFIG_SCSC_CHV_SUPPORT
1257 if (chv_disable_irq
== true) {
1259 *allocated
= platform
->mem_size
;
1260 return platform
->mem
;
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
);
1271 *allocated
= platform
->mem_size
;
1272 /* Set the CR4 base address in Mailbox??*/
1273 return platform
->mem
;
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
)
1279 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1281 /* Avoid unused parameter error */
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);
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
);
1294 platform_mif_unregister_irq(platform
);
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
;
1304 static u32
platform_mif_irq_bit_mask_status_get(struct scsc_mif_abs
*interface
)
1306 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
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
);
1314 static u32
platform_mif_irq_get(struct scsc_mif_abs
*interface
)
1316 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
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
);
1326 static void platform_mif_irq_bit_set(struct scsc_mif_abs
*interface
, int bit_num
, enum scsc_mif_abs_target target
)
1328 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1331 if (bit_num
>= 16) {
1332 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "Incorrect INT number: %d\n", bit_num
);
1336 #ifdef CONFIG_SOC_EXYNOS9610
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
);
1343 static void platform_mif_irq_bit_clear(struct scsc_mif_abs
*interface
, int bit_num
)
1345 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1347 if (bit_num
>= 16) {
1348 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "Incorrect INT number: %d\n", bit_num
);
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
);
1356 static void platform_mif_irq_bit_mask(struct scsc_mif_abs
*interface
, int bit_num
)
1358 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1360 unsigned long flags
;
1362 if (bit_num
>= 16) {
1363 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "Incorrect INT number: %d\n", bit_num
);
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
);
1374 static void platform_mif_irq_bit_unmask(struct scsc_mif_abs
*interface
, int bit_num
)
1376 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1378 unsigned long flags
;
1380 if (bit_num
>= 16) {
1381 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "Incorrect INT number: %d\n", bit_num
);
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
);
1392 /* Return the contents of the mask register */
1393 static u32
__platform_mif_irq_bit_mask_read(struct platform_mif
*platform
)
1396 unsigned long flags
;
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
);
1406 /* Write the mask register, destroying previous contents */
1407 static void __platform_mif_irq_bit_mask_write(struct platform_mif
*platform
, u32 val
)
1409 unsigned long flags
;
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
);
1417 static void platform_mif_irq_reg_handler(struct scsc_mif_abs
*interface
, void (*handler
)(int irq
, void *data
), void *dev
)
1419 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1420 unsigned long flags
;
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
);
1429 static void platform_mif_irq_unreg_handler(struct scsc_mif_abs
*interface
)
1431 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1432 unsigned long flags
;
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
);
1441 static void platform_mif_irq_reg_reset_request_handler(struct scsc_mif_abs
*interface
, void (*handler
)(int irq
, void *data
), void *dev
)
1443 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
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);
1456 static void platform_mif_irq_unreg_reset_request_handler(struct scsc_mif_abs
*interface
)
1458 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
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
;
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
),
1470 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
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
;
1478 static void platform_mif_suspend_unreg_handler(struct scsc_mif_abs
*interface
)
1480 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
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
;
1488 static u32
*platform_mif_get_mbox_ptr(struct scsc_mif_abs
*interface
, u32 mbox_index
)
1490 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
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
));
1498 static int platform_mif_get_mifram_ref(struct scsc_mif_abs
*interface
, void *ptr
, scsc_mifram_ref
*ref
)
1500 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1502 SCSC_TAG_DEBUG_DEV(PLAT_MIF
, platform
->dev
, "\n");
1504 if (!platform
->mem
) {
1505 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "Memory unmmaped\n");
1510 if (ptr
>= (platform
->mem
+ platform
->mem_size
)) {
1511 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "Unable to get pointer reference\n");
1515 *ref
= (scsc_mifram_ref
)((uintptr_t)ptr
- (uintptr_t)platform
->mem
);
1520 static void *platform_mif_get_mifram_ptr(struct scsc_mif_abs
*interface
, scsc_mifram_ref ref
)
1522 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1524 SCSC_TAG_DEBUG_DEV(PLAT_MIF
, platform
->dev
, "\n");
1526 if (!platform
->mem
) {
1527 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "Memory unmmaped\n");
1532 if (ref
>= 0 && ref
< platform
->mem_size
)
1533 return (void *)((uintptr_t)platform
->mem
+ (uintptr_t)ref
);
1538 static void *platform_mif_get_mifram_phy_ptr(struct scsc_mif_abs
*interface
, scsc_mifram_ref ref
)
1540 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1542 SCSC_TAG_DEBUG_DEV(PLAT_MIF
, platform
->dev
, "\n");
1544 if (!platform
->mem_start
) {
1545 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "Memory unmmaped\n");
1549 return (void *)((uintptr_t)platform
->mem_start
+ (uintptr_t)ref
);
1552 static uintptr_t platform_mif_get_mif_pfn(struct scsc_mif_abs
*interface
)
1554 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1556 return vmalloc_to_pfn(platform
->mem
);
1559 static struct device
*platform_mif_get_mif_device(struct scsc_mif_abs
*interface
)
1561 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1563 SCSC_TAG_DEBUG_DEV(PLAT_MIF
, platform
->dev
, "\n");
1565 return platform
->dev
;
1568 static void platform_mif_irq_clear(void)
1570 /* Implement if required */
1573 static int platform_mif_read_register(struct scsc_mif_abs
*interface
, u64 id
, u32
*val
)
1575 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1577 if (id
== SCSC_REG_READ_WLBT_STAT
) {
1578 regmap_read(platform
->pmureg
, WLBT_STAT
, val
);
1585 static void platform_mif_dump_register(struct scsc_mif_abs
*interface
)
1587 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1588 unsigned long flags
;
1590 spin_lock_irqsave(&platform
->mif_spinlock
, flags
);
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
)));
1603 spin_unlock_irqrestore(&platform
->mif_spinlock
, flags
);
1606 static void platform_mif_cleanup(struct scsc_mif_abs
*interface
)
1610 static void platform_mif_restart(struct scsc_mif_abs
*interface
)
1614 #ifdef CONFIG_OF_RESERVED_MEM
1615 static int __init
platform_mif_wifibt_if_reserved_mem_setup(struct reserved_mem
*remem
)
1617 SCSC_TAG_DEBUG(PLAT_MIF
, "memory reserved: mem_base=%#lx, mem_size=%zd\n",
1618 (unsigned long)remem
->base
, (size_t)remem
->size
);
1620 sharedmem_base
= remem
->base
;
1621 sharedmem_size
= remem
->size
;
1624 RESERVEDMEM_OF_DECLARE(wifibt_if
, "exynos,wifibt_if", platform_mif_wifibt_if_reserved_mem_setup
);
1627 struct scsc_mif_abs
*platform_mif_create(struct platform_device
*pdev
)
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
);
1634 struct resource
*reg_res
;
1636 #ifdef CONFIG_SCSC_SMAPPER
1637 u32 smapper_banks
= 0;
1643 SCSC_TAG_INFO_DEV(PLAT_MIF
, &pdev
->dev
, "Creating MIF platform device\n");
1645 platform_if
= &platform
->interface
;
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
;
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
;
1689 platform
->pdev
= pdev
;
1690 platform
->dev
= &pdev
->dev
;
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
;
1700 #ifdef CONFIG_OF_RESERVED_MEM
1701 platform
->mem_start
= sharedmem_base
;
1702 platform
->mem_size
= sharedmem_size
;
1704 /* If CONFIG_OF_RESERVED_MEM is not defined, sharedmem values should be
1705 * parsed from the scsc_wifibt binding
1707 if (of_property_read_u32(pdev
->dev
.of_node
, "sharedmem-base", &sharedmem_base
)) {
1711 platform
->mem_start
= sharedmem_base
;
1713 if (of_property_read_u32(pdev
->dev
.of_node
, "sharedmem-size", &sharedmem_size
)) {
1717 platform
->mem_size
= sharedmem_size
;
1719 #ifdef CONFIG_SCSC_SMAPPER
1720 platform
->smapper
= NULL
;
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");
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.
1732 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "platform->mem_size is 0");
1737 /* Memory resource - Phys Address of MAILBOX_WLBT register map */
1738 reg_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1740 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1741 "Error getting mem resource for MAILBOX_WLBT\n");
1746 platform
->reg_start
= reg_res
->start
;
1747 platform
->reg_size
= resource_size(reg_res
);
1750 devm_ioremap_nocache(platform
->dev
, reg_res
->start
, resource_size(reg_res
));
1752 if (!platform
->base
) {
1753 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1754 "Error mapping register region\n");
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
);
1761 /* Get the 4 IRQ resources */
1762 for (i
= 0; i
< 4; i
++) {
1763 struct resource
*irq_res
;
1766 irq_res
= platform_get_resource(pdev
, IORESOURCE_IRQ
, i
);
1768 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
, "No IRQ resource at index %d\n", i
);
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
;
1786 SCSC_TAG_ERR_DEV(PLAT_MIF
, &pdev
->dev
, "Invalid irq res name: %s\n",
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);
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
));
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
;
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
));
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
));
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
));
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
));
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
));
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
);
1867 #ifdef CONFIG_SCSC_QOS
1868 platform_mif_parse_qos(platform
, platform
->dev
->of_node
);
1870 /* Initialize spinlock */
1871 spin_lock_init(&platform
->mif_spinlock
);
1876 devm_kfree(&pdev
->dev
, platform
);
1880 void platform_mif_destroy_platform(struct platform_device
*pdev
, struct scsc_mif_abs
*interface
)
1884 struct platform_device
*platform_mif_get_platform_dev(struct scsc_mif_abs
*interface
)
1886 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1888 BUG_ON(!interface
|| !platform
);
1890 return platform
->pdev
;
1893 struct device
*platform_mif_get_dev(struct scsc_mif_abs
*interface
)
1895 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1897 BUG_ON(!interface
|| !platform
);
1899 return platform
->dev
;
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.
1906 * Assumption: the AP will not change the register values between the suspend
1907 * and resume handlers being called!
1909 static void platform_mif_reg_save(struct platform_mif
*platform
)
1911 platform
->mif_preserve
.irq_bit_mask
= __platform_mif_irq_bit_mask_read(platform
);
1914 /* Restore MIF registers that may have been lost during suspend */
1915 static void platform_mif_reg_restore(struct platform_mif
*platform
)
1917 __platform_mif_irq_bit_mask_write(platform
, platform
->mif_preserve
.irq_bit_mask
);
1920 int platform_mif_suspend(struct scsc_mif_abs
*interface
)
1923 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1925 if (platform
->suspend_handler
)
1926 r
= platform
->suspend_handler(interface
, platform
->suspendresume_data
);
1928 /* Save the MIF registers.
1929 * This must be done last as the suspend_handler may use the MIF
1931 platform_mif_reg_save(platform
);
1936 void platform_mif_resume(struct scsc_mif_abs
*interface
)
1938 struct platform_mif
*platform
= platform_mif_from_mif_abs(interface
);
1941 /* Restore the MIF registers.
1942 * This must be done first as the resume_handler may use the MIF.
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);
1950 SCSC_TAG_ERR_DEV(PLAT_MIF
, platform
->dev
,
1951 "Failed to Set WLBT_CTRL_NS[WLBT_ACTIVE_CLR]: %d\n", ret
);
1954 if (platform
->resume_handler
)
1955 platform
->resume_handler(interface
, platform
->suspendresume_data
);