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 ;
3135 bool has_extra_clocks ;
3236};
3337
@@ -40,9 +44,14 @@ struct nvdec {
4044 struct device * dev ;
4145 struct clk_bulk_data clks [3 ];
4246 unsigned int num_clks ;
47+ struct reset_control * reset ;
4348
4449 /* Platform configuration */
4550 const struct nvdec_config * config ;
51+
52+ /* RISC-V specific data */
53+ struct tegra_drm_riscv riscv ;
54+ phys_addr_t carveout_base ;
4655};
4756
4857static inline struct nvdec * to_nvdec (struct tegra_drm_client * client )
@@ -56,7 +65,7 @@ static inline void nvdec_writel(struct nvdec *nvdec, u32 value,
5665 writel (value , nvdec -> regs + offset );
5766}
5867
59- static int nvdec_boot (struct nvdec * nvdec )
68+ static int nvdec_boot_falcon (struct nvdec * nvdec )
6069{
6170#ifdef CONFIG_IOMMU_API
6271 struct iommu_fwspec * spec = dev_iommu_fwspec_get (nvdec -> dev );
@@ -92,6 +101,64 @@ static int nvdec_boot(struct nvdec *nvdec)
92101 return 0 ;
93102}
94103
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+
95162static int nvdec_init (struct host1x_client * client )
96163{
97164 struct tegra_drm_client * drm = host1x_to_drm_client (client );
@@ -191,7 +258,7 @@ static const struct host1x_client_ops nvdec_client_ops = {
191258 .exit = nvdec_exit ,
192259};
193260
194- static int nvdec_load_firmware (struct nvdec * nvdec )
261+ static int nvdec_load_falcon_firmware (struct nvdec * nvdec )
195262{
196263 struct host1x_client * client = & nvdec -> client .base ;
197264 struct tegra_drm * tegra = nvdec -> client .drm ;
@@ -254,7 +321,6 @@ static int nvdec_load_firmware(struct nvdec *nvdec)
254321 return err ;
255322}
256323
257-
258324static __maybe_unused int nvdec_runtime_resume (struct device * dev )
259325{
260326 struct nvdec * nvdec = dev_get_drvdata (dev );
@@ -266,13 +332,19 @@ static __maybe_unused int nvdec_runtime_resume(struct device *dev)
266332
267333 usleep_range (10 , 20 );
268334
269- err = nvdec_load_firmware (nvdec );
270- if (err < 0 )
271- 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 ;
272343
273- err = nvdec_boot (nvdec );
274- if (err < 0 )
275- goto disable ;
344+ err = nvdec_boot_falcon (nvdec );
345+ if (err < 0 )
346+ goto disable ;
347+ }
276348
277349 return 0 ;
278350
@@ -348,10 +420,18 @@ static const struct nvdec_config nvdec_t194_config = {
348420 .supports_sid = true,
349421};
350422
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+
351430static const struct of_device_id tegra_nvdec_of_match [] = {
352431 { .compatible = "nvidia,tegra210-nvdec" , .data = & nvdec_t210_config },
353432 { .compatible = "nvidia,tegra186-nvdec" , .data = & nvdec_t186_config },
354433 { .compatible = "nvidia,tegra194-nvdec" , .data = & nvdec_t194_config },
434+ { .compatible = "nvidia,tegra234-nvdec" , .data = & nvdec_t234_config },
355435 { },
356436};
357437MODULE_DEVICE_TABLE (of , tegra_nvdec_of_match );
@@ -410,12 +490,42 @@ static int nvdec_probe(struct platform_device *pdev)
410490 if (err < 0 )
411491 host_class = HOST1X_CLASS_NVDEC ;
412492
413- nvdec -> falcon . dev = dev ;
414- nvdec -> falcon . regs = nvdec -> regs ;
493+ if ( nvdec -> config -> has_riscv ) {
494+ struct tegra_mc * mc ;
415495
416- err = falcon_init (& nvdec -> falcon );
417- if (err < 0 )
418- 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+ }
419529
420530 platform_set_drvdata (pdev , nvdec );
421531
0 commit comments