blob: 105599c24238644ad72601ae0bdc3cfd0c13ae27 [file] [log] [blame]
Kyle Pieferb1027b02017-02-10 13:58:58 -08001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13#ifndef __KGSL_HFI_H
14#define __KGSL_HFI_H
15
16#include <linux/types.h>
17
18#define HFI_QUEUE_SIZE SZ_4K /* bytes */
19#define MAX_RSP_PAYLOAD_SIZE 16 /* dwords */
20#define HFI_MAX_MSG_SIZE (SZ_1K>>2) /* dwords */
21
22/* Below section is for all structures related to HFI queues */
23enum hfi_queue_type {
24 HFI_CMD_QUEUE = 0,
25 HFI_MSG_QUEUE,
26 HFI_DBG_QUEUE,
27 HFI_QUEUE_MAX
28};
29
30/* Add 16B guard band between HFI queues */
31#define HFI_QUEUE_OFFSET(i) \
32 ((sizeof(struct hfi_queue_table)) + \
33 ((i) * (HFI_QUEUE_SIZE + 16)))
34
35#define HOST_QUEUE_START_ADDR(hfi_mem, i) \
36 ((hfi_mem)->hostptr + HFI_QUEUE_OFFSET(i))
37
38#define GMU_QUEUE_START_ADDR(hfi_mem, i) \
39 ((hfi_mem)->gmuaddr + HFI_QUEUE_OFFSET(i))
40
Kyle Piefere7b06b42017-04-06 13:53:01 -070041#define HFI_IRQ_MSGQ_MASK BIT(0)
42#define HFI_IRQ_DBGQ_MASK BIT(1)
43#define HFI_IRQ_BLOCKED_MSG_MASK BIT(2)
44#define HFI_IRQ_CM3_FAULT_MASK BIT(23)
45#define HFI_IRQ_GMU_ERR_MASK GENMASK(22, 16)
46#define HFI_IRQ_OOB_MASK GENMASK(31, 24)
47#define HFI_IRQ_MASK (HFI_IRQ_MSGQ_MASK |\
48 HFI_IRQ_CM3_FAULT_MASK)
49
Kyle Pieferb1027b02017-02-10 13:58:58 -080050/**
51 * struct hfi_queue_table_header - HFI queue table structure
52 * @version: HFI protocol version
53 * @size: queue table size in dwords
54 * @qhdr0_offset: first queue header offset (dwords) in this table
55 * @qhdr_size: queue header size
56 * @num_q: number of queues defined in this table
57 * @num_active_q: number of active queues
58 */
59struct hfi_queue_table_header {
60 uint32_t version;
61 uint32_t size;
62 uint32_t qhdr0_offset;
63 uint32_t qhdr_size;
64 uint32_t num_q;
65 uint32_t num_active_q;
66};
67
68/**
69 * struct hfi_queue_header - HFI queue header structure
70 * @status: active: 1; inactive: 0
71 * @start_addr: starting address of the queue in GMU VA space
72 * @type: queue type encoded the priority, ID and send/recevie types
73 * @queue_size: size of the queue
74 * @msg_size: size of the message if each message has fixed size.
75 * Otherwise, 0 means variable size of message in the queue.
76 * @drop_cnt: count of dropped messages
77 * @rx_wm: receiver watermark
78 * @tx_wm: sender watermark
79 * @rx_req: receiver request
80 * @tx_req: sender request
81 * @read_index: read index of the queue
82 * @write_index: write index of the queue
83 */
84struct hfi_queue_header {
85 uint32_t status;
86 uint32_t start_addr;
87 uint32_t type;
88 uint32_t queue_size;
89 uint32_t msg_size;
90 uint32_t drop_cnt;
91 uint32_t rx_wm;
92 uint32_t tx_wm;
93 uint32_t rx_req;
94 uint32_t tx_req;
95 uint32_t read_index;
96 uint32_t write_index;
97};
98
99struct hfi_queue_table {
100 struct hfi_queue_table_header qtbl_hdr;
101 struct hfi_queue_header qhdr[HFI_QUEUE_MAX];
102};
103
104/* HTOF queue priority, 1 is highest priority */
105enum hfi_h2f_qpri {
106 HFI_H2F_QPRI_CMD = 10,
107 HFI_H2F_QPRI_DISPATCH_P0 = 20,
108 HFI_H2F_QPRI_DISPATCH_P1 = 21,
109 HFI_H2F_QPRI_DISPATCH_P2 = 22,
110};
111
112/* FTOH queue priority, 1 is highest priority */
113enum hfi_f2h_qpri {
114 HFI_F2H_QPRI_MSG = 10,
115 HFI_F2H_QPRI_DEBUG = 40,
116};
117
George Shen08973d42017-10-03 17:40:22 -0700118#define HFI_RSP_TIMEOUT 5000 /* msec */
Kyle Pieferb1027b02017-02-10 13:58:58 -0800119#define HFI_H2F_CMD_IRQ_MASK BIT(0)
120
121enum hfi_msg_type {
122 HFI_MSG_CMD = 0,
123 HFI_MSG_POST = 1,
124 HFI_MSG_ACK = 2,
125 HFI_MSG_INVALID = 3
126};
127
128enum hfi_msg_id {
129 H2F_MSG_INIT = 0,
130 H2F_MSG_FW_VER = 1,
131 H2F_MSG_LM_CFG = 2,
132 H2F_MSG_BW_VOTE_TBL = 3,
133 H2F_MSG_PERF_TBL = 4,
134 H2F_MSG_TEST = 5,
135 H2F_MSG_DCVS_VOTE = 30,
136 H2F_MSG_FW_HALT = 31,
137 H2F_MSG_PREPARE_SLUMBER = 33,
138 F2H_MSG_ERR = 100,
139 F2H_MSG_GMU_CNTR_REGISTER = 101,
140 F2H_MSG_ACK = 126,
141 H2F_MSG_ACK = 127,
142 H2F_MSG_REGISTER_CONTEXT = 128,
143 H2F_MSG_UNREGISTER_CONTEXT = 129,
144 H2F_MSG_ISSUE_IB = 130,
145 H2F_MSG_REGISTER_QUEUE = 131,
146 H2F_MSG_UNREGISTER_QUEUE = 132,
147 H2F_MSG_CLOSE = 133,
148 H2F_REGISTER_CONTEXT_DONE = 134,
149 H2F_UNREG_CONTEXT_DONE = 135,
150 H2F_ISSUE_IB_DONE = 136,
151 H2F_REGISTER_QUEUE_DONE = 137,
152};
153
154#define MAX_GX_LEVELS 16
155#define MAX_CX_LEVELS 4
156#define MAX_CNOC_LEVELS 2
157#define MAX_CNOC_CMDS 6
158#define MAX_BW_CMDS 8
159#define INVALID_DCVS_IDX 0xFF
160
161#if MAX_CNOC_LEVELS > MAX_GX_LEVELS
162#error "CNOC levels cannot exceed GX levels"
163#endif
164
165/**
166 * For detail usage of structures defined below,
167 * please look up HFI spec.
168 */
169
170struct hfi_msg_hdr {
171 uint32_t id: 8; /* 0~127 power, 128~255 ecp */
172 uint32_t size: 8; /* unit in dword */
173 uint32_t type: 4;
174 uint32_t seqnum: 12;
175};
176
177struct hfi_msg_rsp {
178 struct hfi_msg_hdr hdr;
179 struct hfi_msg_hdr ret_hdr;
180 uint32_t error;
181 uint32_t payload[MAX_RSP_PAYLOAD_SIZE];
182};
183
184struct hfi_gmu_init_cmd {
185 struct hfi_msg_hdr hdr;
186 uint32_t seg_id;
187 uint32_t dbg_buffer_addr;
188 uint32_t dbg_buffer_size;
189 uint32_t boot_state;
190};
191
192struct hfi_fw_version_cmd {
193 struct hfi_msg_hdr hdr;
194 uint32_t supported_ver;
195};
196
197struct limits_config {
198 uint32_t lm_type: 4;
199 uint32_t lm_sensor_type: 4;
200 uint32_t throttle_config: 4;
201 uint32_t idle_throttle_en: 4;
202 uint32_t acd_en: 4;
203 uint32_t reserved: 12;
204};
205
206struct bcl_config {
207 uint32_t bcl: 8;
208 uint32_t reserved: 24;
209};
210
211struct hfi_lmconfig_cmd {
212 struct hfi_msg_hdr hdr;
213 struct limits_config limit_conf;
214 struct bcl_config bcl_conf;
215 uint32_t lm_enable_bitmask;
216};
217
218struct hfi_bwtable_cmd {
219 struct hfi_msg_hdr hdr;
220 uint32_t bw_level_num;
221 uint32_t cnoc_cmds_num;
222 uint32_t ddr_cmds_num;
223 uint32_t cnoc_wait_bitmask;
224 uint32_t ddr_wait_bitmask;
225 uint32_t cnoc_cmd_addrs[MAX_CNOC_CMDS];
226 uint32_t cnoc_cmd_data[MAX_CNOC_LEVELS][MAX_CNOC_CMDS];
227 uint32_t ddr_cmd_addrs[MAX_BW_CMDS];
228 uint32_t ddr_cmd_data[MAX_GX_LEVELS][MAX_BW_CMDS];
229};
230
Kyle Piefer950f5922017-07-11 15:11:28 -0700231struct hfi_test_cmd {
232 struct hfi_msg_hdr hdr;
233};
234
Kyle Pieferb1027b02017-02-10 13:58:58 -0800235struct arc_vote_desc {
236 /* In case of GPU freq vote, primary is GX, secondary is MX
237 * in case of GMU freq vote, primary is CX, secondary is MX
238 */
239 uint32_t pri_idx: 8;
240 uint32_t sec_idx : 8;
241 uint32_t vlvl: 16;
242};
243
244struct opp_desc {
245 struct arc_vote_desc vote;
246 uint32_t freq;
247};
248
249struct hfi_dcvstable_cmd {
250 struct hfi_msg_hdr hdr;
251 uint32_t gpu_level_num;
252 uint32_t gmu_level_num;
253 struct opp_desc gx_votes[MAX_GX_LEVELS];
254 struct opp_desc cx_votes[MAX_CX_LEVELS];
255};
256
257enum fw_clkset_options {
258 OPTION_DEFAULT = 0,
259 OPTION_CLOSEST = 1,
260 OPTION_AT_MOST = 2,
261 OPTION_AT_LEAST = 3,
262 OPTION_INVALID = 4
263};
264
265enum rpm_ack_type {
266 ACK_NONBLOCK = 0,
267 ACK_BLOCK = 1,
268 ACK_INVALID = 2,
269};
270
271struct gpu_dcvs_vote {
272 uint32_t perf_idx : 8;
273 uint32_t reserved : 20;
274 uint32_t clkset_opt : 4;
275};
276
277struct gpu_bw_vote {
278 uint32_t bw_idx : 8;
279/* to support split AB and IB vote */
280 uint32_t reserved : 24;
281};
282
283union gpu_perf_vote {
284 struct gpu_dcvs_vote fvote;
285 struct gpu_bw_vote bvote;
286 uint32_t raw;
287};
288
289struct hfi_dcvs_cmd {
290 struct hfi_msg_hdr hdr;
291 uint32_t ack_type;
292 struct gpu_dcvs_vote freq;
293 struct gpu_bw_vote bw;
294};
295
296struct hfi_prep_slumber_cmd {
297 struct hfi_msg_hdr hdr;
298 uint32_t init_bw_idx;
299 uint32_t init_perf_idx;
300};
301
302struct hfi_fw_err_msg {
303 struct hfi_msg_hdr hdr;
304 uint32_t error_code;
305 uint32_t data_1;
306 uint32_t data_2;
307};
308
309/**
310 * struct pending_msg - data structure to track outstanding HFI
311 * command messages
312 * @msg_complete: a blocking mechanism for sender to wait for ACK
313 * @node: a node in pending message queue
314 * @msg_id: the ID of the command message pending for ACK
315 * @seqnum: the seqnum of the command message pending for ACK.
316 * together with msg_id, are used to correlate a receiving ACK
317 * to a pending cmd message
318 * @results: the payload of received return message (ACK)
319 */
320struct pending_msg {
321 struct completion msg_complete;
322 struct list_head node;
323 uint32_t msg_id;
324 uint32_t seqnum;
325 struct hfi_msg_rsp results;
326};
327
328/**
329 * struct kgsl_hfi - HFI control structure
330 * @hfi_interrupt_num: number of GMU asserted HFI interrupt
331 * @msglock: spinlock to protect access to outstanding command message list
332 * @cmdq_mutex: mutex to protect command queue access from multiple senders
333 * @msglist: outstanding command message list. Each message in the list
334 * is waiting for ACK from GMU
335 * @tasklet: the thread handling received messages from GMU
336 * @fw_version: FW version number provided by GMU
337 * @seqnum: atomic counter that is incremented for each message sent. The
338 * value of the counter is used as sequence number for HFI message
339 */
340struct kgsl_hfi {
341 int hfi_interrupt_num;
342 spinlock_t msglock;
343 struct mutex cmdq_mutex;
344 struct list_head msglist;
345 struct tasklet_struct tasklet;
346 uint32_t fw_version;
347 atomic_t seqnum;
348 bool gmu_init_done;
349};
350
351struct gmu_device;
352struct gmu_memdesc;
353
354int hfi_start(struct gmu_device *gmu, uint32_t boot_state);
355void hfi_stop(struct gmu_device *gmu);
356void hfi_receiver(unsigned long data);
357void hfi_init(struct kgsl_hfi *hfi, struct gmu_memdesc *mem_addr,
358 uint32_t queue_sz_bytes);
359int hfi_send_dcvs_vote(struct gmu_device *gmu, uint32_t perf_idx,
360 uint32_t bw_idx, enum rpm_ack_type ack_type);
361int hfi_notify_slumber(struct gmu_device *gmu, uint32_t init_perf_idx,
362 uint32_t init_bw_idx);
363#endif /* __KGSL_HFI_H */