summaryrefslogtreecommitdiff
path: root/gxp-uci.h
blob: 366a8cfb5c804e206b450fd8df710b2f2ec5756e (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
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * GXP user command interface.
 *
 * Copyright (C) 2022 Google LLC
 */

#ifndef __GXP_UCI_H__
#define __GXP_UCI_H__

#include <linux/kthread.h>

#include <gcip/gcip-mailbox.h>

#include "gxp-client.h"
#include "gxp-internal.h"
#include "gxp-mailbox.h"

struct gxp_mcu;

/* Command/Response Structures */

/* Size of `gxp_uci_type` should be u8 to match FW */
enum gxp_uci_type {
	CORE_COMMAND = 0,
	WAKELOCK_COMMAND = 1,
} __packed;

struct gxp_uci_wakelock_command_params {
	/* DVFS operating point of DSP cores */
	uint8_t dsp_operating_point;
	/* DVFS operating point of memory */
	uint8_t memory_operating_point;
};

struct gxp_uci_core_command_params {
	/* iova address of the app command */
	uint64_t address;
	/* size of the app command */
	uint32_t size;
	/* number of dsp cores required for this command */
	uint8_t num_cores;
	/* DVFS operating point of DSP cores */
	uint8_t dsp_operating_point;
	/* DVFS operating point of memory */
	uint8_t memory_operating_point;
};

struct gxp_uci_command {
	/* sequence number, should match the corresponding response */
	uint64_t seq;
	/* unique ID for each client that identifies client VM & security realm*/
	uint32_t client_id;
	/* type of the command */
	enum gxp_uci_type type;
	/* priority level for this command */
	uint8_t priority;
	/* reserved field */
	uint8_t reserved[2];
	/* All possible command parameters */
	union {
		struct gxp_uci_core_command_params core_command_params;
		struct gxp_uci_wakelock_command_params wakelock_command_params;
		uint8_t max_param_size[16];
	};
};

struct gxp_uci_response {
	/* sequence number, should match the corresponding command */
	uint64_t seq;
	/* unique ID for each client that identifies client VM & security realm*/
	uint32_t client_id;
	/* status code that tells the success or error. */
	uint16_t code;
	/* reserved field */
	uint8_t reserved[2];
	/* returned payload field */
	uint64_t payload;
};

/*
 * Wrapper struct for responses consumed by a thread other than the one which
 * sent the command.
 */
struct gxp_uci_async_response {
	struct gxp_uci_response resp;
	struct gxp_uci *uci;
	struct gxp_async_response async_response;
	struct gcip_mailbox_async_response *async_gcip_resp;
};

struct gxp_uci_wait_list {
	struct list_head list;
	struct gxp_uci_response *resp;
	bool is_async;
};

struct gxp_uci {
	struct gxp_dev *gxp;
	struct gxp_mcu *mcu;
	struct gxp_mailbox *gxp_mbx;
	struct gcip_mailbox *gcip_mbx;
	struct gxp_mapped_resource cmd_queue_mem;
	struct gxp_mapped_resource resp_queue_mem;
	struct gxp_mapped_resource descriptor_mem;
};

/* UCI APIs */

/**
 * gxp_uci_init() - API for initializing GXP UCI in MCU, should only be
 * called while initializing MCU
 * @mcu: The MCU that UCI communicate with
 *
 * Return:
 * * 0       - Initialization finished successfully
 * * -ENOMEM - Cannot get memory to finish init.
 */
int gxp_uci_init(struct gxp_mcu *mcu);

/**
 * gxp_uci_exit() - API for releasing the UCI mailbox of MCU.
 * @uci: The UCI to be released
 */
void gxp_uci_exit(struct gxp_uci *uci);

/*
 * gxp_uci_send_command() - API for sending @cmd to MCU firmware, and
 * registering @resp_queue to put the response in after MCU firmware handle the
 * command.
 *
 * Returns 0 on success, a negative errno on failure.
 */
int gxp_uci_send_command(struct gxp_uci *uci, struct gxp_uci_command *cmd,
			 struct list_head *resp_queue, spinlock_t *queue_lock,
			 wait_queue_head_t *queue_waitq,
			 struct gxp_eventfd *eventfd);

#endif /* __GXP_UCI_H__ */