Commit 7a4dde71 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/secboot: move code to boot LS falcons to subdevs

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 91a4e83a
#ifndef __NVFW_PMU_H__
#define __NVFW_PMU_H__
struct nv_pmu_args {
u32 reserved;
u32 freq_hz;
u32 trace_size;
u32 trace_dma_base;
u16 trace_dma_base1;
u8 trace_dma_offset;
u32 trace_dma_idx;
bool secure_mode;
bool raise_priv_sec;
struct {
u32 dma_base;
u16 dma_base1;
u8 dma_offset;
u16 fb_size;
u8 dma_idx;
} gc6_ctx;
u8 pad;
};
#define NV_PMU_UNIT_INIT 0x07
#define NV_PMU_UNIT_ACR 0x0a
......
#ifndef __NVFW_SEC2_H__
#define __NVFW_SEC2_H__
struct nv_sec2_args {
u32 freq_hz;
u32 falc_trace_size;
u32 falc_trace_dma_base;
u32 falc_trace_dma_idx;
bool secure_mode;
};
#define NV_SEC2_UNIT_INIT 0x01
#define NV_SEC2_UNIT_ACR 0x08
......
......@@ -22,17 +22,7 @@
#ifndef __NVKM_CORE_MSGQUEUE_H
#define __NVKM_CORE_MSGQUEUE_H
#include <subdev/secboot.h>
struct nvkm_msgqueue;
/* Hopefully we will never have firmware arguments larger than that... */
#define NVKM_MSGQUEUE_CMDLINE_SIZE 0x100
int nvkm_msgqueue_new(u32, struct nvkm_falcon *, const struct nvkm_secboot *,
struct nvkm_msgqueue **);
void nvkm_msgqueue_del(struct nvkm_msgqueue **);
/* useful if we run a NVIDIA-signed firmware */
void nvkm_msgqueue_write_cmdline(struct nvkm_msgqueue *, void *);
#endif
......@@ -13,7 +13,6 @@ struct nvkm_sec2 {
struct nvkm_falcon_qmgr *qmgr;
struct nvkm_falcon_cmdq *cmdq;
struct nvkm_falcon_msgq *msgq;
struct nvkm_msgqueue *queue;
struct work_struct work;
bool initmsg_received;
......
......@@ -74,6 +74,7 @@ struct nvkm_acr_lsfw {
};
struct nvkm_acr_lsf_func {
int (*boot)(struct nvkm_falcon *);
int (*bootstrap_falcon)(struct nvkm_falcon *, enum nvkm_acr_lsf_id);
int (*bootstrap_multiple_falcons)(struct nvkm_falcon *, u32 mask);
};
......
......@@ -14,7 +14,6 @@ struct nvkm_pmu {
struct nvkm_falcon_cmdq *lpq;
struct nvkm_falcon_msgq *msgq;
bool initmsg_received;
struct nvkm_msgqueue *queue;
struct completion wpr_ready;
......
......@@ -22,7 +22,6 @@
#include "priv.h"
#include <core/firmware.h>
#include <core/msgqueue.h>
#include <subdev/top.h>
static void
......@@ -70,7 +69,6 @@ static void *
nvkm_sec2_dtor(struct nvkm_engine *engine)
{
struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
nvkm_msgqueue_del(&sec2->queue);
nvkm_falcon_msgq_del(&sec2->msgq);
nvkm_falcon_cmdq_del(&sec2->cmdq);
nvkm_falcon_qmgr_del(&sec2->qmgr);
......
......@@ -64,8 +64,19 @@ gp102_sec2_acr_bootstrap_falcon(struct nvkm_falcon *falcon,
msecs_to_jiffies(1000));
}
static int
gp102_sec2_acr_boot(struct nvkm_falcon *falcon)
{
struct nv_sec2_args args = {};
nvkm_falcon_load_dmem(falcon, &args,
falcon->func->emem_addr, sizeof(args), 0);
nvkm_falcon_start(falcon);
return 0;
}
static const struct nvkm_acr_lsf_func
gp102_sec2_acr_0 = {
.boot = gp102_sec2_acr_boot,
.bootstrap_falcon = gp102_sec2_acr_bootstrap_falcon,
};
......@@ -210,6 +221,7 @@ MODULE_FIRMWARE("nvidia/gp107/sec2/sig.bin");
const struct nvkm_acr_lsf_func
gp102_sec2_acr_1 = {
.boot = gp102_sec2_acr_boot,
.bootstrap_falcon = gp102_sec2_acr_bootstrap_falcon,
};
......
......@@ -4,6 +4,3 @@ nvkm-y += nvkm/falcon/cmdq.o
nvkm-y += nvkm/falcon/msgq.o
nvkm-y += nvkm/falcon/qmgr.o
nvkm-y += nvkm/falcon/v1.o
nvkm-y += nvkm/falcon/msgqueue.o
nvkm-y += nvkm/falcon/msgqueue_0137c63d.o
nvkm-y += nvkm/falcon/msgqueue_0148cdec.o
/*
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "msgqueue.h"
#include <engine/falcon.h>
#include <subdev/secboot.h>
void
nvkm_msgqueue_write_cmdline(struct nvkm_msgqueue *queue, void *buf)
{
if (!queue || !queue->func || !queue->func->init_func)
return;
queue->func->init_func->gen_cmdline(queue, buf);
}
int
nvkm_msgqueue_new(u32 version, struct nvkm_falcon *falcon,
const struct nvkm_secboot *sb, struct nvkm_msgqueue **queue)
{
const struct nvkm_subdev *subdev = falcon->owner;
int ret = -EINVAL;
switch (version) {
case 0x0137c63d:
ret = msgqueue_0137c63d_new(falcon, sb, queue);
break;
case 0x0137bca5:
ret = msgqueue_0137bca5_new(falcon, sb, queue);
break;
case 0x0148cdec:
case 0x015ccf3e:
case 0x0167d263:
ret = msgqueue_0148cdec_new(falcon, sb, queue);
break;
default:
nvkm_error(subdev, "unhandled firmware version 0x%08x\n",
version);
break;
}
if (ret == 0) {
nvkm_debug(subdev, "firmware version: 0x%08x\n", version);
(*queue)->fw_version = version;
}
return ret;
}
void
nvkm_msgqueue_del(struct nvkm_msgqueue **queue)
{
if (*queue) {
(*queue)->func->dtor(*queue);
*queue = NULL;
}
}
void
nvkm_msgqueue_ctor(const struct nvkm_msgqueue_func *func,
struct nvkm_falcon *falcon,
struct nvkm_msgqueue *queue)
{
queue->func = func;
queue->falcon = falcon;
}
/*
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __NVKM_CORE_FALCON_MSGQUEUE_H
#define __NVKM_CORE_FALCON_MSGQUEUE_H
#include <core/falcon.h>
#include <core/msgqueue.h>
/*
* The struct nvkm_msgqueue (named so for lack of better candidate) manages
* a firmware (typically, NVIDIA signed firmware) running under a given falcon.
*
* Such firmwares expect to receive commands (through one or several command
* queues) and will reply to such command by sending messages (using one
* message queue).
*
* Each firmware can support one or several units - ACR for managing secure
* falcons, PMU for power management, etc. A unit can be seen as a class to
* which command can be sent.
*
* One usage example would be to send a command to the SEC falcon to ask it to
* reset a secure falcon. The SEC falcon will receive the command, process it,
* and send a message to signal success or failure. Only when the corresponding
* message is received can the requester assume the request has been processed.
*
* Since we expect many variations between the firmwares NVIDIA will release
* across GPU generations, this library is built in a very modular way. Message
* formats and queues details (such as number of usage) are left to
* specializations of struct nvkm_msgqueue, while the functions in msgqueue.c
* take care of posting commands and processing messages in a fashion that is
* universal.
*
*/
struct nvkm_msgqueue;
/**
* struct nvkm_msgqueue_init_func - msgqueue functions related to initialization
*
* @gen_cmdline: build the commandline into a pre-allocated buffer
* @init_callback: called to process the init message
*/
struct nvkm_msgqueue_init_func {
void (*gen_cmdline)(struct nvkm_msgqueue *, void *);
};
struct nvkm_msgqueue_func {
const struct nvkm_msgqueue_init_func *init_func;
void (*dtor)(struct nvkm_msgqueue *);
};
/**
* struct nvkm_msgqueue - manage a command/message based FW on a falcon
*
* @falcon: falcon to be managed
* @func: implementation of the firmware to use
* @init_msg_received: whether the init message has already been received
*/
struct nvkm_msgqueue {
struct nvkm_falcon *falcon;
const struct nvkm_msgqueue_func *func;
u32 fw_version;
};
void nvkm_msgqueue_ctor(const struct nvkm_msgqueue_func *, struct nvkm_falcon *,
struct nvkm_msgqueue *);
int msgqueue_0137c63d_new(struct nvkm_falcon *, const struct nvkm_secboot *,
struct nvkm_msgqueue **);
int msgqueue_0137bca5_new(struct nvkm_falcon *, const struct nvkm_secboot *,
struct nvkm_msgqueue **);
int msgqueue_0148cdec_new(struct nvkm_falcon *, const struct nvkm_secboot *,
struct nvkm_msgqueue **);
#endif
/*
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "msgqueue.h"
#include <engine/falcon.h>
#include <subdev/pmu.h>
#include <subdev/secboot.h>
struct msgqueue_0137c63d {
struct nvkm_msgqueue base;
};
#define msgqueue_0137c63d(q) \
container_of(q, struct msgqueue_0137c63d, base)
struct msgqueue_0137bca5 {
struct msgqueue_0137c63d base;
u64 wpr_addr;
};
#define msgqueue_0137bca5(q) \
container_of(container_of(q, struct msgqueue_0137c63d, base), \
struct msgqueue_0137bca5, base);
/* Init unit */
static void
init_gen_cmdline(struct nvkm_msgqueue *queue, void *buf)
{
struct {
u32 reserved;
u32 freq_hz;
u32 trace_size;
u32 trace_dma_base;
u16 trace_dma_base1;
u8 trace_dma_offset;
u32 trace_dma_idx;
bool secure_mode;
bool raise_priv_sec;
struct {
u32 dma_base;
u16 dma_base1;
u8 dma_offset;
u16 fb_size;
u8 dma_idx;
} gc6_ctx;
u8 pad;
} *args = buf;
args->secure_mode = 1;
}
static const struct nvkm_msgqueue_init_func
msgqueue_0137c63d_init_func = {
.gen_cmdline = init_gen_cmdline,
};
static void
msgqueue_0137c63d_dtor(struct nvkm_msgqueue *queue)
{
kfree(msgqueue_0137c63d(queue));
}
static const struct nvkm_msgqueue_func
msgqueue_0137c63d_func = {
.init_func = &msgqueue_0137c63d_init_func,
.dtor = msgqueue_0137c63d_dtor,
};
int
msgqueue_0137c63d_new(struct nvkm_falcon *falcon, const struct nvkm_secboot *sb,
struct nvkm_msgqueue **queue)
{
struct msgqueue_0137c63d *ret;
ret = kzalloc(sizeof(*ret), GFP_KERNEL);
if (!ret)
return -ENOMEM;
*queue = &ret->base;
nvkm_msgqueue_ctor(&msgqueue_0137c63d_func, falcon, &ret->base);
return 0;
}
static const struct nvkm_msgqueue_func
msgqueue_0137bca5_func = {
.init_func = &msgqueue_0137c63d_init_func,
.dtor = msgqueue_0137c63d_dtor,
};
int
msgqueue_0137bca5_new(struct nvkm_falcon *falcon, const struct nvkm_secboot *sb,
struct nvkm_msgqueue **queue)
{
struct msgqueue_0137bca5 *ret;
ret = kzalloc(sizeof(*ret), GFP_KERNEL);
if (!ret)
return -ENOMEM;
*queue = &ret->base.base;
/*
* FIXME this must be set to the address of a *GPU* mapping within the
* ACR address space!
*/
/* ret->wpr_addr = sb->wpr_addr; */
nvkm_msgqueue_ctor(&msgqueue_0137bca5_func, falcon, &ret->base.base);
return 0;
}
/*
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "msgqueue.h"
#include <engine/falcon.h>
#include <engine/sec2.h>
#include <subdev/secboot.h>
/*
* This firmware runs on the SEC falcon. It only has one command and one
* message queue, and uses a different command line and init message.
*/
struct msgqueue_0148cdec {
struct nvkm_msgqueue base;
};
#define msgqueue_0148cdec(q) \
container_of(q, struct msgqueue_0148cdec, base)
static void
init_gen_cmdline(struct nvkm_msgqueue *queue, void *buf)
{
struct {
u32 freq_hz;
u32 falc_trace_size;
u32 falc_trace_dma_base;
u32 falc_trace_dma_idx;
bool secure_mode;
} *args = buf;
args->secure_mode = false;
}
static const struct nvkm_msgqueue_init_func
msgqueue_0148cdec_init_func = {
.gen_cmdline = init_gen_cmdline,
};
static void
msgqueue_0148cdec_dtor(struct nvkm_msgqueue *queue)
{
kfree(msgqueue_0148cdec(queue));
}
const struct nvkm_msgqueue_func
msgqueue_0148cdec_func = {
.init_func = &msgqueue_0148cdec_init_func,
.dtor = msgqueue_0148cdec_dtor,
};
int
msgqueue_0148cdec_new(struct nvkm_falcon *falcon, const struct nvkm_secboot *sb,
struct nvkm_msgqueue **queue)
{
struct msgqueue_0148cdec *ret;
ret = kzalloc(sizeof(*ret), GFP_KERNEL);
if (!ret)
return -ENOMEM;
*queue = &ret->base;
nvkm_msgqueue_ctor(&msgqueue_0148cdec_func, falcon, &ret->base);
return 0;
}
......@@ -2,7 +2,6 @@
#ifndef __NVKM_FALCON_QMGR_H__
#define __NVKM_FALCON_QMGR_H__
#include <core/falcon.h>
#include "msgqueue.h"
#define HDR_SIZE sizeof(struct nv_falcon_msg)
#define QUEUE_ALIGNMENT 4
......
......@@ -62,6 +62,27 @@ nvkm_acr_bootstrap_falcons(struct nvkm_device *device, unsigned long mask)
return 0;
}
int
nvkm_acr_boot_ls_falcons(struct nvkm_device *device)
{
struct nvkm_acr *acr = device->acr;
struct nvkm_acr_lsf *lsf;
int ret;
if (!acr)
return -ENOSYS;
list_for_each_entry(lsf, &acr->lsf, head) {
if (lsf->func->boot) {
ret = lsf->func->boot(lsf->falcon);
if (ret)
break;
}
}
return ret;
}
static void
nvkm_acr_cleanup(struct nvkm_acr *acr)
{
......
......@@ -24,7 +24,6 @@
#include "priv.h"
#include <core/firmware.h>
#include <core/msgqueue.h>
#include <subdev/timer.h>
bool
......@@ -144,7 +143,6 @@ static void *
nvkm_pmu_dtor(struct nvkm_subdev *subdev)
{
struct nvkm_pmu *pmu = nvkm_pmu(subdev);
nvkm_msgqueue_del(&pmu->queue);
nvkm_falcon_msgq_del(&pmu->msgq);
nvkm_falcon_cmdq_del(&pmu->lpq);
nvkm_falcon_cmdq_del(&pmu->hpq);
......
......@@ -56,8 +56,19 @@ gm20b_pmu_acr_bootstrap_falcon(struct nvkm_falcon *falcon,
return ret;
}
int
gm20b_pmu_acr_boot(struct nvkm_falcon *falcon)
{
struct nv_pmu_args args = { .secure_mode = true };
const u32 addr_args = falcon->data.limit - NVKM_MSGQUEUE_CMDLINE_SIZE; /*XXX*/
nvkm_falcon_load_dmem(falcon, &args, addr_args, sizeof(args), 0);
nvkm_falcon_start(falcon);
return 0;
}
static const struct nvkm_acr_lsf_func
gm20b_pmu_acr = {
.boot = gm20b_pmu_acr_boot,
.bootstrap_falcon = gm20b_pmu_acr_bootstrap_falcon,
};
......
......@@ -900,12 +900,12 @@ acr_r352_wpr_is_set(const struct acr_r352 *acr, const struct nvkm_secboot *sb)
wpr_hi > wpr_range_lo && wpr_hi <= wpr_range_hi);
}
int nvkm_acr_boot_ls_falcons(struct nvkm_device *);
static int
acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb)
{
const struct nvkm_subdev *subdev = &sb->subdev;
unsigned long managed_falcons = acr->base.managed_falcons;
int falcon_id;
int ret;
if (sb->wpr_set)
......@@ -934,19 +934,7 @@ acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb)
return -EINVAL;
}
/* Run LS firmwares post_run hooks */
for_each_set_bit(falcon_id, &managed_falcons, NVKM_SECBOOT_FALCON_END) {
const struct acr_r352_ls_func *func =
acr->func->ls_func[falcon_id];
if (func->post_run) {
ret = func->post_run(&acr->base, sb);
if (ret)
return ret;
}
}
return 0;
return nvkm_acr_boot_ls_falcons(subdev->device);
}
/**
......@@ -1168,7 +1156,6 @@ acr_r352_ls_pmu_func_0 = {
static const struct acr_r352_ls_func
acr_r352_ls_pmu_func = {
.load = acr_ls_ucode_load_pmu,
.post_run = acr_ls_pmu_post_run,
.version_max = 0,
.version = {
&acr_r352_ls_pmu_func_0,
......
......@@ -65,12 +65,10 @@ struct acr_r352_lsf_func {
* struct acr_r352_ls_func - manages a single LS falcon
*
* @load: load the external firmware into a ls_ucode_img
* @post_run: hook called right after the ACR is executed
*/
struct acr_r352_ls_func {
int (*load)(const struct nvkm_secboot *, int maxver,
struct ls_ucode_img *);
int (*post_run)(const struct nvkm_acr *, const struct nvkm_secboot *);
int version_max;
const struct acr_r352_lsf_func *version[];
};
......
......@@ -150,7 +150,6 @@ acr_r361_ls_pmu_func_0 = {
const struct acr_r352_ls_func
acr_r361_ls_pmu_func = {
.load = acr_ls_ucode_load_pmu,
.post_run = acr_ls_pmu_post_run,
.version_max = 0,
.version = {
&acr_r361_ls_pmu_func_0,
......@@ -197,7 +196,6 @@ acr_r361_ls_sec2_func_0 = {
static const struct acr_r352_ls_func
acr_r361_ls_sec2_func = {
.load = acr_ls_ucode_load_sec2,
.post_run = acr_ls_sec2_post_run,
.version_max = 0,
.version = {
&acr_r361_ls_sec2_func_0,
......
......@@ -385,7 +385,6 @@ acr_r367_fixup_hs_desc(struct acr_r352 *acr, struct nvkm_secboot *sb,
static const struct acr_r352_ls_func
acr_r367_ls_sec2_func = {
.load = acr_ls_ucode_load_sec2,
.post_run = acr_ls_sec2_post_run,
.version_max = 1,
.version = {
&acr_r361_ls_sec2_func_0,
......
......@@ -120,7 +120,6 @@ acr_r370_ls_sec2_func_0 = {
const struct acr_r352_ls_func
acr_r370_ls_sec2_func = {
.load = acr_ls_ucode_load_sec2,
.post_run = acr_ls_sec2_post_run,
.version_max = 0,
.version = {
&acr_r370_ls_sec2_func_0,
......
......@@ -63,7 +63,6 @@ acr_r375_ls_pmu_func_0 = {
const struct acr_r352_ls_func
acr_r375_ls_pmu_func = {
.load = acr_ls_ucode_load_pmu,
.post_run = acr_ls_pmu_post_run,
.version_max = 0,
.version = {
&acr_r375_ls_pmu_func_0,
......
......@@ -75,62 +75,16 @@ acr_ls_ucode_load_msgqueue(const struct nvkm_subdev *subdev, const char *name,
return ver;
}
static int
acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue,
struct nvkm_falcon *falcon, u32 addr_args)
{
struct nvkm_device *device = falcon->owner->device;
u8 buf[NVKM_MSGQUEUE_CMDLINE_SIZE];
memset(buf, 0, sizeof(buf));
nvkm_msgqueue_write_cmdline(queue, buf);
nvkm_falcon_load_dmem(falcon, buf, addr_args, sizeof(buf), 0);
/* Enable interrupts */
nvkm_falcon_wr32(falcon, 0x10, 0xff);
nvkm_mc_intr_mask(device, falcon->owner->index, true);
/* Start LS firmware on boot falcon */
nvkm_falcon_start(falcon);
return 0;
}
int
acr_ls_ucode_load_pmu(const struct nvkm_secboot *sb, int maxver,
struct ls_ucode_img *img)
{
struct nvkm_pmu *pmu = sb->subdev.device->pmu;
int ret;
ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "pmu", maxver, img);
if (ret)
return ret;
/* Allocate the PMU queue corresponding to the FW version */
ret = nvkm_msgqueue_new(img->ucode_desc.app_version, &pmu->falcon,
sb, &pmu->queue);
if (ret)
return ret;
return 0;
}
int
acr_ls_pmu_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb)
{
struct nvkm_device *device = sb->subdev.device;
struct nvkm_pmu *pmu = device->pmu;
u32 addr_args = pmu->falcon.data.limit - NVKM_MSGQUEUE_CMDLINE_SIZE;
int ret;
ret = acr_ls_msgqueue_post_run(pmu->queue, &pmu->falcon, addr_args);
if (ret)
return ret;
nvkm_debug(&sb->subdev, "%s started\n",
nvkm_secboot_falcon_name[acr->boot_falcon]);
return 0;
}
......@@ -138,38 +92,11 @@ int
acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, int maxver,
struct ls_ucode_img *img)
{
struct nvkm_sec2 *sec = sb->subdev.device->sec2;
int ver, ret;
int ver;
ver = acr_ls_ucode_load_msgqueue(&sb->subdev, "sec2", maxver, img);
if (ver < 0)
return ver;
/* Allocate the PMU queue corresponding to the FW version */
ret = nvkm_msgqueue_new(img->ucode_desc.app_version, &sec->falcon,
sb, &sec->queue);
if (ret)
return ret;
return ver;
}
int
acr_ls_sec2_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb)
{
const struct nvkm_subdev *subdev = &sb->subdev;
struct nvkm_device *device = subdev->device;
struct nvkm_sec2 *sec = device->sec2;
/* on SEC arguments are always at the beginning of EMEM */
const u32 addr_args = 0x01000000;
int ret;
ret = acr_ls_msgqueue_post_run(sec->queue, &sec->falcon, addr_args);
if (ret)
return ret;
nvkm_debug(&sb->subdev, "%s started\n",
nvkm_secboot_falcon_name[acr->boot_falcon]);
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment