1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Intel OnChip System Fabric MailBox access support |
4 | */ |
5 | |
6 | #ifndef IOSF_MBI_SYMS_H |
7 | #define IOSF_MBI_SYMS_H |
8 | |
9 | #include <linux/notifier.h> |
10 | |
11 | #define MBI_MCR_OFFSET 0xD0 |
12 | #define MBI_MDR_OFFSET 0xD4 |
13 | #define MBI_MCRX_OFFSET 0xD8 |
14 | |
15 | #define MBI_RD_MASK 0xFEFFFFFF |
16 | #define MBI_WR_MASK 0X01000000 |
17 | |
18 | #define MBI_MASK_HI 0xFFFFFF00 |
19 | #define MBI_MASK_LO 0x000000FF |
20 | #define MBI_ENABLE 0xF0 |
21 | |
22 | /* IOSF SB read/write opcodes */ |
23 | #define MBI_MMIO_READ 0x00 |
24 | #define MBI_MMIO_WRITE 0x01 |
25 | #define MBI_CFG_READ 0x04 |
26 | #define MBI_CFG_WRITE 0x05 |
27 | #define MBI_CR_READ 0x06 |
28 | #define MBI_CR_WRITE 0x07 |
29 | #define MBI_REG_READ 0x10 |
30 | #define MBI_REG_WRITE 0x11 |
31 | #define MBI_ESRAM_READ 0x12 |
32 | #define MBI_ESRAM_WRITE 0x13 |
33 | |
34 | /* Baytrail available units */ |
35 | #define BT_MBI_UNIT_AUNIT 0x00 |
36 | #define BT_MBI_UNIT_SMC 0x01 |
37 | #define BT_MBI_UNIT_CPU 0x02 |
38 | #define BT_MBI_UNIT_BUNIT 0x03 |
39 | #define BT_MBI_UNIT_PMC 0x04 |
40 | #define BT_MBI_UNIT_GFX 0x06 |
41 | #define BT_MBI_UNIT_SMI 0x0C |
42 | #define BT_MBI_UNIT_CCK 0x14 |
43 | #define BT_MBI_UNIT_USB 0x43 |
44 | #define BT_MBI_UNIT_SATA 0xA3 |
45 | #define BT_MBI_UNIT_PCIE 0xA6 |
46 | |
47 | /* Quark available units */ |
48 | #define QRK_MBI_UNIT_HBA 0x00 |
49 | #define QRK_MBI_UNIT_HB 0x03 |
50 | #define QRK_MBI_UNIT_RMU 0x04 |
51 | #define QRK_MBI_UNIT_MM 0x05 |
52 | #define QRK_MBI_UNIT_SOC 0x31 |
53 | |
54 | /* Action values for the pmic_bus_access_notifier functions */ |
55 | #define MBI_PMIC_BUS_ACCESS_BEGIN 1 |
56 | #define MBI_PMIC_BUS_ACCESS_END 2 |
57 | |
58 | #if IS_ENABLED(CONFIG_IOSF_MBI) |
59 | |
60 | bool iosf_mbi_available(void); |
61 | |
62 | /** |
63 | * iosf_mbi_read() - MailBox Interface read command |
64 | * @port: port indicating subunit being accessed |
65 | * @opcode: port specific read or write opcode |
66 | * @offset: register address offset |
67 | * @mdr: register data to be read |
68 | * |
69 | * Locking is handled by spinlock - cannot sleep. |
70 | * Return: Nonzero on error |
71 | */ |
72 | int iosf_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr); |
73 | |
74 | /** |
75 | * iosf_mbi_write() - MailBox unmasked write command |
76 | * @port: port indicating subunit being accessed |
77 | * @opcode: port specific read or write opcode |
78 | * @offset: register address offset |
79 | * @mdr: register data to be written |
80 | * |
81 | * Locking is handled by spinlock - cannot sleep. |
82 | * Return: Nonzero on error |
83 | */ |
84 | int iosf_mbi_write(u8 port, u8 opcode, u32 offset, u32 mdr); |
85 | |
86 | /** |
87 | * iosf_mbi_modify() - MailBox masked write command |
88 | * @port: port indicating subunit being accessed |
89 | * @opcode: port specific read or write opcode |
90 | * @offset: register address offset |
91 | * @mdr: register data being modified |
92 | * @mask: mask indicating bits in mdr to be modified |
93 | * |
94 | * Locking is handled by spinlock - cannot sleep. |
95 | * Return: Nonzero on error |
96 | */ |
97 | int iosf_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask); |
98 | |
99 | /** |
100 | * iosf_mbi_punit_acquire() - Acquire access to the P-Unit |
101 | * |
102 | * One some systems the P-Unit accesses the PMIC to change various voltages |
103 | * through the same bus as other kernel drivers use for e.g. battery monitoring. |
104 | * |
105 | * If a driver sends requests to the P-Unit which require the P-Unit to access |
106 | * the PMIC bus while another driver is also accessing the PMIC bus various bad |
107 | * things happen. |
108 | * |
109 | * Call this function before sending requests to the P-Unit which may make it |
110 | * access the PMIC, be it through iosf_mbi* functions or through other means. |
111 | * This function will block all kernel access to the PMIC I2C bus, so that the |
112 | * P-Unit can safely access the PMIC over the shared I2C bus. |
113 | * |
114 | * Note on these systems the i2c-bus driver will request a sempahore from the |
115 | * P-Unit for exclusive access to the PMIC bus when i2c drivers are accessing |
116 | * it, but this does not appear to be sufficient, we still need to avoid making |
117 | * certain P-Unit requests during the access window to avoid problems. |
118 | * |
119 | * This function locks a mutex, as such it may sleep. |
120 | */ |
121 | void iosf_mbi_punit_acquire(void); |
122 | |
123 | /** |
124 | * iosf_mbi_punit_release() - Release access to the P-Unit |
125 | */ |
126 | void iosf_mbi_punit_release(void); |
127 | |
128 | /** |
129 | * iosf_mbi_block_punit_i2c_access() - Block P-Unit accesses to the PMIC bus |
130 | * |
131 | * Call this function to block P-Unit access to the PMIC I2C bus, so that the |
132 | * kernel can safely access the PMIC over the shared I2C bus. |
133 | * |
134 | * This function acquires the P-Unit bus semaphore and notifies |
135 | * pmic_bus_access_notifier listeners that they may no longer access the |
136 | * P-Unit in a way which may cause it to access the shared I2C bus. |
137 | * |
138 | * Note this function may be called multiple times and the bus will not |
139 | * be released until iosf_mbi_unblock_punit_i2c_access() has been called the |
140 | * same amount of times. |
141 | * |
142 | * Return: Nonzero on error |
143 | */ |
144 | int iosf_mbi_block_punit_i2c_access(void); |
145 | |
146 | /* |
147 | * iosf_mbi_unblock_punit_i2c_access() - Release PMIC I2C bus block |
148 | * |
149 | * Release i2c access block gotten through iosf_mbi_block_punit_i2c_access(). |
150 | */ |
151 | void iosf_mbi_unblock_punit_i2c_access(void); |
152 | |
153 | /** |
154 | * iosf_mbi_register_pmic_bus_access_notifier - Register PMIC bus notifier |
155 | * |
156 | * This function can be used by drivers which may need to acquire P-Unit |
157 | * managed resources from interrupt context, where iosf_mbi_punit_acquire() |
158 | * can not be used. |
159 | * |
160 | * This function allows a driver to register a notifier to get notified (in a |
161 | * process context) before other drivers start accessing the PMIC bus. |
162 | * |
163 | * This allows the driver to acquire any resources, which it may need during |
164 | * the window the other driver is accessing the PMIC, before hand. |
165 | * |
166 | * @nb: notifier_block to register |
167 | */ |
168 | int iosf_mbi_register_pmic_bus_access_notifier(struct notifier_block *nb); |
169 | |
170 | /** |
171 | * iosf_mbi_register_pmic_bus_access_notifier - Unregister PMIC bus notifier |
172 | * |
173 | * @nb: notifier_block to unregister |
174 | */ |
175 | int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb); |
176 | |
177 | /** |
178 | * iosf_mbi_unregister_pmic_bus_access_notifier_unlocked - Unregister PMIC bus |
179 | * notifier, unlocked |
180 | * |
181 | * Like iosf_mbi_unregister_pmic_bus_access_notifier(), but for use when the |
182 | * caller has already called iosf_mbi_punit_acquire() itself. |
183 | * |
184 | * @nb: notifier_block to unregister |
185 | */ |
186 | int iosf_mbi_unregister_pmic_bus_access_notifier_unlocked( |
187 | struct notifier_block *nb); |
188 | |
189 | /** |
190 | * iosf_mbi_assert_punit_acquired - Assert that the P-Unit has been acquired. |
191 | */ |
192 | void iosf_mbi_assert_punit_acquired(void); |
193 | |
194 | #else /* CONFIG_IOSF_MBI is not enabled */ |
195 | static inline |
196 | bool iosf_mbi_available(void) |
197 | { |
198 | return false; |
199 | } |
200 | |
201 | static inline |
202 | int iosf_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr) |
203 | { |
204 | WARN(1, "IOSF_MBI driver not available" ); |
205 | return -EPERM; |
206 | } |
207 | |
208 | static inline |
209 | int iosf_mbi_write(u8 port, u8 opcode, u32 offset, u32 mdr) |
210 | { |
211 | WARN(1, "IOSF_MBI driver not available" ); |
212 | return -EPERM; |
213 | } |
214 | |
215 | static inline |
216 | int iosf_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask) |
217 | { |
218 | WARN(1, "IOSF_MBI driver not available" ); |
219 | return -EPERM; |
220 | } |
221 | |
222 | static inline void iosf_mbi_punit_acquire(void) {} |
223 | static inline void iosf_mbi_punit_release(void) {} |
224 | |
225 | static inline |
226 | int iosf_mbi_register_pmic_bus_access_notifier(struct notifier_block *nb) |
227 | { |
228 | return 0; |
229 | } |
230 | |
231 | static inline |
232 | int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb) |
233 | { |
234 | return 0; |
235 | } |
236 | |
237 | static inline int |
238 | iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(struct notifier_block *nb) |
239 | { |
240 | return 0; |
241 | } |
242 | |
243 | static inline |
244 | int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v) |
245 | { |
246 | return 0; |
247 | } |
248 | |
249 | static inline void iosf_mbi_assert_punit_acquired(void) {} |
250 | |
251 | #endif /* CONFIG_IOSF_MBI */ |
252 | |
253 | #endif /* IOSF_MBI_SYMS_H */ |
254 | |