Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'v5.5-next-soc' of https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux into arm/drivers

cmdq:
- clean ups of unused code and debuggability
- add cmdq_instruction to make the function call interface more readable
- add functions for polling and providing info for the user of cmdq

scpsys:
- add bindings for MT6765

* tag 'v5.5-next-soc' of https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux:
dt-bindings: mediatek: add MT6765 power dt-bindings
soc: mediatek: cmdq: delete not used define
soc: mediatek: cmdq: add cmdq_dev_get_client_reg function
soc: mediatek: cmdq: add polling function
soc: mediatek: cmdq: define the instruction struct
soc: mediatek: cmdq: remove OR opertaion from err return

Link: https://lore.kernel.org/r/9b365e76-e346-f813-d750-d7cfd0d16e4e@gmail.com
Signed-off-by: Olof Johansson <olof@lixom.net>

+205 -28
+6
Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
··· 11 11 power/power-domain.yaml. It provides the power domains defined in 12 12 - include/dt-bindings/power/mt8173-power.h 13 13 - include/dt-bindings/power/mt6797-power.h 14 + - include/dt-bindings/power/mt6765-power.h 14 15 - include/dt-bindings/power/mt2701-power.h 15 16 - include/dt-bindings/power/mt2712-power.h 16 17 - include/dt-bindings/power/mt7622-power.h ··· 20 19 - compatible: Should be one of: 21 20 - "mediatek,mt2701-scpsys" 22 21 - "mediatek,mt2712-scpsys" 22 + - "mediatek,mt6765-scpsys" 23 23 - "mediatek,mt6797-scpsys" 24 24 - "mediatek,mt7622-scpsys" 25 25 - "mediatek,mt7623-scpsys", "mediatek,mt2701-scpsys": For MT7623 SoC ··· 35 33 enabled before enabling certain power domains. 36 34 Required clocks for MT2701 or MT7623: "mm", "mfg", "ethif" 37 35 Required clocks for MT2712: "mm", "mfg", "venc", "jpgdec", "audio", "vdec" 36 + Required clocks for MT6765: MUX: "mm", "mfg" 37 + CG: "mm-0", "mm-1", "mm-2", "mm-3", "isp-0", 38 + "isp-1", "cam-0", "cam-1", "cam-2", 39 + "cam-3","cam-4" 38 40 Required clocks for MT6797: "mm", "mfg", "vdec" 39 41 Required clocks for MT7622 or MT7629: "hif_sel" 40 42 Required clocks for MT7623A: "ethif"
+121 -28
drivers/soc/mediatek/mtk-cmdq-helper.c
··· 9 9 #include <linux/mailbox_controller.h> 10 10 #include <linux/soc/mediatek/mtk-cmdq.h> 11 11 12 - #define CMDQ_ARG_A_WRITE_MASK 0xffff 13 12 #define CMDQ_WRITE_ENABLE_MASK BIT(0) 13 + #define CMDQ_POLL_ENABLE_MASK BIT(0) 14 14 #define CMDQ_EOC_IRQ_EN BIT(0) 15 - #define CMDQ_EOC_CMD ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \ 16 - << 32 | CMDQ_EOC_IRQ_EN) 15 + 16 + struct cmdq_instruction { 17 + union { 18 + u32 value; 19 + u32 mask; 20 + }; 21 + union { 22 + u16 offset; 23 + u16 event; 24 + }; 25 + u8 subsys; 26 + u8 op; 27 + }; 28 + 29 + int cmdq_dev_get_client_reg(struct device *dev, 30 + struct cmdq_client_reg *client_reg, int idx) 31 + { 32 + struct of_phandle_args spec; 33 + int err; 34 + 35 + if (!client_reg) 36 + return -ENOENT; 37 + 38 + err = of_parse_phandle_with_fixed_args(dev->of_node, 39 + "mediatek,gce-client-reg", 40 + 3, idx, &spec); 41 + if (err < 0) { 42 + dev_err(dev, 43 + "error %d can't parse gce-client-reg property (%d)", 44 + err, idx); 45 + 46 + return err; 47 + } 48 + 49 + client_reg->subsys = (u8)spec.args[0]; 50 + client_reg->offset = (u16)spec.args[1]; 51 + client_reg->size = (u16)spec.args[2]; 52 + of_node_put(spec.np); 53 + 54 + return 0; 55 + } 56 + EXPORT_SYMBOL(cmdq_dev_get_client_reg); 17 57 18 58 static void cmdq_client_timeout(struct timer_list *t) 19 59 { ··· 150 110 } 151 111 EXPORT_SYMBOL(cmdq_pkt_destroy); 152 112 153 - static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code, 154 - u32 arg_a, u32 arg_b) 113 + static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, 114 + struct cmdq_instruction inst) 155 115 { 156 - u64 *cmd_ptr; 116 + struct cmdq_instruction *cmd_ptr; 157 117 158 118 if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) { 159 119 /* ··· 169 129 __func__, (u32)pkt->buf_size); 170 130 return -ENOMEM; 171 131 } 132 + 172 133 cmd_ptr = pkt->va_base + pkt->cmd_buf_size; 173 - (*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b; 134 + *cmd_ptr = inst; 174 135 pkt->cmd_buf_size += CMDQ_INST_SIZE; 175 136 176 137 return 0; ··· 179 138 180 139 int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value) 181 140 { 182 - u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) | 183 - (subsys << CMDQ_SUBSYS_SHIFT); 141 + struct cmdq_instruction inst; 184 142 185 - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WRITE, arg_a, value); 143 + inst.op = CMDQ_CODE_WRITE; 144 + inst.value = value; 145 + inst.offset = offset; 146 + inst.subsys = subsys; 147 + 148 + return cmdq_pkt_append_command(pkt, inst); 186 149 } 187 150 EXPORT_SYMBOL(cmdq_pkt_write); 188 151 189 152 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys, 190 153 u16 offset, u32 value, u32 mask) 191 154 { 192 - u32 offset_mask = offset; 193 - int err = 0; 155 + struct cmdq_instruction inst = { {0} }; 156 + u16 offset_mask = offset; 157 + int err; 194 158 195 159 if (mask != 0xffffffff) { 196 - err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask); 160 + inst.op = CMDQ_CODE_MASK; 161 + inst.mask = ~mask; 162 + err = cmdq_pkt_append_command(pkt, inst); 163 + if (err < 0) 164 + return err; 165 + 197 166 offset_mask |= CMDQ_WRITE_ENABLE_MASK; 198 167 } 199 - err |= cmdq_pkt_write(pkt, subsys, offset_mask, value); 168 + err = cmdq_pkt_write(pkt, subsys, offset_mask, value); 200 169 201 170 return err; 202 171 } ··· 214 163 215 164 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event) 216 165 { 217 - u32 arg_b; 166 + struct cmdq_instruction inst = { {0} }; 218 167 219 168 if (event >= CMDQ_MAX_EVENT) 220 169 return -EINVAL; 221 170 222 - /* 223 - * WFE arg_b 224 - * bit 0-11: wait value 225 - * bit 15: 1 - wait, 0 - no wait 226 - * bit 16-27: update value 227 - * bit 31: 1 - update, 0 - no update 228 - */ 229 - arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE; 171 + inst.op = CMDQ_CODE_WFE; 172 + inst.value = CMDQ_WFE_OPTION; 173 + inst.event = event; 230 174 231 - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b); 175 + return cmdq_pkt_append_command(pkt, inst); 232 176 } 233 177 EXPORT_SYMBOL(cmdq_pkt_wfe); 234 178 235 179 int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event) 236 180 { 181 + struct cmdq_instruction inst = { {0} }; 182 + 237 183 if (event >= CMDQ_MAX_EVENT) 238 184 return -EINVAL; 239 185 240 - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, 241 - CMDQ_WFE_UPDATE); 186 + inst.op = CMDQ_CODE_WFE; 187 + inst.value = CMDQ_WFE_UPDATE; 188 + inst.event = event; 189 + 190 + return cmdq_pkt_append_command(pkt, inst); 242 191 } 243 192 EXPORT_SYMBOL(cmdq_pkt_clear_event); 244 193 194 + int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys, 195 + u16 offset, u32 value) 196 + { 197 + struct cmdq_instruction inst = { {0} }; 198 + int err; 199 + 200 + inst.op = CMDQ_CODE_POLL; 201 + inst.value = value; 202 + inst.offset = offset; 203 + inst.subsys = subsys; 204 + err = cmdq_pkt_append_command(pkt, inst); 205 + 206 + return err; 207 + } 208 + EXPORT_SYMBOL(cmdq_pkt_poll); 209 + 210 + int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys, 211 + u16 offset, u32 value, u32 mask) 212 + { 213 + struct cmdq_instruction inst = { {0} }; 214 + int err; 215 + 216 + inst.op = CMDQ_CODE_MASK; 217 + inst.mask = ~mask; 218 + err = cmdq_pkt_append_command(pkt, inst); 219 + if (err < 0) 220 + return err; 221 + 222 + offset = offset | CMDQ_POLL_ENABLE_MASK; 223 + err = cmdq_pkt_poll(pkt, subsys, offset, value); 224 + 225 + return err; 226 + } 227 + EXPORT_SYMBOL(cmdq_pkt_poll_mask); 228 + 245 229 static int cmdq_pkt_finalize(struct cmdq_pkt *pkt) 246 230 { 231 + struct cmdq_instruction inst = { {0} }; 247 232 int err; 248 233 249 234 /* insert EOC and generate IRQ for each command iteration */ 250 - err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, CMDQ_EOC_IRQ_EN); 235 + inst.op = CMDQ_CODE_EOC; 236 + inst.value = CMDQ_EOC_IRQ_EN; 237 + err = cmdq_pkt_append_command(pkt, inst); 238 + if (err < 0) 239 + return err; 251 240 252 241 /* JUMP to end */ 253 - err |= cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS); 242 + inst.op = CMDQ_CODE_JUMP; 243 + inst.value = CMDQ_JUMP_PASS; 244 + err = cmdq_pkt_append_command(pkt, inst); 254 245 255 246 return err; 256 247 }
+14
include/dt-bindings/power/mt6765-power.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _DT_BINDINGS_POWER_MT6765_POWER_H 3 + #define _DT_BINDINGS_POWER_MT6765_POWER_H 4 + 5 + #define MT6765_POWER_DOMAIN_CONN 0 6 + #define MT6765_POWER_DOMAIN_MM 1 7 + #define MT6765_POWER_DOMAIN_MFG_ASYNC 2 8 + #define MT6765_POWER_DOMAIN_ISP 3 9 + #define MT6765_POWER_DOMAIN_MFG 4 10 + #define MT6765_POWER_DOMAIN_MFG_CORE0 5 11 + #define MT6765_POWER_DOMAIN_CAM 6 12 + #define MT6765_POWER_DOMAIN_VCODEC 7 13 + 14 + #endif /* _DT_BINDINGS_POWER_MT6765_POWER_H */
+11
include/linux/mailbox/mtk-cmdq-mailbox.h
··· 20 20 #define CMDQ_WFE_WAIT BIT(15) 21 21 #define CMDQ_WFE_WAIT_VALUE 0x1 22 22 23 + /* 24 + * WFE arg_b 25 + * bit 0-11: wait value 26 + * bit 15: 1 - wait, 0 - no wait 27 + * bit 16-27: update value 28 + * bit 31: 1 - update, 0 - no update 29 + */ 30 + #define CMDQ_WFE_OPTION (CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | \ 31 + CMDQ_WFE_WAIT_VALUE) 32 + 23 33 /** cmdq event maximum */ 24 34 #define CMDQ_MAX_EVENT 0x3ff 25 35 ··· 55 45 enum cmdq_code { 56 46 CMDQ_CODE_MASK = 0x02, 57 47 CMDQ_CODE_WRITE = 0x04, 48 + CMDQ_CODE_POLL = 0x08, 58 49 CMDQ_CODE_JUMP = 0x10, 59 50 CMDQ_CODE_WFE = 0x20, 60 51 CMDQ_CODE_EOC = 0x40,
+53
include/linux/soc/mediatek/mtk-cmdq.h
··· 15 15 16 16 struct cmdq_pkt; 17 17 18 + struct cmdq_client_reg { 19 + u8 subsys; 20 + u16 offset; 21 + u16 size; 22 + }; 23 + 18 24 struct cmdq_client { 19 25 spinlock_t lock; 20 26 u32 pkt_cnt; ··· 29 23 struct timer_list timer; 30 24 u32 timeout_ms; /* in unit of microsecond */ 31 25 }; 26 + 27 + /** 28 + * cmdq_dev_get_client_reg() - parse cmdq client reg from the device 29 + * node of CMDQ client 30 + * @dev: device of CMDQ mailbox client 31 + * @client_reg: CMDQ client reg pointer 32 + * @idx: the index of desired reg 33 + * 34 + * Return: 0 for success; else the error code is returned 35 + * 36 + * Help CMDQ client parsing the cmdq client reg 37 + * from the device node of CMDQ client. 38 + */ 39 + int cmdq_dev_get_client_reg(struct device *dev, 40 + struct cmdq_client_reg *client_reg, int idx); 32 41 33 42 /** 34 43 * cmdq_mbox_create() - create CMDQ mailbox client and channel ··· 120 99 */ 121 100 int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event); 122 101 102 + /** 103 + * cmdq_pkt_poll() - Append polling command to the CMDQ packet, ask GCE to 104 + * execute an instruction that wait for a specified 105 + * hardware register to check for the value w/o mask. 106 + * All GCE hardware threads will be blocked by this 107 + * instruction. 108 + * @pkt: the CMDQ packet 109 + * @subsys: the CMDQ sub system code 110 + * @offset: register offset from CMDQ sub system 111 + * @value: the specified target register value 112 + * 113 + * Return: 0 for success; else the error code is returned 114 + */ 115 + int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys, 116 + u16 offset, u32 value); 117 + 118 + /** 119 + * cmdq_pkt_poll_mask() - Append polling command to the CMDQ packet, ask GCE to 120 + * execute an instruction that wait for a specified 121 + * hardware register to check for the value w/ mask. 122 + * All GCE hardware threads will be blocked by this 123 + * instruction. 124 + * @pkt: the CMDQ packet 125 + * @subsys: the CMDQ sub system code 126 + * @offset: register offset from CMDQ sub system 127 + * @value: the specified target register value 128 + * @mask: the specified target register mask 129 + * 130 + * Return: 0 for success; else the error code is returned 131 + */ 132 + int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys, 133 + u16 offset, u32 value, u32 mask); 123 134 /** 124 135 * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ 125 136 * packet and call back at the end of done packet