summaryrefslogtreecommitdiff
path: root/gxp-kci.h
blob: ca7c1433b8396a43a974f9532ffdd7339f0ecd2c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Kernel Control Interface, implements the protocol between DSP Kernel driver and MCU firmware.
 *
 * Copyright (C) 2022 Google LLC
 */

#ifndef __GXP_KCI_H__
#define __GXP_KCI_H__

#include <linux/bits.h>

#include <gcip/gcip-kci.h>
#include <gcip/gcip-telemetry.h>

#include "gxp-internal.h"
#include "gxp-mailbox.h"
#include "gxp-mcu-firmware.h"
#include "gxp-vd.h"

/*
 * Maximum number of outstanding KCI requests from firmware
 * This is used to size a circular buffer, so it must be a power of 2
 */
#define GXP_REVERSE_KCI_BUFFER_SIZE (32)

/* Timeout for KCI responses from the firmware (milliseconds) */
#ifndef GXP_KCI_TIMEOUT
#if IS_ENABLED(CONFIG_GXP_TEST)
#define GXP_KCI_TIMEOUT (200) /* Fake firmware could respond in a short time. */
#else
#define GXP_KCI_TIMEOUT (5000) /* 5 secs. */
#endif
#endif /* GXP_KCI_TIMEOUT */

/*
 * Operations of `allocate_vmbox` KCI command.
 * The bits of @operation of `struct gxp_kci_allocate_vmbox_detail` will be set with these.
 */
#define KCI_ALLOCATE_VMBOX_OP_ALLOCATE_VMBOX BIT(0)
#define KCI_ALLOCATE_VMBOX_OP_LINK_OFFLOAD_VMBOX BIT(1)

/*
 * Type of chip to link offload virtual mailbox.
 * @offload_type of `struct gxp_kci_allocate_vmbox_detail` will be set with these.
 */
#define KCI_ALLOCATE_VMBOX_OFFLOAD_TYPE_TPU 0

/*
 * Chip specific reverse KCI request codes.
 */
enum gxp_reverse_rkci_code {
	GXP_RKCI_CODE_PM_QOS_BTS = GCIP_RKCI_CHIP_CODE_FIRST + 3,
	GXP_RKCI_CODE_CORE_TELEMETRY_READ = GCIP_RKCI_CHIP_CODE_FIRST + 4,
};

struct gxp_mcu;

struct gxp_kci {
	struct gxp_dev *gxp;
	struct gxp_mcu *mcu;
	struct gxp_mailbox *mbx;

	struct gxp_mapped_resource cmd_queue_mem;
	struct gxp_mapped_resource resp_queue_mem;
	struct gxp_mapped_resource descriptor_mem;
};

/* Used when sending the details about allocate_vmbox KCI command. */
struct gxp_kci_allocate_vmbox_detail {
	/* Client ID. */
	u32 client_id;
	/* The number of required cores. */
	u8 num_cores;
	/*
	 * Slice index of client_id used for identifying the 12KB slice buffer of memory to be
	 * used for MCU<->core mailbox.
	 */
	u8 slice_index;
	/* Whether it's the first time allocating a VMBox for this VD. */
	bool first_open;
	/* Reserved */
	u8 reserved[57];
} __packed;

/* Used when sending the details about release_vmbox KCI command. */
struct gxp_kci_release_vmbox_detail {
	/* Client ID. */
	u32 client_id;
	/* Reserved */
	u8 reserved[60];
} __packed;

/* Used when sending the details about {link,unlink}_offload_vmbox KCI command. */
struct gxp_kci_link_unlink_offload_vmbox_detail {
	/* DSP Client ID. */
	u32 client_id;
	/* Client ID of offload mailbox. */
	u32 offload_client_id;
	/*
	 * Chip type of offload mailbox.
	 * See enum gcip_kci_offload_chip_type.
	 */
	u8 offload_chip_type;
	/* Reserved */
	u8 reserved[55];
} __packed;

/*
 * Initializes a KCI object.
 *
 * Will request a mailbox from @mgr and allocate cmd/resp queues.
 */
int gxp_kci_init(struct gxp_mcu *mcu);

/*
 * Re-initializes the initialized KCI object.
 *
 * This function is used when the DSP device is reset, it re-programs CSRs
 * related to KCI mailbox.
 *
 * Returns 0 on success, -errno on error.
 */
int gxp_kci_reinit(struct gxp_kci *gkci);

