/* * On module freeup, we need to unbind the module with modules * it is already bind. * Find the pin allocated and unbind then using bind_unbind IPC */ int skl_unbind_modules(struct skl_sst *ctx, struct skl_module_cfg *src_mcfg, struct skl_module_cfg *dst_mcfg) { int ret; struct skl_ipc_bind_unbind_msg msg; struct skl_module_inst_id src_id = src_mcfg->id; struct skl_module_inst_id dst_id = dst_mcfg->id; int in_max = dst_mcfg->max_in_queue; int out_max = src_mcfg->max_out_queue; int src_index, dst_index; skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); if (src_mcfg->m_state != SKL_MODULE_BIND_DONE) return 0; /* * if intra module unbind, check if both modules are BIND, * then send unbind */ if ((src_mcfg->pipe->ppl_id != dst_mcfg->pipe->ppl_id) && dst_mcfg->m_state != SKL_MODULE_BIND_DONE) return 0; else if (src_mcfg->m_state < SKL_MODULE_INIT_DONE && dst_mcfg->m_state < SKL_MODULE_INIT_DONE) return 0; /* get src queue index */ src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); if (src_index < 0) return -EINVAL; msg.src_queue = src_mcfg->m_out_pin[src_index].pin_index; /* get dst queue index */ dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max); if (dst_index < 0) return -EINVAL; msg.dst_queue = dst_mcfg->m_in_pin[dst_index].pin_index; msg.module_id = src_mcfg->id.module_id; msg.instance_id = src_mcfg->id.instance_id; msg.dst_module_id = dst_mcfg->id.module_id; msg.dst_instance_id = dst_mcfg->id.instance_id; msg.bind = false; ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); if (!ret) { src_mcfg->m_state = SKL_MODULE_UNINIT; /* free queue only if unbind is success */ skl_free_queue(src_mcfg->m_out_pin, src_index); skl_free_queue(dst_mcfg->m_in_pin, dst_index); } return ret; }
/* * On module freeup, we need to unbind the module with modules * it is already bind. * Find the pin allocated and unbind then using bind_unbind IPC */ int skl_unbind_modules(struct skl_sst *ctx, struct skl_module_cfg *src_mcfg, struct skl_module_cfg *dst_mcfg) { int ret; struct skl_ipc_bind_unbind_msg msg; struct skl_module_inst_id src_id = src_mcfg->id; struct skl_module_inst_id dst_id = dst_mcfg->id; int in_max = dst_mcfg->module->max_input_pins; int out_max = src_mcfg->module->max_output_pins; int src_index, dst_index, src_pin_state, dst_pin_state; skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); /* get src queue index */ src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); if (src_index < 0) return 0; msg.src_queue = src_index; /* get dst queue index */ dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max); if (dst_index < 0) return 0; msg.dst_queue = dst_index; src_pin_state = src_mcfg->m_out_pin[src_index].pin_state; dst_pin_state = dst_mcfg->m_in_pin[dst_index].pin_state; if (src_pin_state != SKL_PIN_BIND_DONE || dst_pin_state != SKL_PIN_BIND_DONE) return 0; msg.module_id = src_mcfg->id.module_id; msg.instance_id = src_mcfg->id.pvt_id; msg.dst_module_id = dst_mcfg->id.module_id; msg.dst_instance_id = dst_mcfg->id.pvt_id; msg.bind = false; ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); if (!ret) { /* free queue only if unbind is success */ skl_free_queue(src_mcfg->m_out_pin, src_index); skl_free_queue(dst_mcfg->m_in_pin, dst_index); /* * check only if src module bind state, bind is * always from src -> sink */ skl_clear_module_state(src_mcfg->m_out_pin, out_max, src_mcfg); } return ret; }
/* * Once a module is instantiated it need to be 'bind' with other modules in * the pipeline. For binding we need to find the module pins which are bind * together * This function finds the pins and then sends bund_unbind IPC message to * DSP using IPC helper */ int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg *src_mcfg, struct skl_module_cfg *dst_mcfg) { int ret; struct skl_ipc_bind_unbind_msg msg; int in_max = dst_mcfg->max_in_queue; int out_max = src_mcfg->max_out_queue; int src_index, dst_index; skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); if (src_mcfg->m_state < SKL_MODULE_INIT_DONE || dst_mcfg->m_state < SKL_MODULE_INIT_DONE) return 0; src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_mcfg, out_max); if (src_index < 0) return -EINVAL; msg.src_queue = src_index; dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_mcfg, in_max); if (dst_index < 0) { skl_free_queue(src_mcfg->m_out_pin, src_index); return -EINVAL; } msg.dst_queue = dst_index; dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", msg.src_queue, msg.dst_queue); msg.module_id = src_mcfg->id.module_id; msg.instance_id = src_mcfg->id.instance_id; msg.dst_module_id = dst_mcfg->id.module_id; msg.dst_instance_id = dst_mcfg->id.instance_id; msg.bind = true; ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); if (!ret) { src_mcfg->m_state = SKL_MODULE_BIND_DONE; src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE; dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE; } else { /* error case , if IPC fails, clear the queue index */ skl_free_queue(src_mcfg->m_out_pin, src_index); skl_free_queue(dst_mcfg->m_in_pin, dst_index); } return ret; }
/* * Once a module is instantiated it need to be 'bind' with other modules in * the pipeline. For binding we need to find the module pins which are bind * together * This function finds the pins and then sends bund_unbind IPC message to * DSP using IPC helper */ int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg *src_mcfg, struct skl_module_cfg *dst_mcfg) { int ret = 0; struct skl_ipc_bind_unbind_msg msg; int in_max = dst_mcfg->module->max_input_pins; int out_max = src_mcfg->module->max_output_pins; int src_index, dst_index; struct skl_module_fmt *format; struct skl_cpr_pin_fmt pin_fmt; struct skl_module *module; struct skl_module_iface *fmt; skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); if (src_mcfg->m_state < SKL_MODULE_INIT_DONE || dst_mcfg->m_state < SKL_MODULE_INIT_DONE) return 0; src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_mcfg, out_max); if (src_index < 0) return -EINVAL; msg.src_queue = src_index; dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_mcfg, in_max); if (dst_index < 0) { skl_free_queue(src_mcfg->m_out_pin, src_index); return -EINVAL; } /* * Copier module requires the separate large_config_set_ipc to * configure the pins other than 0 */ if (src_mcfg->m_type == SKL_MODULE_TYPE_COPIER && src_index > 0) { pin_fmt.sink_id = src_index; module = src_mcfg->module; fmt = &module->formats[src_mcfg->fmt_idx]; /* Input fmt is same as that of src module input cfg */ format = &fmt->inputs[0].fmt; fill_pin_params(&(pin_fmt.src_fmt), format); format = &fmt->outputs[src_index].fmt; fill_pin_params(&(pin_fmt.dst_fmt), format); ret = skl_set_module_params(ctx, (void *)&pin_fmt, sizeof(struct skl_cpr_pin_fmt), CPR_SINK_FMT_PARAM_ID, src_mcfg); if (ret < 0) goto out; } msg.dst_queue = dst_index; dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", msg.src_queue, msg.dst_queue); msg.module_id = src_mcfg->id.module_id; msg.instance_id = src_mcfg->id.pvt_id; msg.dst_module_id = dst_mcfg->id.module_id; msg.dst_instance_id = dst_mcfg->id.pvt_id; msg.bind = true; ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); if (!ret) { src_mcfg->m_state = SKL_MODULE_BIND_DONE; src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE; dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE; return ret; } out: /* error case , if IPC fails, clear the queue index */ skl_free_queue(src_mcfg->m_out_pin, src_index); skl_free_queue(dst_mcfg->m_in_pin, dst_index); return ret; }