d448b7ea43d18f6af9a4fd05034f0f145c6e652c
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / drivers / staging / nanohub / chub_ipc.h
1 /*
2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3 *
4 * Boojin Kim <boojin.kim@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12 #ifndef _MAILBOX_CHUB_IPC_H
13 #define _MAILBOX_CHUB_IPC_H
14
15 #if defined(SEOS) || defined(EMBOS)
16 #define CHUB_IPC
17 #else
18 #define AP_IPC
19 #endif
20
21 #define IPC_VERSION (180831)
22
23 #if defined(CHUB_IPC)
24 #if defined(SEOS)
25 #include <nanohubPacket.h>
26 #elif defined(EMBOS)
27 /* TODO: Add embos */
28 #define SUPPORT_LOOPBACKTEST
29 #endif
30 #include <csp_common.h>
31 #elif defined(AP_IPC)
32 #if defined(CONFIG_NANOHUB)
33 #include "comms.h"
34 #elif defined(CONFIG_CONTEXTHUB_DRV)
35 // TODO: Add packet size.. #define PACKET_SIZE_MAX ()
36 #endif
37 #endif
38
39 #ifndef PACKET_SIZE_MAX
40 #define PACKET_SIZE_MAX (272)
41 #endif
42
43 #ifdef LOWLEVEL_DEBUG
44 #define DEBUG_LEVEL (0)
45 #else
46 #if defined(CHUB_IPC)
47 #define DEBUG_LEVEL (LOG_ERROR)
48 #elif defined(AP_IPC)
49 #define DEBUG_LEVEL (KERN_ERR)
50 #endif
51 #endif
52
53 #ifndef CSP_PRINTF_INFO
54 #ifdef AP_IPC
55 #ifdef LOWLEVEL_DEBUG
56 #define CSP_PRINTF_INFO(fmt, ...) log_printf(fmt, ##__VA_ARGS__)
57 #define CSP_PRINTF_ERROR(fmt, ...) log_printf(fmt, ##__VA_ARGS__)
58 #else
59 #define CSP_PRINTF_INFO(fmt, ...) pr_info(fmt, ##__VA_ARGS__)
60 #define CSP_PRINTF_ERROR(fmt, ...) pr_err(fmt, ##__VA_ARGS__)
61 #endif
62 #endif
63 #endif
64
65 #ifdef LOWLEVEL_DEBUG
66 #define DEBUG_PRINT(lv, fmt, ...) \
67 ((DEBUG_LEVEL == (0)) ? (CSP_PRINTF_INFO(fmt, ##__VA_ARGS__)) : \
68 ((DEBUG_LEVEL == (lv)) ? (CSP_PRINTF_INFO(fmt, ##__VA_ARGS__)) : (NULL)))
69 #else
70 #define DEBUG_PRINT(level, fmt, ...)
71 #endif
72
73 /* contexthub bootargs */
74 #define BL_OFFSET (0x0)
75 #define MAP_INFO_OFFSET (256)
76 #define MAP_INFO_MAX_SIZE (128)
77 #define CHUB_PERSISTBUF_SIZE (96)
78
79 #define OS_UPDT_MAGIC "Nanohub OS"
80
81 #define BOOTMODE_COLD (0x77773333)
82 #define BOOTMODE_PWRGATING (0x11118888)
83
84 struct chub_bootargs {
85 char magic[16];
86 u32 ipc_version;
87 u32 bl_start;
88 u32 bl_end;
89 u32 code_start;
90 u32 code_end;
91 u32 ipc_start;
92 u32 ipc_end;
93 u32 ram_start;
94 u32 ram_end;
95 u32 shared_start;
96 u32 shared_end;
97 u32 dump_start;
98 u32 dump_end;
99 u32 chubclk;
100 u32 bootmode;
101 #if defined(LOCAL_POWERGATE)
102 u32 psp;
103 u32 msp;
104 #endif
105 };
106
107 /* ipc map
108 * data channel: AP -> CHUB
109 * data channel: CHUB -> AP
110 * event channel: AP -> CHUB / ctrl
111 * event channel: CHUB -> AP / ctrl
112 * logbuf / logbuf_ctrl
113 */
114 #define IPC_BUF_NUM (IRQ_EVT_CH_MAX)
115 #define IPC_EVT_NUM (15)
116 #define IPC_LOGBUF_NUM (256)
117
118 enum sr_num {
119 SR_0 = 0,
120 SR_1 = 1,
121 SR_2 = 2,
122 SR_3 = 3,
123 };
124
125 #define SR_A2C_ADDR SR_0
126 #define SR_A2C_SIZE SR_1
127 #define SR_C2A_ADDR SR_2
128 #define SR_C2A_SIZE SR_3
129 #define SR_DEBUG_ACTION SR_0
130 #define SR_DEBUG_VAL_LOW SR_1
131 #define SR_DEBUG_VAL_HIGH SR_2
132 #define SR_CHUB_ALIVE SR_3
133 #define SR_BOOT_MODE SR_0
134
135 enum irq_chub {
136 IRQ_C2A_START,
137 IRQ_C2A_END = 2,
138 IRQ_EVT_START,
139 IRQ_EVT_END = 15,
140 IRQ_CHUB_ALIVE = 15,
141 IRQ_INVAL = 0xff,
142 };
143
144 enum irq_evt_chub {
145 IRQ_EVT_CH0, /* data channel */
146 IRQ_EVT_CH1,
147 IRQ_EVT_CH2,
148 IRQ_EVT_CH_MAX,
149 IRQ_EVT_A2C_RESET = IRQ_EVT_CH_MAX,
150 IRQ_EVT_A2C_WAKEUP,
151 IRQ_EVT_A2C_WAKEUP_CLR,
152 IRQ_EVT_A2C_SHUTDOWN,
153 IRQ_EVT_A2C_LOG,
154 IRQ_EVT_A2C_DEBUG,
155 IRQ_EVT_C2A_DEBUG = IRQ_EVT_CH_MAX,
156 IRQ_EVT_C2A_ASSERT,
157 IRQ_EVT_C2A_INT,
158 IRQ_EVT_C2A_INTCLR,
159 IRQ_EVT_CHUB_EVT_MAX = 15,
160 IRQ_EVT_CHUB_ALIVE = IRQ_EVT_CHUB_EVT_MAX,
161 IRQ_EVT_CHUB_MAX = 16, /* max irq number on mailbox */
162 IRQ_EVT_INVAL = 0xff,
163 };
164
165 enum ipc_debug_event {
166 IPC_DEBUG_UTC_STOP, /* no used. UTC_NONE */
167 IPC_DEBUG_UTC_AGING,
168 IPC_DEBUG_UTC_WDT,
169 IPC_DEBUG_UTC_RTC,
170 IPC_DEBUG_UTC_MEM,
171 IPC_DEBUG_UTC_TIMER,
172 IPC_DEBUG_UTC_GPIO,
173 IPC_DEBUG_UTC_SPI,
174 IPC_DEBUG_UTC_CMU,
175 IPC_DEBUG_UTC_TIME_SYNC,
176 IPC_DEBUG_UTC_ASSERT, /* 10 */
177 IPC_DEBUG_UTC_FAULT,
178 IPC_DEBUG_UTC_CHECK_STATUS,
179 IPC_DEBUG_UTC_CHECK_CPU_UTIL,
180 IPC_DEBUG_UTC_HEAP_DEBUG,
181 IPC_DEBUG_UTC_HANG,
182 IPC_DEBUG_UTC_HANG_ITMON,
183 IPC_DEBUG_UTC_SENSOR_CHIPID, /* ap request */
184 IPC_DEBUG_UTC_IPC_TEST_START,
185 IPC_DEBUG_UTC_IPC_TEST_END,
186 IPC_DEBUG_DUMP_STATUS,
187 IPC_DEBUG_UTC_MAX,
188 IPC_DEBUG_NANOHUB_MAX,
189 IPC_DEBUG_CHUB_PRINT_LOG, /* chub request */
190 IPC_DEBUG_CHUB_FULL_LOG,
191 IPC_DEBUG_CHUB_FAULT,
192 IPC_DEBUG_CHUB_ASSERT,
193 IPC_DEBUG_CHUB_ERROR,
194 };
195
196 enum ipc_region {
197 IPC_REG_BL,
198 IPC_REG_BL_MAP,
199 IPC_REG_OS,
200 IPC_REG_IPC,
201 IPC_REG_IPC_EVT_A2C,
202 IPC_REG_IPC_EVT_A2C_CTRL,
203 IPC_REG_IPC_EVT_C2A,
204 IPC_REG_IPC_EVT_C2A_CTRL,
205 IPC_REG_IPC_A2C,
206 IPC_REG_IPC_C2A,
207 IPC_REG_SHARED,
208 IPC_REG_RAM,
209 IPC_REG_LOG,
210 IPC_REG_PERSISTBUF,
211 IPC_REG_DUMP,
212 IPC_REG_MAX,
213 };
214
215 struct ipc_area {
216 void *base;
217 u32 offset;
218 };
219
220 enum ipc_owner {
221 AP,
222 #if defined(CHUB_IPC)
223 APM,
224 CP,
225 GNSS,
226 #endif
227 IPC_OWN_MAX
228 };
229
230 enum ipc_data_list {
231 IPC_DATA_C2A,
232 IPC_DATA_A2C,
233 IPC_DATA_MAX,
234 };
235
236 enum ipc_evt_list {
237 IPC_EVT_C2A,
238 IPC_EVT_A2C,
239 IPC_EVT_AP_MAX,
240 IPC_EVT_MAX = IPC_EVT_AP_MAX
241 };
242
243 enum ipc_packet {
244 IPC_ALIVE_HELLO = 0xab,
245 IPC_ALIVE_OK = 0xcd,
246 };
247
248 enum ipc_direction {
249 IPC_DST,
250 IPC_SRC,
251 };
252
253 /* channel status define
254 * IDLE_A2C: 100
255 * AP_WRITE : 110
256 * CHUB_RECV: 101
257 * IDLE_C2A: 000
258 * CHUB_WRITE: 010
259 * AP_RECV: 001
260 */
261 #define CS_OWN_OFFSET (3)
262 #define CS_AP (0x1)
263 #define CS_CHUB (0x0)
264 #define CS_AP_OWN (CS_AP << CS_OWN_OFFSET)
265 #define CS_CHUB_OWN (CS_CHUB << CS_OWN_OFFSET)
266 #define CS_WRITE (0x2)
267 #define CS_RECV (0x1)
268 #define CS_IPC_REG_CMP (0x3)
269
270 enum channel_status {
271 #ifdef AP_IPC
272 CS_IDLE = CS_AP_OWN,
273 #else
274 CS_IDLE = CS_CHUB_OWN,
275 #endif
276 CS_AP_WRITE = CS_AP_OWN | CS_WRITE,
277 CS_CHUB_RECV = CS_AP_OWN | CS_RECV,
278 CS_CHUB_WRITE = CS_CHUB_OWN | CS_WRITE,
279 CS_AP_RECV = CS_CHUB_OWN | CS_RECV,
280 CS_MAX = 0xf
281 };
282
283 #define INVAL_CHANNEL (-1)
284
285 #if defined(AP_IPC) || defined(EMBOS)
286 #define HOSTINTF_SENSOR_DATA_MAX 240
287 #endif
288
289 /* event structure */
290 struct ipc_evt_ctrl {
291 u32 eq;
292 u32 dq;
293 u32 full;
294 u32 empty;
295 u32 irq;
296 };
297
298 struct ipc_evt_buf {
299 u32 evt;
300 u32 irq;
301 u32 status;
302 };
303
304 struct ipc_evt {
305 struct ipc_evt_buf data[IPC_EVT_NUM];
306 struct ipc_evt_ctrl ctrl;
307 };
308
309 /* it's from struct HostIntfDataBuffer buf */
310 struct ipc_log_content {
311 u8 pad0;
312 u8 length;
313 u16 pad1;
314 u8 buffer[sizeof(u64) + HOSTINTF_SENSOR_DATA_MAX - sizeof(u32)];
315 };
316
317 struct ipc_logbuf {
318 u32 eq; /* write owner chub (index_writer) */
319 u32 dq; /* read onwer ap (index_reader) */
320 u32 size;
321 u32 token;
322 u32 full;
323 char buf[0];
324 };
325
326 #ifndef IPC_DATA_SIZE
327 #define IPC_DATA_SIZE (4096)
328 #endif
329
330 struct ipc_channel_buf {
331 u32 size;
332 u8 buf[PACKET_SIZE_MAX];
333 };
334
335 #define IPC_CH_BUF_NUM (6)
336 struct ipc_buf {
337 volatile u32 eq;
338 volatile u32 dq;
339 volatile u32 full;
340 volatile u32 empty;
341 #ifdef USE_IPC_BUF
342 u8 buf[IPC_DATA_SIZE];
343 #else
344 struct ipc_channel_buf ch[IPC_CH_BUF_NUM];
345 #endif
346 };
347
348 struct ipc_debug {
349 u32 event;
350 u32 val[IPC_DATA_MAX];
351 };
352
353 struct ipc_map_area {
354 struct ipc_buf data[IPC_DATA_MAX];
355 struct ipc_evt evt[IPC_EVT_MAX];
356 struct ipc_debug dbg;
357 struct ipc_logbuf logbuf;
358 };
359
360 /* mailbox Registers */
361 #define REG_MAILBOX_MCUCTL (0x000)
362 #define REG_MAILBOX_INTGR0 (0x008)
363 #define REG_MAILBOX_INTCR0 (0x00C)
364 #define REG_MAILBOX_INTMR0 (0x010)
365 #define REG_MAILBOX_INTSR0 (0x014)
366 #define REG_MAILBOX_INTMSR0 (0x018)
367 #define REG_MAILBOX_INTGR1 (0x01C)
368 #define REG_MAILBOX_INTCR1 (0x020)
369 #define REG_MAILBOX_INTMR1 (0x024)
370 #define REG_MAILBOX_INTSR1 (0x028)
371 #define REG_MAILBOX_INTMSR1 (0x02C)
372
373 #if defined(AP_IPC)
374 #if defined(CONFIG_SOC_EXYNOS9810)
375 #define REG_MAILBOX_VERSION (0x050)
376 #elif defined(CONFIG_SOC_EXYNOS9610)
377 #define REG_MAILBOX_VERSION (0x070)
378 #else
379 //
380 //Need to check !!!
381 //
382 #define REG_MAILBOX_VERSION (0x0)
383 #endif
384 #endif
385
386 #define REG_MAILBOX_ISSR0 (0x080)
387 #define REG_MAILBOX_ISSR1 (0x084)
388 #define REG_MAILBOX_ISSR2 (0x088)
389 #define REG_MAILBOX_ISSR3 (0x08C)
390
391 #define IPC_HW_READ_STATUS(base) \
392 __raw_readl((base) + REG_MAILBOX_INTSR0)
393 #define IPC_HW_READ_STATUS1(base) \
394 __raw_readl((base) + REG_MAILBOX_INTSR1)
395 #define IPC_HW_READ_PEND(base, irq) \
396 (__raw_readl((base) + REG_MAILBOX_INTSR1) & (1 << (irq)))
397 #define IPC_HW_CLEAR_PEND(base, irq) \
398 __raw_writel(1 << (irq), (base) + REG_MAILBOX_INTCR0)
399 #define IPC_HW_CLEAR_PEND1(base, irq) \
400 __raw_writel(1 << (irq), (base) + REG_MAILBOX_INTCR1)
401 #define IPC_HW_WRITE_SHARED_REG(base, num, data) \
402 __raw_writel((data), (base) + REG_MAILBOX_ISSR0 + (num) * 4)
403 #define IPC_HW_READ_SHARED_REG(base, num) \
404 __raw_readl((base) + REG_MAILBOX_ISSR0 + (num) * 4)
405 #define IPC_HW_GEN_INTERRUPT_GR1(base, num) \
406 __raw_writel(1 << (num), (base) + REG_MAILBOX_INTGR1)
407 #define IPC_HW_GEN_INTERRUPT_GR0(base, num) \
408 __raw_writel(1 << ((num) + 16), (base) + REG_MAILBOX_INTGR0)
409 #define IPC_HW_SET_MCUCTL(base, val) \
410 __raw_write32((val), (base) + REG_MAILBOX_MCUCTL)
411
412 /* channel ctrl functions */
413 void ipc_print_channel(void);
414 int ipc_check_valid(void);
415 char *ipc_get_cs_name(enum channel_status cs);
416 void ipc_set_base(void *addr);
417 void *ipc_get_base(enum ipc_region area);
418 u32 ipc_get_offset(enum ipc_region area);
419 void *ipc_get_addr(enum ipc_region area, int buf_num);
420 int ipc_check_reset_valid(void);
421 void ipc_init(void);
422 int ipc_hw_read_int_start_index(enum ipc_owner owner);
423 /* logbuf functions */
424 void *ipc_get_logbuf(void);
425 unsigned int ipc_logbuf_get_token(void);
426 /* evt functions */
427 struct ipc_evt_buf *ipc_get_evt(enum ipc_evt_list evt);
428 int ipc_add_evt(enum ipc_evt_list evt, enum irq_evt_chub irq);
429 void ipc_print_evt(enum ipc_evt_list evt);
430 /* mailbox hw access */
431 void ipc_set_owner(enum ipc_owner owner, void *base, enum ipc_direction dir);
432 unsigned int ipc_hw_read_gen_int_status_reg(enum ipc_owner owner, int irq);
433 void ipc_hw_write_shared_reg(enum ipc_owner owner, unsigned int val, int num);
434 unsigned int ipc_hw_read_shared_reg(enum ipc_owner owner, int num);
435 unsigned int ipc_hw_read_int_status_reg(enum ipc_owner owner);
436 unsigned int ipc_hw_read_int_gen_reg(enum ipc_owner owner);
437 void ipc_hw_clear_int_pend_reg(enum ipc_owner owner, int irq);
438 void ipc_hw_clear_all_int_pend_reg(enum ipc_owner owner);
439 void ipc_hw_gen_interrupt(enum ipc_owner owner, int irq);
440 void ipc_hw_set_mcuctrl(enum ipc_owner owner, unsigned int val);
441 void ipc_hw_mask_irq(enum ipc_owner owner, int irq);
442 void ipc_hw_unmask_irq(enum ipc_owner owner, int irq);
443 void ipc_logbuf_put_with_char(char ch);
444 int ipc_logbuf_need_flush(void);
445 void ipc_write_debug_event(enum ipc_owner owner, enum ipc_debug_event action);
446 u32 ipc_read_debug_event(enum ipc_owner owner);
447 void ipc_write_debug_val(enum ipc_data_list dir, u32 val);
448 u32 ipc_read_debug_val(enum ipc_data_list dir);
449
450 void *ipc_get_chub_map(void);
451 u32 ipc_get_chub_mem_size(void);
452 u64 ipc_read_val(enum ipc_owner owner);
453 void ipc_write_val(enum ipc_owner owner, u64 result);
454 void ipc_set_chub_clk(u32 clk);
455 u32 ipc_get_chub_clk(void);
456 void ipc_set_chub_bootmode(u32 bootmode);
457 u32 ipc_get_chub_bootmode(void);
458 void ipc_dump(void);
459 #if defined(LOCAL_POWERGATE)
460 u32 *ipc_get_chub_psp(void);
461 u32 *ipc_get_chub_msp(void);
462 #endif
463
464 #ifdef USE_IPC_BUF
465 int ipc_read_data(enum ipc_data_list dir, u8 *rx);
466 #else
467 void *ipc_read_data(enum ipc_data_list dir, u32 *len);
468 #endif
469 int ipc_write_data(enum ipc_data_list dir, void *tx, u16 length);
470
471 #endif