1
0
Fork 0

MLK-18497-5: ASoC: fsl: dsp_proxy: Introduce client API

This will allow DSP driver to create/destroy a client on
DSP audio-framework proxy.

Registering a client on remote DSP proxy means creating
a component.

The implementation is similar with userspace application
proxy implementation.

Reviewed-by: Cosmin-Gabriel Samoila <cosmin.samoila@nxp.com>
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
pull/10/head
Daniel Baluta 2018-10-04 16:05:45 +03:00 committed by Jason Liu
parent c9594348db
commit 21fa331157
2 changed files with 190 additions and 5 deletions

View File

@ -766,3 +766,90 @@ int xf_cmd_send_resume(struct xf_proxy *proxy)
return ret;
}
/* ...open component handle */
int xf_open(struct xf_client *client, struct xf_proxy *proxy,
struct xf_handle *handle, const char *id, u32 core,
xf_response_cb response)
{
void *b;
struct xf_message msg;
struct xf_message *rmsg;
/* ...retrieve auxiliary control buffer from proxy - need I */
handle->aux = xf_buffer_get(proxy->aux);
b = xf_handle_aux(handle);
msg.id = __XF_MSG_ID(__XF_AP_PROXY(0), __XF_DSP_PROXY(0));
msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
msg.opcode = XF_REGISTER;
msg.buffer = b;
msg.length = strlen(id) + 1;
msg.ret = 0;
/* ...copy component identifier */
memcpy(b, (void *)id, xf_buffer_length(handle->aux));
/* ...execute command synchronously */
rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
msg.buffer, msg.length, &client->work,
&client->compr_complete);
if (IS_ERR(rmsg)) {
xf_buffer_put(handle->aux), handle->aux = NULL;
return PTR_ERR(rmsg);
}
/* ...save received component global client-id */
handle->id = XF_MSG_SRC(rmsg->id);
/* TODO: review cleanup */
/* xf_msg_free(proxy, rmsg);
* xf_unlock(&proxy->lock); */
/* ...if failed, release buffer handle */
/* ...operation completed successfully; assign handle data */
handle->response = response;
handle->proxy = proxy;
return 0;
}
/* ...close component handle */
int xf_close(struct xf_client *client, struct xf_handle *handle)
{
struct xf_proxy *proxy = handle->proxy;
struct xf_message msg;
struct xf_message *rmsg;
/* ...do I need to take component lock here? guess no - tbd */
/* ...buffers and stuff? - tbd */
/* ...acquire global proxy lock */
/* ...unregister component from remote DSP proxy (ignore result code) */
msg.id = __XF_MSG_ID(__XF_AP_PROXY(0), handle->id);
msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
msg.opcode = XF_UNREGISTER;
msg.buffer = NULL;
msg.length = 0;
msg.ret = 0;
/* ...execute command synchronously */
rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
msg.buffer, msg.length, &client->work,
&client->compr_complete);
if (IS_ERR(rmsg)) {
xf_buffer_put(handle->aux), handle->aux = NULL;
return PTR_ERR(rmsg);
}
/* TODO: review cleanup */
/* xf_msg_free(proxy, rmsg);
* xf_unlock(&proxy->lock); */
/* ...wipe out proxy pointer */
handle->proxy = NULL;
return 0;
}

View File