/* Cancel work queues or wait until they're done */
void gxp_kci_cancel_work_queues(struct gxp_kci *gkci);

/*
 * Releases resources allocated by @kci.
 *
 * Note: must invoke this function after the interrupt of mailbox disabled and
 * before free the mailbox pointer.
 */
void gxp_kci_exit(struct gxp_kci *gkci);

/*
 * Sends a FIRMWARE_INFO command and expects a response with a
 * gxp_mcu_firmware_info struct filled out, including what firmware type is running,
 * along with build CL and time.
 * Also serves as an initial handshake with firmware at load time.
 *
 * @fw_info: a struct gxp_mcu_firmware_info to be filled out by fw
 *
 * Returns >=0 gcip_fw_flavor when response received from firmware,
 *         <0 on error communicating with firmware (typically -ETIMEDOUT).
 */
enum gcip_fw_flavor gxp_kci_fw_info(struct gxp_kci *gkci,
				    struct gcip_fw_info *fw_info);

/*
 * Retrieves usage tracking data from firmware, update info on host.
 * Also used as a watchdog ping to firmware.
 *
 * Returns KCI response code on success or < 0 on error (typically -ETIMEDOUT).
 */
int gxp_kci_update_usage(struct gxp_kci *gkci);
void gxp_kci_update_usage_async(struct gxp_kci *gkci);

/*
 * Works the same as gxp_kci_update_usage() except the caller of this
 * function must guarantee the device stays powered up.
 *
 * Returns KCI response code on success or < 0 on error (typically -ETIMEDOUT).
 */
int gxp_kci_update_usage_locked(struct gxp_kci *gkci);

/*
 * Sends the "Map Log Buffer" command and waits for remote response.
 *
 * Returns the code of response, or a negative errno on error.
 */
int gxp_kci_map_mcu_log_buffer(struct gcip_telemetry_kci_args *args);

/*
 * Sends the "Map Trace Buffer" command and waits for remote response.
 *
 * Returns the code of response, or a negative errno on error.
 */
int gxp_kci_map_mcu_trace_buffer(struct gcip_telemetry_kci_args *args);

/* Send shutdown request to firmware */
int gxp_kci_shutdown(struct gxp_kci *gkci);

/*
 * Set the GXP thermal throttling.
 *
 * Returns the code of response, or a negative errno on error.
 */
int gxp_kci_notify_throttling(struct gxp_kci *gkci, u32 rate);

/*
 * Allocates a virtual mailbox to communicate with MCU firmware.
 *
 * A new client wants to run a workload on DSP, it needs to allocate a virtual mailbox. Creating
 * mailbox will be initiated from the application by calling GXP_ALLOCATE_VIRTUAL_DEVICE ioctl.
 * Allocated virtual mailbox should be released by calling `gxp_kci_release_vmbox`.
 *
 * Returns the code of response, or a negative errno on error.
 */
int gxp_kci_allocate_vmbox(struct gxp_kci *gkci, u32 client_id, u8 num_cores,
			   u8 slice_index, bool first_open);

/*
 * Releases a virtual mailbox which is allocated by `gxp_kci_allocate_vmbox`.
 * This function will be called by `gxp_vd_release`.
 *
 * Returns the code of response, or a negative errno on error.
 */
int gxp_kci_release_vmbox(struct gxp_kci *gkci, u32 client_id);

/*
 * Links or unlinks @client_id (DSP client ID) and @offload_client_id (Client ID of offloading
 * chip). It will link them if @link is true. Otherwise, it will unlink them.
 *
 * Link: Should be called before sending offload commands from DSP to the target chip.
 * Unlink: Should be called after offloading is completed.
 *
 * The type of the target chip should be passed to the @offload_chip_type.
 *
 * Returns the code of response, or a negative errno on error.
 */
int gxp_kci_link_unlink_offload_vmbox(
	struct gxp_kci *gkci, u32 client_id, u32 offload_client_id,
	enum gcip_kci_offload_chip_type offload_chip_type, bool link);

/*
 * Send an ack to the FW after handling a reverse KCI request.
 *
 * The FW may wait for a response from the kernel for an RKCI request so a
 * response could be sent as an ack.
 */
void gxp_kci_resp_rkci_ack(struct gxp_kci *gkci,
			   struct gcip_kci_response_element *rkci_cmd);

#endif /* __GXP_KCI_H__ */