[RAMEN9610-20413][9610] wlbt: SCSC Driver version 10.6.1.0
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / misc / samsung / scsc / pcie_mbox.c
1 /****************************************************************************
2 *
3 * Copyright (c) 2014 - 2016 Samsung Electronics Co., Ltd. All rights reserved
4 *
5 * Maxwell Mailbox Hardware Emulation (Implementation)
6 *
7 ****************************************************************************/
8
9 /* Implements */
10
11 #include "pcie_mbox.h"
12
13 /* Uses */
14
15 #include <linux/pci.h>
16 #include <asm/barrier.h>
17 #include <scsc/scsc_logring.h>
18 #include "pcie_mbox_shared_data.h"
19 #include "pcie_mbox_intgen.h"
20
21 /* Private Functions */
22
23 /**
24 * Initialise the mailbox emulation shared structure.
25 */
26 static void pcie_mbox_shared_data_init(struct pcie_mbox_shared_data *shared_data)
27 {
28 memset(shared_data, 0, sizeof(*shared_data));
29 shared_data->magic = PCIE_MIF_MBOX_MAGIC_NUMBER;
30 shared_data->version = PCIE_MIF_MBOX_VERSION_NUMBER;
31 pcie_mbox_shared_data_wmb();
32 }
33
34 /* Public Functions */
35
36 void pcie_mbox_init(
37 struct pcie_mbox *mbox,
38 void *shared_data_region,
39 __iomem void *pcie_registers,
40 struct functor *ap_interrupt_trigger,
41 struct functor *r4_interrupt_trigger,
42 #ifdef CONFIG_SCSC_MX450_GDB_SUPPORT
43 struct functor *m4_interrupt_trigger,
44 struct functor *m4_1_interrupt_trigger
45 #else
46 struct functor *m4_interrupt_trigger
47 #endif
48 )
49 {
50 mbox->shared_data = (struct pcie_mbox_shared_data *)shared_data_region;
51
52 pcie_mbox_shared_data_init(mbox->shared_data);
53
54 /* Interrupt Generator Emulations */
55
56 pcie_mbox_intgen_init(&mbox->ap_intgen, "AP", &mbox->shared_data->ap_interrupt, ap_interrupt_trigger);
57 pcie_mbox_intgen_init(&mbox->r4_intgen, "R4", &mbox->shared_data->r4_interrupt, r4_interrupt_trigger);
58 pcie_mbox_intgen_init(&mbox->m4_intgen, "M4", &mbox->shared_data->m4_interrupt, m4_interrupt_trigger);
59 #ifdef CONFIG_SCSC_MX450_GDB_SUPPORT
60 pcie_mbox_intgen_init(&mbox->m4_intgen_1, "M4", &mbox->shared_data->m4_1_interrupt, m4_1_interrupt_trigger);
61 #endif
62 }
63
64 u32 pcie_mbox_get_ap_interrupt_masked_bitmask(const struct pcie_mbox *mbox)
65 {
66 /* Delegate to ap intgen component */
67 return pcie_mbox_intgen_get_masked_bitmask(&mbox->ap_intgen);
68 }
69
70 u32 pcie_mbox_get_ap_interrupt_pending_bitmask(const struct pcie_mbox *mbox)
71 {
72 /* Delegate to ap intgen component */
73 return pcie_mbox_intgen_get_pending_bitmask(&mbox->ap_intgen);
74 }
75
76 bool pcie_mbox_is_ap_interrupt_source_pending(const struct pcie_mbox *mbox, int source_num)
77 {
78 return pcie_mbox_intgen_is_source_pending(&mbox->ap_intgen, source_num);
79 }
80
81 void pcie_mbox_clear_ap_interrupt_source(struct pcie_mbox *mbox, int source_num)
82 {
83 /* Delegate to ap intgen component */
84 pcie_mbox_intgen_clear_source(&mbox->ap_intgen, source_num);
85 }
86
87 void pcie_mbox_mask_ap_interrupt_source(struct pcie_mbox *mbox, int source_num)
88 {
89 /* Delegate to ap intgen component */
90 pcie_mbox_intgen_mask_source(&mbox->ap_intgen, source_num);
91 }
92
93 void pcie_mbox_unmask_ap_interrupt_source(struct pcie_mbox *mbox, int source_num)
94 {
95 /* Delegate to ap intgen component */
96 pcie_mbox_intgen_unmask_source(&mbox->ap_intgen, source_num);
97 }
98
99 void pcie_mbox_set_outgoing_interrupt_source(struct pcie_mbox *mbox, enum scsc_mif_abs_target target_node, int source_num)
100 {
101 /* Delegate to appropriate intgen instance*/
102 switch (target_node) {
103 case SCSC_MIF_ABS_TARGET_R4:
104 pcie_mbox_intgen_set_source(&mbox->r4_intgen, source_num);
105 break;
106 case SCSC_MIF_ABS_TARGET_M4:
107 pcie_mbox_intgen_set_source(&mbox->m4_intgen, source_num);
108 break;
109 #ifdef CONFIG_SCSC_MX450_GDB_SUPPORT
110 case SCSC_MIF_ABS_TARGET_M4_1:
111 pcie_mbox_intgen_set_source(&mbox->m4_intgen, source_num);
112 break;
113 #endif
114 default:
115 SCSC_TAG_ERR(PCIE_MIF, "Invalid interrupt target %d\n", target_node);
116 return;
117 }
118 }
119
120 u32 *pcie_mbox_get_mailbox_ptr(struct pcie_mbox *mbox, u32 mbox_index)
121 {
122 if (mbox_index >= PCIE_MIF_MBOX_ISSR_COUNT) {
123 SCSC_TAG_ERR(PCIE_MIF, "Invalid mailbox index %d\n", mbox_index);
124 return NULL;
125 }
126
127 return &mbox->shared_data->mailbox[mbox_index];
128 }
129