@ -19,6 +19,7 @@
#include <linux/mx8_mu.h>
#include <linux/interrupt.h>
#include "fsl_dsp_pool.h"
#define XF_CFG_MESSAGE_POOL_SIZE 256
struct xf_client;
@ -27,6 +28,10 @@ struct xf_client;
* Local proxy data
******************************************************************************/
struct xf_message;
struct xf_handle;
typedef void (*xf_response_cb)(struct xf_handle *h, struct xf_message *msg);
/* ...execution message */
struct xf_message {
/* ...pointer to next message in a list */
@ -84,8 +89,10 @@ enum icm_action_t {
/* ...adjust IPC client of message going from user-space */
#define XF_MSG_AP_FROM_USER(id, client) (((id) & ~(0xF << 2)) | (client << 2))
/* ...message id contains source and destination ports specification */
#define __XF_MSG_ID(src, dst) (((src) & 0xFFFF) | (((dst) & 0xFFFF) << 16))
#define __XF_PORT_SPEC(core, id, port) ((core) | ((id) << 2) | ((port) << 8))
#define __XF_PORT_SPEC2(id, port) ((id) | ((port) << 8))
/* ...wipe out IPC client from message going to user-space */
#define XF_MSG_AP_TO_USER(id) ((id) & ~(0xF << 18))
@ -94,13 +101,17 @@ enum icm_action_t {
/* ...message id contains source and destination ports specification */
#define __XF_MSG_ID(src, dst) (((src) & 0xFFFF) | (((dst) & 0xFFFF) << 16))
#define XF_MSG_SRC(id) (((id) >> 0) & 0xFFFF)
#define XF_MSG_SRC_CORE(id) (((id) >> 0) & 0x3)
#define XF_MSG_SRC_CLIENT(id) (((id) >> 2) & 0x3F)
#define XF_MSG_DST_CLIENT(id) (((id) >> 18) & 0x3F)
/* ...special treatment of AP-proxy destination field */
#define XF_AP_IPC_CLIENT(id) (((id) >> 18) & 0xF)
#define __XF_AP_PROXY(core) ((core) | 0x8000)
#define __XF_DSP_PROXY(core) ((core) | 0x8000)
#define XF_AP_IPC_CLIENT(id) (((id) >> 18) & 0xF)
#define XF_AP_CLIENT(id) (((id) >> 22) & 0x1FF)
#define __XF_AP_PROXY(core) ((core) | 0x8000)
#define __XF_DSP_PROXY(core) ((core) | 0x8000)
#define __XF_AP_CLIENT(core, client) ((core) | ((client) << 6) | 0x8000)
/* ...opcode composition with command/response data tags */
#define __XF_OPCODE(c, r, op) (((c) << 31) | ((r) << 30) | ((op) & 0x3F))
@ -417,4 +428,91 @@ void *xf_proxy_a2b(struct xf_proxy *proxy, u32 address);
int xf_cmd_send_suspend(struct xf_proxy *proxy);
int xf_cmd_send_resume(struct xf_proxy *proxy);
int xf_cmd_alloc(struct xf_proxy *proxy, void **buffer, u32 length);
int xf_cmd_free(struct xf_proxy *proxy, void *buffer, u32 length);
int xf_open(struct xf_client *client, struct xf_proxy *proxy,
struct xf_handle *handle, const char *id, u32 core,
xf_response_cb response);
int xf_close(struct xf_client *client, struct xf_handle *handle);
/*******************************************************************************
* Opcode composition
******************************************************************************/
/* ...opcode composition with command/response data tags */
#define __XF_OPCODE(c, r, op) (((c) << 31) | ((r) << 30) | ((op) & 0x3F))
/* ...accessors */
#define XF_OPCODE_CDATA(opcode) ((opcode) & (1 << 31))
#define XF_OPCODE_RDATA(opcode) ((opcode) & (1 << 30))
#define XF_OPCODE_TYPE(opcode) ((opcode) & (0x3F))
/*******************************************************************************
* Opcode types
******************************************************************************/
/* ...unregister client */
#define XF_UNREGISTER __XF_OPCODE(0, 0, 0)
/* ...register client at proxy */
#define XF_REGISTER __XF_OPCODE(1, 0, 1)
/* ...port routing command */
#define XF_ROUTE __XF_OPCODE(1, 0, 2)
/* ...port unrouting command */
#define XF_UNROUTE __XF_OPCODE(1, 0, 3)
/* ...shared buffer allocation */
#define XF_ALLOC __XF_OPCODE(0, 0, 4)
/* ...shared buffer freeing */
#define XF_FREE __XF_OPCODE(0, 0, 5)
/* ...set component parameters */
#define XF_SET_PARAM __XF_OPCODE(1, 0, 6)
/* ...get component parameters */
#define XF_GET_PARAM __XF_OPCODE(1, 1, 7)
/* ...input buffer reception */
#define XF_EMPTY_THIS_BUFFER __XF_OPCODE(1, 0, 8)
/* ...output buffer reception */
#define XF_FILL_THIS_BUFFER __XF_OPCODE(0, 1, 9)
/* ...flush specific port */
#define XF_FLUSH __XF_OPCODE(0, 0, 10)
/* ...start component operation */
#define XF_START __XF_OPCODE(0, 0, 11)
/* ...stop component operation */
#define XF_STOP __XF_OPCODE(0, 0, 12)
/* ...pause component operation */
#define XF_PAUSE __XF_OPCODE(0, 0, 13)
/* ...resume component operation */
#define XF_RESUME __XF_OPCODE(0, 0, 14)
/* ...resume component operation */
#define XF_SUSPEND __XF_OPCODE(0, 0, 15)
/* ...load lib for component operation */
#define XF_LOAD_LIB __XF_OPCODE(0, 0, 16)
/* ...unload lib for component operation */
#define XF_UNLOAD_LIB __XF_OPCODE(0, 0, 17)
/* ...component output eos operation */
#define XF_OUTPUT_EOS __XF_OPCODE(0, 0, 18)
/* ...total amount of supported decoder commands */
#define __XF_OP_NUM 19
#endif