11// SPDX-License-Identifier: GPL-2.0-only
22/*
3- * Copyright (c) 2015-2021 , NVIDIA Corporation.
3+ * Copyright (c) 2015-2022 , NVIDIA Corporation.
44 */
55
66#include <linux/clk.h>
77#include <linux/delay.h>
88#include <linux/dma-mapping.h>
99#include <linux/host1x.h>
1010#include <linux/iommu.h>
11+ #include <linux/iopoll.h>
1112#include <linux/module.h>
1213#include <linux/of.h>
1314#include <linux/of_device.h>
1617#include <linux/pm_runtime.h>
1718#include <linux/reset.h>
1819
19- #include <soc/tegra/pmc .h>
20+ #include <soc/tegra/mc .h>
2021
2122#include "drm.h"
2223#include "falcon.h"
24+ #include "riscv.h"
2325#include "vic.h"
2426
27+ #define NVDEC_FALCON_DEBUGINFO 0x1094
2528#define NVDEC_TFBIF_TRANSCFG 0x2c44
2629
2730struct nvdec_config {
2831 const char * firmware ;
2932 unsigned int version ;
3033 bool supports_sid ;
34+ bool has_riscv ;
35+ bool has_extra_clocks ;
3136};
3237
3338struct nvdec {
@@ -37,10 +42,16 @@ struct nvdec {
3742 struct tegra_drm_client client ;
3843 struct host1x_channel * channel ;
3944 struct device * dev ;
40- struct clk * clk ;
45+ struct clk_bulk_data clks [3 ];
46+ unsigned int num_clks ;
47+ struct reset_control * reset ;
4148
4249 /* Platform configuration */
4350 const struct nvdec_config * config ;
51+
52+ /* RISC-V specific data */
53+ struct tegra_drm_riscv riscv ;
54+ phys_addr_t carveout_base ;
4455};
4556
4657static inline struct nvdec * to_nvdec (struct tegra_drm_client * client )
@@ -54,7 +65,7 @@ static inline void nvdec_writel(struct nvdec *nvdec, u32 value,
5465 writel (value , nvdec -> regs + offset );
5566}
5667
57- static int nvdec_boot (struct nvdec * nvdec )
68+ static int nvdec_boot_falcon (struct nvdec * nvdec )
5869{
5970#ifdef CONFIG_IOMMU_API
6071 struct iommu_fwspec * spec = dev_iommu_fwspec_get (nvdec -> dev );
@@ -90,6 +101,64 @@ static int nvdec_boot(struct nvdec *nvdec)
90101 return 0 ;
91102}
92103
104+ static int nvdec_wait_debuginfo (struct nvdec * nvdec , const char * phase )
105+ {
106+ int err ;
107+ u32 val ;
108+
109+ err = readl_poll_timeout (nvdec -> regs + NVDEC_FALCON_DEBUGINFO , val , val == 0x0 , 10 , 100000 );
110+ if (err ) {
111+ dev_err (nvdec -> dev , "failed to boot %s, debuginfo=0x%x\n" , phase , val );
112+ return err ;
113+ }
114+
115+ return 0 ;
116+ }
117+
118+ static int nvdec_boot_riscv (struct nvdec * nvdec )
119+ {
120+ int err ;
121+
122+ err = reset_control_acquire (nvdec -> reset );
123+ if (err )
124+ return err ;
125+
126+ nvdec_writel (nvdec , 0xabcd1234 , NVDEC_FALCON_DEBUGINFO );
127+
128+ err = tegra_drm_riscv_boot_bootrom (& nvdec -> riscv , nvdec -> carveout_base , 1 ,
129+ & nvdec -> riscv .bl_desc );
130+ if (err ) {
131+ dev_err (nvdec -> dev , "failed to execute bootloader\n" );
132+ goto release_reset ;
133+ }
134+
135+ err = nvdec_wait_debuginfo (nvdec , "bootloader" );
136+ if (err )
137+ goto release_reset ;
138+
139+ err = reset_control_reset (nvdec -> reset );
140+ if (err )
141+ goto release_reset ;
142+
143+ nvdec_writel (nvdec , 0xabcd1234 , NVDEC_FALCON_DEBUGINFO );
144+
145+ err = tegra_drm_riscv_boot_bootrom (& nvdec -> riscv , nvdec -> carveout_base , 1 ,
146+ & nvdec -> riscv .os_desc );
147+ if (err ) {
148+ dev_err (nvdec -> dev , "failed to execute firmware\n" );
149+ goto release_reset ;
150+ }
151+
152+ err = nvdec_wait_debuginfo (nvdec , "firmware" );
153+ if (err )
154+ goto release_reset ;
155+
156+ release_reset :
157+ reset_control_release (nvdec -> reset );
158+
159+ return err ;
160+ }
161+
93162static int nvdec_init (struct host1x_client * client )
94163{
95164 struct tegra_drm_client * drm = host1x_to_drm_client (client );
@@ -189,7 +258,7 @@ static const struct host1x_client_ops nvdec_client_ops = {
189258 .exit = nvdec_exit ,
190259};
191260
192- static int nvdec_load_firmware (struct nvdec * nvdec )
261+ static int nvdec_load_falcon_firmware (struct nvdec * nvdec )
193262{
194263 struct host1x_client * client = & nvdec -> client .base ;
195264 struct tegra_drm * tegra = nvdec -> client .drm ;
@@ -252,30 +321,35 @@ static int nvdec_load_firmware(struct nvdec *nvdec)
252321 return err ;
253322}
254323
255-
256324static __maybe_unused int nvdec_runtime_resume (struct device * dev )
257325{
258326 struct nvdec * nvdec = dev_get_drvdata (dev );
259327 int err ;
260328
261- err = clk_prepare_enable (nvdec -> clk );
329+ err = clk_bulk_prepare_enable (nvdec -> num_clks , nvdec -> clks );
262330 if (err < 0 )
263331 return err ;
264332
265333 usleep_range (10 , 20 );
266334
267- err = nvdec_load_firmware (nvdec );
268- if (err < 0 )
269- goto disable ;
335+ if (nvdec -> config -> has_riscv ) {
336+ err = nvdec_boot_riscv (nvdec );
337+ if (err < 0 )
338+ goto disable ;
339+ } else {
340+ err = nvdec_load_falcon_firmware (nvdec );
341+ if (err < 0 )
342+ goto disable ;
270343
271- err = nvdec_boot (nvdec );
272- if (err < 0 )
273- goto disable ;
344+ err = nvdec_boot_falcon (nvdec );
345+ if (err < 0 )
346+ goto disable ;
347+ }
274348
275349 return 0 ;
276350
277351disable :
278- clk_disable_unprepare (nvdec -> clk );
352+ clk_bulk_disable_unprepare (nvdec -> num_clks , nvdec -> clks );
279353 return err ;
280354}
281355
@@ -285,7 +359,7 @@ static __maybe_unused int nvdec_runtime_suspend(struct device *dev)
285359
286360 host1x_channel_stop (nvdec -> channel );
287361
288- clk_disable_unprepare (nvdec -> clk );
362+ clk_bulk_disable_unprepare (nvdec -> num_clks , nvdec -> clks );
289363
290364 return 0 ;
291365}
@@ -346,10 +420,18 @@ static const struct nvdec_config nvdec_t194_config = {
346420 .supports_sid = true,
347421};
348422
423+ static const struct nvdec_config nvdec_t234_config = {
424+ .version = 0x23 ,
425+ .supports_sid = true,
426+ .has_riscv = true,
427+ .has_extra_clocks = true,
428+ };
429+
349430static const struct of_device_id tegra_nvdec_of_match [] = {
350431 { .compatible = "nvidia,tegra210-nvdec" , .data = & nvdec_t210_config },
351432 { .compatible = "nvidia,tegra186-nvdec" , .data = & nvdec_t186_config },
352433 { .compatible = "nvidia,tegra194-nvdec" , .data = & nvdec_t194_config },
434+ { .compatible = "nvidia,tegra234-nvdec" , .data = & nvdec_t234_config },
353435 { },
354436};
355437MODULE_DEVICE_TABLE (of , tegra_nvdec_of_match );
@@ -383,13 +465,22 @@ static int nvdec_probe(struct platform_device *pdev)
383465 if (IS_ERR (nvdec -> regs ))
384466 return PTR_ERR (nvdec -> regs );
385467
386- nvdec -> clk = devm_clk_get (dev , NULL );
387- if (IS_ERR (nvdec -> clk )) {
388- dev_err (& pdev -> dev , "failed to get clock\n" );
389- return PTR_ERR (nvdec -> clk );
468+ nvdec -> clks [0 ].id = "nvdec" ;
469+ nvdec -> num_clks = 1 ;
470+
471+ if (nvdec -> config -> has_extra_clocks ) {
472+ nvdec -> num_clks = 3 ;
473+ nvdec -> clks [1 ].id = "fuse" ;
474+ nvdec -> clks [2 ].id = "tsec_pka" ;
390475 }
391476
392- err = clk_set_rate (nvdec -> clk , ULONG_MAX );
477+ err = devm_clk_bulk_get (dev , nvdec -> num_clks , nvdec -> clks );
478+ if (err ) {
479+ dev_err (& pdev -> dev , "failed to get clock(s)\n" );
480+ return err ;
481+ }
482+
483+ err = clk_set_rate (nvdec -> clks [0 ].clk , ULONG_MAX );
393484 if (err < 0 ) {
394485 dev_err (& pdev -> dev , "failed to set clock rate\n" );
395486 return err ;
@@ -399,12 +490,42 @@ static int nvdec_probe(struct platform_device *pdev)
399490 if (err < 0 )
400491 host_class = HOST1X_CLASS_NVDEC ;
401492
402- nvdec -> falcon . dev = dev ;
403- nvdec -> falcon . regs = nvdec -> regs ;
493+ if ( nvdec -> config -> has_riscv ) {
494+ struct tegra_mc * mc ;
404495
405- err = falcon_init (& nvdec -> falcon );
406- if (err < 0 )
407- return err ;
496+ mc = devm_tegra_memory_controller_get (dev );
497+ if (IS_ERR (mc )) {
498+ dev_err_probe (dev , PTR_ERR (mc ),
499+ "failed to get memory controller handle\n" );
500+ return PTR_ERR (mc );
501+ }
502+
503+ err = tegra_mc_get_carveout_info (mc , 1 , & nvdec -> carveout_base , NULL );
504+ if (err ) {
505+ dev_err (dev , "failed to get carveout info: %d\n" , err );
506+ return err ;
507+ }
508+
509+ nvdec -> reset = devm_reset_control_get_exclusive_released (dev , "nvdec" );
510+ if (IS_ERR (nvdec -> reset )) {
511+ dev_err_probe (dev , PTR_ERR (nvdec -> reset ), "failed to get reset\n" );
512+ return PTR_ERR (nvdec -> reset );
513+ }
514+
515+ nvdec -> riscv .dev = dev ;
516+ nvdec -> riscv .regs = nvdec -> regs ;
517+
518+ err = tegra_drm_riscv_read_descriptors (& nvdec -> riscv );
519+ if (err < 0 )
520+ return err ;
521+ } else {
522+ nvdec -> falcon .dev = dev ;
523+ nvdec -> falcon .regs = nvdec -> regs ;
524+
525+ err = falcon_init (& nvdec -> falcon );
526+ if (err < 0 )
527+ return err ;
528+ }
408529
409530 platform_set_drvdata (pdev , nvdec );
410531
0 commit comments