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 #define CMDQ_ADDR_HIGH(addr) ((u32)(((addr) >> 16) & GENMASK(31, 0))) 16 #define CMDQ_ADDR_LOW(addr) ((u16)(addr) | BIT(1)) 17 18 struct cmdq_pkt; 19 20 struct cmdq_client_reg { 21 u8 subsys; 22 u16 offset; 23 u16 size; 24 }; 25 26 struct cmdq_client { 27 spinlock_t lock; 28 u32 pkt_cnt; 29 struct mbox_client client; 30 struct mbox_chan *chan; 31 struct timer_list timer; 32 u32 timeout_ms; /* in unit of microsecond */ 33 }; 34 35 /** 36 * cmdq_dev_get_client_reg() - parse cmdq client reg from the device 37 * node of CMDQ client 38 * @dev: device of CMDQ mailbox client 39 * @client_reg: CMDQ client reg pointer 40 * @idx: the index of desired reg 41 * 42 * Return: 0 for success; else the error code is returned 43 * 44 * Help CMDQ client parsing the cmdq client reg 45 * from the device node of CMDQ client. 46 */ 47 int cmdq_dev_get_client_reg(struct device *dev, 48 struct cmdq_client_reg *client_reg, int idx); 49 50 /** 51 * cmdq_mbox_create() - create CMDQ mailbox client and channel 52 * @dev: device of CMDQ mailbox client 53 * @index: index of CMDQ mailbox channel 54 * @timeout: timeout of a pkt execution by GCE, in unit of microsecond, set 55 * CMDQ_NO_TIMEOUT if a timer is not used. 56 * 57 * Return: CMDQ mailbox client pointer 58 */ 59 struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, 60 u32 timeout); 61 62 /** 63 * cmdq_mbox_destroy() - destroy CMDQ mailbox client and channel 64 * @client: the CMDQ mailbox client 65 */ 66 void cmdq_mbox_destroy(struct cmdq_client *client); 67 68 /** 69 * cmdq_pkt_create() - create a CMDQ packet 70 * @client: the CMDQ mailbox client 71 * @size: required CMDQ buffer size 72 * 73 * Return: CMDQ packet pointer 74 */ 75 struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size); 76 77 /** 78 * cmdq_pkt_destroy() - destroy the CMDQ packet 79 * @pkt: the CMDQ packet 80 */ 81 void cmdq_pkt_destroy(struct cmdq_pkt *pkt); 82 83 /** 84 * cmdq_pkt_write() - append write command to the CMDQ packet 85 * @pkt: the CMDQ packet 86 * @subsys: the CMDQ sub system code 87 * @offset: register offset from CMDQ sub system 88 * @value: the specified target register value 89 * 90 * Return: 0 for success; else the error code is returned 91 */ 92 int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value); 93 94 /** 95 * cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet 96 * @pkt: the CMDQ packet 97 * @subsys: the CMDQ sub system code 98 * @offset: register offset from CMDQ sub system 99 * @value: the specified target register value 100 * @mask: the specified target register mask 101 * 102 * Return: 0 for success; else the error code is returned 103 */ 104 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys, 105 u16 offset, u32 value, u32 mask); 106 107 /* 108 * cmdq_pkt_read_s() - append read_s command to the CMDQ packet 109 * @pkt: the CMDQ packet 110 * @high_addr_reg_idx: internal register ID which contains high address of pa 111 * @addr_low: low address of pa 112 * @reg_idx: the CMDQ internal register ID to cache read data 113 * 114 * Return: 0 for success; else the error code is returned 115 */ 116 int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low, 117 u16 reg_idx); 118 119 /** 120 * cmdq_pkt_write_s() - append write_s command to the CMDQ packet 121 * @pkt: the CMDQ packet 122 * @high_addr_reg_idx: internal register ID which contains high address of pa 123 * @addr_low: low address of pa 124 * @src_reg_idx: the CMDQ internal register ID which cache source value 125 * 126 * Return: 0 for success; else the error code is returned 127 * 128 * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH() 129 * to get high address and call cmdq_pkt_assign() to assign value into internal 130 * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when 131 * call to this function. 132 */ 133 int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, 134 u16 addr_low, u16 src_reg_idx); 135 136 /** 137 * cmdq_pkt_write_s_mask() - append write_s with mask command to the CMDQ packet 138 * @pkt: the CMDQ packet 139 * @high_addr_reg_idx: internal register ID which contains high address of pa 140 * @addr_low: low address of pa 141 * @src_reg_idx: the CMDQ internal register ID which cache source value 142 * @mask: the specified target address mask, use U32_MAX if no need 143 * 144 * Return: 0 for success; else the error code is returned 145 * 146 * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH() 147 * to get high address and call cmdq_pkt_assign() to assign value into internal 148 * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when 149 * call to this function. 150 */ 151 int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, 152 u16 addr_low, u16 src_reg_idx, u32 mask); 153 154 /** 155 * cmdq_pkt_write_s_value() - append write_s command to the CMDQ packet which 156 * write value to a physical address 157 * @pkt: the CMDQ packet 158 * @high_addr_reg_idx: internal register ID which contains high address of pa 159 * @addr_low: low address of pa 160 * @value: the specified target value 161 * 162 * Return: 0 for success; else the error code is returned 163 */ 164 int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx, 165 u16 addr_low, u32 value); 166 167 /** 168 * cmdq_pkt_write_s_mask_value() - append write_s command with mask to the CMDQ 169 * packet which write value to a physical 170 * address 171 * @pkt: the CMDQ packet 172 * @high_addr_reg_idx: internal register ID which contains high address of pa 173 * @addr_low: low address of pa 174 * @value: the specified target value 175 * @mask: the specified target mask 176 * 177 * Return: 0 for success; else the error code is returned 178 */ 179 int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx, 180 u16 addr_low, u32 value, u32 mask); 181 182 /** 183 * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet 184 * @pkt: the CMDQ packet 185 * @event: the desired event type to wait 186 * @clear: clear event or not after event arrive 187 * 188 * Return: 0 for success; else the error code is returned 189 */ 190 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear); 191 192 /** 193 * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet 194 * @pkt: the CMDQ packet 195 * @event: the desired event to be cleared 196 * 197 * Return: 0 for success; else the error code is returned 198 */ 199 int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event); 200 201 /** 202 * cmdq_pkt_set_event() - append set event command to the CMDQ packet 203 * @pkt: the CMDQ packet 204 * @event: the desired event to be set 205 * 206 * Return: 0 for success; else the error code is returned 207 */ 208 int cmdq_pkt_set_event(struct cmdq_pkt *pkt, u16 event); 209 210 /** 211 * cmdq_pkt_poll() - Append polling command to the CMDQ packet, ask GCE to 212 * execute an instruction that wait for a specified 213 * hardware register to check for the value w/o mask. 214 * All GCE hardware threads will be blocked by this 215 * instruction. 216 * @pkt: the CMDQ packet 217 * @subsys: the CMDQ sub system code 218 * @offset: register offset from CMDQ sub system 219 * @value: the specified target register value 220 * 221 * Return: 0 for success; else the error code is returned 222 */ 223 int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys, 224 u16 offset, u32 value); 225 226 /** 227 * cmdq_pkt_poll_mask() - Append polling command to the CMDQ packet, ask GCE to 228 * execute an instruction that wait for a specified 229 * hardware register to check for the value w/ mask. 230 * All GCE hardware threads will be blocked by this 231 * instruction. 232 * @pkt: the CMDQ packet 233 * @subsys: the CMDQ sub system code 234 * @offset: register offset from CMDQ sub system 235 * @value: the specified target register value 236 * @mask: the specified target register mask 237 * 238 * Return: 0 for success; else the error code is returned 239 */ 240 int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys, 241 u16 offset, u32 value, u32 mask); 242 243 /** 244 * cmdq_pkt_assign() - Append logic assign command to the CMDQ packet, ask GCE 245 * to execute an instruction that set a constant value into 246 * internal register and use as value, mask or address in 247 * read/write instruction. 248 * @pkt: the CMDQ packet 249 * @reg_idx: the CMDQ internal register ID 250 * @value: the specified value 251 * 252 * Return: 0 for success; else the error code is returned 253 */ 254 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value); 255 256 /** 257 * cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE 258 * to execute an instruction that change current thread PC to 259 * a physical address which should contains more instruction. 260 * @pkt: the CMDQ packet 261 * @addr: physical address of target instruction buffer 262 * 263 * Return: 0 for success; else the error code is returned 264 */ 265 int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr); 266 267 /** 268 * cmdq_pkt_finalize() - Append EOC and jump command to pkt. 269 * @pkt: the CMDQ packet 270 * 271 * Return: 0 for success; else the error code is returned 272 */ 273 int cmdq_pkt_finalize(struct cmdq_pkt *pkt); 274 275 /** 276 * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ 277 * packet and call back at the end of done packet 278 * @pkt: the CMDQ packet 279 * @cb: called at the end of done packet 280 * @data: this data will pass back to cb 281 * 282 * Return: 0 for success; else the error code is returned 283 * 284 * Trigger CMDQ to asynchronously execute the CMDQ packet and call back 285 * at the end of done packet. Note that this is an ASYNC function. When the 286 * function returned, it may or may not be finished. 287 */ 288 int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb, 289 void *data); 290 291 /** 292 * cmdq_pkt_flush() - trigger CMDQ to execute the CMDQ packet 293 * @pkt: the CMDQ packet 294 * 295 * Return: 0 for success; else the error code is returned 296 * 297 * Trigger CMDQ to execute the CMDQ packet. Note that this is a 298 * synchronous flush function. When the function returned, the recorded 299 * commands have been done. 300 */ 301 int cmdq_pkt_flush(struct cmdq_pkt *pkt); 302 303 #endif /* __MTK_CMDQ_H__ */ 304