Skip to content

Commit ee8f49f

Browse files
committed
[BACKPORTED] drm/v3d: Allocate all resources before enabling the clock
Move all resource allocation operations before actually enabling the clock, as those operations don't require the GPU to be powered on. This is a preparation for runtime PM support. The next commit will move all code related to powering on and initiating the GPU into the runtime PM resume callback and all resource allocation will happen before resume(). Reviewed-by: Melissa Wen <mwen@igalia.com> Signed-off-by: Maíra Canal <mcanal@igalia.com>
1 parent 9ac85b3 commit ee8f49f

File tree

4 files changed

+61
-65
lines changed

4 files changed

+61
-65
lines changed

drivers/gpu/drm/v3d/v3d_drv.c

Lines changed: 47 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -364,14 +364,50 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
364364
return ret;
365365
}
366366

367+
if (v3d->ver < V3D_GEN_41) {
368+
ret = map_regs(v3d, &v3d->gca_regs, "gca");
369+
if (ret)
370+
return ret;
371+
}
372+
373+
v3d->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
374+
if (IS_ERR(v3d->reset))
375+
return dev_err_probe(dev, PTR_ERR(v3d->reset),
376+
"Failed to get reset control\n");
377+
378+
if (!v3d->reset) {
379+
ret = map_regs(v3d, &v3d->bridge_regs, "bridge");
380+
if (ret) {
381+
dev_err(dev, "Failed to get bridge registers\n");
382+
return ret;
383+
}
384+
}
385+
367386
v3d->clk = devm_clk_get_optional(dev, NULL);
368387
if (IS_ERR(v3d->clk))
369388
return dev_err_probe(dev, PTR_ERR(v3d->clk), "Failed to get V3D clock\n");
370389

390+
ret = v3d_irq_init(v3d);
391+
if (ret)
392+
return ret;
393+
394+
v3d_perfmon_init(v3d);
395+
396+
v3d->mmu_scratch = dma_alloc_wc(dev, 4096, &v3d->mmu_scratch_paddr,
397+
GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO);
398+
if (!v3d->mmu_scratch) {
399+
dev_err(dev, "Failed to allocate MMU scratch page\n");
400+
return -ENOMEM;
401+
}
402+
403+
ret = v3d_gem_init(drm);
404+
if (ret)
405+
goto dma_free;
406+
371407
ret = clk_prepare_enable(v3d->clk);
372408
if (ret) {
373409
dev_err(&pdev->dev, "Couldn't enable the V3D clock\n");
374-
return ret;
410+
goto gem_destroy;
375411
}
376412

377413
v3d_idle_sms(v3d);
@@ -398,44 +434,9 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
398434
ident3 = V3D_READ(V3D_HUB_IDENT3);
399435
v3d->rev = V3D_GET_FIELD(ident3, V3D_HUB_IDENT3_IPREV);
400436

401-
v3d_perfmon_init(v3d);
402-
403-
v3d->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
404-
if (IS_ERR(v3d->reset)) {
405-
ret = dev_err_probe(dev, PTR_ERR(v3d->reset),
406-
"Failed to get reset control\n");
407-
goto clk_disable;
408-
}
409-
410-
if (!v3d->reset) {
411-
ret = map_regs(v3d, &v3d->bridge_regs, "bridge");
412-
if (ret) {
413-
dev_err(dev, "Failed to get bridge registers\n");
414-
goto clk_disable;
415-
}
416-
}
417-
418-
if (v3d->ver < V3D_GEN_41) {
419-
ret = map_regs(v3d, &v3d->gca_regs, "gca");
420-
if (ret)
421-
goto clk_disable;
422-
}
423-
424-
v3d->mmu_scratch = dma_alloc_wc(dev, 4096, &v3d->mmu_scratch_paddr,
425-
GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO);
426-
if (!v3d->mmu_scratch) {
427-
dev_err(dev, "Failed to allocate MMU scratch page\n");
428-
ret = -ENOMEM;
429-
goto clk_disable;
430-
}
431-
432-
ret = v3d_gem_init(drm);
433-
if (ret)
434-
goto dma_free;
435-
436-
ret = v3d_irq_init(v3d);
437-
if (ret)
438-
goto gem_destroy;
437+
v3d_init_hw_state(v3d);
438+
v3d_mmu_set_page_table(v3d);
439+
v3d_irq_enable(v3d);
439440

