Skip to content

Commit 926ac50

Browse files
mairacanalpopcornmix
authored andcommitted
[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 5931ee2 commit 926ac50

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);
@@ -400,44 +436,9 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
400436
ident3 = V3D_READ(V3D_HUB_IDENT3);
401437
v3d->rev = V3D_GET_FIELD(ident3, V3D_HUB_IDENT3_IPREV);
402438

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

442443
ret = drm_dev_register(drm, 0);
443444
if (ret)
@@ -453,12 +454,13 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
453454
drm_dev_unregister(drm);
454455
irq_disable:
455456
v3d_irq_disable(v3d);
457+
clk_disable:
458+
v3d_power_off_sms(v3d);
459+
clk_disable_unprepare(v3d->clk);
456460
gem_destroy:
457461
v3d_gem_destroy(drm);
458462
dma_free:
459463
dma_free_wc(dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr);
460-
clk_disable:
461-
clk_disable_unprepare(v3d->clk);
462464
return ret;
463465
}
464466

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

473475
drm_dev_unregister(drm);
474476

475-
v3d_gem_destroy(drm);
476-
477-
dma_free_wc(v3d->drm.dev, 4096, v3d->mmu_scratch,
478-
v3d->mmu_scratch_paddr);
479-
480477
v3d_power_off_sms(v3d);
481478

482479
clk_disable_unprepare(v3d->clk);
480+
481+
v3d_gem_destroy(drm);
482+
483+
dma_free_wc(dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr);
483484
}
484485

485486
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)