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

Configure Feed

Select the types of activity you want to include in your feed.

soc: mediatek: mtk-cmdq: Extend cmdq_pkt_write API for SoCs without subsys ID

This patch extends the cmdq_pkt_write API to support SoCs that do not
have subsys ID mapping by introducing new register write APIs:
- cmdq_pkt_write_pa() and cmdq_pkt_write_subsys() replace
cmdq_pkt_write()
- cmdq_pkt_write_mask_pa() and cmdq_pkt_write_mask_subsys() replace
cmdq_pkt_write_mask()

To ensure consistent function pointer interfaces, both
cmdq_pkt_write_pa() and cmdq_pkt_write_subsys() provide subsys and
pa_base parameters. This unifies how register writes are invoked,
regardless of whether subsys ID is supported by the device.

All GCEs support writing registers by PA (with mask) without subsys,
but this requires extra GCE instructions to convert the PA into a GCE
readable format, reducing performance compared to using subsys directly.
Therefore, subsys is preferred for register writes when available.

API documentation and function pointer declarations in cmdq_client_reg
have been updated. The original write APIs will be removed after all
CMDQ users transition to the new interfaces.

Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

authored by

Jason-JH Lin and committed by
AngeloGioacchino Del Regno
40dc5bba 4bf783d8

+144
+54
drivers/soc/mediatek/mtk-cmdq-helper.c
··· 85 85 /* make subsys invalid */ 86 86 client_reg->subsys = CMDQ_SUBSYS_INVALID; 87 87 88 + /* 89 + * All GCEs support writing register PA with mask without subsys, 90 + * but this requires extra GCE instructions to convert the PA into 91 + * a format that GCE can handle, which is less performance than 92 + * directly using subsys. Therefore, when subsys is available, 93 + * we prefer to use subsys for writing register PA. 94 + */ 95 + client_reg->pkt_write = cmdq_pkt_write_pa; 96 + client_reg->pkt_write_mask = cmdq_pkt_write_mask_pa; 97 + 88 98 return 0; 89 99 } 90 100 ··· 102 92 client_reg->offset = (u16)spec.args[1]; 103 93 client_reg->size = (u16)spec.args[2]; 104 94 of_node_put(spec.np); 95 + 96 + client_reg->pkt_write = cmdq_pkt_write_subsys; 97 + client_reg->pkt_write_mask = cmdq_pkt_write_mask_subsys; 105 98 106 99 return 0; 107 100 } ··· 227 214 } 228 215 EXPORT_SYMBOL(cmdq_pkt_write); 229 216 217 + int cmdq_pkt_write_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/, u32 pa_base, 218 + u16 offset, u32 value) 219 + { 220 + int err; 221 + 222 + err = cmdq_pkt_assign(pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(pa_base)); 223 + if (err < 0) 224 + return err; 225 + 226 + return cmdq_pkt_write_s_value(pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_LOW(offset), value); 227 + } 228 + EXPORT_SYMBOL(cmdq_pkt_write_pa); 229 + 230 + int cmdq_pkt_write_subsys(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base /*unused*/, 231 + u16 offset, u32 value) 232 + { 233 + return cmdq_pkt_write(pkt, subsys, offset, value); 234 + } 235 + EXPORT_SYMBOL(cmdq_pkt_write_subsys); 236 + 230 237 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys, 231 238 u16 offset, u32 value, u32 mask) 232 239 { ··· 263 230 return cmdq_pkt_write(pkt, subsys, offset_mask, value); 264 231 } 265 232 EXPORT_SYMBOL(cmdq_pkt_write_mask); 233 + 234 + int cmdq_pkt_write_mask_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/, u32 pa_base, 235 + u16 offset, u32 value, u32 mask) 236 + { 237 + int err; 238 + 239 + err = cmdq_pkt_assign(pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(pa_base)); 240 + if (err < 0) 241 + return err; 242 + 243 + return cmdq_pkt_write_s_mask_value(pkt, CMDQ_THR_SPR_IDX0, 244 + CMDQ_ADDR_LOW(offset), value, mask); 245 + } 246 + EXPORT_SYMBOL(cmdq_pkt_write_mask_pa); 247 + 248 + int cmdq_pkt_write_mask_subsys(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base /*unused*/, 249 + u16 offset, u32 value, u32 mask) 250 + { 251 + return cmdq_pkt_write_mask(pkt, subsys, offset, value, mask); 252 + } 253 + EXPORT_SYMBOL(cmdq_pkt_write_mask_subsys); 266 254 267 255 int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low, 268 256 u16 reg_idx)
+90
include/linux/soc/mediatek/mtk-cmdq.h
··· 57 57 phys_addr_t pa_base; 58 58 u16 offset; 59 59 u16 size; 60 + 61 + /* 62 + * Client only uses these functions for MMIO access, 63 + * so doesn't need to handle the mminfra_offset. 64 + * The mminfra_offset is used for DRAM access and 65 + * is handled internally by CMDQ APIs. 66 + */ 67 + int (*pkt_write)(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base, 68 + u16 offset, u32 value); 69 + int (*pkt_write_mask)(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base, 70 + u16 offset, u32 value, u32 mask); 60 71 }; 61 72 62 73 struct cmdq_client { ··· 136 125 int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value); 137 126 138 127 /** 128 + * cmdq_pkt_write_pa() - append write command to the CMDQ packet with pa_base 129 + * @pkt: the CMDQ packet 130 + * @subsys: unused parameter 131 + * @pa_base: the physical address base of the hardware register 132 + * @offset: register offset from CMDQ sub system 133 + * @value: the specified target register value 134 + * 135 + * Return: 0 for success; else the error code is returned 136 + */ 137 + int cmdq_pkt_write_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/, 138 + u32 pa_base, u16 offset, u32 value); 139 + 140 + /** 141 + * cmdq_pkt_write_subsys() - append write command to the CMDQ packet with subsys 142 + * @pkt: the CMDQ packet 143 + * @subsys: the CMDQ sub system code 144 + * @pa_base: unused parameter 145 + * @offset: register offset from CMDQ sub system 146 + * @value: the specified target register value 147 + * 148 + * Return: 0 for success; else the error code is returned 149 + */ 150 + int cmdq_pkt_write_subsys(struct cmdq_pkt *pkt, u8 subsys, 151 + u32 pa_base /*unused*/, u16 offset, u32 value); 152 + 153 + /** 139 154 * cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet 140 155 * @pkt: the CMDQ packet 141 156 * @subsys: the CMDQ sub system code ··· 173 136 */ 174 137 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys, 175 138 u16 offset, u32 value, u32 mask); 139 + 140 + /** 141 + * cmdq_pkt_write_mask_pa() - append write command with mask to the CMDQ packet with pa 142 + * @pkt: the CMDQ packet 143 + * @subsys: unused parameter 144 + * @pa_base: the physical address base of the hardware register 145 + * @offset: register offset from CMDQ sub system 146 + * @value: the specified target register value 147 + * @mask: the specified target register mask 148 + * 149 + * Return: 0 for success; else the error code is returned 150 + */ 151 + int cmdq_pkt_write_mask_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/, 152 + u32 pa_base, u16 offset, u32 value, u32 mask); 153 + 154 + /** 155 + * cmdq_pkt_write_mask_subsys() - append write command with mask to the CMDQ packet with subsys 156 + * @pkt: the CMDQ packet 157 + * @subsys: the CMDQ sub system code 158 + * @pa_base: unused parameter 159 + * @offset: register offset from CMDQ sub system 160 + * @value: the specified target register value 161 + * @mask: the specified target register mask 162 + * 163 + * Return: 0 for success; else the error code is returned 164 + */ 165 + int cmdq_pkt_write_mask_subsys(struct cmdq_pkt *pkt, u8 subsys, 166 + u32 pa_base /*unused*/, u16 offset, u32 value, u32 mask); 176 167 177 168 /* 178 169 * cmdq_pkt_read_s() - append read_s command to the CMDQ packet ··· 486 421 return -ENOENT; 487 422 } 488 423 424 + static inline int cmdq_pkt_write_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/, 425 + u32 pa_base, u16 offset, u32 value) 426 + { 427 + return -ENOENT; 428 + } 429 + 430 + static inline int cmdq_pkt_write_subsys(struct cmdq_pkt *pkt, u8 subsys, 431 + u32 pa_base /*unused*/, u16 offset, u32 value) 432 + { 433 + return -ENOENT; 434 + } 435 + 489 436 static inline int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys, 490 437 u16 offset, u32 value, u32 mask) 438 + { 439 + return -ENOENT; 440 + } 441 + 442 + static inline int cmdq_pkt_write_mask_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/, 443 + u32 pa_base, u16 offset, u32 value, u32 mask) 444 + { 445 + return -ENOENT; 446 + } 447 + 448 + static inline int cmdq_pkt_write_mask_subsys(struct cmdq_pkt *pkt, u8 subsys, 449 + u32 pa_base /*unused*/, u16 offset, 450 + u32 value, u32 mask) 491 451 { 492 452 return -ENOENT; 493 453 }