Skip to content

Commit

Permalink
drm/nouveau/flcn/cmdq: move command generation to subdevs
Browse files Browse the repository at this point in the history
This moves the code to generate commands for the ACR unit of the PMU/SEC2 LS
firmwares to those subdevs.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Jan 15, 2020
1 parent 25fd061 commit 86ce2a7
Show file tree
Hide file tree
Showing 16 changed files with 300 additions and 276 deletions.
47 changes: 47 additions & 0 deletions drivers/gpu/drm/nouveau/include/nvfw/pmu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef __NVFW_PMU_H__
#define __NVFW_PMU_H__

#define NV_PMU_UNIT_ACR 0x0a

struct nv_pmu_acr_cmd {
struct nv_falcon_cmd hdr;
#define NV_PMU_ACR_CMD_INIT_WPR_REGION 0x00
#define NV_PMU_ACR_CMD_BOOTSTRAP_FALCON 0x01
#define NV_PMU_ACR_CMD_BOOTSTRAP_MULTIPLE_FALCONS 0x03
u8 cmd_type;
};

struct nv_pmu_acr_msg {
struct nv_falcon_cmd hdr;
u8 msg_type;
};

struct nv_pmu_acr_bootstrap_falcon_cmd {
struct nv_pmu_acr_cmd cmd;
#define NV_PMU_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_YES 0x00000000
#define NV_PMU_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_NO 0x00000001
u32 flags;
u32 falcon_id;
};

struct nv_pmu_acr_bootstrap_falcon_msg {
struct nv_pmu_acr_msg msg;
u32 falcon_id;
};

struct nv_pmu_acr_bootstrap_multiple_falcons_cmd {
struct nv_pmu_acr_cmd cmd;
#define NV_PMU_ACR_BOOTSTRAP_MULTIPLE_FALCONS_FLAGS_RESET_YES 0x00000000
#define NV_PMU_ACR_BOOTSTRAP_MULTIPLE_FALCONS_FLAGS_RESET_NO 0x00000001
u32 flags;
u32 falcon_mask;
u32 use_va_mask;
u32 wpr_lo;
u32 wpr_hi;
};

struct nv_pmu_acr_bootstrap_multiple_falcons_msg {
struct nv_pmu_acr_msg msg;
u32 falcon_mask;
};
#endif
30 changes: 30 additions & 0 deletions drivers/gpu/drm/nouveau/include/nvfw/sec2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef __NVFW_SEC2_H__
#define __NVFW_SEC2_H__

#define NV_SEC2_UNIT_ACR 0x08

struct nv_sec2_acr_cmd {
struct nv_falcon_cmd hdr;
#define NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON 0x00
u8 cmd_type;
};

struct nv_sec2_acr_msg {
struct nv_falcon_cmd hdr;
u8 msg_type;
};

struct nv_sec2_acr_bootstrap_falcon_cmd {
struct nv_sec2_acr_cmd cmd;
#define NV_SEC2_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_YES 0x00000000
#define NV_SEC2_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_NO 0x00000001
u32 flags;
u32 falcon_id;
};

struct nv_sec2_acr_bootstrap_falcon_msg {
struct nv_sec2_acr_msg msg;
u32 error_code;
u32 falcon_id;
};
#endif
3 changes: 0 additions & 3 deletions drivers/gpu/drm/nouveau/include/nvkm/core/msgqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,4 @@ int nvkm_msgqueue_reinit(struct nvkm_msgqueue *);
/* useful if we run a NVIDIA-signed firmware */
void nvkm_msgqueue_write_cmdline(struct nvkm_msgqueue *, void *);

/* interface to ACR unit running on falcon (NVIDIA signed firmware) */
int nvkm_msgqueue_acr_boot_falcons(struct nvkm_msgqueue *, unsigned long);

#endif
23 changes: 22 additions & 1 deletion drivers/gpu/drm/nouveau/include/nvkm/subdev/acr.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,34 @@ enum nvkm_acr_lsf_id {
NVKM_ACR_LSF_NVDEC = 4,
NVKM_ACR_LSF_SEC2 = 7,
NVKM_ACR_LSF_MINION = 10,
NVKM_ACR_LSF_NUM
};

static inline const char *
nvkm_acr_lsf_id(enum nvkm_acr_lsf_id id)
{
switch (id) {
case NVKM_ACR_LSF_PMU : return "pmu";
case NVKM_ACR_LSF_GSPLITE: return "gsplite";
case NVKM_ACR_LSF_FECS : return "fecs";
case NVKM_ACR_LSF_GPCCS : return "gpccs";
case NVKM_ACR_LSF_NVDEC : return "nvdec";
case NVKM_ACR_LSF_SEC2 : return "sec2";
case NVKM_ACR_LSF_MINION : return "minion";
default:
return "unknown";
}
}

struct nvkm_acr {
const struct nvkm_acr_func *func;
struct nvkm_subdev subdev;

struct list_head lsfw;
struct list_head lsfw, lsf;
};

int nvkm_acr_bootstrap_falcons(struct nvkm_device *, unsigned long mask);

int gm200_acr_new(struct nvkm_device *, int, struct nvkm_acr **);
int gm20b_acr_new(struct nvkm_device *, int, struct nvkm_acr **);
int gp102_acr_new(struct nvkm_device *, int, struct nvkm_acr **);
Expand Down Expand Up @@ -55,6 +74,8 @@ struct nvkm_acr_lsfw {
};

