drm/nouveau: factor out r535_gsp_msgq_peek()

To receive a GSP message queue element from the GSP status queue, the
driver needs to make sure there are available elements in the queue.

The previous r535_gsp_msgq_wait() consists of three functions, which is
a little too complicated for a single function:
- wait for an available element.
- peek the message element header in the queue.
- recevice the element from the queue.

Factor out r535_gsp_msgq_peek() and divide the functions in
r535_gsp_msgq_wait() into three functions.

No functional change is intended.

Cc: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20250124182958.2040494-13-zhiw@nvidia.com
This commit is contained in:
Zhi Wang 2025-01-24 10:29:55 -08:00 committed by Danilo Krummrich
parent 1829ee0b05
commit c965e3598b

View File

@ -148,20 +148,16 @@ r535_rpc_status_to_errno(uint32_t rpc_status)
}
}
static void *
r535_gsp_msgq_wait(struct nvkm_gsp *gsp, u32 gsp_rpc_len, u32 *prepc,
int *ptime)
static int
r535_gsp_msgq_wait(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *ptime)
{
struct r535_gsp_msg *mqe;
u32 size, rptr = *gsp->msgq.rptr;
int used;
u8 *msg;
u32 len;
size = DIV_ROUND_UP(GSP_MSG_HDR_SIZE + gsp_rpc_len,
GSP_PAGE_SIZE);
if (WARN_ON(!size || size >= gsp->msgq.cnt))
return ERR_PTR(-EINVAL);
return -EINVAL;
do {
u32 wptr = *gsp->msgq.wptr;
@ -176,15 +172,69 @@ r535_gsp_msgq_wait(struct nvkm_gsp *gsp, u32 gsp_rpc_len, u32 *prepc,
} while (--(*ptime));
if (WARN_ON(!*ptime))
return ERR_PTR(-ETIMEDOUT);
return -ETIMEDOUT;
mqe = (void *)((u8 *)gsp->shm.msgq.ptr + 0x1000 + rptr * 0x1000);
return used;
}
if (prepc) {
*prepc = (used * GSP_PAGE_SIZE) - sizeof(*mqe);
return mqe->data;
}
static struct r535_gsp_msg *
r535_gsp_msgq_get_entry(struct nvkm_gsp *gsp)
{
u32 rptr = *gsp->msgq.rptr;
/* Skip the first page, which is the message queue info */
return (void *)((u8 *)gsp->shm.msgq.ptr + GSP_PAGE_SIZE +
rptr * GSP_PAGE_SIZE);
}
/**
* DOC: Receive a GSP message queue element
*
* Receiving a GSP message queue element from the message queue consists of
* the following steps:
*
* - Peek the element from the queue: r535_gsp_msgq_peek().
* Peek the first page of the element to determine the total size of the
* message before allocating the proper memory.
*
* - Allocate memory and receive the message: r535_gsp_msgq_recv().
* Once the total size of the message is determined from the GSP message
* queue element, allocate memory and copy the pages of the message
* into the allocated memory.
*
* - Free the allocated memory after processing the GSP message.
* The caller is responsible for freeing the memory allocated for the GSP
* message pages after they have been processed.
*/
static void *
r535_gsp_msgq_peek(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
{
struct r535_gsp_msg *mqe;
int ret;
ret = r535_gsp_msgq_wait(gsp, gsp_rpc_len, retries);
if (ret < 0)
return ERR_PTR(ret);
mqe = r535_gsp_msgq_get_entry(gsp);
return mqe->data;
}
static void *
r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
{
u32 rptr = *gsp->msgq.rptr;
struct r535_gsp_msg *mqe;
u32 size, len;
u8 *msg;
int ret;
ret = r535_gsp_msgq_wait(gsp, gsp_rpc_len, retries);
if (ret < 0)
return ERR_PTR(ret);
mqe = r535_gsp_msgq_get_entry(gsp);
size = ALIGN(gsp_rpc_len + GSP_MSG_HDR_SIZE, GSP_PAGE_SIZE);
msg = kvmalloc(gsp_rpc_len, GFP_KERNEL);
@ -209,12 +259,6 @@ r535_gsp_msgq_wait(struct nvkm_gsp *gsp, u32 gsp_rpc_len, u32 *prepc,
return msg;
}
static void *
r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *ptime)
{
return r535_gsp_msgq_wait(gsp, gsp_rpc_len, NULL, ptime);
}
static int
r535_gsp_cmdq_push(struct nvkm_gsp *gsp, void *rpc)
{
@ -337,15 +381,14 @@ r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len)
{
struct nvkm_subdev *subdev = &gsp->subdev;
struct nvfw_gsp_rpc *rpc;
int time = 4000000, i;
u32 size;
int retries = 4000000, i;
retry:
rpc = r535_gsp_msgq_wait(gsp, sizeof(*rpc), &size, &time);
rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), &retries);
if (IS_ERR_OR_NULL(rpc))
return rpc;
rpc = r535_gsp_msgq_recv(gsp, rpc->length, &time);
rpc = r535_gsp_msgq_recv(gsp, rpc->length, &retries);
if (IS_ERR_OR_NULL(rpc))
return rpc;