summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gk20a.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2014-10-27 05:03:00 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:11:56 -0400
commit8371833f4273c2d4a6f923eb3270b4ab93967743 (patch)
tree92faf9b7bc19bdc14a5c46b25f3ab7acc6cf65e3 /drivers/gpu/nvgpu/gk20a/gk20a.c
parenteb690cb391ca0578a2c086eff5085f16c32f651e (diff)
gpu: nvgpu: Per-chip interrupt processing
Move accesses to MC registers under HAL so that they can be reimplemented per chip. Do chip detection and HAL initialization only once. Bug 1567274 Change-Id: I20bf2f439d267d284bfd536f1a1dfb5d5a2dce4c Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/590385
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c120
1 files changed, 19 insertions, 101 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index cea53e00..2e1bd003 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -524,48 +524,18 @@ int gk20a_sim_esc_read(struct gk20a *g, char *path, u32 index, u32 count, u32 *d
524static irqreturn_t gk20a_intr_isr_stall(int irq, void *dev_id) 524static irqreturn_t gk20a_intr_isr_stall(int irq, void *dev_id)
525{ 525{
526 struct gk20a *g = dev_id; 526 struct gk20a *g = dev_id;
527 u32 mc_intr_0;
528 527
529 if (!g->power_on) 528 return g->ops.mc.isr_stall(g);
530 return IRQ_NONE;
531
532 /* not from gpu when sharing irq with others */
533 mc_intr_0 = gk20a_readl(g, mc_intr_0_r());
534 if (unlikely(!mc_intr_0))
535 return IRQ_NONE;
536
537 gk20a_writel(g, mc_intr_en_0_r(),
538 mc_intr_en_0_inta_disabled_f());
539
540 /* flush previous write */
541 gk20a_readl(g, mc_intr_en_0_r());
542
543 return IRQ_WAKE_THREAD;
544} 529}
545 530
546static irqreturn_t gk20a_intr_isr_nonstall(int irq, void *dev_id) 531static irqreturn_t gk20a_intr_isr_nonstall(int irq, void *dev_id)
547{ 532{
548 struct gk20a *g = dev_id; 533 struct gk20a *g = dev_id;
549 u32 mc_intr_1;
550
551 if (!g->power_on)
552 return IRQ_NONE;
553
554 /* not from gpu when sharing irq with others */
555 mc_intr_1 = gk20a_readl(g, mc_intr_1_r());
556 if (unlikely(!mc_intr_1))
557 return IRQ_NONE;
558
559 gk20a_writel(g, mc_intr_en_1_r(),
560 mc_intr_en_1_inta_disabled_f());
561
562 /* flush previous write */
563 gk20a_readl(g, mc_intr_en_1_r());
564 534
565 return IRQ_WAKE_THREAD; 535 return g->ops.mc.isr_nonstall(g);
566} 536}
567 537
568static void gk20a_pbus_isr(struct gk20a *g) 538void gk20a_pbus_isr(struct gk20a *g)
569{ 539{
570 u32 val; 540 u32 val;
571 val = gk20a_readl(g, bus_intr_0_r()); 541 val = gk20a_readl(g, bus_intr_0_r());
@@ -595,59 +565,13 @@ static void gk20a_pbus_isr(struct gk20a *g)
595static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id) 565static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id)
596{ 566{
597 struct gk20a *g = dev_id; 567 struct gk20a *g = dev_id;
598 u32 mc_intr_0; 568 return g->ops.mc.isr_thread_stall(g);
599
600 gk20a_dbg(gpu_dbg_intr, "interrupt thread launched");
601
602 mc_intr_0 = gk20a_readl(g, mc_intr_0_r());
603
604 gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0);
605
606 if (mc_intr_0 & mc_intr_0_pgraph_pending_f())
607 gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g));
608 if (mc_intr_0 & mc_intr_0_pfifo_pending_f())
609 gk20a_fifo_isr(g);
610 if (mc_intr_0 & mc_intr_0_pmu_pending_f())
611 gk20a_pmu_isr(g);
612 if (mc_intr_0 & mc_intr_0_priv_ring_pending_f())
613 gk20a_priv_ring_isr(g);
614 if (mc_intr_0 & mc_intr_0_ltc_pending_f())
615 g->ops.ltc.isr(g);
616 if (mc_intr_0 & mc_intr_0_pbus_pending_f())
617 gk20a_pbus_isr(g);
618
619 gk20a_writel(g, mc_intr_en_0_r(),
620 mc_intr_en_0_inta_hardware_f());
621
622 /* flush previous write */
623 gk20a_readl(g, mc_intr_en_0_r());
624
625 return IRQ_HANDLED;
626} 569}
627 570
628static irqreturn_t gk20a_intr_thread_nonstall(int irq, void *dev_id) 571static irqreturn_t gk20a_intr_thread_nonstall(int irq, void *dev_id)
629{ 572{
630 struct gk20a *g = dev_id; 573 struct gk20a *g = dev_id;
631 u32 mc_intr_1; 574 return g->ops.mc.isr_thread_nonstall(g);
632
633 gk20a_dbg(gpu_dbg_intr, "interrupt thread launched");
634
635 mc_intr_1 = gk20a_readl(g, mc_intr_1_r());
636
637 gk20a_dbg(gpu_dbg_intr, "non-stall intr %08x\n", mc_intr_1);
638
639 if (mc_intr_1 & mc_intr_0_pfifo_pending_f())
640 gk20a_fifo_nonstall_isr(g);
641 if (mc_intr_1 & mc_intr_0_pgraph_pending_f())
642 gk20a_gr_nonstall_isr(g);
643
644 gk20a_writel(g, mc_intr_en_1_r(),
645 mc_intr_en_1_inta_hardware_f());
646
647 /* flush previous write */
648 gk20a_readl(g, mc_intr_en_1_r());
649
650 return IRQ_HANDLED;
651} 575}
652 576
653static void gk20a_remove_support(struct platform_device *dev) 577static void gk20a_remove_support(struct platform_device *dev)
@@ -776,11 +700,15 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
776 return ret; 700 return ret;
777} 701}
778 702
779static void gk20a_detect_chip(struct gk20a *g) 703static int gk20a_detect_chip(struct gk20a *g)
780{ 704{
781 struct nvgpu_gpu_characteristics *gpu = &g->gpu_characteristics; 705 struct nvgpu_gpu_characteristics *gpu = &g->gpu_characteristics;
706 u32 mc_boot_0_value;
782 707
783 u32 mc_boot_0_value = gk20a_readl(g, mc_boot_0_r()); 708 if (gpu->arch)
709 return 0;
710
711 mc_boot_0_value = gk20a_readl(g, mc_boot_0_r());
784 gpu->arch = mc_boot_0_architecture_v(mc_boot_0_value) << 712 gpu->arch = mc_boot_0_architecture_v(mc_boot_0_value) <<
785 NVGPU_GPU_ARCHITECTURE_SHIFT; 713 NVGPU_GPU_ARCHITECTURE_SHIFT;
786 gpu->impl = mc_boot_0_implementation_v(mc_boot_0_value); 714 gpu->impl = mc_boot_0_implementation_v(mc_boot_0_value);
@@ -792,6 +720,8 @@ static void gk20a_detect_chip(struct gk20a *g)
792 g->gpu_characteristics.arch, 720 g->gpu_characteristics.arch,
793 g->gpu_characteristics.impl, 721 g->gpu_characteristics.impl,
794 g->gpu_characteristics.rev); 722 g->gpu_characteristics.rev);
723
724 return gpu_init_hal(g);
795} 725}
796 726
797static int gk20a_pm_finalize_poweron(struct device *dev) 727static int gk20a_pm_finalize_poweron(struct device *dev)
@@ -815,23 +745,16 @@ static int gk20a_pm_finalize_poweron(struct device *dev)
815 nice_value = task_nice(current); 745 nice_value = task_nice(current);
816 set_user_nice(current, -20); 746 set_user_nice(current, -20);
817 747
818 enable_irq(g->irq_stall);
819 enable_irq(g->irq_nonstall);
820
821 g->power_on = true; 748 g->power_on = true;
822 749
823 gk20a_writel(g, mc_intr_en_1_r(), 750 err = gk20a_detect_chip(g);
824 mc_intr_en_1_inta_hardware_f()); 751 if (err)
752 goto done;
825 753
826 gk20a_writel(g, mc_intr_en_0_r(), 754 enable_irq(g->irq_stall);
827 mc_intr_en_0_inta_hardware_f()); 755 enable_irq(g->irq_nonstall);
828 756
829 if (g->ops.clock_gating.slcg_bus_load_gating_prod) 757 g->ops.mc.intr_enable(g);
830 g->ops.clock_gating.slcg_bus_load_gating_prod(g,
831 g->slcg_enabled);
832 if (g->ops.clock_gating.blcg_bus_load_gating_prod)
833 g->ops.clock_gating.blcg_bus_load_gating_prod(g,
834 g->blcg_enabled);
835 758
836 if (!tegra_platform_is_silicon()) 759 if (!tegra_platform_is_silicon())
837 gk20a_writel(g, bus_intr_en_0_r(), 0x0); 760 gk20a_writel(g, bus_intr_en_0_r(), 0x0);
@@ -843,11 +766,6 @@ static int gk20a_pm_finalize_poweron(struct device *dev)
843 766
844 gk20a_reset_priv_ring(g); 767 gk20a_reset_priv_ring(g);
845 768
846 gk20a_detect_chip(g);
847 err = gpu_init_hal(g);
848 if (err)
849 goto done;
850
851 /* TBD: move this after graphics init in which blcg/slcg is enabled. 769 /* TBD: move this after graphics init in which blcg/slcg is enabled.
852 This function removes SlowdownOnBoot which applies 32x divider 770 This function removes SlowdownOnBoot which applies 32x divider
853 on gpcpll bypass path. The purpose of slowdown is to save power 771 on gpcpll bypass path. The purpose of slowdown is to save power