struct nvkm_acr_lsf_func {
int (*bootstrap_falcon)(struct nvkm_falcon *, enum nvkm_acr_lsf_id);
int (*bootstrap_multiple_falcons)(struct nvkm_falcon *, u32 mask);
};

int
Expand Down
44 changes: 44 additions & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,53 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "priv.h"

#include <subdev/acr.h>
#include <subdev/timer.h>

#include <nvfw/sec2.h>

static int
gp102_sec2_acr_bootstrap_falcon_callback(void *priv, struct nv_falcon_msg *hdr)
{
struct nv_sec2_acr_bootstrap_falcon_msg *msg =
container_of(hdr, typeof(*msg), msg.hdr);
struct nvkm_subdev *subdev = priv;
const char *name = nvkm_acr_lsf_id(msg->falcon_id);

if (msg->error_code) {
nvkm_error(subdev, "ACR_BOOTSTRAP_FALCON failed for "
"falcon %d [%s]: %08x\n",
msg->falcon_id, name, msg->error_code);
return -EINVAL;
}

nvkm_debug(subdev, "%s booted\n", name);
return 0;
}

static int
gp102_sec2_acr_bootstrap_falcon(struct nvkm_falcon *falcon,
enum nvkm_acr_lsf_id id)
{
struct nvkm_sec2 *sec2 = container_of(falcon, typeof(*sec2), falcon);
struct nv_sec2_acr_bootstrap_falcon_cmd cmd = {
.cmd.hdr.unit_id = sec2->func->unit_acr,
.cmd.hdr.size = sizeof(cmd),
.cmd.cmd_type = NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON,
.flags = NV_SEC2_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_YES,
.falcon_id = id,
};

return nvkm_falcon_cmdq_send(sec2->cmdq, &cmd.cmd.hdr,
gp102_sec2_acr_bootstrap_falcon_callback,
&sec2->engine.subdev,
msecs_to_jiffies(1000));
}

static const struct nvkm_acr_lsf_func
gp102_sec2_acr_0 = {
.bootstrap_falcon = gp102_sec2_acr_bootstrap_falcon,
};

void
Expand Down Expand Up @@ -117,6 +159,7 @@ gp102_sec2_flcn = {
const struct nvkm_sec2_func
gp102_sec2 = {
.flcn = &gp102_sec2_flcn,
.unit_acr = NV_SEC2_UNIT_ACR,
.intr = gp102_sec2_intr,
};

Expand All @@ -135,6 +178,7 @@ MODULE_FIRMWARE("nvidia/gp107/sec2/sig.bin");

const struct nvkm_acr_lsf_func
gp102_sec2_acr_1 = {
.bootstrap_falcon = gp102_sec2_acr_bootstrap_falcon,
};

int
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/sec2/priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

struct nvkm_sec2_func {
const struct nvkm_falcon_func *flcn;
u8 unit_acr;
void (*intr)(struct nvkm_sec2 *);
};

Expand Down
28 changes: 0 additions & 28 deletions drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,6 @@ nvkm_msgqueue_write_cmdline(struct nvkm_msgqueue *queue, void *buf)
queue->func->init_func->gen_cmdline(queue, buf);
}

int
nvkm_msgqueue_acr_boot_falcons(struct nvkm_msgqueue *queue,
unsigned long falcon_mask)
{
unsigned long falcon;

if (!queue || !queue->func->acr_func)
return -ENODEV;

/* Does the firmware support booting multiple falcons? */
if (queue->func->acr_func->boot_multiple_falcons)
return queue->func->acr_func->boot_multiple_falcons(queue,
falcon_mask);

/* Else boot all requested falcons individually */
if (!queue->func->acr_func->boot_falcon)
return -ENODEV;

for_each_set_bit(falcon, &falcon_mask, NVKM_SECBOOT_FALCON_END) {
int ret = queue->func->acr_func->boot_falcon(queue, falcon);

if (ret)
return ret;
}

return 0;
}

int
nvkm_msgqueue_new(u32 version, struct nvkm_falcon *falcon,
const struct nvkm_secboot *sb, struct nvkm_msgqueue **queue)
Expand Down
12 changes: 0 additions & 12 deletions drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,8 @@ struct nvkm_msgqueue_init_func {
int (*init_callback)(struct nvkm_msgqueue *, struct nvkm_msgqueue_hdr *);
};

/**
* struct nvkm_msgqueue_acr_func - msgqueue functions related to ACR
*
* @boot_falcon: build and send the command to reset a given falcon
* @boot_multiple_falcons: build and send the command to reset several falcons
*/
struct nvkm_msgqueue_acr_func {
int (*boot_falcon)(struct nvkm_msgqueue *, enum nvkm_secboot_falcon);
int (*boot_multiple_falcons)(struct nvkm_msgqueue *, unsigned long);
};

struct nvkm_msgqueue_func {
const struct nvkm_msgqueue_init_func *init_func;
const struct nvkm_msgqueue_acr_func *acr_func;
void (*dtor)(struct nvkm_msgqueue *);
void (*recv)(struct nvkm_msgqueue *queue);
};
Expand Down
Loading

0 comments on commit 86ce2a7

Please sign in to comment.