440441
ret = drm_dev_register(drm, 0);
441442
if (ret)
@@ -451,12 +452,13 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
451452
drm_dev_unregister(drm);
452453
irq_disable:
453454
v3d_irq_disable(v3d);
455+
clk_disable:
456+
v3d_power_off_sms(v3d);
457+
clk_disable_unprepare(v3d->clk);
454458
gem_destroy:
455459
v3d_gem_destroy(drm);
456460
dma_free:
457461
dma_free_wc(dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr);
458-
clk_disable:
459-
clk_disable_unprepare(v3d->clk);
460462
return ret;
461463
}
462464

@@ -470,14 +472,13 @@ static void v3d_platform_drm_remove(struct platform_device *pdev)
470472

471473
drm_dev_unregister(drm);
472474

473-
v3d_gem_destroy(drm);
474-
475-
dma_free_wc(v3d->drm.dev, 4096, v3d->mmu_scratch,
476-
v3d->mmu_scratch_paddr);
477-
478475
v3d_power_off_sms(v3d);
479476

480477
clk_disable_unprepare(v3d->clk);
478+
479+
v3d_gem_destroy(drm);
480+
481+
dma_free_wc(dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr);
481482
}
482483

483484
static struct platform_driver v3d_platform_driver = {

drivers/gpu/drm/v3d/v3d_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,7 @@ extern const struct dma_fence_ops v3d_fence_ops;
570570
struct dma_fence *v3d_fence_create(struct v3d_dev *v3d, enum v3d_queue q);
571571

572572
/* v3d_gem.c */
573+
void v3d_init_hw_state(struct v3d_dev *v3d);
573574
int v3d_gem_init(struct drm_device *dev);
574575
void v3d_gem_destroy(struct drm_device *dev);
575576
void v3d_reset_sms(struct v3d_dev *v3d);

drivers/gpu/drm/v3d/v3d_gem.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,6 @@ v3d_init_core(struct v3d_dev *v3d, int core)
3636
V3D_CORE_WRITE(core, V3D_CTL_L2TFLEND, ~0);
3737
}
3838

39-
/* Sets invariant state for the HW. */
40-
static void
41-
v3d_init_hw_state(struct v3d_dev *v3d)
42-
{
43-
v3d_init_core(v3d, 0);
44-
}
45-
4639
static void
4740
v3d_idle_axi(struct v3d_dev *v3d, int core)
4841
{
@@ -259,6 +252,13 @@ v3d_invalidate_caches(struct v3d_dev *v3d)
259252
v3d_invalidate_slices(v3d, 0);
260253
}
261254

255+
/* Sets invariant state for the HW. */
256+
void
257+
v3d_init_hw_state(struct v3d_dev *v3d)
258+
{
259+
v3d_init_core(v3d, 0);
260+
}
261+
262262
int
263263
v3d_gem_init(struct drm_device *dev)
264264
{
@@ -307,9 +307,6 @@ v3d_gem_init(struct drm_device *dev)
307307
return -ENOMEM;
308308
}
309309

310-
v3d_init_hw_state(v3d);
311-
v3d_mmu_set_page_table(v3d);
312-
313310
v3d_gemfs_init(v3d);
314311

315312
ret = v3d_sched_init(v3d);

drivers/gpu/drm/v3d/v3d_irq.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -251,17 +251,10 @@ v3d_hub_irq(int irq, void *arg)
251251
int
252252
v3d_irq_init(struct v3d_dev *v3d)
253253
{
254-
int irq, ret, core;
254+
int irq, ret;
255255

256256
INIT_WORK(&v3d->overflow_mem_work, v3d_overflow_mem_work);
257257

258-
/* Clear any pending interrupts someone might have left around
259-
* for us.
260-
*/
261-
for (core = 0; core < v3d->cores; core++)
262-
V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS(v3d->ver));
263-
V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS(v3d->ver));
264-
265258
irq = platform_get_irq_optional(v3d_to_pdev(v3d), 1);
266259
if (irq == -EPROBE_DEFER)
267260
return irq;
@@ -299,7 +292,6 @@ v3d_irq_init(struct v3d_dev *v3d)
299292
goto fail;
300293
}
301294

302-
v3d_irq_enable(v3d);
303295
return 0;
304296

305297
fail:
@@ -313,6 +305,11 @@ v3d_irq_enable(struct v3d_dev *v3d)
313305
{
314306
int core;
315307

308+
/* Clear any pending interrupts someone might have left around for us. */
309+
for (core = 0; core < v3d->cores; core++)
310+
V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS(v3d->ver));
311+
V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS(v3d->ver));
312+
316313
/* Enable our set of interrupts, masking out any others. */
317314
for (core = 0; core < v3d->cores; core++) {
318315
V3D_CORE_WRITE(core, V3D_CTL_INT_MSK_SET, ~V3D_CORE_IRQS(v3d->ver));

0 commit comments

Comments
 (0)