summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--drivers/gpu/nvgpu/Makefile4
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c120
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h12
-rw-r--r--drivers/gpu/nvgpu/gk20a/hal_gk20a.c2
-rw-r--r--drivers/gpu/nvgpu/gk20a/mc_gk20a.c136
-rw-r--r--drivers/gpu/nvgpu/gk20a/mc_gk20a.h24
-rw-r--r--drivers/gpu/nvgpu/gm20b/hal_gm20b.c2
-rw-r--r--drivers/gpu/nvgpu/gm20b/mc_gm20b.c29
-rw-r--r--drivers/gpu/nvgpu/gm20b/mc_gm20b.h18
9 files changed, 244 insertions, 103 deletions
diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile
index cf5d65cc..391ccec7 100644
--- a/drivers/gpu/nvgpu/Makefile
+++ b/drivers/gpu/nvgpu/Makefile
@@ -38,6 +38,7 @@ nvgpu-y := \
38 gk20a/cde_gk20a.o \ 38 gk20a/cde_gk20a.o \
39 gk20a/platform_gk20a_generic.o \ 39 gk20a/platform_gk20a_generic.o \
40 gk20a/tsg_gk20a.o \ 40 gk20a/tsg_gk20a.o \
41 gk20a/mc_gk20a.o \
41 gm20b/hal_gm20b.o \ 42 gm20b/hal_gm20b.o \
42 gm20b/ltc_gm20b.o \ 43 gm20b/ltc_gm20b.o \
43 gm20b/gr_gm20b.o \ 44 gm20b/gr_gm20b.o \
@@ -49,7 +50,8 @@ nvgpu-y := \
49 gm20b/acr_gm20b.o \ 50 gm20b/acr_gm20b.o \
50 gm20b/pmu_gm20b.o \ 51 gm20b/pmu_gm20b.o \
51 gm20b/mm_gm20b.o \ 52 gm20b/mm_gm20b.o \
52 gm20b/regops_gm20b.o 53 gm20b/regops_gm20b.o \
54 gm20b/mc_gm20b.o
53 55
54nvgpu-$(CONFIG_TEGRA_GK20A) += gk20a/platform_gk20a_tegra.o 56nvgpu-$(CONFIG_TEGRA_GK20A) += gk20a/platform_gk20a_tegra.o
55nvgpu-$(CONFIG_SYNC) += gk20a/sync_gk20a.o 57nvgpu-$(CONFIG_SYNC) += gk20a/sync_gk20a.o
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
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 5669e1c5..a111a040 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -29,7 +29,8 @@ struct acr_gm20b;
29 29
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/spinlock.h> 31#include <linux/spinlock.h>
32#include <uapi/linux/nvgpu.h> 32#include <linux/nvgpu.h>
33#include <linux/irqreturn.h>
33#include <linux/tegra-soc.h> 34#include <linux/tegra-soc.h>
34 35
35#include "../../../arch/arm/mach-tegra/iomap.h" 36#include "../../../arch/arm/mach-tegra/iomap.h"
@@ -335,6 +336,13 @@ struct gpu_ops {
335 *get_qctl_whitelist_ranges)(void); 336 *get_qctl_whitelist_ranges)(void);
336 int (*get_qctl_whitelist_ranges_count)(void); 337 int (*get_qctl_whitelist_ranges_count)(void);
337 } regops; 338 } regops;
339 struct {
340 void (*intr_enable)(struct gk20a *g);
341 irqreturn_t (*isr_stall)(struct gk20a *g);
342 irqreturn_t (*isr_nonstall)(struct gk20a *g);
343 irqreturn_t (*isr_thread_stall)(struct gk20a *g);
344 irqreturn_t (*isr_thread_nonstall)(struct gk20a *g);
345 } mc;
338}; 346};
339 347
340struct gk20a { 348struct gk20a {
@@ -734,6 +742,8 @@ gk20a_request_firmware(struct gk20a *g, const char *fw_name);
734 742
735int gk20a_init_gpu_characteristics(struct gk20a *g); 743int gk20a_init_gpu_characteristics(struct gk20a *g);
736 744
745void gk20a_pbus_isr(struct gk20a *g);
746
737int gk20a_user_init(struct platform_device *dev); 747int gk20a_user_init(struct platform_device *dev);
738void gk20a_user_deinit(struct platform_device *dev); 748void gk20a_user_deinit(struct platform_device *dev);
739 749
diff --git a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c
index 578b77bf..208c1ef0 100644
--- a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c
@@ -23,6 +23,7 @@
23#include "channel_gk20a.h" 23#include "channel_gk20a.h"
24#include "gr_ctx_gk20a.h" 24#include "gr_ctx_gk20a.h"
25#include "mm_gk20a.h" 25#include "mm_gk20a.h"
26#include "mc_gk20a.h"
26#include "pmu_gk20a.h" 27#include "pmu_gk20a.h"
27#include "clk_gk20a.h" 28#include "clk_gk20a.h"
28#include "regops_gk20a.h" 29#include "regops_gk20a.h"
@@ -48,6 +49,7 @@ int gk20a_init_hal(struct gpu_ops *gops)
48{ 49{
49 *gops = gk20a_ops; 50 *gops = gk20a_ops;
50 gops->privsecurity = 0; 51 gops->privsecurity = 0;
52 gk20a_init_mc(gops);
51 gk20a_init_ltc(gops); 53 gk20a_init_ltc(gops);
52 gk20a_init_gr_ops(gops); 54 gk20a_init_gr_ops(gops);
53 gk20a_init_fb(gops); 55 gk20a_init_fb(gops);
diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c
new file mode 100644
index 00000000..53701605
--- /dev/null
+++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c
@@ -0,0 +1,136 @@
1/*
2 * GK20A memory interface
3 *
4 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 */
15
16#include <linux/types.h>
17
18#include "gk20a.h"
19#include "mc_gk20a.h"
20#include "hw_mc_gk20a.h"
21
22irqreturn_t mc_gk20a_isr_stall(struct gk20a *g)
23{
24 u32 mc_intr_0;
25
26 if (!g->power_on)
27 return IRQ_NONE;
28
29 /* not from gpu when sharing irq with others */
30 mc_intr_0 = gk20a_readl(g, mc_intr_0_r());
31 if (unlikely(!mc_intr_0))
32 return IRQ_NONE;
33
34 gk20a_writel(g, mc_intr_en_0_r(),
35 mc_intr_en_0_inta_disabled_f());
36
37 /* flush previous write */
38 gk20a_readl(g, mc_intr_en_0_r());
39
40 return IRQ_WAKE_THREAD;
41}
42
43irqreturn_t mc_gk20a_isr_nonstall(struct gk20a *g)
44{
45 u32 mc_intr_1;
46
47 if (!g->power_on)
48 return IRQ_NONE;
49
50 /* not from gpu when sharing irq with others */
51 mc_intr_1 = gk20a_readl(g, mc_intr_1_r());
52 if (unlikely(!mc_intr_1))
53 return IRQ_NONE;
54
55 gk20a_writel(g, mc_intr_en_1_r(),
56 mc_intr_en_1_inta_disabled_f());
57
58 /* flush previous write */
59 gk20a_readl(g, mc_intr_en_1_r());
60
61 return IRQ_WAKE_THREAD;
62}
63
64irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g)
65{
66 u32 mc_intr_0;
67
68 gk20a_dbg(gpu_dbg_intr, "interrupt thread launched");
69
70 mc_intr_0 = gk20a_readl(g, mc_intr_0_r());
71
72 gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0);
73
74 if (mc_intr_0 & mc_intr_0_pgraph_pending_f())
75 gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g));
76 if (mc_intr_0 & mc_intr_0_pfifo_pending_f())
77 gk20a_fifo_isr(g);
78 if (mc_intr_0 & mc_intr_0_pmu_pending_f())
79 gk20a_pmu_isr(g);
80 if (mc_intr_0 & mc_intr_0_priv_ring_pending_f())
81 gk20a_priv_ring_isr(g);
82 if (mc_intr_0 & mc_intr_0_ltc_pending_f())
83 g->ops.ltc.isr(g);
84 if (mc_intr_0 & mc_intr_0_pbus_pending_f())
85 gk20a_pbus_isr(g);
86
87 gk20a_writel(g, mc_intr_en_0_r(),
88 mc_intr_en_0_inta_hardware_f());
89
90 /* flush previous write */
91 gk20a_readl(g, mc_intr_en_0_r());
92
93 return IRQ_HANDLED;
94}
95
96irqreturn_t mc_gk20a_intr_thread_nonstall(struct gk20a *g)
97{
98 u32 mc_intr_1;
99
100 gk20a_dbg(gpu_dbg_intr, "interrupt thread launched");
101
102 mc_intr_1 = gk20a_readl(g, mc_intr_1_r());
103
104 gk20a_dbg(gpu_dbg_intr, "non-stall intr %08x\n", mc_intr_1);
105
106 if (mc_intr_1 & mc_intr_0_pfifo_pending_f())
107 gk20a_fifo_nonstall_isr(g);
108 if (mc_intr_1 & mc_intr_0_pgraph_pending_f())
109 gk20a_gr_nonstall_isr(g);
110
111 gk20a_writel(g, mc_intr_en_1_r(),
112 mc_intr_en_1_inta_hardware_f());
113
114 /* flush previous write */
115 gk20a_readl(g, mc_intr_en_1_r());
116
117 return IRQ_HANDLED;
118}
119
120void mc_gk20a_intr_enable(struct gk20a *g)
121{
122 gk20a_writel(g, mc_intr_en_1_r(),
123 mc_intr_en_1_inta_hardware_f());
124
125 gk20a_writel(g, mc_intr_en_0_r(),
126 mc_intr_en_0_inta_hardware_f());
127}
128
129void gk20a_init_mc(struct gpu_ops *gops)
130{
131 gops->mc.intr_enable = mc_gk20a_intr_enable;
132 gops->mc.isr_stall = mc_gk20a_isr_stall;
133 gops->mc.isr_nonstall = mc_gk20a_isr_nonstall;
134 gops->mc.isr_thread_stall = mc_gk20a_intr_thread_stall;
135 gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall;
136}
diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.h b/drivers/gpu/nvgpu/gk20a/mc_gk20a.h
new file mode 100644
index 00000000..7264ab41
--- /dev/null
+++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 */
13
14#ifndef MC_GK20A_H
15#define MC_GK20A_H
16struct gk20a;
17
18void gk20a_init_mc(struct gpu_ops *gops);
19void mc_gk20a_intr_enable(struct gk20a *g);
20irqreturn_t mc_gk20a_isr_stall(struct gk20a *g);
21irqreturn_t mc_gk20a_isr_nonstall(struct gk20a *g);
22irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g);
23irqreturn_t mc_gk20a_intr_thread_nonstall(struct gk20a *g);
24#endif
diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
index ec786a44..574ad926 100644
--- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
@@ -27,6 +27,7 @@
27#include "mm_gm20b.h" 27#include "mm_gm20b.h"
28#include "pmu_gm20b.h" 28#include "pmu_gm20b.h"
29#include "clk_gm20b.h" 29#include "clk_gm20b.h"
30#include "mc_gm20b.h"
30#include <linux/tegra-fuse.h> 31#include <linux/tegra-fuse.h>
31#include "regops_gm20b.h" 32#include "regops_gm20b.h"
32 33
@@ -113,6 +114,7 @@ int gm20b_init_hal(struct gpu_ops *gops)
113 } 114 }
114#endif 115#endif
115 116
117 gm20b_init_mc(gops);
116 gm20b_init_ltc(gops); 118 gm20b_init_ltc(gops);
117 gm20b_init_gr(gops); 119 gm20b_init_gr(gops);
118 gm20b_init_ltc(gops); 120 gm20b_init_ltc(gops);
diff --git a/drivers/gpu/nvgpu/gm20b/mc_gm20b.c b/drivers/gpu/nvgpu/gm20b/mc_gm20b.c
new file mode 100644
index 00000000..22dce1e7
--- /dev/null
+++ b/drivers/gpu/nvgpu/gm20b/mc_gm20b.c
@@ -0,0 +1,29 @@
1/*
2 * GK20A memory interface
3 *
4 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 */
15
16#include <linux/types.h>
17
18#include "gk20a/gk20a.h"
19#include "gk20a/mc_gk20a.h"
20#include "mc_gm20b.h"
21
22void gm20b_init_mc(struct gpu_ops *gops)
23{
24 gops->mc.intr_enable = mc_gk20a_intr_enable;
25 gops->mc.isr_stall = mc_gk20a_isr_stall;
26 gops->mc.isr_nonstall = mc_gk20a_isr_nonstall;
27 gops->mc.isr_thread_stall = mc_gk20a_intr_thread_stall;
28 gops->mc.isr_thread_nonstall = mc_gk20a_intr_thread_nonstall;
29}
diff --git a/drivers/gpu/nvgpu/gm20b/mc_gm20b.h b/drivers/gpu/nvgpu/gm20b/mc_gm20b.h
new file mode 100644
index 00000000..b19bf6fe
--- /dev/null
+++ b/drivers/gpu/nvgpu/gm20b/mc_gm20b.h
@@ -0,0 +1,18 @@
1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 */
13
14#ifndef MC_GM20B_H
15#define MC_GM20B_H
16
17void gm20b_init_mc(struct gpu_ops *gops);
18#endif