summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/Makefile1
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c3
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c5
-rw-r--r--drivers/gpu/nvgpu/gk20a/css_gr_gk20a.c4
-rw-r--r--drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c5
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c65
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h5
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c39
-rw-r--r--drivers/gpu/nvgpu/gk20a/hw_bus_gk20a.h24
-rw-r--r--drivers/gpu/nvgpu/gk20a/hw_pram_gk20a.h57
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c102
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.h15
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c4
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c3
-rw-r--r--drivers/gpu/nvgpu/gm20b/hw_bus_gm20b.h24
-rw-r--r--drivers/gpu/nvgpu/gm20b/hw_pram_gm20b.h57
-rw-r--r--drivers/gpu/nvgpu/gm20b/pmu_gm20b.c38
-rw-r--r--drivers/gpu/nvgpu/pci.c24
-rw-r--r--drivers/gpu/nvgpu/vgpu/vgpu.c4
19 files changed, 365 insertions, 114 deletions
diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile
index f3e2c29d..6b3c9e16 100644
--- a/drivers/gpu/nvgpu/Makefile
+++ b/drivers/gpu/nvgpu/Makefile
@@ -8,6 +8,7 @@ ccflags-y += -I../nvgpu/include/uapi
8ccflags-y += -Wno-multichar 8ccflags-y += -Wno-multichar
9ccflags-y += -Werror 9ccflags-y += -Werror
10ccflags-y += -Wno-error=cpp 10ccflags-y += -Wno-error=cpp
11ccflags-y += -Wno-duplicate-decl-specifier
11 12
12ifeq ($(CONFIG_ARCH_TEGRA_18x_SOC),y) 13ifeq ($(CONFIG_ARCH_TEGRA_18x_SOC),y)
13ccflags-y += -I$(srctree)/../nvgpu-t18x/drivers/gpu/nvgpu 14ccflags-y += -I$(srctree)/../nvgpu-t18x/drivers/gpu/nvgpu
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index f70c4bb7..a73a314c 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -2081,7 +2081,6 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
2081 } 2081 }
2082 2082
2083 if (err) { 2083 if (err) {
2084 gk20a_err(d, "timeout waiting for gpfifo space");
2085 err = -ENOSPC; 2084 err = -ENOSPC;
2086 goto clean_up; 2085 goto clean_up;
2087 } 2086 }
@@ -2279,7 +2278,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
2279 return err; 2278 return err;
2280 2279
2281clean_up: 2280clean_up:
2282 gk20a_err(d, "fail"); 2281 gk20a_dbg_fn("fail");
2283 free_priv_cmdbuf(c, wait_cmd); 2282 free_priv_cmdbuf(c, wait_cmd);
2284 free_priv_cmdbuf(c, incr_cmd); 2283 free_priv_cmdbuf(c, incr_cmd);
2285 gk20a_fence_put(pre_fence); 2284 gk20a_fence_put(pre_fence);
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
index 011c980e..10f1213b 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
@@ -204,11 +204,8 @@ static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s,
204 incr_cmd_size += 2; 204 incr_cmd_size += 2;
205 205
206 err = gk20a_channel_alloc_priv_cmdbuf(c, incr_cmd_size, &incr_cmd); 206 err = gk20a_channel_alloc_priv_cmdbuf(c, incr_cmd_size, &incr_cmd);
207 if (err) { 207 if (err)
208 gk20a_err(dev_from_gk20a(c->g),
209 "not enough priv cmd buffer space");
210 return err; 208 return err;
211 }
212 209
213 off = incr_cmd->off; 210 off = incr_cmd->off;
214 211
diff --git a/drivers/gpu/nvgpu/gk20a/css_gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/css_gr_gk20a.c
index 2008289b..1d05c902 100644
--- a/drivers/gpu/nvgpu/gk20a/css_gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/css_gr_gk20a.c
@@ -662,6 +662,10 @@ int gr_gk20a_css_attach(struct gk20a *g,
662 if (!cs_client) 662 if (!cs_client)
663 return -EINVAL; 663 return -EINVAL;
664 664
665 if (!perfmon_count ||
666 perfmon_count > CSS_MAX_PERFMON_IDS - CSS_FIRST_PERFMON_ID)
667 return -EINVAL;
668
665 gr = &g->gr; 669 gr = &g->gr;
666 *cs_client = NULL; 670 *cs_client = NULL;
667 671
diff --git a/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c
index 6744699f..77e93458 100644
--- a/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c
@@ -70,11 +70,6 @@ static inline int ring_len(struct nvgpu_ctxsw_ring_header *hdr)
70 return (hdr->write_idx - hdr->read_idx) % hdr->num_ents; 70 return (hdr->write_idx - hdr->read_idx) % hdr->num_ents;
71} 71}
72 72
73static inline int ring_space(struct nvgpu_ctxsw_ring_header *hdr)
74{
75 return (hdr->read_idx - hdr->write_idx - 1) % hdr->num_ents;
76}
77
78ssize_t gk20a_ctxsw_dev_read(struct file *filp, char __user *buf, size_t size, 73ssize_t gk20a_ctxsw_dev_read(struct file *filp, char __user *buf, size_t size,
79 loff_t *off) 74 loff_t *off)
80{ 75{
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index 3ab26fb9..2e40a675 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -705,6 +705,13 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
705 if (!g->power_on) 705 if (!g->power_on)
706 goto done; 706 goto done;
707 707
708 /*
709 * After this point, gk20a interrupts should not get
710 * serviced.
711 */
712 disable_irq(g->irq_stall);
713 disable_irq(g->irq_nonstall);
714
708 gk20a_scale_suspend(dev); 715 gk20a_scale_suspend(dev);
709 716
710 /* cancel any pending cde work */ 717 /* cancel any pending cde work */
@@ -716,12 +723,6 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
716 723
717 /* disable elpg before gr or fifo suspend */ 724 /* disable elpg before gr or fifo suspend */
718 ret |= gk20a_pmu_destroy(g); 725 ret |= gk20a_pmu_destroy(g);
719 /*
720 * After this point, gk20a interrupts should not get
721 * serviced.
722 */
723 disable_irq(g->irq_stall);
724 disable_irq(g->irq_nonstall);
725 726
726 ret |= gk20a_gr_suspend(g); 727 ret |= gk20a_gr_suspend(g);
727 ret |= gk20a_mm_suspend(g); 728 ret |= gk20a_mm_suspend(g);
@@ -966,7 +967,8 @@ static int gk20a_create_device(
966 struct device *dev, int devno, 967 struct device *dev, int devno,
967 const char *interface_name, const char *cdev_name, 968 const char *interface_name, const char *cdev_name,
968 struct cdev *cdev, struct device **out, 969 struct cdev *cdev, struct device **out,
969 const struct file_operations *ops) 970 const struct file_operations *ops,
971 struct class *class)
970{ 972{
971 struct device *subdev; 973 struct device *subdev;
972 int err; 974 int err;
@@ -982,7 +984,7 @@ static int gk20a_create_device(
982 return err; 984 return err;
983 } 985 }
984 986
985 subdev = device_create(&nvgpu_class, NULL, devno, NULL, 987 subdev = device_create(class, NULL, devno, NULL,
986 interface_name, cdev_name); 988 interface_name, cdev_name);
987 989
988 if (IS_ERR(subdev)) { 990 if (IS_ERR(subdev)) {
@@ -997,42 +999,42 @@ static int gk20a_create_device(
997 return 0; 999 return 0;
998} 1000}
999 1001
1000void gk20a_user_deinit(struct device *dev) 1002void gk20a_user_deinit(struct device *dev, struct class *class)
1001{ 1003{
1002 struct gk20a *g = gk20a_from_dev(dev); 1004 struct gk20a *g = gk20a_from_dev(dev);
1003 1005
1004 if (g->channel.node) { 1006 if (g->channel.node) {
1005 device_destroy(&nvgpu_class, g->channel.cdev.dev); 1007 device_destroy(class, g->channel.cdev.dev);
1006 cdev_del(&g->channel.cdev); 1008 cdev_del(&g->channel.cdev);
1007 } 1009 }
1008 1010
1009 if (g->as.node) { 1011 if (g->as.node) {
1010 device_destroy(&nvgpu_class, g->as.cdev.dev); 1012 device_destroy(class, g->as.cdev.dev);
1011 cdev_del(&g->as.cdev); 1013 cdev_del(&g->as.cdev);
1012 } 1014 }
1013 1015
1014 if (g->ctrl.node) { 1016 if (g->ctrl.node) {
1015 device_destroy(&nvgpu_class, g->ctrl.cdev.dev); 1017 device_destroy(class, g->ctrl.cdev.dev);
1016 cdev_del(&g->ctrl.cdev); 1018 cdev_del(&g->ctrl.cdev);
1017 } 1019 }
1018 1020
1019 if (g->dbg.node) { 1021 if (g->dbg.node) {
1020 device_destroy(&nvgpu_class, g->dbg.cdev.dev); 1022 device_destroy(class, g->dbg.cdev.dev);
1021 cdev_del(&g->dbg.cdev); 1023 cdev_del(&g->dbg.cdev);
1022 } 1024 }
1023 1025
1024 if (g->prof.node) { 1026 if (g->prof.node) {
1025 device_destroy(&nvgpu_class, g->prof.cdev.dev); 1027 device_destroy(class, g->prof.cdev.dev);
1026 cdev_del(&g->prof.cdev); 1028 cdev_del(&g->prof.cdev);
1027 } 1029 }
1028 1030
1029 if (g->tsg.node) { 1031 if (g->tsg.node) {
1030 device_destroy(&nvgpu_class, g->tsg.cdev.dev); 1032 device_destroy(class, g->tsg.cdev.dev);
1031 cdev_del(&g->tsg.cdev); 1033 cdev_del(&g->tsg.cdev);
1032 } 1034 }
1033 1035
1034 if (g->ctxsw.node) { 1036 if (g->ctxsw.node) {
1035 device_destroy(&nvgpu_class, g->ctxsw.cdev.dev); 1037 device_destroy(class, g->ctxsw.cdev.dev);
1036 cdev_del(&g->ctxsw.cdev); 1038 cdev_del(&g->ctxsw.cdev);
1037 } 1039 }
1038 1040
@@ -1040,7 +1042,8 @@ void gk20a_user_deinit(struct device *dev)
1040 unregister_chrdev_region(g->cdev_region, GK20A_NUM_CDEVS); 1042 unregister_chrdev_region(g->cdev_region, GK20A_NUM_CDEVS);
1041} 1043}
1042 1044
1043int gk20a_user_init(struct device *dev, const char *interface_name) 1045int gk20a_user_init(struct device *dev, const char *interface_name,
1046 struct class *class)
1044{ 1047{
1045 int err; 1048 int err;
1046 dev_t devno; 1049 dev_t devno;
@@ -1055,44 +1058,51 @@ int gk20a_user_init(struct device *dev, const char *interface_name)
1055 1058
1056 err = gk20a_create_device(dev, devno++, interface_name, "", 1059 err = gk20a_create_device(dev, devno++, interface_name, "",
1057 &g->channel.cdev, &g->channel.node, 1060 &g->channel.cdev, &g->channel.node,
1058 &gk20a_channel_ops); 1061 &gk20a_channel_ops,
1062 class);
1059 if (err) 1063 if (err)
1060 goto fail; 1064 goto fail;
1061 1065
1062 err = gk20a_create_device(dev, devno++, interface_name, "-as", 1066 err = gk20a_create_device(dev, devno++, interface_name, "-as",
1063 &g->as.cdev, &g->as.node, 1067 &g->as.cdev, &g->as.node,
1064 &gk20a_as_ops); 1068 &gk20a_as_ops,
1069 class);
1065 if (err) 1070 if (err)
1066 goto fail; 1071 goto fail;
1067 1072
1068 err = gk20a_create_device(dev, devno++, interface_name, "-ctrl", 1073 err = gk20a_create_device(dev, devno++, interface_name, "-ctrl",
1069 &g->ctrl.cdev, &g->ctrl.node, 1074 &g->ctrl.cdev, &g->ctrl.node,
1070 &gk20a_ctrl_ops); 1075 &gk20a_ctrl_ops,
1076 class);
1071 if (err) 1077 if (err)
1072 goto fail; 1078 goto fail;
1073 1079
1074 err = gk20a_create_device(dev, devno++, interface_name, "-dbg", 1080 err = gk20a_create_device(dev, devno++, interface_name, "-dbg",
1075 &g->dbg.cdev, &g->dbg.node, 1081 &g->dbg.cdev, &g->dbg.node,
1076 &gk20a_dbg_ops); 1082 &gk20a_dbg_ops,
1083 class);
1077 if (err) 1084 if (err)
1078 goto fail; 1085 goto fail;
1079 1086
1080 err = gk20a_create_device(dev, devno++, interface_name, "-prof", 1087 err = gk20a_create_device(dev, devno++, interface_name, "-prof",
1081 &g->prof.cdev, &g->prof.node, 1088 &g->prof.cdev, &g->prof.node,
1082 &gk20a_prof_ops); 1089 &gk20a_prof_ops,
1090 class);
1083 if (err) 1091 if (err)
1084 goto fail; 1092 goto fail;
1085 1093
1086 err = gk20a_create_device(dev, devno++, interface_name, "-tsg", 1094 err = gk20a_create_device(dev, devno++, interface_name, "-tsg",
1087 &g->tsg.cdev, &g->tsg.node, 1095 &g->tsg.cdev, &g->tsg.node,
1088 &gk20a_tsg_ops); 1096 &gk20a_tsg_ops,
1097 class);
1089 if (err) 1098 if (err)
1090 goto fail; 1099 goto fail;
1091 1100
1092#ifdef CONFIG_GK20A_CTXSW_TRACE 1101#ifdef CONFIG_GK20A_CTXSW_TRACE
1093 err = gk20a_create_device(dev, devno++, interface_name, "-ctxsw", 1102 err = gk20a_create_device(dev, devno++, interface_name, "-ctxsw",
1094 &g->ctxsw.cdev, &g->ctxsw.node, 1103 &g->ctxsw.cdev, &g->ctxsw.node,
1095 &gk20a_ctxsw_ops); 1104 &gk20a_ctxsw_ops,
1105 class);
1096 if (err) 1106 if (err)
1097 goto fail; 1107 goto fail;
1098#endif 1108#endif
@@ -1100,7 +1110,7 @@ int gk20a_user_init(struct device *dev, const char *interface_name)
1100 1110
1101 return 0; 1111 return 0;
1102fail: 1112fail:
1103 gk20a_user_deinit(dev); 1113 gk20a_user_deinit(dev, &nvgpu_class);
1104 return err; 1114 return err;
1105} 1115}
1106 1116
@@ -1464,7 +1474,7 @@ static int gk20a_probe(struct platform_device *dev)
1464 if (gk20a->irq_stall != gk20a->irq_nonstall) 1474 if (gk20a->irq_stall != gk20a->irq_nonstall)
1465 disable_irq(gk20a->irq_nonstall); 1475 disable_irq(gk20a->irq_nonstall);
1466 1476
1467 err = gk20a_user_init(&dev->dev, INTERFACE_NAME); 1477 err = gk20a_user_init(&dev->dev, INTERFACE_NAME, &nvgpu_class);
1468 if (err) 1478 if (err)
1469 return err; 1479 return err;
1470 1480
@@ -1644,7 +1654,7 @@ static int __exit gk20a_remove(struct platform_device *pdev)
1644 if (g->remove_support) 1654 if (g->remove_support)
1645 g->remove_support(dev); 1655 g->remove_support(dev);
1646 1656
1647 gk20a_user_deinit(dev); 1657 gk20a_user_deinit(dev, &nvgpu_class);
1648 1658
1649 debugfs_remove_recursive(platform->debugfs); 1659 debugfs_remove_recursive(platform->debugfs);
1650 debugfs_remove_recursive(platform->debugfs_alias); 1660 debugfs_remove_recursive(platform->debugfs_alias);
@@ -1751,7 +1761,6 @@ static int gk20a_domain_init(struct of_device_id *matches)
1751} 1761}
1752#endif 1762#endif
1753 1763
1754
1755struct class nvgpu_class = { 1764struct class nvgpu_class = {
1756 .owner = THIS_MODULE, 1765 .owner = THIS_MODULE,
1757 .name = CLASS_NAME, 1766 .name = CLASS_NAME,
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index f5b4bb3f..d131862b 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -1067,8 +1067,9 @@ int gk20a_init_gpu_characteristics(struct gk20a *g);
1067 1067
1068void gk20a_pbus_isr(struct gk20a *g); 1068void gk20a_pbus_isr(struct gk20a *g);
1069 1069
1070int gk20a_user_init(struct device *dev, const char *interface_name); 1070int gk20a_user_init(struct device *dev, const char *interface_name,
1071void gk20a_user_deinit(struct device *dev); 1071 struct class *class);
1072void gk20a_user_deinit(struct device *dev, struct class *class);
1072 1073
1073void gk20a_debug_dump_device(void *dev); 1074void gk20a_debug_dump_device(void *dev);
1074 1075
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 60247da8..e8d363e1 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -1203,15 +1203,18 @@ static int gr_gk20a_setup_alpha_beta_tables(struct gk20a *g,
1203 u32 reg_offset; 1203 u32 reg_offset;
1204 bool assign_alpha; 1204 bool assign_alpha;
1205 1205
1206 u32 map_alpha[gr_pd_alpha_ratio_table__size_1_v()]; 1206 u32 *map_alpha;
1207 u32 map_beta[gr_pd_alpha_ratio_table__size_1_v()]; 1207 u32 *map_beta;
1208 u32 map_reg_used[gr_pd_alpha_ratio_table__size_1_v()]; 1208 u32 *map_reg_used;
1209 1209
1210 gk20a_dbg_fn(""); 1210 gk20a_dbg_fn("");
1211 1211
1212 memset(map_alpha, 0, gr_pd_alpha_ratio_table__size_1_v() * sizeof(u32)); 1212 map_alpha = kzalloc(3 * gr_pd_alpha_ratio_table__size_1_v() *
1213 memset(map_beta, 0, gr_pd_alpha_ratio_table__size_1_v() * sizeof(u32)); 1213 sizeof(u32), GFP_KERNEL);
1214 memset(map_reg_used, 0, gr_pd_alpha_ratio_table__size_1_v() * sizeof(u32)); 1214 if (!map_alpha)
1215 return -ENOMEM;
1216 map_beta = map_alpha + gr_pd_alpha_ratio_table__size_1_v();
1217 map_reg_used = map_beta + gr_pd_alpha_ratio_table__size_1_v();
1215 1218
1216 for (row = 0; row < rows; ++row) { 1219 for (row = 0; row < rows; ++row) {
1217 alpha_target = max_t(u32, gr->tpc_count * row / rows, 1); 1220 alpha_target = max_t(u32, gr->tpc_count * row / rows, 1);
@@ -1277,6 +1280,7 @@ static int gr_gk20a_setup_alpha_beta_tables(struct gk20a *g,
1277 } 1280 }
1278 } 1281 }
1279 1282
1283 kfree(map_alpha);
1280 return 0; 1284 return 0;
1281} 1285}
1282 1286
@@ -2032,8 +2036,7 @@ int gr_gk20a_init_ctxsw_ucode(struct gk20a *g)
2032 g->gr.ctx_vars.ucode.gpccs.inst.count * sizeof(u32), 2036 g->gr.ctx_vars.ucode.gpccs.inst.count * sizeof(u32),
2033 g->gr.ctx_vars.ucode.gpccs.data.count * sizeof(u32)); 2037 g->gr.ctx_vars.ucode.gpccs.data.count * sizeof(u32));
2034 2038
2035 err = gk20a_gmmu_alloc_attr(g, DMA_ATTR_READ_ONLY, ucode_size, 2039 err = gk20a_gmmu_alloc(g, ucode_size, &ucode_info->surface_desc);
2036 &ucode_info->surface_desc);
2037 if (err) 2040 if (err)
2038 goto clean_up; 2041 goto clean_up;
2039 2042
@@ -3261,15 +3264,17 @@ static int gr_gk20a_init_gr_config(struct gk20a *g, struct gr_gk20a *gr)
3261 g->ops.gr.get_gpc_tpc_mask(g, gpc_index); 3264 g->ops.gr.get_gpc_tpc_mask(g, gpc_index);
3262 3265
3263 for (pes_index = 0; pes_index < gr->pe_count_per_gpc; pes_index++) { 3266 for (pes_index = 0; pes_index < gr->pe_count_per_gpc; pes_index++) {
3264 gr->pes_tpc_count[pes_index] = 3267 if (!gr->pes_tpc_count[pes_index]) {
3265 kzalloc(gr->gpc_count * sizeof(u32), 3268 gr->pes_tpc_count[pes_index] =
3266 GFP_KERNEL); 3269 kzalloc(gr->gpc_count * sizeof(u32),
3267 gr->pes_tpc_mask[pes_index] = 3270 GFP_KERNEL);
3268 kzalloc(gr->gpc_count * sizeof(u32), 3271 gr->pes_tpc_mask[pes_index] =
3269 GFP_KERNEL); 3272 kzalloc(gr->gpc_count * sizeof(u32),
3270 if (!gr->pes_tpc_count[pes_index] || 3273 GFP_KERNEL);
3271 !gr->pes_tpc_mask[pes_index]) 3274 if (!gr->pes_tpc_count[pes_index] ||
3272 goto clean_up; 3275 !gr->pes_tpc_mask[pes_index])
3276 goto clean_up;
3277 }
3273 3278
3274 tmp = gk20a_readl(g, 3279 tmp = gk20a_readl(g,
3275 gr_gpc0_gpm_pd_pes_tpc_id_mask_r(pes_index) + 3280 gr_gpc0_gpm_pd_pes_tpc_id_mask_r(pes_index) +
diff --git a/drivers/gpu/nvgpu/gk20a/hw_bus_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_bus_gk20a.h
index 8a69c573..2c902f52 100644
--- a/drivers/gpu/nvgpu/gk20a/hw_bus_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/hw_bus_gk20a.h
@@ -50,6 +50,30 @@
50#ifndef _hw_bus_gk20a_h_ 50#ifndef _hw_bus_gk20a_h_
51#define _hw_bus_gk20a_h_ 51#define _hw_bus_gk20a_h_
52 52
53static inline u32 bus_bar0_window_r(void)
54{
55 return 0x00001700;
56}
57static inline u32 bus_bar0_window_base_f(u32 v)
58{
59 return (v & 0xffffff) << 0;
60}
61static inline u32 bus_bar0_window_target_vid_mem_f(void)
62{
63 return 0x0;
64}
65static inline u32 bus_bar0_window_target_sys_mem_coherent_f(void)
66{
67 return 0x2000000;
68}
69static inline u32 bus_bar0_window_target_sys_mem_noncoherent_f(void)
70{
71 return 0x3000000;
72}
73static inline u32 bus_bar0_window_target_bar0_window_base_shift_v(void)
74{
75 return 0x00000010;
76}
53static inline u32 bus_bar1_block_r(void) 77static inline u32 bus_bar1_block_r(void)
54{ 78{
55 return 0x00001704; 79 return 0x00001704;
diff --git a/drivers/gpu/nvgpu/gk20a/hw_pram_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_pram_gk20a.h
new file mode 100644
index 00000000..918dad9a
--- /dev/null
+++ b/drivers/gpu/nvgpu/gk20a/hw_pram_gk20a.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 2016, 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 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16/*
17 * Function naming determines intended use:
18 *
19 * <x>_r(void) : Returns the offset for register <x>.
20 *
21 * <x>_o(void) : Returns the offset for element <x>.
22 *
23 * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
24 *
25 * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
26 *
27 * <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
28 * and masked to place it at field <y> of register <x>. This value
29 * can be |'d with others to produce a full register value for
30 * register <x>.
31 *
32 * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
33 * value can be ~'d and then &'d to clear the value of field <y> for
34 * register <x>.
35 *
36 * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
37 * to place it at field <y> of register <x>. This value can be |'d
38 * with others to produce a full register value for <x>.
39 *
40 * <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
41 * <x> value 'r' after being shifted to place its LSB at bit 0.
42 * This value is suitable for direct comparison with other unshifted
43 * values appropriate for use in field <y> of register <x>.
44 *
45 * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
46 * field <y> of register <x>. This value is suitable for direct
47 * comparison with unshifted values appropriate for use in field <y>
48 * of register <x>.
49 */
50#ifndef _hw_pram_gk20a_h_
51#define _hw_pram_gk20a_h_
52
53static inline u32 pram_data032_r(u32 i)
54{
55 return 0x00700000 + i*4;
56}
57#endif
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index eb4f01e0..ec946fb6 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -37,6 +37,7 @@
37#include "hw_fb_gk20a.h" 37#include "hw_fb_gk20a.h"
38#include "hw_bus_gk20a.h" 38#include "hw_bus_gk20a.h"
39#include "hw_ram_gk20a.h" 39#include "hw_ram_gk20a.h"
40#include "hw_pram_gk20a.h"
40#include "hw_mc_gk20a.h" 41#include "hw_mc_gk20a.h"
41#include "hw_flush_gk20a.h" 42#include "hw_flush_gk20a.h"
42#include "hw_ltc_gk20a.h" 43#include "hw_ltc_gk20a.h"
@@ -44,10 +45,20 @@
44#include "kind_gk20a.h" 45#include "kind_gk20a.h"
45#include "semaphore_gk20a.h" 46#include "semaphore_gk20a.h"
46 47
48/*
49 * Flip this to force all gk20a_mem* accesses via PRAMIN from the start of the
50 * boot, even for buffers that would work via cpu_va. In runtime, the flag is
51 * in debugfs, called "force_pramin".
52 */
53#define GK20A_FORCE_PRAMIN_DEFAULT false
54
47int gk20a_mem_begin(struct gk20a *g, struct mem_desc *mem) 55int gk20a_mem_begin(struct gk20a *g, struct mem_desc *mem)
48{ 56{
49 void *cpu_va; 57 void *cpu_va;
50 58
59 if (mem->aperture != APERTURE_SYSMEM || g->mm.force_pramin)
60 return 0;
61
51 if (WARN_ON(mem->cpu_va)) { 62 if (WARN_ON(mem->cpu_va)) {
52 gk20a_warn(dev_from_gk20a(g), "nested %s", __func__); 63 gk20a_warn(dev_from_gk20a(g), "nested %s", __func__);
53 return -EBUSY; 64 return -EBUSY;
@@ -66,20 +77,66 @@ int gk20a_mem_begin(struct gk20a *g, struct mem_desc *mem)
66 77
67void gk20a_mem_end(struct gk20a *g, struct mem_desc *mem) 78void gk20a_mem_end(struct gk20a *g, struct mem_desc *mem)
68{ 79{
80 if (mem->aperture != APERTURE_SYSMEM || g->mm.force_pramin)
81 return;
82
69 vunmap(mem->cpu_va); 83 vunmap(mem->cpu_va);
70 mem->cpu_va = NULL; 84 mem->cpu_va = NULL;
71} 85}
72 86
87/* WARNING: returns pramin_base_lock taken, complement with pramin_exit() */
88static u32 gk20a_pramin_enter(struct gk20a *g, struct mem_desc *mem, u32 w)
89{
90 u64 bufbase = g->ops.mm.get_iova_addr(g, mem->sgt->sgl, 0);
91 u64 addr = bufbase + w * sizeof(u32);
92 u32 hi = (u32)((addr & ~(u64)0xfffff)
93 >> bus_bar0_window_target_bar0_window_base_shift_v());
94 u32 lo = (addr & 0xfffff);
95
96 gk20a_dbg(gpu_dbg_mem, "0x%08x:%08x begin for %p", hi, lo, mem);
97
98 WARN_ON(!bufbase);
99 spin_lock(&g->mm.pramin_base_lock);
100 if (g->mm.pramin_base != hi) {
101 gk20a_writel(g, bus_bar0_window_r(),
102 (g->mm.vidmem_is_vidmem
103 && mem->aperture == APERTURE_SYSMEM ?
104 bus_bar0_window_target_sys_mem_noncoherent_f() :
105 bus_bar0_window_target_vid_mem_f()) |
106 bus_bar0_window_base_f(hi));
107 gk20a_readl(g, bus_bar0_window_r());
108 g->mm.pramin_base = hi;
109 }
110
111 return lo;
112}
113
114static void gk20a_pramin_exit(struct gk20a *g, struct mem_desc *mem)
115{
116 gk20a_dbg(gpu_dbg_mem, "end for %p", mem);
117 spin_unlock(&g->mm.pramin_base_lock);
118}
119
73u32 gk20a_mem_rd32(struct gk20a *g, struct mem_desc *mem, u32 w) 120u32 gk20a_mem_rd32(struct gk20a *g, struct mem_desc *mem, u32 w)
74{ 121{
75 u32 *ptr = mem->cpu_va; 122 u32 data = 0;
76 u32 data; 123
124 if (mem->aperture == APERTURE_SYSMEM && !g->mm.force_pramin) {
125 u32 *ptr = mem->cpu_va;
77 126
78 WARN_ON(!ptr); 127 WARN_ON(!ptr);
79 data = ptr[w]; 128 data = ptr[w];
80#ifdef CONFIG_TEGRA_SIMULATION_PLATFORM 129#ifdef CONFIG_TEGRA_SIMULATION_PLATFORM
81 gk20a_dbg(gpu_dbg_mem, " %p = 0x%x", ptr + w, data); 130 gk20a_dbg(gpu_dbg_mem, " %p = 0x%x", ptr + w, data);
82#endif 131#endif
132 } else if (mem->aperture == APERTURE_VIDMEM || g->mm.force_pramin) {
133 u32 addr = gk20a_pramin_enter(g, mem, w);
134 data = gk20a_readl(g, pram_data032_r(addr / sizeof(u32)));
135 gk20a_pramin_exit(g, mem);
136 } else {
137 WARN_ON("Accessing unallocated mem_desc");
138 }
139
83 return data; 140 return data;
84} 141}
85 142
@@ -106,13 +163,23 @@ void gk20a_mem_rd_n(struct gk20a *g, struct mem_desc *mem,
106 163
107void gk20a_mem_wr32(struct gk20a *g, struct mem_desc *mem, u32 w, u32 data) 164void gk20a_mem_wr32(struct gk20a *g, struct mem_desc *mem, u32 w, u32 data)
108{ 165{
109 u32 *ptr = mem->cpu_va; 166 if (mem->aperture == APERTURE_SYSMEM && !g->mm.force_pramin) {
167 u32 *ptr = mem->cpu_va;
110 168
111 WARN_ON(!ptr); 169 WARN_ON(!ptr);
112#ifdef CONFIG_TEGRA_SIMULATION_PLATFORM 170#ifdef CONFIG_TEGRA_SIMULATION_PLATFORM
113 gk20a_dbg(gpu_dbg_mem, " %p = 0x%x", ptr + w, data); 171 gk20a_dbg(gpu_dbg_mem, " %p = 0x%x", ptr + w, data);
114#endif 172#endif
115 ptr[w] = data; 173 ptr[w] = data;
174 } else if (mem->aperture == APERTURE_VIDMEM || g->mm.force_pramin) {
175 u32 addr = gk20a_pramin_enter(g, mem, w);
176 gk20a_writel(g, pram_data032_r(addr / sizeof(u32)), data);
177 /* read back to synchronize accesses*/
178 gk20a_readl(g, pram_data032_r(addr / sizeof(u32)));
179 gk20a_pramin_exit(g, mem);
180 } else {
181 WARN_ON("Accessing unallocated mem_desc");
182 }
116} 183}
117 184
118void gk20a_mem_wr(struct gk20a *g, struct mem_desc *mem, u32 offset, u32 data) 185void gk20a_mem_wr(struct gk20a *g, struct mem_desc *mem, u32 offset, u32 data)
@@ -535,6 +602,13 @@ static int gk20a_alloc_sysmem_flush(struct gk20a *g)
535 return gk20a_gmmu_alloc(g, SZ_4K, &g->mm.sysmem_flush); 602 return gk20a_gmmu_alloc(g, SZ_4K, &g->mm.sysmem_flush);
536} 603}
537 604
605static void gk20a_init_pramin(struct mm_gk20a *mm)
606{
607 mm->pramin_base = 0;
608 spin_lock_init(&mm->pramin_base_lock);
609 mm->force_pramin = GK20A_FORCE_PRAMIN_DEFAULT;
610}
611
538int gk20a_init_mm_setup_sw(struct gk20a *g) 612int gk20a_init_mm_setup_sw(struct gk20a *g)
539{ 613{
540 struct mm_gk20a *mm = &g->mm; 614 struct mm_gk20a *mm = &g->mm;
@@ -558,6 +632,8 @@ int gk20a_init_mm_setup_sw(struct gk20a *g)
558 (int)(mm->channel.user_size >> 20), 632 (int)(mm->channel.user_size >> 20),
559 (int)(mm->channel.kernel_size >> 20)); 633 (int)(mm->channel.kernel_size >> 20));
560 634
635 gk20a_init_pramin(mm);
636
561 err = gk20a_alloc_sysmem_flush(g); 637 err = gk20a_alloc_sysmem_flush(g);
562 if (err) 638 if (err)
563 return err; 639 return err;
@@ -586,6 +662,7 @@ int gk20a_init_mm_setup_sw(struct gk20a *g)
586 /* set vm_alloc_share op here as gk20a_as_alloc_share needs it */ 662 /* set vm_alloc_share op here as gk20a_as_alloc_share needs it */
587 g->ops.mm.vm_alloc_share = gk20a_vm_alloc_share; 663 g->ops.mm.vm_alloc_share = gk20a_vm_alloc_share;
588 mm->remove_support = gk20a_remove_mm_support; 664 mm->remove_support = gk20a_remove_mm_support;
665
589 mm->sw_ready = true; 666 mm->sw_ready = true;
590 667
591 gk20a_dbg_fn("done"); 668 gk20a_dbg_fn("done");
@@ -690,6 +767,7 @@ static int alloc_gmmu_phys_pages(struct vm_gk20a *vm, u32 order,
690 entry->mem.cpu_va = page_address(pages); 767 entry->mem.cpu_va = page_address(pages);
691 memset(entry->mem.cpu_va, 0, len); 768 memset(entry->mem.cpu_va, 0, len);
692 entry->mem.size = len; 769 entry->mem.size = len;
770 entry->mem.aperture = APERTURE_SYSMEM;
693 FLUSH_CPU_DCACHE(entry->mem.cpu_va, sg_phys(entry->mem.sgt->sgl), len); 771 FLUSH_CPU_DCACHE(entry->mem.cpu_va, sg_phys(entry->mem.sgt->sgl), len);
694 772
695 return 0; 773 return 0;
@@ -716,6 +794,7 @@ static void free_gmmu_phys_pages(struct vm_gk20a *vm,
716 kfree(entry->mem.sgt); 794 kfree(entry->mem.sgt);
717 entry->mem.sgt = NULL; 795 entry->mem.sgt = NULL;
718 entry->mem.size = 0; 796 entry->mem.size = 0;
797 entry->mem.aperture = APERTURE_INVALID;
719} 798}
720 799
721static int map_gmmu_phys_pages(struct gk20a_mm_entry *entry) 800static int map_gmmu_phys_pages(struct gk20a_mm_entry *entry)
@@ -2164,6 +2243,7 @@ int gk20a_gmmu_alloc_attr(struct gk20a *g, enum dma_attr attr, size_t size, stru
2164 goto fail_free; 2243 goto fail_free;
2165 2244
2166 mem->size = size; 2245 mem->size = size;
2246 mem->aperture = APERTURE_SYSMEM;
2167 2247
2168 gk20a_dbg_fn("done"); 2248 gk20a_dbg_fn("done");
2169 2249
@@ -2210,6 +2290,7 @@ void gk20a_gmmu_free_attr(struct gk20a *g, enum dma_attr attr,
2210 gk20a_free_sgtable(&mem->sgt); 2290 gk20a_free_sgtable(&mem->sgt);
2211 2291
2212 mem->size = 0; 2292 mem->size = 0;
2293 mem->aperture = APERTURE_INVALID;
2213} 2294}
2214 2295
2215void gk20a_gmmu_free(struct gk20a *g, struct mem_desc *mem) 2296void gk20a_gmmu_free(struct gk20a *g, struct mem_desc *mem)
@@ -4015,6 +4096,9 @@ void gk20a_mm_debugfs_init(struct device *dev)
4015 4096
4016 debugfs_create_x64("separate_fixed_allocs", 0664, gpu_root, 4097 debugfs_create_x64("separate_fixed_allocs", 0664, gpu_root,
4017 &g->separate_fixed_allocs); 4098 &g->separate_fixed_allocs);
4099
4100 debugfs_create_bool("force_pramin", 0664, gpu_root,
4101 &g->mm.force_pramin);
4018} 4102}
4019 4103
4020void gk20a_init_mm(struct gpu_ops *gops) 4104void gk20a_init_mm(struct gpu_ops *gops)
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
index d943b231..c58a4fec 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
@@ -40,10 +40,17 @@
40 outer_flush_range(pa, pa + (size_t)(size)); \ 40 outer_flush_range(pa, pa + (size_t)(size)); \
41 } while (0) 41 } while (0)
42 42
43enum gk20a_aperture {
44 APERTURE_INVALID, /* e.g., unallocated */
45 APERTURE_SYSMEM,
46 APERTURE_VIDMEM
47};
48
43struct mem_desc { 49struct mem_desc {
44 void *cpu_va; 50 void *cpu_va;
45 struct page **pages; 51 struct page **pages;
46 struct sg_table *sgt; 52 struct sg_table *sgt;
53 enum gk20a_aperture aperture;
47 size_t size; 54 size_t size;
48 u64 gpu_va; 55 u64 gpu_va;
49}; 56};
@@ -357,6 +364,14 @@ struct mm_gk20a {
357 bool vidmem_is_vidmem; 364 bool vidmem_is_vidmem;
358 365
359 struct mem_desc sysmem_flush; 366 struct mem_desc sysmem_flush;
367
368 u32 pramin_base;
369 spinlock_t pramin_base_lock;
370#if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0)
371 u32 force_pramin; /* via debugfs */
372#else
373 bool force_pramin; /* via debugfs */
374#endif
360}; 375};
361 376
362int gk20a_mm_init(struct mm_gk20a *mm); 377int gk20a_mm_init(struct mm_gk20a *mm);
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
index abe6771c..ca36d481 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
@@ -52,12 +52,12 @@ struct gk20a_emc_params {
52}; 52};
53 53
54static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); 54static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
55static inline u32 pmc_read(unsigned long reg) 55static inline u32 __maybe_unused pmc_read(unsigned long reg)
56{ 56{
57 return readl(pmc + reg); 57 return readl(pmc + reg);
58} 58}
59 59
60static inline void pmc_write(u32 val, unsigned long reg) 60static inline void __maybe_unused pmc_write(u32 val, unsigned long reg)
61{ 61{
62 writel_relaxed(val, pmc + reg); 62 writel_relaxed(val, pmc + reg);
63} 63}
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
index 8bf382fd..08ef7738 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
@@ -2443,8 +2443,7 @@ static int gk20a_prepare_ucode(struct gk20a *g)
2443 pmu->ucode_image = (u32 *)((u8 *)pmu->desc + 2443 pmu->ucode_image = (u32 *)((u8 *)pmu->desc +
2444 pmu->desc->descriptor_size); 2444 pmu->desc->descriptor_size);
2445 2445
2446 err = gk20a_gmmu_alloc_map_attr(vm, DMA_ATTR_READ_ONLY, 2446 err = gk20a_gmmu_alloc_map(vm, GK20A_PMU_UCODE_SIZE_MAX, &pmu->ucode);
2447 GK20A_PMU_UCODE_SIZE_MAX, &pmu->ucode);
2448 if (err) 2447 if (err)
2449 goto err_release_fw; 2448 goto err_release_fw;
2450 2449
diff --git a/drivers/gpu/nvgpu/gm20b/hw_bus_gm20b.h b/drivers/gpu/nvgpu/gm20b/hw_bus_gm20b.h
index e69275e0..0b4eefe0 100644
--- a/drivers/gpu/nvgpu/gm20b/hw_bus_gm20b.h
+++ b/drivers/gpu/nvgpu/gm20b/hw_bus_gm20b.h
@@ -50,6 +50,30 @@
50#ifndef _hw_bus_gm20b_h_ 50#ifndef _hw_bus_gm20b_h_
51#define _hw_bus_gm20b_h_ 51#define _hw_bus_gm20b_h_
52 52
53static inline u32 bus_bar0_window_r(void)
54{
55 return 0x00001700;
56}
57static inline u32 bus_bar0_window_base_f(u32 v)
58{
59 return (v & 0xffffff) << 0;
60}
61static inline u32 bus_bar0_window_target_vid_mem_f(void)
62{
63 return 0x0;
64}
65static inline u32 bus_bar0_window_target_sys_mem_coherent_f(void)
66{
67 return 0x2000000;
68}
69static inline u32 bus_bar0_window_target_sys_mem_noncoherent_f(void)
70{
71 return 0x3000000;
72}
73static inline u32 bus_bar0_window_target_bar0_window_base_shift_v(void)
74{
75 return 0x00000010;
76}
53static inline u32 bus_bar1_block_r(void) 77static inline u32 bus_bar1_block_r(void)
54{ 78{
55 return 0x00001704; 79 return 0x00001704;
diff --git a/drivers/gpu/nvgpu/gm20b/hw_pram_gm20b.h b/drivers/gpu/nvgpu/gm20b/hw_pram_gm20b.h
new file mode 100644
index 00000000..f9c6f3d4
--- /dev/null
+++ b/drivers/gpu/nvgpu/gm20b/hw_pram_gm20b.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 2016, 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 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16/*
17 * Function naming determines intended use:
18 *
19 * <x>_r(void) : Returns the offset for register <x>.
20 *
21 * <x>_o(void) : Returns the offset for element <x>.
22 *
23 * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
24 *
25 * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
26 *
27 * <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
28 * and masked to place it at field <y> of register <x>. This value
29 * can be |'d with others to produce a full register value for
30 * register <x>.
31 *
32 * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
33 * value can be ~'d and then &'d to clear the value of field <y> for
34 * register <x>.
35 *
36 * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
37 * to place it at field <y> of register <x>. This value can be |'d
38 * with others to produce a full register value for <x>.
39 *
40 * <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
41 * <x> value 'r' after being shifted to place its LSB at bit 0.
42 * This value is suitable for direct comparison with other unshifted
43 * values appropriate for use in field <y> of register <x>.
44 *
45 * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
46 * field <y> of register <x>. This value is suitable for direct
47 * comparison with unshifted values appropriate for use in field <y>
48 * of register <x>.
49 */
50#ifndef _hw_pram_gm20b_h_
51#define _hw_pram_gm20b_h_
52
53static inline u32 pram_data032_r(u32 i)
54{
55 return 0x00700000 + i*4;
56}
57#endif
diff --git a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
index 8eb600ef..8702658c 100644
--- a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
@@ -69,44 +69,6 @@ static struct pg_init_sequence_list _pginitseq_gm20b[] = {
69 { 0x0010e06c, 0x00000099}, 69 { 0x0010e06c, 0x00000099},
70 { 0x0010e06c, 0x0000009a}, 70 { 0x0010e06c, 0x0000009a},
71 { 0x0010e06c, 0x0000009b}, 71 { 0x0010e06c, 0x0000009b},
72 { 0x0010e06c, 0x00000000},
73 { 0x0010e06c, 0x00000000},
74 { 0x0010e06c, 0x00000000},
75 { 0x0010e06c, 0x00000000},
76 { 0x0010e06c, 0x00000000},
77 { 0x0010e06c, 0x00000000},
78 { 0x0010e06c, 0x00000000},
79 { 0x0010e06c, 0x00000000},
80 { 0x0010e06c, 0x00000000},
81 { 0x0010e06c, 0x00000000},
82 { 0x0010e06c, 0x00000000},
83 { 0x0010e06c, 0x00000000},
84 { 0x0010e06c, 0x00000000},
85 { 0x0010e06c, 0x00000000},
86 { 0x0010e06c, 0x00000000},
87 { 0x0010e06c, 0x00000000},
88 { 0x0010e06c, 0x00000000},
89 { 0x0010e06c, 0x00000000},
90 { 0x0010e06c, 0x00000000},
91 { 0x0010e06c, 0x00000000},
92 { 0x0010e06c, 0x00000000},
93 { 0x0010e06c, 0x00000000},
94 { 0x0010e06c, 0x00000000},
95 { 0x0010e06c, 0x00000000},
96 { 0x0010e06c, 0x00000000},
97 { 0x0010e06c, 0x00000000},
98 { 0x0010e06c, 0x00000000},
99 { 0x0010e06c, 0x00000000},
100 { 0x0010e06c, 0x00000000},
101 { 0x0010e06c, 0x00000000},
102 { 0x0010e06c, 0x00000000},
103 { 0x0010e06c, 0x00000000},
104 { 0x0010e06c, 0x00000000},
105 { 0x0010e06c, 0x00000000},
106 { 0x0010e06c, 0x00000000},
107 { 0x0010e06c, 0x00000000},
108 { 0x0010e06c, 0x00000000},
109 { 0x0010e06c, 0x00000000},
110 { 0x0010ab14, 0x00000000}, 72 { 0x0010ab14, 0x00000000},
111 { 0x0010ab18, 0x00000000}, 73 { 0x0010ab18, 0x00000000},
112 { 0x0010e024, 0x00000000}, 74 { 0x0010e024, 0x00000000},
diff --git a/drivers/gpu/nvgpu/pci.c b/drivers/gpu/nvgpu/pci.c
index 9ae5e2c6..3057a625 100644
--- a/drivers/gpu/nvgpu/pci.c
+++ b/drivers/gpu/nvgpu/pci.c
@@ -21,7 +21,7 @@
21#include "gk20a/gk20a.h" 21#include "gk20a/gk20a.h"
22#include "gk20a/platform_gk20a.h" 22#include "gk20a/platform_gk20a.h"
23 23
24#define PCI_INTERFACE_NAME "nvgpu-pci-%s%%s" 24#define PCI_INTERFACE_NAME "card-%s%%s"
25 25
26static int nvgpu_pci_tegra_probe(struct device *dev) 26static int nvgpu_pci_tegra_probe(struct device *dev)
27{ 27{
@@ -135,6 +135,17 @@ static int nvgpu_pci_init_support(struct pci_dev *pdev)
135 return err; 135 return err;
136} 136}
137 137
138static char *nvgpu_pci_devnode(struct device *dev, umode_t *mode)
139{
140 return kasprintf(GFP_KERNEL, "nvgpu-pci/%s", dev_name(dev));
141}
142
143struct class nvgpu_pci_class = {
144 .owner = THIS_MODULE,
145 .name = "nvidia-pci-gpu",
146 .devnode = nvgpu_pci_devnode,
147};
148
138static int nvgpu_pci_probe(struct pci_dev *pdev, 149static int nvgpu_pci_probe(struct pci_dev *pdev,
139 const struct pci_device_id *pent) 150 const struct pci_device_id *pent)
140{ 151{
@@ -187,7 +198,7 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
187 if (!nodefmt) 198 if (!nodefmt)
188 return -ENOMEM; 199 return -ENOMEM;
189 200
190 err = gk20a_user_init(&pdev->dev, nodefmt); 201 err = gk20a_user_init(&pdev->dev, nodefmt, &nvgpu_pci_class);
191 kfree(nodefmt); 202 kfree(nodefmt);
192 nodefmt = NULL; 203 nodefmt = NULL;
193 if (err) 204 if (err)
@@ -248,7 +259,7 @@ static void nvgpu_pci_remove(struct pci_dev *pdev)
248 if (g->remove_support) 259 if (g->remove_support)
249 g->remove_support(g->dev); 260 g->remove_support(g->dev);
250 261
251 gk20a_user_deinit(g->dev); 262 gk20a_user_deinit(g->dev, &nvgpu_pci_class);
252 263
253 debugfs_remove_recursive(platform->debugfs); 264 debugfs_remove_recursive(platform->debugfs);
254 debugfs_remove_recursive(platform->debugfs_alias); 265 debugfs_remove_recursive(platform->debugfs_alias);
@@ -270,10 +281,17 @@ static struct pci_driver nvgpu_pci_driver = {
270 281
271int __init nvgpu_pci_init(void) 282int __init nvgpu_pci_init(void)
272{ 283{
284 int ret;
285
286 ret = class_register(&nvgpu_pci_class);
287 if (ret)
288 return ret;
289
273 return pci_register_driver(&nvgpu_pci_driver); 290 return pci_register_driver(&nvgpu_pci_driver);
274} 291}
275 292
276void __exit nvgpu_pci_exit(void) 293void __exit nvgpu_pci_exit(void)
277{ 294{
278 pci_unregister_driver(&nvgpu_pci_driver); 295 pci_unregister_driver(&nvgpu_pci_driver);
296 class_unregister(&nvgpu_pci_class);
279} 297}
diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c
index 78492d3b..3c06652b 100644
--- a/drivers/gpu/nvgpu/vgpu/vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/vgpu.c
@@ -418,7 +418,7 @@ int vgpu_probe(struct platform_device *pdev)
418 platform->g = gk20a; 418 platform->g = gk20a;
419 gk20a->dev = dev; 419 gk20a->dev = dev;
420 420
421 err = gk20a_user_init(dev, INTERFACE_NAME); 421 err = gk20a_user_init(dev, INTERFACE_NAME, &nvgpu_class);
422 if (err) 422 if (err)
423 return err; 423 return err;
424 424
@@ -498,7 +498,7 @@ int vgpu_remove(struct platform_device *pdev)
498 kfree(vgpu_gpd); 498 kfree(vgpu_gpd);
499 499
500 vgpu_comm_deinit(); 500 vgpu_comm_deinit();
501 gk20a_user_deinit(dev); 501 gk20a_user_deinit(dev, &nvgpu_class);
502 gk20a_get_platform(dev)->g = NULL; 502 gk20a_get_platform(dev)->g = NULL;
503 kfree(g); 503 kfree(g);
504 return 0; 504 return 0;