Skip to content

Commit b118863

Browse files
committed
Merge tag 'tegra-for-5.17-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into arm/drivers
soc/tegra: Changes for v5.17-rc1 This set of changes contains some preparatory work that is shared by several branches and trees to support DVFS via power domains. There's also a bit of cleanup and improvements to reboot on chips that use PSCI. * tag 'tegra-for-5.17-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: soc/tegra: pmc: Rename core power domain soc/tegra: pmc: Rename 3d power domains soc/tegra: regulators: Prepare for suspend soc/tegra: fuse: Use resource-managed helpers soc/tegra: fuse: Reset hardware soc/tegra: pmc: Add reboot notifier soc/tegra: Don't print error message when OPPs not available Link: https://lore.kernel.org/r/20211217162253.1801077-1-thierry.reding@gmail.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2 parents a1539b2 + 81c4c86 commit b118863

7 files changed

Lines changed: 326 additions & 25 deletions

File tree

drivers/soc/tegra/common.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,7 @@ int devm_tegra_core_dev_init_opp_table(struct device *dev,
136136
*/
137137
err = devm_pm_opp_of_add_table(dev);
138138
if (err) {
139-
if (err == -ENODEV)
140-
dev_err_once(dev, "OPP table not found, please update device-tree\n");
141-
else
139+
if (err != -ENODEV)
142140
dev_err(dev, "failed to add OPP table: %d\n", err);
143141

144142
return err;

drivers/soc/tegra/fuse/fuse-tegra.c

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/of_address.h>
1515
#include <linux/platform_device.h>
1616
#include <linux/pm_runtime.h>
17+
#include <linux/reset.h>
1718
#include <linux/slab.h>
1819
#include <linux/sys_soc.h>
1920

@@ -181,20 +182,29 @@ static const struct nvmem_cell_info tegra_fuse_cells[] = {
181182
},
182183
};
183184

185+
static void tegra_fuse_restore(void *base)
186+
{
187+
fuse->clk = NULL;
188+
fuse->base = base;
189+
}
190+
184191
static int tegra_fuse_probe(struct platform_device *pdev)
185192
{
186193
void __iomem *base = fuse->base;
187194
struct nvmem_config nvmem;
188195
struct resource *res;
189196
int err;
190197

198+
err = devm_add_action(&pdev->dev, tegra_fuse_restore, base);
199+
if (err)
200+
return err;
201+
191202
/* take over the memory region from the early initialization */
192203
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
193204
fuse->phys = res->start;
194205
fuse->base = devm_ioremap_resource(&pdev->dev, res);
195206
if (IS_ERR(fuse->base)) {
196207
err = PTR_ERR(fuse->base);
197-
fuse->base = base;
198208
return err;
199209
}
200210

@@ -204,19 +214,20 @@ static int tegra_fuse_probe(struct platform_device *pdev)
204214
dev_err(&pdev->dev, "failed to get FUSE clock: %ld",
205215
PTR_ERR(fuse->clk));
206216

207-
fuse->base = base;
208217
return PTR_ERR(fuse->clk);
209218
}
210219

211220
platform_set_drvdata(pdev, fuse);
212221
fuse->dev = &pdev->dev;
213222

214-
pm_runtime_enable(&pdev->dev);
223+
err = devm_pm_runtime_enable(&pdev->dev);
224+
if (err)
225+
return err;
215226

216227
if (fuse->soc->probe) {
217228
err = fuse->soc->probe(fuse);
218229
if (err < 0)
219-
goto restore;
230+
return err;
220231
}
221232

222233
memset(&nvmem, 0, sizeof(nvmem));
@@ -240,19 +251,37 @@ static int tegra_fuse_probe(struct platform_device *pdev)
240251
err = PTR_ERR(fuse->nvmem);
241252
dev_err(&pdev->dev, "failed to register NVMEM device: %d\n",
242253
err);
243-
goto restore;
254+
return err;
255+
}
256+
257+
fuse->rst = devm_reset_control_get_optional(&pdev->dev, "fuse");
258+
if (IS_ERR(fuse->rst)) {
259+
err = PTR_ERR(fuse->rst);
260+
dev_err(&pdev->dev, "failed to get FUSE reset: %pe\n",
261+
fuse->rst);
262+
return err;
263+
}
264+
265+
/*
266+
* FUSE clock is enabled at a boot time, hence this resume/suspend
267+
* disables the clock besides the h/w resetting.
268+
*/
269+
err = pm_runtime_resume_and_get(&pdev->dev);
270+
if (err)
271+
return err;
272+
273+
err = reset_control_reset(fuse->rst);
274+
pm_runtime_put(&pdev->dev);
275+
276+
if (err < 0) {
277+
dev_err(&pdev->dev, "failed to reset FUSE: %d\n", err);
278+
return err;
244279
}
245280

