diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 120 |
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 | |||
524 | static irqreturn_t gk20a_intr_isr_stall(int irq, void *dev_id) | 524 | static 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 | ||
546 | static irqreturn_t gk20a_intr_isr_nonstall(int irq, void *dev_id) | 531 | static 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 | ||
568 | static void gk20a_pbus_isr(struct gk20a *g) | 538 | void 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) | |||
595 | static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id) | 565 | static 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 | ||
628 | static irqreturn_t gk20a_intr_thread_nonstall(int irq, void *dev_id) | 571 | static 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 | ||
653 | static void gk20a_remove_support(struct platform_device *dev) | 577 | static 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 | ||
779 | static void gk20a_detect_chip(struct gk20a *g) | 703 | static 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 | ||
797 | static int gk20a_pm_finalize_poweron(struct device *dev) | 727 | static 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 |