brintos

brintos / linux-shallow public Read only

0
0
Text · 4.4 KiB · f2c60da Raw
165 lines · c
1/*2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER20 * DEALINGS IN THE SOFTWARE.21 */22#include "priv.h"23 24#include <core/firmware.h>25#include <subdev/mc.h>26#include <subdev/timer.h>27 28#include <nvfw/sec2.h>29 30static int31nvkm_sec2_finimsg(void *priv, struct nvfw_falcon_msg *hdr)32{33	struct nvkm_sec2 *sec2 = priv;34 35	atomic_set(&sec2->running, 0);36	return 0;37}38 39static int40nvkm_sec2_fini(struct nvkm_engine *engine, bool suspend)41{42	struct nvkm_sec2 *sec2 = nvkm_sec2(engine);43	struct nvkm_subdev *subdev = &sec2->engine.subdev;44	struct nvkm_falcon *falcon = &sec2->falcon;45	struct nvkm_falcon_cmdq *cmdq = sec2->cmdq;46	struct nvfw_falcon_cmd cmd = {47		.unit_id = sec2->func->unit_unload,48		.size = sizeof(cmd),49	};50	int ret;51 52	if (!subdev->use.enabled)53		return 0;54 55	if (atomic_read(&sec2->initmsg) == 1) {56		ret = nvkm_falcon_cmdq_send(cmdq, &cmd, nvkm_sec2_finimsg, sec2,57					    msecs_to_jiffies(1000));58		WARN_ON(ret);59 60		nvkm_msec(subdev->device, 2000,61			if (nvkm_falcon_rd32(falcon, 0x100) & 0x00000010)62				break;63		);64	}65 66	nvkm_inth_block(&subdev->inth);67 68	nvkm_falcon_cmdq_fini(cmdq);69	falcon->func->disable(falcon);70	nvkm_falcon_put(falcon, subdev);71	return 0;72}73 74static int75nvkm_sec2_init(struct nvkm_engine *engine)76{77	struct nvkm_sec2 *sec2 = nvkm_sec2(engine);78	struct nvkm_subdev *subdev = &sec2->engine.subdev;79	struct nvkm_falcon *falcon = &sec2->falcon;80	int ret;81 82	ret = nvkm_falcon_get(falcon, subdev);83	if (ret)84		return ret;85 86	nvkm_falcon_wr32(falcon, 0x014, 0xffffffff);87	atomic_set(&sec2->initmsg, 0);88	atomic_set(&sec2->running, 1);89	nvkm_inth_allow(&subdev->inth);90 91	nvkm_falcon_start(falcon);92	return 0;93}94 95static int96nvkm_sec2_oneinit(struct nvkm_engine *engine)97{98	struct nvkm_sec2 *sec2 = nvkm_sec2(engine);99	struct nvkm_subdev *subdev = &sec2->engine.subdev;100	struct nvkm_intr *intr = &sec2->engine.subdev.device->mc->intr;101	enum nvkm_intr_type type = NVKM_INTR_SUBDEV;102 103	if (sec2->func->intr_vector) {104		intr = sec2->func->intr_vector(sec2, &type);105		if (IS_ERR(intr))106			return PTR_ERR(intr);107	}108 109	return nvkm_inth_add(intr, type, NVKM_INTR_PRIO_NORMAL, subdev, sec2->func->intr,110			     &subdev->inth);111}112 113static void *114nvkm_sec2_dtor(struct nvkm_engine *engine)115{116	struct nvkm_sec2 *sec2 = nvkm_sec2(engine);117 118	nvkm_falcon_msgq_del(&sec2->msgq);119	nvkm_falcon_cmdq_del(&sec2->cmdq);120	nvkm_falcon_qmgr_del(&sec2->qmgr);121	nvkm_falcon_dtor(&sec2->falcon);122	return sec2;123}124 125static const struct nvkm_engine_func126nvkm_sec2 = {127	.dtor = nvkm_sec2_dtor,128	.oneinit = nvkm_sec2_oneinit,129	.init = nvkm_sec2_init,130	.fini = nvkm_sec2_fini,131};132 133int134nvkm_sec2_new_(const struct nvkm_sec2_fwif *fwif, struct nvkm_device *device,135	       enum nvkm_subdev_type type, int inst, u32 addr, struct nvkm_sec2 **psec2)136{137	struct nvkm_sec2 *sec2;138	int ret;139 140	if (!(sec2 = *psec2 = kzalloc(sizeof(*sec2), GFP_KERNEL)))141		return -ENOMEM;142 143	ret = nvkm_engine_ctor(&nvkm_sec2, device, type, inst, true, &sec2->engine);144	if (ret)145		return ret;146 147	fwif = nvkm_firmware_load(&sec2->engine.subdev, fwif, "Sec2", sec2);148	if (IS_ERR(fwif))149		return PTR_ERR(fwif);150 151	sec2->func = fwif->func;152 153	ret = nvkm_falcon_ctor(sec2->func->flcn, &sec2->engine.subdev,154			       sec2->engine.subdev.name, addr, &sec2->falcon);155	if (ret)156		return ret;157 158	if ((ret = nvkm_falcon_qmgr_new(&sec2->falcon, &sec2->qmgr)) ||159	    (ret = nvkm_falcon_cmdq_new(sec2->qmgr, "cmdq", &sec2->cmdq)) ||160	    (ret = nvkm_falcon_msgq_new(sec2->qmgr, "msgq", &sec2->msgq)))161		return ret;162 163	return 0;164};165