116307b5dSAlexandre Courbot /*
216307b5dSAlexandre Courbot  * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
316307b5dSAlexandre Courbot  *
416307b5dSAlexandre Courbot  * Permission is hereby granted, free of charge, to any person obtaining a
516307b5dSAlexandre Courbot  * copy of this software and associated documentation files (the "Software"),
616307b5dSAlexandre Courbot  * to deal in the Software without restriction, including without limitation
716307b5dSAlexandre Courbot  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
816307b5dSAlexandre Courbot  * and/or sell copies of the Software, and to permit persons to whom the
916307b5dSAlexandre Courbot  * Software is furnished to do so, subject to the following conditions:
1016307b5dSAlexandre Courbot  *
1116307b5dSAlexandre Courbot  * The above copyright notice and this permission notice shall be included in
1216307b5dSAlexandre Courbot  * all copies or substantial portions of the Software.
1316307b5dSAlexandre Courbot  *
1416307b5dSAlexandre Courbot  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1516307b5dSAlexandre Courbot  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1616307b5dSAlexandre Courbot  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1716307b5dSAlexandre Courbot  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1816307b5dSAlexandre Courbot  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1916307b5dSAlexandre Courbot  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2016307b5dSAlexandre Courbot  * DEALINGS IN THE SOFTWARE.
2116307b5dSAlexandre Courbot  */
2216307b5dSAlexandre Courbot #include "priv.h"
2316307b5dSAlexandre Courbot 
2498a34d99SBen Skeggs #include <core/firmware.h>
2504574273SBen Skeggs #include <subdev/top.h>
2616307b5dSAlexandre Courbot #include <engine/falcon.h>
2716307b5dSAlexandre Courbot 
2816307b5dSAlexandre Courbot static int
2916307b5dSAlexandre Courbot nvkm_nvdec_oneinit(struct nvkm_engine *engine)
3016307b5dSAlexandre Courbot {
3116307b5dSAlexandre Courbot 	struct nvkm_nvdec *nvdec = nvkm_nvdec(engine);
3204574273SBen Skeggs 	struct nvkm_subdev *subdev = &nvdec->engine.subdev;
3304574273SBen Skeggs 
3404574273SBen Skeggs 	nvdec->addr = nvkm_top_addr(subdev->device, subdev->index);
3504574273SBen Skeggs 	if (!nvdec->addr)
3604574273SBen Skeggs 		return -EINVAL;
3704574273SBen Skeggs 
3804574273SBen Skeggs 	/*XXX: fix naming of this when adding support for multiple-NVDEC */
3904574273SBen Skeggs 	return nvkm_falcon_v1_new(subdev, "NVDEC", nvdec->addr,
4016307b5dSAlexandre Courbot 				  &nvdec->falcon);
4116307b5dSAlexandre Courbot }
4216307b5dSAlexandre Courbot 
4316307b5dSAlexandre Courbot static void *
4416307b5dSAlexandre Courbot nvkm_nvdec_dtor(struct nvkm_engine *engine)
4516307b5dSAlexandre Courbot {
4616307b5dSAlexandre Courbot 	struct nvkm_nvdec *nvdec = nvkm_nvdec(engine);
4716307b5dSAlexandre Courbot 	nvkm_falcon_del(&nvdec->falcon);
4816307b5dSAlexandre Courbot 	return nvdec;
4916307b5dSAlexandre Courbot }
5016307b5dSAlexandre Courbot 
5116307b5dSAlexandre Courbot static const struct nvkm_engine_func
5216307b5dSAlexandre Courbot nvkm_nvdec = {
5316307b5dSAlexandre Courbot 	.dtor = nvkm_nvdec_dtor,
5416307b5dSAlexandre Courbot 	.oneinit = nvkm_nvdec_oneinit,
5516307b5dSAlexandre Courbot };
5616307b5dSAlexandre Courbot 
5716307b5dSAlexandre Courbot int
5898a34d99SBen Skeggs nvkm_nvdec_new_(const struct nvkm_nvdec_fwif *fwif, struct nvkm_device *device,
5998a34d99SBen Skeggs 		int index, struct nvkm_nvdec **pnvdec)
6016307b5dSAlexandre Courbot {
6116307b5dSAlexandre Courbot 	struct nvkm_nvdec *nvdec;
6298a34d99SBen Skeggs 	int ret;
6316307b5dSAlexandre Courbot 
6416307b5dSAlexandre Courbot 	if (!(nvdec = *pnvdec = kzalloc(sizeof(*nvdec), GFP_KERNEL)))
6516307b5dSAlexandre Courbot 		return -ENOMEM;
6616307b5dSAlexandre Courbot 
6798a34d99SBen Skeggs 	ret = nvkm_engine_ctor(&nvkm_nvdec, device, index, true,
6816307b5dSAlexandre Courbot 			       &nvdec->engine);
6998a34d99SBen Skeggs 	if (ret)
7098a34d99SBen Skeggs 		return ret;
7198a34d99SBen Skeggs 
7298a34d99SBen Skeggs 	fwif = nvkm_firmware_load(&nvdec->engine.subdev, fwif, "Nvdec", nvdec);
7398a34d99SBen Skeggs 	if (IS_ERR(fwif))
7498a34d99SBen Skeggs 		return -ENODEV;
7598a34d99SBen Skeggs 
7698a34d99SBen Skeggs 	nvdec->func = fwif->func;
7798a34d99SBen Skeggs 	return 0;
7816307b5dSAlexandre Courbot };
79