246281
/* release the early I/O memory mapping */
247282
iounmap(base);
248283

249284
return 0;
250-
251-
restore:
252-
fuse->clk = NULL;
253-
fuse->base = base;
254-
pm_runtime_disable(&pdev->dev);
255-
return err;
256285
}
257286

258287
static int __maybe_unused tegra_fuse_runtime_resume(struct device *dev)

drivers/soc/tegra/fuse/fuse-tegra20.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,28 @@ static bool dma_filter(struct dma_chan *chan, void *filter_param)
9494
return of_device_is_compatible(np, "nvidia,tegra20-apbdma");
9595
}
9696

97+
static void tegra20_fuse_release_channel(void *data)
98+
{
99+
struct tegra_fuse *fuse = data;
100+
101+
dma_release_channel(fuse->apbdma.chan);
102+
fuse->apbdma.chan = NULL;
103+
}
104+
105+
static void tegra20_fuse_free_coherent(void *data)
106+
{
107+
struct tegra_fuse *fuse = data;
108+
109+
dma_free_coherent(fuse->dev, sizeof(u32), fuse->apbdma.virt,
110+
fuse->apbdma.phys);
111+
fuse->apbdma.virt = NULL;
112+
fuse->apbdma.phys = 0x0;
113+
}
114+
97115
static int tegra20_fuse_probe(struct tegra_fuse *fuse)
98116
{
99117
dma_cap_mask_t mask;
118+
int err;
100119

101120
dma_cap_zero(mask);
102121
dma_cap_set(DMA_SLAVE, mask);
@@ -105,13 +124,21 @@ static int tegra20_fuse_probe(struct tegra_fuse *fuse)
105124
if (!fuse->apbdma.chan)
106125
return -EPROBE_DEFER;
107126

127+
err = devm_add_action_or_reset(fuse->dev, tegra20_fuse_release_channel,
128+
fuse);
129+
if (err)
130+
return err;
131+
108132
fuse->apbdma.virt = dma_alloc_coherent(fuse->dev, sizeof(u32),
109133
&fuse->apbdma.phys,
110134
GFP_KERNEL);
111-
if (!fuse->apbdma.virt) {
112-
dma_release_channel(fuse->apbdma.chan);
135+
if (!fuse->apbdma.virt)
113136
return -ENOMEM;
114-
}
137+
138+
err = devm_add_action_or_reset(fuse->dev, tegra20_fuse_free_coherent,
139+
fuse);
140+
if (err)
141+
return err;
115142

116143
fuse->apbdma.config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
117144
fuse->apbdma.config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;

drivers/soc/tegra/fuse/fuse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct tegra_fuse {
4343
void __iomem *base;
4444
phys_addr_t phys;
4545
struct clk *clk;
46+
struct reset_control *rst;
4647

4748
u32 (*read_early)(struct tegra_fuse *fuse, unsigned int offset);
4849
u32 (*read)(struct tegra_fuse *fuse, unsigned int offset);

drivers/soc/tegra/pmc.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,10 +1064,8 @@ int tegra_pmc_cpu_remove_clamping(unsigned int cpuid)
10641064
return tegra_powergate_remove_clamping(id);
10651065
}
10661066

1067-
static int tegra_pmc_restart_notify(struct notifier_block *this,
1068-
unsigned long action, void *data)
1067+
static void tegra_pmc_program_reboot_reason(const char *cmd)
10691068
{
1070-
const char *cmd = data;
10711069
u32 value;
10721070

10731071
value = tegra_pmc_scratch_readl(pmc, pmc->soc->regs->scratch0);
@@ -1085,6 +1083,25 @@ static int tegra_pmc_restart_notify(struct notifier_block *this,
10851083
}
10861084

10871085
tegra_pmc_scratch_writel(pmc, value, pmc->soc->regs->scratch0);
1086+
}
1087+
1088+
static int tegra_pmc_reboot_notify(struct notifier_block *this,
1089+
unsigned long action, void *data)
1090+
{
1091+
if (action == SYS_RESTART)
1092+
tegra_pmc_program_reboot_reason(data);
1093+
1094+
return NOTIFY_DONE;
1095+
}
1096+
1097+
static struct notifier_block tegra_pmc_reboot_notifier = {
1098+
.notifier_call = tegra_pmc_reboot_notify,
1099+
};
1100+
1101+
static int tegra_pmc_restart_notify(struct notifier_block *this,
1102+
unsigned long action, void *data)
1103+
{
1104+
u32 value;
10881105

10891106
/* reset everything but PMC_SCRATCH0 and PMC_RST_STATUS */
10901107
value = tegra_pmc_readl(pmc, PMC_CNTRL);
@@ -1353,7 +1370,7 @@ static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np)
13531370
if (!genpd)
13541371
return -ENOMEM;
13551372

1356-
genpd->name = np->name;
1373+
genpd->name = "core";
13571374
genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state;
13581375
genpd->opp_to_performance_state = tegra_pmc_core_pd_opp_to_performance_state;
13591376

@@ -2890,6 +2907,14 @@ static int tegra_pmc_probe(struct platform_device *pdev)
28902907
goto cleanup_sysfs;
28912908
}
28922909

