Skip to content

Commit 02339a8

Browse files
committed
Merge tag 'drm/tegra/for-6.2-rc1' of https://gitlab.freedesktop.org/drm/tegra into drm-next
drm/tegra: Changes for v6.2-rc1 This contains a bunch of cleanups across the board as well as support for the NVDEC hardware found on the Tegra234 SoC. Signed-off-by: Dave Airlie <[email protected]> From: Thierry Reding <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 795bd9b + 08fef75 commit 02339a8

File tree

18 files changed

+362
-76
lines changed

18 files changed

+362
-76
lines changed

drivers/gpu/drm/tegra/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ tegra-drm-y := \
2424
gr3d.o \
2525
falcon.o \
2626
vic.o \
27-
nvdec.o
27+
nvdec.o \
28+
riscv.o
2829

2930
tegra-drm-y += trace.o
3031

drivers/gpu/drm/tegra/dc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3205,8 +3205,10 @@ static int tegra_dc_probe(struct platform_device *pdev)
32053205
usleep_range(2000, 4000);
32063206

32073207
err = reset_control_assert(dc->rst);
3208-
if (err < 0)
3208+
if (err < 0) {
3209+
clk_disable_unprepare(dc->clk);
32093210
return err;
3211+
}
32103212

32113213
usleep_range(2000, 4000);
32123214

drivers/gpu/drm/tegra/drm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,7 @@ static const struct of_device_id host1x_drm_subdevs[] = {
13861386
{ .compatible = "nvidia,tegra194-vic", },
13871387
{ .compatible = "nvidia,tegra194-nvdec", },
13881388
{ .compatible = "nvidia,tegra234-vic", },
1389+
{ .compatible = "nvidia,tegra234-nvdec", },
13891390
{ /* sentinel */ }
13901391
};
13911392

drivers/gpu/drm/tegra/hdmi.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -867,14 +867,7 @@ static int tegra_hdmi_reconfigure_audio(struct tegra_hdmi *hdmi)
867867

868868
static bool tegra_output_is_hdmi(struct tegra_output *output)
869869
{
870-
struct edid *edid;
871-
872-
if (!output->connector.edid_blob_ptr)
873-
return false;
874-
875-
edid = (struct edid *)output->connector.edid_blob_ptr->data;
876-
877-
return drm_detect_hdmi_monitor(edid);
870+
return output->connector.display_info.is_hdmi;
878871
}
879872

880873
static enum drm_connector_status

drivers/gpu/drm/tegra/nvdec.c

Lines changed: 146 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
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>
@@ -16,18 +17,22 @@
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

2730
struct 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

3338
struct 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

4657
static 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+
93162
static 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-
256324
static __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

277351
disable:
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+
349430
static 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
};
355437
MODULE_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

drivers/gpu/drm/tegra/output.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,11 @@ int tegra_output_probe(struct tegra_output *output)
133133
}
134134
}
135135

136-
output->hpd_gpio = devm_gpiod_get_from_of_node(output->dev,
137-
output->of_node,
138-
"nvidia,hpd-gpio", 0,
139-
GPIOD_IN,
140-
"HDMI hotplug detect");
136+
output->hpd_gpio = devm_fwnode_gpiod_get(output->dev,
137+
of_fwnode_handle(output->of_node),
138+
"nvidia,hpd",
139+
GPIOD_IN,
140+
"HDMI hotplug detect");
141141
if (IS_ERR(output->hpd_gpio)) {
142142
if (PTR_ERR(output->hpd_gpio) != -ENOENT)
143143
return PTR_ERR(output->hpd_gpio);

0 commit comments

Comments
 (0)