162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright 2022 Red Hat Inc.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
562306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
662306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation
762306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
862306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
962306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
1262306a36Sopenharmony_ci * all copies or substantial portions of the Software.
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1562306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1662306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1762306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1862306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1962306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2062306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_ci#include "priv.h"
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#include <core/memory.h>
2562306a36Sopenharmony_ci#include <subdev/mc.h>
2662306a36Sopenharmony_ci#include <subdev/timer.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_civoid
2962306a36Sopenharmony_cigm200_flcn_tracepc(struct nvkm_falcon *falcon)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	u32 sctl = nvkm_falcon_rd32(falcon, 0x240);
3262306a36Sopenharmony_ci	u32 tidx = nvkm_falcon_rd32(falcon, 0x148);
3362306a36Sopenharmony_ci	int nr = (tidx & 0x00ff0000) >> 16, sp, ip;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	FLCN_ERR(falcon, "TRACEPC SCTL %08x TIDX %08x", sctl, tidx);
3662306a36Sopenharmony_ci	for (sp = 0; sp < nr; sp++) {
3762306a36Sopenharmony_ci		nvkm_falcon_wr32(falcon, 0x148, sp);
3862306a36Sopenharmony_ci		ip = nvkm_falcon_rd32(falcon, 0x14c);
3962306a36Sopenharmony_ci		FLCN_ERR(falcon, "TRACEPC: %08x", ip);
4062306a36Sopenharmony_ci	}
4162306a36Sopenharmony_ci}
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistatic void
4462306a36Sopenharmony_cigm200_flcn_pio_dmem_rd(struct nvkm_falcon *falcon, u8 port, const u8 *img, int len)
4562306a36Sopenharmony_ci{
4662306a36Sopenharmony_ci	while (len >= 4) {
4762306a36Sopenharmony_ci		*(u32 *)img = nvkm_falcon_rd32(falcon, 0x1c4 + (port * 8));
4862306a36Sopenharmony_ci		img += 4;
4962306a36Sopenharmony_ci		len -= 4;
5062306a36Sopenharmony_ci	}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	/* Sigh.  Tegra PMU FW's init message... */
5362306a36Sopenharmony_ci	if (len) {
5462306a36Sopenharmony_ci		u32 data = nvkm_falcon_rd32(falcon, 0x1c4 + (port * 8));
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci		while (len--) {
5762306a36Sopenharmony_ci			*(u8 *)img++ = data & 0xff;
5862306a36Sopenharmony_ci			data >>= 8;
5962306a36Sopenharmony_ci		}
6062306a36Sopenharmony_ci	}
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic void
6462306a36Sopenharmony_cigm200_flcn_pio_dmem_rd_init(struct nvkm_falcon *falcon, u8 port, u32 dmem_base)
6562306a36Sopenharmony_ci{
6662306a36Sopenharmony_ci	nvkm_falcon_wr32(falcon, 0x1c0 + (port * 8), BIT(25) | dmem_base);
6762306a36Sopenharmony_ci}
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistatic void
7062306a36Sopenharmony_cigm200_flcn_pio_dmem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int len, u16 tag)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	while (len >= 4) {
7362306a36Sopenharmony_ci		nvkm_falcon_wr32(falcon, 0x1c4 + (port * 8), *(u32 *)img);
7462306a36Sopenharmony_ci		img += 4;
7562306a36Sopenharmony_ci		len -= 4;
7662306a36Sopenharmony_ci	}
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	WARN_ON(len);
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cistatic void
8262306a36Sopenharmony_cigm200_flcn_pio_dmem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 dmem_base)
8362306a36Sopenharmony_ci{
8462306a36Sopenharmony_ci	nvkm_falcon_wr32(falcon, 0x1c0 + (port * 8), BIT(24) | dmem_base);
8562306a36Sopenharmony_ci}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ciconst struct nvkm_falcon_func_pio
8862306a36Sopenharmony_cigm200_flcn_dmem_pio = {
8962306a36Sopenharmony_ci	.min = 1,
9062306a36Sopenharmony_ci	.max = 0x100,
9162306a36Sopenharmony_ci	.wr_init = gm200_flcn_pio_dmem_wr_init,
9262306a36Sopenharmony_ci	.wr = gm200_flcn_pio_dmem_wr,
9362306a36Sopenharmony_ci	.rd_init = gm200_flcn_pio_dmem_rd_init,
9462306a36Sopenharmony_ci	.rd = gm200_flcn_pio_dmem_rd,
9562306a36Sopenharmony_ci};
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistatic void
9862306a36Sopenharmony_cigm200_flcn_pio_imem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 imem_base)
9962306a36Sopenharmony_ci{
10062306a36Sopenharmony_ci	nvkm_falcon_wr32(falcon, 0x180 + (port * 0x10), (sec ? BIT(28) : 0) | BIT(24) | imem_base);
10162306a36Sopenharmony_ci}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_cistatic void
10462306a36Sopenharmony_cigm200_flcn_pio_imem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int len, u16 tag)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag++);
10762306a36Sopenharmony_ci	while (len >= 4) {
10862306a36Sopenharmony_ci		nvkm_falcon_wr32(falcon, 0x184 + (port * 0x10), *(u32 *)img);
10962306a36Sopenharmony_ci		img += 4;
11062306a36Sopenharmony_ci		len -= 4;
11162306a36Sopenharmony_ci	}
11262306a36Sopenharmony_ci}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ciconst struct nvkm_falcon_func_pio
11562306a36Sopenharmony_cigm200_flcn_imem_pio = {
11662306a36Sopenharmony_ci	.min = 0x100,
11762306a36Sopenharmony_ci	.max = 0x100,
11862306a36Sopenharmony_ci	.wr_init = gm200_flcn_pio_imem_wr_init,
11962306a36Sopenharmony_ci	.wr = gm200_flcn_pio_imem_wr,
12062306a36Sopenharmony_ci};
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ciint
12362306a36Sopenharmony_cigm200_flcn_bind_stat(struct nvkm_falcon *falcon, bool intr)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci	if (intr && !(nvkm_falcon_rd32(falcon, 0x008) & 0x00000008))
12662306a36Sopenharmony_ci		return -1;
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	return (nvkm_falcon_rd32(falcon, 0x0dc) & 0x00007000) >> 12;
12962306a36Sopenharmony_ci}
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_civoid
13262306a36Sopenharmony_cigm200_flcn_bind_inst(struct nvkm_falcon *falcon, int target, u64 addr)
13362306a36Sopenharmony_ci{
13462306a36Sopenharmony_ci	nvkm_falcon_mask(falcon, 0x604, 0x00000007, 0x00000000); /* DMAIDX_VIRT */
13562306a36Sopenharmony_ci	nvkm_falcon_wr32(falcon, 0x054, (1 << 30) | (target << 28) | (addr >> 12));
13662306a36Sopenharmony_ci	nvkm_falcon_mask(falcon, 0x090, 0x00010000, 0x00010000);
13762306a36Sopenharmony_ci	nvkm_falcon_mask(falcon, 0x0a4, 0x00000008, 0x00000008);
13862306a36Sopenharmony_ci}
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ciint
14162306a36Sopenharmony_cigm200_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *falcon)
14262306a36Sopenharmony_ci{
14362306a36Sopenharmony_ci	nvkm_falcon_mask(falcon, 0x040, 0x00000000, 0x00000000);
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci	if (nvkm_msec(falcon->owner->device, 10,
14662306a36Sopenharmony_ci		if (!(nvkm_falcon_rd32(falcon, 0x10c) & 0x00000006))
14762306a36Sopenharmony_ci			break;
14862306a36Sopenharmony_ci	) < 0)
14962306a36Sopenharmony_ci		return -ETIMEDOUT;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	return 0;
15262306a36Sopenharmony_ci}
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ciint
15562306a36Sopenharmony_cigm200_flcn_enable(struct nvkm_falcon *falcon)
15662306a36Sopenharmony_ci{
15762306a36Sopenharmony_ci	struct nvkm_device *device = falcon->owner->device;
15862306a36Sopenharmony_ci	int ret;
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	if (falcon->func->reset_eng) {
16162306a36Sopenharmony_ci		ret = falcon->func->reset_eng(falcon);
16262306a36Sopenharmony_ci		if (ret)
16362306a36Sopenharmony_ci			return ret;
16462306a36Sopenharmony_ci	}
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	if (falcon->func->select) {
16762306a36Sopenharmony_ci		ret = falcon->func->select(falcon);
16862306a36Sopenharmony_ci		if (ret)
16962306a36Sopenharmony_ci			return ret;
17062306a36Sopenharmony_ci	}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	if (falcon->func->reset_pmc)
17362306a36Sopenharmony_ci		nvkm_mc_enable(device, falcon->owner->type, falcon->owner->inst);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	ret = falcon->func->reset_wait_mem_scrubbing(falcon);
17662306a36Sopenharmony_ci	if (ret)
17762306a36Sopenharmony_ci		return ret;
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	nvkm_falcon_wr32(falcon, 0x084, nvkm_rd32(device, 0x000000));
18062306a36Sopenharmony_ci	return 0;
18162306a36Sopenharmony_ci}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ciint
18462306a36Sopenharmony_cigm200_flcn_disable(struct nvkm_falcon *falcon)
18562306a36Sopenharmony_ci{
18662306a36Sopenharmony_ci	struct nvkm_device *device = falcon->owner->device;
18762306a36Sopenharmony_ci	int ret;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	if (falcon->func->select) {
19062306a36Sopenharmony_ci		ret = falcon->func->select(falcon);
19162306a36Sopenharmony_ci		if (ret)
19262306a36Sopenharmony_ci			return ret;
19362306a36Sopenharmony_ci	}
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	nvkm_falcon_mask(falcon, 0x048, 0x00000003, 0x00000000);
19662306a36Sopenharmony_ci	nvkm_falcon_wr32(falcon, 0x014, 0xffffffff);
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	if (falcon->func->reset_pmc) {
19962306a36Sopenharmony_ci		if (falcon->func->reset_prep) {
20062306a36Sopenharmony_ci			ret = falcon->func->reset_prep(falcon);
20162306a36Sopenharmony_ci			if (ret)
20262306a36Sopenharmony_ci				return ret;
20362306a36Sopenharmony_ci		}
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci		nvkm_mc_disable(device, falcon->owner->type, falcon->owner->inst);
20662306a36Sopenharmony_ci	}
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci	if (falcon->func->reset_eng) {
20962306a36Sopenharmony_ci		ret = falcon->func->reset_eng(falcon);
21062306a36Sopenharmony_ci		if (ret)
21162306a36Sopenharmony_ci			return ret;
21262306a36Sopenharmony_ci	}
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	return 0;
21562306a36Sopenharmony_ci}
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ciint
21862306a36Sopenharmony_cigm200_flcn_fw_boot(struct nvkm_falcon_fw *fw, u32 *pmbox0, u32 *pmbox1, u32 mbox0_ok, u32 irqsclr)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	struct nvkm_falcon *falcon = fw->falcon;
22162306a36Sopenharmony_ci	u32 mbox0, mbox1;
22262306a36Sopenharmony_ci	int ret = 0;
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	nvkm_falcon_wr32(falcon, 0x040, pmbox0 ? *pmbox0 : 0xcafebeef);
22562306a36Sopenharmony_ci	if (pmbox1)
22662306a36Sopenharmony_ci		nvkm_falcon_wr32(falcon, 0x044, *pmbox1);
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	nvkm_falcon_wr32(falcon, 0x104, fw->boot_addr);
22962306a36Sopenharmony_ci	nvkm_falcon_wr32(falcon, 0x100, 0x00000002);
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	if (nvkm_msec(falcon->owner->device, 2000,
23262306a36Sopenharmony_ci		if (nvkm_falcon_rd32(falcon, 0x100) & 0x00000010)
23362306a36Sopenharmony_ci			break;
23462306a36Sopenharmony_ci	) < 0)
23562306a36Sopenharmony_ci		ret = -ETIMEDOUT;
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	mbox0 = nvkm_falcon_rd32(falcon, 0x040);
23862306a36Sopenharmony_ci	mbox1 = nvkm_falcon_rd32(falcon, 0x044);
23962306a36Sopenharmony_ci	if (FLCN_ERRON(falcon, ret || mbox0 != mbox0_ok, "mbox %08x %08x", mbox0, mbox1))
24062306a36Sopenharmony_ci		ret = ret ?: -EIO;
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci	if (irqsclr)
24362306a36Sopenharmony_ci		nvkm_falcon_mask(falcon, 0x004, 0xffffffff, irqsclr);
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	return ret;
24662306a36Sopenharmony_ci}
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ciint
24962306a36Sopenharmony_cigm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
25062306a36Sopenharmony_ci{
25162306a36Sopenharmony_ci	struct nvkm_falcon *falcon = fw->falcon;
25262306a36Sopenharmony_ci	int target, ret;
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci	if (fw->inst) {
25562306a36Sopenharmony_ci		nvkm_falcon_mask(falcon, 0x048, 0x00000001, 0x00000001);
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci		switch (nvkm_memory_target(fw->inst)) {
25862306a36Sopenharmony_ci		case NVKM_MEM_TARGET_VRAM: target = 0; break;
25962306a36Sopenharmony_ci		case NVKM_MEM_TARGET_HOST: target = 2; break;
26062306a36Sopenharmony_ci		case NVKM_MEM_TARGET_NCOH: target = 3; break;
26162306a36Sopenharmony_ci		default:
26262306a36Sopenharmony_ci			WARN_ON(1);
26362306a36Sopenharmony_ci			return -EINVAL;
26462306a36Sopenharmony_ci		}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci		falcon->func->bind_inst(falcon, target, nvkm_memory_addr(fw->inst));
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci		if (nvkm_msec(falcon->owner->device, 10,
26962306a36Sopenharmony_ci			if (falcon->func->bind_stat(falcon, falcon->func->bind_intr) == 5)
27062306a36Sopenharmony_ci				break;
27162306a36Sopenharmony_ci		) < 0)
27262306a36Sopenharmony_ci			return -ETIMEDOUT;
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci		nvkm_falcon_mask(falcon, 0x004, 0x00000008, 0x00000008);
27562306a36Sopenharmony_ci		nvkm_falcon_mask(falcon, 0x058, 0x00000002, 0x00000002);
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci		if (nvkm_msec(falcon->owner->device, 10,
27862306a36Sopenharmony_ci			if (falcon->func->bind_stat(falcon, false) == 0)
27962306a36Sopenharmony_ci				break;
28062306a36Sopenharmony_ci		) < 0)
28162306a36Sopenharmony_ci			return -ETIMEDOUT;
28262306a36Sopenharmony_ci	} else {
28362306a36Sopenharmony_ci		nvkm_falcon_mask(falcon, 0x624, 0x00000080, 0x00000080);
28462306a36Sopenharmony_ci		nvkm_falcon_wr32(falcon, 0x10c, 0x00000000);
28562306a36Sopenharmony_ci	}
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	if (fw->boot) {
28862306a36Sopenharmony_ci		switch (nvkm_memory_target(&fw->fw.mem.memory)) {
28962306a36Sopenharmony_ci		case NVKM_MEM_TARGET_VRAM: target = 4; break;
29062306a36Sopenharmony_ci		case NVKM_MEM_TARGET_HOST: target = 5; break;
29162306a36Sopenharmony_ci		case NVKM_MEM_TARGET_NCOH: target = 6; break;
29262306a36Sopenharmony_ci		default:
29362306a36Sopenharmony_ci			WARN_ON(1);
29462306a36Sopenharmony_ci			return -EINVAL;
29562306a36Sopenharmony_ci		}
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci		ret = nvkm_falcon_pio_wr(falcon, fw->boot, 0, 0,
29862306a36Sopenharmony_ci					 IMEM, falcon->code.limit - fw->boot_size, fw->boot_size,
29962306a36Sopenharmony_ci					 fw->boot_addr >> 8, false);
30062306a36Sopenharmony_ci		if (ret)
30162306a36Sopenharmony_ci			return ret;
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci		return fw->func->load_bld(fw);
30462306a36Sopenharmony_ci	}
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	ret = nvkm_falcon_pio_wr(falcon, fw->fw.img + fw->nmem_base_img, fw->nmem_base_img, 0,
30762306a36Sopenharmony_ci				 IMEM, fw->nmem_base, fw->nmem_size, fw->nmem_base >> 8, false);
30862306a36Sopenharmony_ci	if (ret)
30962306a36Sopenharmony_ci		return ret;
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	ret = nvkm_falcon_pio_wr(falcon, fw->fw.img + fw->imem_base_img, fw->imem_base_img, 0,
31262306a36Sopenharmony_ci				 IMEM, fw->imem_base, fw->imem_size, fw->imem_base >> 8, true);
31362306a36Sopenharmony_ci	if (ret)
31462306a36Sopenharmony_ci		return ret;
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	ret = nvkm_falcon_pio_wr(falcon, fw->fw.img + fw->dmem_base_img, fw->dmem_base_img, 0,
31762306a36Sopenharmony_ci				 DMEM, fw->dmem_base, fw->dmem_size, 0, false);
31862306a36Sopenharmony_ci	if (ret)
31962306a36Sopenharmony_ci		return ret;
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	return 0;
32262306a36Sopenharmony_ci}
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ciint
32562306a36Sopenharmony_cigm200_flcn_fw_reset(struct nvkm_falcon_fw *fw)
32662306a36Sopenharmony_ci{
32762306a36Sopenharmony_ci	return nvkm_falcon_reset(fw->falcon);
32862306a36Sopenharmony_ci}
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ciint
33162306a36Sopenharmony_cigm200_flcn_fw_signature(struct nvkm_falcon_fw *fw, u32 *sig_base_src)
33262306a36Sopenharmony_ci{
33362306a36Sopenharmony_ci	struct nvkm_falcon *falcon = fw->falcon;
33462306a36Sopenharmony_ci	u32 addr = falcon->func->debug;
33562306a36Sopenharmony_ci	int ret = 0;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	if (addr) {
33862306a36Sopenharmony_ci		ret = nvkm_falcon_enable(falcon);
33962306a36Sopenharmony_ci		if (ret)
34062306a36Sopenharmony_ci			return ret;
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci		if (nvkm_falcon_rd32(falcon, addr) & 0x00100000) {
34362306a36Sopenharmony_ci			*sig_base_src = fw->sig_base_dbg;
34462306a36Sopenharmony_ci			return 1;
34562306a36Sopenharmony_ci		}
34662306a36Sopenharmony_ci	}
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	return ret;
34962306a36Sopenharmony_ci}
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ciconst struct nvkm_falcon_fw_func
35262306a36Sopenharmony_cigm200_flcn_fw = {
35362306a36Sopenharmony_ci	.signature = gm200_flcn_fw_signature,
35462306a36Sopenharmony_ci	.reset = gm200_flcn_fw_reset,
35562306a36Sopenharmony_ci	.load = gm200_flcn_fw_load,
35662306a36Sopenharmony_ci	.boot = gm200_flcn_fw_boot,
35762306a36Sopenharmony_ci};
358