Lines Matching +full:fw +full:- +full:cfg
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2013--2024 Intel Corporation
7 #include <linux/dma-mapping.h>
14 #include "ipu6-bus.h"
15 #include "ipu6-fw-com.h"
18 * FWCOM layer is a shared resource between FW and driver. It consist
23 * see the same buffer. Indexes are located in ISP DMEM so that FW code
31 /* Shared structure between driver and FW - do not modify */
109 /* pass pkg_dir address to SPC in non-secure mode */
111 /* Tunit CFG blob for secure - provided by host.*/
113 /* syscom commands - modified by the host */
115 /* Store interrupt status - updated by SP */
128 /* syscom state - modified by SP */
141 q->size = size + 1; in ipu6_sys_queue_init()
142 q->token_size = token_size; in ipu6_sys_queue_init()
145 q->host_address = res->host_address; in ipu6_sys_queue_init()
146 res->host_address += buf_size; in ipu6_sys_queue_init()
147 q->vied_address = res->vied_address; in ipu6_sys_queue_init()
148 res->vied_address += buf_size; in ipu6_sys_queue_init()
151 q->wr_reg = res->reg; in ipu6_sys_queue_init()
152 res->reg++; in ipu6_sys_queue_init()
153 q->rd_reg = res->reg; in ipu6_sys_queue_init()
154 res->reg++; in ipu6_sys_queue_init()
157 void *ipu6_fw_com_prepare(struct ipu6_fw_com_cfg *cfg, in ipu6_fw_com_prepare() argument
165 struct device *dev = &adev->auxdev.dev; in ipu6_fw_com_prepare()
171 if (!cfg || !cfg->cell_start || !cfg->cell_ready) in ipu6_fw_com_prepare()
177 ctx->dmem_addr = base + cfg->dmem_addr + REGMEM_OFFSET; in ipu6_fw_com_prepare()
178 ctx->adev = adev; in ipu6_fw_com_prepare()
179 ctx->cell_start = cfg->cell_start; in ipu6_fw_com_prepare()
180 ctx->cell_ready = cfg->cell_ready; in ipu6_fw_com_prepare()
181 ctx->buttress_boot_offset = cfg->buttress_boot_offset; in ipu6_fw_com_prepare()
182 ctx->base_addr = base; in ipu6_fw_com_prepare()
187 /* Base cfg for FW */ in ipu6_fw_com_prepare()
190 inq_size = size_mul(cfg->num_input_queues, in ipu6_fw_com_prepare()
192 outq_size = size_mul(cfg->num_output_queues, in ipu6_fw_com_prepare()
194 /* FW specific information structure */ in ipu6_fw_com_prepare()
195 specific_size = roundup(cfg->specific_size, 8); in ipu6_fw_com_prepare()
199 for (i = 0; i < cfg->num_input_queues; i++) in ipu6_fw_com_prepare()
200 sizeinput += size_mul(cfg->input[i].queue_size + 1, in ipu6_fw_com_prepare()
201 cfg->input[i].token_size); in ipu6_fw_com_prepare()
203 for (i = 0; i < cfg->num_output_queues; i++) in ipu6_fw_com_prepare()
204 sizeoutput += size_mul(cfg->output[i].queue_size + 1, in ipu6_fw_com_prepare()
205 cfg->output[i].token_size); in ipu6_fw_com_prepare()
209 ctx->dma_buffer = dma_alloc_attrs(dev, sizeall, &ctx->dma_addr, in ipu6_fw_com_prepare()
211 ctx->attrs = attrs; in ipu6_fw_com_prepare()
212 if (!ctx->dma_buffer) { in ipu6_fw_com_prepare()
218 ctx->dma_size = sizeall; in ipu6_fw_com_prepare()
220 config_host_addr = ctx->dma_buffer; in ipu6_fw_com_prepare()
221 ctx->config_vied_addr = ctx->dma_addr; in ipu6_fw_com_prepare()
224 ctx->input_queue = ctx->dma_buffer + offset; in ipu6_fw_com_prepare()
225 config_host_addr->input_queue = ctx->dma_addr + offset; in ipu6_fw_com_prepare()
226 config_host_addr->num_input_queues = cfg->num_input_queues; in ipu6_fw_com_prepare()
229 ctx->output_queue = ctx->dma_buffer + offset; in ipu6_fw_com_prepare()
230 config_host_addr->output_queue = ctx->dma_addr + offset; in ipu6_fw_com_prepare()
231 config_host_addr->num_output_queues = cfg->num_output_queues; in ipu6_fw_com_prepare()
235 specific_host_addr = ctx->dma_buffer + offset; in ipu6_fw_com_prepare()
236 config_host_addr->specific_addr = ctx->dma_addr + offset; in ipu6_fw_com_prepare()
237 config_host_addr->specific_size = cfg->specific_size; in ipu6_fw_com_prepare()
238 if (cfg->specific_addr && cfg->specific_size) in ipu6_fw_com_prepare()
239 memcpy(specific_host_addr, cfg->specific_addr, in ipu6_fw_com_prepare()
240 cfg->specific_size); in ipu6_fw_com_prepare()
245 res.host_address = (u64)(ctx->dma_buffer + offset); in ipu6_fw_com_prepare()
246 res.vied_address = ctx->dma_addr + offset; in ipu6_fw_com_prepare()
247 for (i = 0; i < cfg->num_input_queues; i++) in ipu6_fw_com_prepare()
248 ipu6_sys_queue_init(ctx->input_queue + i, in ipu6_fw_com_prepare()
249 cfg->input[i].queue_size, in ipu6_fw_com_prepare()
250 cfg->input[i].token_size, &res); in ipu6_fw_com_prepare()
254 res.host_address = (u64)(ctx->dma_buffer + offset); in ipu6_fw_com_prepare()
255 res.vied_address = ctx->dma_addr + offset; in ipu6_fw_com_prepare()
256 for (i = 0; i < cfg->num_output_queues; i++) { in ipu6_fw_com_prepare()
257 ipu6_sys_queue_init(ctx->output_queue + i, in ipu6_fw_com_prepare()
258 cfg->output[i].queue_size, in ipu6_fw_com_prepare()
259 cfg->output[i].token_size, &res); in ipu6_fw_com_prepare()
269 writel(TUNIT_MAGIC_PATTERN, ctx->dmem_addr + TUNIT_CFG_DWR_REG * 4); in ipu6_fw_com_open()
271 if (!ctx->cell_ready(ctx->adev)) in ipu6_fw_com_open()
272 return -EIO; in ipu6_fw_com_open()
275 writel(SYSCOM_COMMAND_UNINIT, ctx->dmem_addr + SYSCOM_COMMAND_REG * 4); in ipu6_fw_com_open()
279 BUTTRESS_FW_BOOT_PARAM_REG(ctx->base_addr, in ipu6_fw_com_open()
280 ctx->buttress_boot_offset, in ipu6_fw_com_open()
284 writel(ctx->config_vied_addr, in ipu6_fw_com_open()
285 BUTTRESS_FW_BOOT_PARAM_REG(ctx->base_addr, in ipu6_fw_com_open()
286 ctx->buttress_boot_offset, in ipu6_fw_com_open()
288 ctx->cell_start(ctx->adev); in ipu6_fw_com_open()
298 state = readl(BUTTRESS_FW_BOOT_PARAM_REG(ctx->base_addr, in ipu6_fw_com_close()
299 ctx->buttress_boot_offset, in ipu6_fw_com_close()
302 return -EBUSY; in ipu6_fw_com_close()
305 writel(SYSCOM_COMMAND_INACTIVE, ctx->dmem_addr + in ipu6_fw_com_close()
315 if (!force && !ctx->cell_ready(ctx->adev)) in ipu6_fw_com_release()
316 return -EBUSY; in ipu6_fw_com_release()
318 dma_free_attrs(&ctx->adev->auxdev.dev, ctx->dma_size, in ipu6_fw_com_release()
319 ctx->dma_buffer, ctx->dma_addr, ctx->attrs); in ipu6_fw_com_release()
329 state = readl(BUTTRESS_FW_BOOT_PARAM_REG(ctx->base_addr, in ipu6_fw_com_ready()
330 ctx->buttress_boot_offset, in ipu6_fw_com_ready()
339 struct ipu6_fw_sys_queue *q = &ctx->input_queue[q_nbr]; in ipu6_send_get_token()
340 void __iomem *q_dmem = ctx->dmem_addr + q->wr_reg * 4; in ipu6_send_get_token()
348 if (WARN_ON_ONCE(wr >= q->size || rd >= q->size)) in ipu6_send_get_token()
352 packets = rd - wr - 1; in ipu6_send_get_token()
354 packets = q->size - (wr - rd + 1); in ipu6_send_get_token()
361 return (void *)(q->host_address + index * q->token_size); in ipu6_send_get_token()
367 struct ipu6_fw_sys_queue *q = &ctx->input_queue[q_nbr]; in ipu6_send_put_token()
368 void __iomem *q_dmem = ctx->dmem_addr + q->wr_reg * 4; in ipu6_send_put_token()
371 if (wr >= q->size) in ipu6_send_put_token()
380 struct ipu6_fw_sys_queue *q = &ctx->output_queue[q_nbr]; in ipu6_recv_get_token()
381 void __iomem *q_dmem = ctx->dmem_addr + q->wr_reg * 4; in ipu6_recv_get_token()
388 if (WARN_ON_ONCE(wr >= q->size || rd >= q->size)) in ipu6_recv_get_token()
392 wr += q->size; in ipu6_recv_get_token()
394 packets = wr - rd; in ipu6_recv_get_token()
398 return (void *)(q->host_address + rd * q->token_size); in ipu6_recv_get_token()
404 struct ipu6_fw_sys_queue *q = &ctx->output_queue[q_nbr]; in ipu6_recv_put_token()
405 void __iomem *q_dmem = ctx->dmem_addr + q->wr_reg * 4; in ipu6_recv_put_token()
408 if (rd >= q->size) in ipu6_recv_put_token()