2910+
err = devm_register_reboot_notifier(&pdev->dev,
2911+
&tegra_pmc_reboot_notifier);
2912+
if (err) {
2913+
dev_err(&pdev->dev, "unable to register reboot notifier, %d\n",
2914+
err);
2915+
goto cleanup_debugfs;
2916+
}
2917+
28932918
err = register_restart_handler(&tegra_pmc_restart_handler);
28942919
if (err) {
28952920
dev_err(&pdev->dev, "unable to register restart handler, %d\n",
@@ -2963,7 +2988,7 @@ static SIMPLE_DEV_PM_OPS(tegra_pmc_pm_ops, tegra_pmc_suspend, tegra_pmc_resume);
29632988

29642989
static const char * const tegra20_powergates[] = {
29652990
[TEGRA_POWERGATE_CPU] = "cpu",
2966-
[TEGRA_POWERGATE_3D] = "3d",
2991+
[TEGRA_POWERGATE_3D] = "td",
29672992
[TEGRA_POWERGATE_VENC] = "venc",
29682993
[TEGRA_POWERGATE_VDEC] = "vdec",
29692994
[TEGRA_POWERGATE_PCIE] = "pcie",
@@ -3071,7 +3096,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
30713096

30723097
static const char * const tegra30_powergates[] = {
30733098
[TEGRA_POWERGATE_CPU] = "cpu0",
3074-
[TEGRA_POWERGATE_3D] = "3d0",
3099+
[TEGRA_POWERGATE_3D] = "td",
30753100
[TEGRA_POWERGATE_VENC] = "venc",
30763101
[TEGRA_POWERGATE_VDEC] = "vdec",
30773102
[TEGRA_POWERGATE_PCIE] = "pcie",
@@ -3083,7 +3108,7 @@ static const char * const tegra30_powergates[] = {
30833108
[TEGRA_POWERGATE_CPU2] = "cpu2",
30843109
[TEGRA_POWERGATE_CPU3] = "cpu3",
30853110
[TEGRA_POWERGATE_CELP] = "celp",
3086-
[TEGRA_POWERGATE_3D1] = "3d1",
3111+
[TEGRA_POWERGATE_3D1] = "td2",
30873112
};
30883113

30893114
static const u8 tegra30_cpu_powergates[] = {
@@ -3132,7 +3157,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
31323157

31333158
static const char * const tegra114_powergates[] = {
31343159
[TEGRA_POWERGATE_CPU] = "crail",
3135-
[TEGRA_POWERGATE_3D] = "3d",
3160+
[TEGRA_POWERGATE_3D] = "td",
31363161
[TEGRA_POWERGATE_VENC] = "venc",
31373162
[TEGRA_POWERGATE_VDEC] = "vdec",
31383163
[TEGRA_POWERGATE_MPE] = "mpe",

0 commit comments

Comments
 (0)