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