1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (c) 2018 MediaTek Inc. 4 * 5 */ 6 7 #ifndef __MTK_CMDQ_H__ 8 #define __MTK_CMDQ_H__ 9 10 #include <linux/mailbox_client.h> 11 #include <linux/mailbox/mtk-cmdq-mailbox.h> 12 #include <linux/timer.h> 13 14 #define CMDQ_NO_TIMEOUT 0xffffffffu 15 16 struct cmdq_pkt; 17 18 struct cmdq_client_reg { 19 u8 subsys; 20 u16 offset; 21 u16 size; 22 }; 23 24 struct cmdq_client { 25 spinlock_t lock; 26 u32 pkt_cnt; 27 struct mbox_client client; 28 struct mbox_chan *chan; 29 struct timer_list timer; 30 u32 timeout_ms; /* in unit of microsecond */ 31 }; 32 33 /** 34 * cmdq_dev_get_client_reg() - parse cmdq client reg from the device 35 * node of CMDQ client 36 * @dev: device of CMDQ mailbox client 37 * @client_reg: CMDQ client reg pointer 38 * @idx: the index of desired reg 39 * 40 * Return: 0 for success; else the error code is returned 41 * 42 * Help CMDQ client parsing the cmdq client reg 43 * from the device node of CMDQ client. 44 */ 45 int cmdq_dev_get_client_reg(struct device *dev, 46 struct cmdq_client_reg *client_reg, int idx); 47 48 /** 49 * cmdq_mbox_create() - create CMDQ mailbox client and channel 50 * @dev: device of CMDQ mailbox client 51 * @index: index of CMDQ mailbox channel 52 * @timeout: timeout of a pkt execution by GCE, in unit of microsecond, set 53 * CMDQ_NO_TIMEOUT if a timer is not used. 54 * 55 * Return: CMDQ mailbox client pointer 56 */ 57 struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, 58 u32 timeout); 59 60 /** 61 * cmdq_mbox_destroy() - destroy CMDQ mailbox client and channel 62 * @client: the CMDQ mailbox client 63 */ 64 void cmdq_mbox_destroy(struct cmdq_client *client); 65 66 /** 67 * cmdq_pkt_create() - create a CMDQ packet 68 * @client: the CMDQ mailbox client 69 * @size: required CMDQ buffer size 70 * 71 * Return: CMDQ packet pointer 72 */ 73 struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size); 74 75 /** 76 * cmdq_pkt_destroy() - destroy the CMDQ packet 77 * @pkt: the CMDQ packet 78 */ 79 void cmdq_pkt_destroy(struct cmdq_pkt *pkt); 80 81 /** 82 * cmdq_pkt_write() - append write command to the CMDQ packet 83 * @pkt: the CMDQ packet 84 * @subsys: the CMDQ sub system code 85 * @offset: register offset from CMDQ sub system 86 * @value: the specified target register value 87 * 88 * Return: 0 for success; else the error code is returned 89 */ 90 int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value); 91 92 /** 93 * cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet 94 * @pkt: the CMDQ packet 95 * @subsys: the CMDQ sub system code 96 * @offset: register offset from CMDQ sub system 97 * @value: the specified target register value 98 * @mask: the specified target register mask 99 * 100 * Return: 0 for success; else the error code is returned 101 */ 102 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys, 103 u16 offset, u32 value, u32 mask); 104 105 /** 106 * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet 107 * @pkt: the CMDQ packet 108 * @event: the desired event type to "wait and CLEAR" 109 * 110 * Return: 0 for success; else the error code is returned 111 */ 112 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event); 113 114 /** 115 * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet 116 * @pkt: the CMDQ packet 117 * @event: the desired event to be cleared 118 * 119 * Return: 0 for success; else the error code is returned 120 */ 121 int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event); 122 123 /** 124 * cmdq_pkt_set_event() - append set event command to the CMDQ packet 125 * @pkt: the CMDQ packet 126 * @event: the desired event to be set 127 * 128 * Return: 0 for success; else the error code is returned 129 */ 130 int cmdq_pkt_set_event(struct cmdq_pkt *pkt, u16 event); 131 132 /** 133 * cmdq_pkt_poll() - Append polling command to the CMDQ packet, ask GCE to 134 * execute an instruction that wait for a specified 135 * hardware register to check for the value w/o mask. 136 * All GCE hardware threads will be blocked by this 137 * instruction. 138 * @pkt: the CMDQ packet 139 * @subsys: the CMDQ sub system code 140 * @offset: register offset from CMDQ sub system 141 * @value: the specified target register value 142 * 143 * Return: 0 for success; else the error code is returned 144 */ 145 int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys, 146 u16 offset, u32 value); 147 148 /** 149 * cmdq_pkt_poll_mask() - Append polling command to the CMDQ packet, ask GCE to 150 * execute an instruction that wait for a specified 151 * hardware register to check for the value w/ mask. 152 * All GCE hardware threads will be blocked by this 153 * instruction. 154 * @pkt: the CMDQ packet 155 * @subsys: the CMDQ sub system code 156 * @offset: register offset from CMDQ sub system 157 * @value: the specified target register value 158 * @mask: the specified target register mask 159 * 160 * Return: 0 for success; else the error code is returned 161 */ 162 int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys, 163 u16 offset, u32 value, u32 mask); 164 165 /** 166 * cmdq_pkt_assign() - Append logic assign command to the CMDQ packet, ask GCE 167 * to execute an instruction that set a constant value into 168 * internal register and use as value, mask or address in 169 * read/write instruction. 170 * @pkt: the CMDQ packet 171 * @reg_idx: the CMDQ internal register ID 172 * @value: the specified value 173 * 174 * Return: 0 for success; else the error code is returned 175 */ 176 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value); 177 178 /** 179 * cmdq_pkt_finalize() - Append EOC and jump command to pkt. 180 * @pkt: the CMDQ packet 181 * 182 * Return: 0 for success; else the error code is returned 183 */ 184 int cmdq_pkt_finalize(struct cmdq_pkt *pkt); 185 186 /** 187 * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ 188 * packet and call back at the end of done packet 189 * @pkt: the CMDQ packet 190 * @cb: called at the end of done packet 191 * @data: this data will pass back to cb 192 * 193 * Return: 0 for success; else the error code is returned 194 * 195 * Trigger CMDQ to asynchronously execute the CMDQ packet and call back 196 * at the end of done packet. Note that this is an ASYNC function. When the 197 * function returned, it may or may not be finished. 198 */ 199 int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb, 200 void *data); 201 202 /** 203 * cmdq_pkt_flush() - trigger CMDQ to execute the CMDQ packet 204 * @pkt: the CMDQ packet 205 * 206 * Return: 0 for success; else the error code is returned 207 * 208 * Trigger CMDQ to execute the CMDQ packet. Note that this is a 209 * synchronous flush function. When the function returned, the recorded 210 * commands have been done. 211 */ 212 int cmdq_pkt_flush(struct cmdq_pkt *pkt); 213 214 #endif /* __MTK_CMDQ_H__ */ 215