1 /*
2  * Support for Intel Camera Imaging ISP subsystem.
3  * Copyright (c) 2010-2015, Intel Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  */
14 
15 #ifndef __DEBUG_PRIVATE_H_INCLUDED__
16 #define __DEBUG_PRIVATE_H_INCLUDED__
17 
18 #include "debug_public.h"
19 
20 #include "sp.h"
21 
22 #define __INLINE_ISP__
23 #include "isp.h"
24 
25 #include "assert_support.h"
26 
27 STORAGE_CLASS_DEBUG_C bool is_debug_buffer_empty(void)
28 {
29 	return (debug_data_ptr->head == debug_data_ptr->tail);
30 }
31 
32 STORAGE_CLASS_DEBUG_C hrt_data debug_dequeue(void)
33 {
34 	hrt_data value = 0;
35 
36 	assert(debug_buffer_address != ((hrt_address) - 1));
37 
38 	debug_synch_queue();
39 
40 	if (!is_debug_buffer_empty()) {
41 		value = debug_data_ptr->buf[debug_data_ptr->head];
42 		debug_data_ptr->head = (debug_data_ptr->head + 1) & DEBUG_BUF_MASK;
43 		sp_dmem_store_uint32(SP0_ID, debug_buffer_address + DEBUG_DATA_HEAD_ADDR,
44 				     debug_data_ptr->head);
45 	}
46 
47 	return value;
48 }
49 
50 STORAGE_CLASS_DEBUG_C void debug_synch_queue(void)
51 {
52 	u32 remote_tail = sp_dmem_load_uint32(SP0_ID,
53 					      debug_buffer_address + DEBUG_DATA_TAIL_ADDR);
54 	/* We could move the remote head after the upload, but we would have to limit the upload w.r.t. the local head. This is easier */
55 	if (remote_tail > debug_data_ptr->tail) {
56 		size_t	delta = remote_tail - debug_data_ptr->tail;
57 
58 		sp_dmem_load(SP0_ID, debug_buffer_address + DEBUG_DATA_BUF_ADDR +
59 			     debug_data_ptr->tail * sizeof(uint32_t),
60 			     (void *)&debug_data_ptr->buf[debug_data_ptr->tail], delta * sizeof(uint32_t));
61 	} else if (remote_tail < debug_data_ptr->tail) {
62 		size_t	delta = DEBUG_BUF_SIZE - debug_data_ptr->tail;
63 
64 		sp_dmem_load(SP0_ID, debug_buffer_address + DEBUG_DATA_BUF_ADDR +
65 			     debug_data_ptr->tail * sizeof(uint32_t),
66 			     (void *)&debug_data_ptr->buf[debug_data_ptr->tail], delta * sizeof(uint32_t));
67 		sp_dmem_load(SP0_ID, debug_buffer_address + DEBUG_DATA_BUF_ADDR,
68 			     (void *)&debug_data_ptr->buf[0],
69 			     remote_tail * sizeof(uint32_t));
70 	} /* else we are up to date */
71 	debug_data_ptr->tail = remote_tail;
72 }
73 
74 STORAGE_CLASS_DEBUG_C void debug_synch_queue_isp(void)
75 {
76 	u32 remote_tail = isp_dmem_load_uint32(ISP0_ID,
77 					       DEBUG_BUFFER_ISP_DMEM_ADDR + DEBUG_DATA_TAIL_ADDR);
78 	/* We could move the remote head after the upload, but we would have to limit the upload w.r.t. the local head. This is easier */
79 	if (remote_tail > debug_data_ptr->tail) {
80 		size_t	delta = remote_tail - debug_data_ptr->tail;
81 
82 		isp_dmem_load(ISP0_ID, DEBUG_BUFFER_ISP_DMEM_ADDR + DEBUG_DATA_BUF_ADDR +
83 			      debug_data_ptr->tail * sizeof(uint32_t),
84 			      (void *)&debug_data_ptr->buf[debug_data_ptr->tail], delta * sizeof(uint32_t));
85 	} else if (remote_tail < debug_data_ptr->tail) {
86 		size_t	delta = DEBUG_BUF_SIZE - debug_data_ptr->tail;
87 
88 		isp_dmem_load(ISP0_ID, DEBUG_BUFFER_ISP_DMEM_ADDR + DEBUG_DATA_BUF_ADDR +
89 			      debug_data_ptr->tail * sizeof(uint32_t),
90 			      (void *)&debug_data_ptr->buf[debug_data_ptr->tail], delta * sizeof(uint32_t));
91 		isp_dmem_load(ISP0_ID, DEBUG_BUFFER_ISP_DMEM_ADDR + DEBUG_DATA_BUF_ADDR,
92 			      (void *)&debug_data_ptr->buf[0],
93 			      remote_tail * sizeof(uint32_t));
94 	} /* else we are up to date */
95 	debug_data_ptr->tail = remote_tail;
96 }
97 
98 STORAGE_CLASS_DEBUG_C void debug_synch_queue_ddr(void)
99 {
100 	u32	remote_tail;
101 
102 	hmm_load(debug_buffer_ddr_address + DEBUG_DATA_TAIL_DDR_ADDR, &remote_tail,
103 		  sizeof(uint32_t));
104 	/* We could move the remote head after the upload, but we would have to limit the upload w.r.t. the local head. This is easier */
105 	if (remote_tail > debug_data_ptr->tail) {
106 		size_t	delta = remote_tail - debug_data_ptr->tail;
107 
108 		hmm_load(debug_buffer_ddr_address + DEBUG_DATA_BUF_DDR_ADDR +
109 			  debug_data_ptr->tail * sizeof(uint32_t),
110 			  (void *)&debug_data_ptr->buf[debug_data_ptr->tail], delta * sizeof(uint32_t));
111 	} else if (remote_tail < debug_data_ptr->tail) {
112 		size_t	delta = DEBUG_BUF_SIZE - debug_data_ptr->tail;
113 
114 		hmm_load(debug_buffer_ddr_address + DEBUG_DATA_BUF_DDR_ADDR +
115 			  debug_data_ptr->tail * sizeof(uint32_t),
116 			  (void *)&debug_data_ptr->buf[debug_data_ptr->tail], delta * sizeof(uint32_t));
117 		hmm_load(debug_buffer_ddr_address + DEBUG_DATA_BUF_DDR_ADDR,
118 			  (void *)&debug_data_ptr->buf[0],
119 			  remote_tail * sizeof(uint32_t));
120 	} /* else we are up to date */
121 	debug_data_ptr->tail = remote_tail;
122 }
123 
124 #endif /* __DEBUG_PRIVATE_H_INCLUDED__ */
125