summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Singh <sumsingh@nvidia.com>2015-01-04 03:00:33 -0500
committerDan Willemsen <dwillemsen@nvidia.com>2015-04-04 21:57:41 -0400
commit86637dcef9a978d21bae9978ce3f6863a45fc973 (patch)
tree98a00bd140aa0454d188cf897c2c6c69f748e7f4
parent182730599e3636b337b76fa49adbc1a5b243667f (diff)
gpu: nvgpu: Add DT support for gpu power-domain
First, defining a new structure to support gk20a power domain. Then making necessary modifications to add so as to add DT support for gpu power-domain. bug 200070810 Change-Id: I29e1c24b181e14743d3969103abfd1882d171f07 Signed-off-by: Sumit Singh <sumsingh@nvidia.com> Reviewed-on: http://git-master/r/668973 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c137
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h7
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c10
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c8
-rw-r--r--drivers/gpu/nvgpu/vgpu/vgpu.c17
5 files changed, 157 insertions, 22 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index b7357c6b..67aa49c6 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -1134,10 +1134,11 @@ static int _gk20a_pm_railgate(struct platform_device *pdev)
1134 1134
1135static int gk20a_pm_railgate(struct generic_pm_domain *domain) 1135static int gk20a_pm_railgate(struct generic_pm_domain *domain)
1136{ 1136{
1137 struct gk20a *g = container_of(domain, struct gk20a, pd); 1137 struct gk20a_domain_data *gk20a_domain = container_of(domain,
1138 struct gk20a_platform *platform = platform_get_drvdata(g->dev); 1138 struct gk20a_domain_data, gpd);
1139 struct gk20a *g = gk20a_domain->gk20a;
1139 1140
1140 return _gk20a_pm_railgate(platform->g->dev); 1141 return _gk20a_pm_railgate(g->dev);
1141} 1142}
1142 1143
1143static int _gk20a_pm_unrailgate(struct platform_device *pdev) 1144static int _gk20a_pm_unrailgate(struct platform_device *pdev)
@@ -1156,12 +1157,12 @@ static int _gk20a_pm_unrailgate(struct platform_device *pdev)
1156 1157
1157static int gk20a_pm_unrailgate(struct generic_pm_domain *domain) 1158static int gk20a_pm_unrailgate(struct generic_pm_domain *domain)
1158{ 1159{
1159 struct gk20a *g = container_of(domain, struct gk20a, pd); 1160 struct gk20a_domain_data *gk20a_domain = container_of(domain,
1160 struct gk20a_platform *platform = platform_get_drvdata(g->dev); 1161 struct gk20a_domain_data, gpd);
1161 1162 struct gk20a *g = gk20a_domain->gk20a;
1162 trace_gk20a_pm_unrailgate(dev_name(&g->dev->dev)); 1163 trace_gk20a_pm_unrailgate(dev_name(&g->dev->dev));
1163 1164
1164 return _gk20a_pm_unrailgate(platform->g->dev); 1165 return _gk20a_pm_unrailgate(g->dev);
1165} 1166}
1166 1167
1167#if 0 1168#if 0
@@ -1191,12 +1192,41 @@ static int gk20a_pm_resume(struct device *dev)
1191} 1192}
1192#endif 1193#endif
1193 1194
1195#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
1196static int gk20a_pm_initialise_domain(struct platform_device *pdev)
1197{
1198 struct gk20a_platform *platform = platform_get_drvdata(pdev);
1199 struct dev_power_governor *pm_domain_gov = NULL;
1200 struct generic_pm_domain *domain = dev_to_genpd(&pdev->dev);
1201
1202#ifdef CONFIG_PM_RUNTIME
1203 if (!platform->can_railgate)
1204 pm_domain_gov = &pm_domain_always_on_gov;
1205#endif
1206 domain->gov = pm_domain_gov;
1207
1208 if (platform->railgate_delay)
1209 pm_genpd_set_poweroff_delay(domain, platform->railgate_delay);
1210
1211 device_set_wakeup_capable(&pdev->dev, 0);
1212 return 0;
1213}
1214
1215#else
1194static int gk20a_pm_initialise_domain(struct platform_device *pdev) 1216static int gk20a_pm_initialise_domain(struct platform_device *pdev)
1195{ 1217{
1196 struct gk20a_platform *platform = platform_get_drvdata(pdev); 1218 struct gk20a_platform *platform = platform_get_drvdata(pdev);
1197 struct dev_power_governor *pm_domain_gov = NULL; 1219 struct dev_power_governor *pm_domain_gov = NULL;
1198 struct generic_pm_domain *domain = &platform->g->pd; 1220 struct generic_pm_domain *domain = NULL;
1199 int ret = 0; 1221 int ret = 0;
1222 struct gk20a_domain_data *gpu_gpd_data = (struct gk20a_domain_data *)
1223 kzalloc(sizeof(struct gk20a_domain_data), GFP_KERNEL);
1224
1225 if (!gpu_gpd_data)
1226 return -ENOMEM;
1227
1228 gpu_gpd_data->gk20a = platform->g;
1229 domain = &gpu_gpd_data->gpd;
1200 1230
1201 domain->name = "gpu"; 1231 domain->name = "gpu";
1202 1232
@@ -1227,6 +1257,7 @@ static int gk20a_pm_initialise_domain(struct platform_device *pdev)
1227 1257
1228 return ret; 1258 return ret;
1229} 1259}
1260#endif
1230 1261
1231static int gk20a_pm_init(struct platform_device *dev) 1262static int gk20a_pm_init(struct platform_device *dev)
1232{ 1263{
@@ -1280,12 +1311,21 @@ static int gk20a_secure_page_alloc(struct platform_device *pdev)
1280 return err; 1311 return err;
1281} 1312}
1282 1313
1314static struct of_device_id tegra_gpu_domain_match[] = {
1315 {.compatible = "nvidia,tegra210-gpu-pd"},
1316 {},
1317};
1318
1283static int gk20a_probe(struct platform_device *dev) 1319static int gk20a_probe(struct platform_device *dev)
1284{ 1320{
1285 struct gk20a *gk20a; 1321 struct gk20a *gk20a;
1286 int err; 1322 int err;
1287 struct gk20a_platform *platform = NULL; 1323 struct gk20a_platform *platform = NULL;
1288 1324
1325#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
1326 struct gk20a_domain_data *gk20a_domain;
1327#endif
1328
1289 if (dev->dev.of_node) { 1329 if (dev->dev.of_node) {
1290 const struct of_device_id *match; 1330 const struct of_device_id *match;
1291 1331
@@ -1313,6 +1353,12 @@ static int gk20a_probe(struct platform_device *dev)
1313 return -ENOMEM; 1353 return -ENOMEM;
1314 } 1354 }
1315 1355
1356#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
1357 gk20a_domain = container_of(dev_to_genpd(&dev->dev),
1358 struct gk20a_domain_data, gpd);
1359 gk20a_domain->gk20a = gk20a;
1360#endif
1361
1316 set_gk20a(dev, gk20a); 1362 set_gk20a(dev, gk20a);
1317 gk20a->dev = dev; 1363 gk20a->dev = dev;
1318 1364
@@ -1451,6 +1497,7 @@ static int __exit gk20a_remove(struct platform_device *dev)
1451{ 1497{
1452 struct gk20a *g = get_gk20a(dev); 1498 struct gk20a *g = get_gk20a(dev);
1453 struct gk20a_platform *platform = gk20a_get_platform(dev); 1499 struct gk20a_platform *platform = gk20a_get_platform(dev);
1500 struct gk20a_domain_data *gk20a_gpd;
1454 1501
1455 gk20a_dbg_fn(""); 1502 gk20a_dbg_fn("");
1456 1503
@@ -1481,6 +1528,10 @@ static int __exit gk20a_remove(struct platform_device *dev)
1481 platform->secure_buffer.destroy(dev, 1528 platform->secure_buffer.destroy(dev,
1482 &platform->secure_buffer); 1529 &platform->secure_buffer);
1483 1530
1531 gk20a_gpd = container_of(&g, struct gk20a_domain_data, gk20a);
1532 gk20a_gpd->gk20a = NULL;
1533 kfree(gk20a_gpd);
1534
1484 if (pm_runtime_enabled(&dev->dev)) 1535 if (pm_runtime_enabled(&dev->dev))
1485 pm_runtime_disable(&dev->dev); 1536 pm_runtime_disable(&dev->dev);
1486 else 1537 else
@@ -1513,8 +1564,78 @@ static struct platform_driver gk20a_driver = {
1513 } 1564 }
1514}; 1565};
1515 1566
1567#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
1568
1569
1570static int _gk20a_init_domain(struct device_node *np,
1571 struct generic_pm_domain *gpd)
1572{
1573 bool is_off = false;
1574
1575 gpd->name = (char *)np->name;
1576
1577 if (of_property_read_bool(np, "is_off"))
1578 is_off = true;
1579
1580 pm_genpd_init(gpd, NULL, is_off);
1581
1582 gpd->power_on = gk20a_pm_unrailgate;
1583 gpd->power_off = gk20a_pm_railgate;
1584 gpd->dev_ops.start = gk20a_pm_enable_clk;
1585 gpd->dev_ops.stop = gk20a_pm_disable_clk;
1586 gpd->dev_ops.save_state = gk20a_pm_prepare_poweroff;
1587 gpd->dev_ops.restore_state = gk20a_pm_finalize_poweron;
1588#warning domain suspend/resume ops have been removed upstream
1589#if 0
1590 gpd->dev_ops.suspend = gk20a_pm_suspend;
1591 gpd->dev_ops.resume = gk20a_pm_resume;
1592#endif
1593
1594 of_genpd_add_provider_simple(np, gpd);
1595 gpd->of_node = of_node_get(np);
1596
1597 genpd_pm_subdomain_attach(gpd);
1598 return 0;
1599}
1600
1601static int gk20a_domain_init(struct of_device_id *matches)
1602{
1603 int ret = 0;
1604 struct device_node *np;
1605 const struct of_device_id *match;
1606 struct gk20a_domain_data *gk20a_domain;
1607
1608 np = of_find_matching_node(NULL, matches);
1609 if (!np)
1610 return -ENOENT;
1611
1612 match = of_match_node(matches, np);
1613 gk20a_domain = (struct gk20a_domain_data *)kzalloc
1614 (sizeof(struct gk20a_domain_data), GFP_KERNEL);
1615 if (!gk20a_domain)
1616 return -ENOMEM;
1617
1618 ret = _gk20a_init_domain(np, &gk20a_domain->gpd);
1619
1620 return ret;
1621}
1622#else
1623static int gk20a_domain_init(struct of_device_id *matches)
1624{
1625 return 0;
1626}
1627#endif
1628
1629
1516static int __init gk20a_init(void) 1630static int __init gk20a_init(void)
1517{ 1631{
1632
1633 int ret;
1634
1635 ret = gk20a_domain_init(tegra_gpu_domain_match);
1636 if (ret)
1637 return ret;
1638
1518 return platform_driver_register(&gk20a_driver); 1639 return platform_driver_register(&gk20a_driver);
1519} 1640}
1520 1641
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 4fac3cc5..b9bdc6e6 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -504,8 +504,6 @@ struct gk20a {
504 u32 max_ltc_count; 504 u32 max_ltc_count;
505 u32 ltc_count; 505 u32 ltc_count;
506 506
507 struct generic_pm_domain pd;
508
509 struct devfreq *devfreq; 507 struct devfreq *devfreq;
510 508
511 struct gk20a_scale_profile *scale_profile; 509 struct gk20a_scale_profile *scale_profile;
@@ -556,6 +554,11 @@ struct gk20a_cyclestate_buffer_elem {
556 u64 data; 554 u64 data;
557}; 555};
558 556
557struct gk20a_domain_data {
558 struct generic_pm_domain gpd;
559 struct gk20a *gk20a;
560};
561
559/* debug accessories */ 562/* debug accessories */
560 563
561#ifdef CONFIG_DEBUG_FS 564#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c b/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c
index ee176b8b..78132320 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c
@@ -112,19 +112,19 @@ static int gk20a_generic_probe(struct platform_device *dev)
112 112
113static int gk20a_generic_late_probe(struct platform_device *dev) 113static int gk20a_generic_late_probe(struct platform_device *dev)
114{ 114{
115 struct gk20a_platform *platform = gk20a_get_platform(dev); 115 struct generic_pm_domain *gpd = dev_to_genpd(&dev->dev);
116 116
117 /* Make gk20a power domain a subdomain of mc */ 117 /* Make gk20a power domain a subdomain of host1x */
118 tegra_pd_add_sd(&platform->g->pd); 118 tegra_pd_add_sd(gpd);
119 119
120 return 0; 120 return 0;
121} 121}
122 122
123static int gk20a_generic_remove(struct platform_device *dev) 123static int gk20a_generic_remove(struct platform_device *dev)
124{ 124{
125 struct gk20a_platform *platform = gk20a_get_platform(dev); 125 struct generic_pm_domain *gpd = dev_to_genpd(&dev->dev);
126 126
127 tegra_pd_remove_sd(&platform->g->pd); 127 tegra_pd_remove_sd(gpd);
128 128
129 return 0; 129 return 0;
130} 130}
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
index 313962a1..8609e3ae 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
@@ -472,10 +472,8 @@ static int gk20a_tegra_probe(struct platform_device *dev)
472 472
473static int gk20a_tegra_late_probe(struct platform_device *dev) 473static int gk20a_tegra_late_probe(struct platform_device *dev)
474{ 474{
475 struct gk20a_platform *platform = gk20a_get_platform(dev);
476
477 /* Make gk20a power domain a subdomain of host1x */ 475 /* Make gk20a power domain a subdomain of host1x */
478 nvhost_register_client_domain(&platform->g->pd); 476 nvhost_register_client_domain(dev_to_genpd(&dev->dev));
479 477
480 /* Initialise tegra specific scaling quirks */ 478 /* Initialise tegra specific scaling quirks */
481 gk20a_tegra_scale_init(dev); 479 gk20a_tegra_scale_init(dev);
@@ -485,10 +483,8 @@ static int gk20a_tegra_late_probe(struct platform_device *dev)
485 483
486static int gk20a_tegra_remove(struct platform_device *dev) 484static int gk20a_tegra_remove(struct platform_device *dev)
487{ 485{
488 struct gk20a_platform *platform = gk20a_get_platform(dev);
489
490 /* remove gk20a power subdomain from host1x */ 486 /* remove gk20a power subdomain from host1x */
491 nvhost_unregister_client_domain(&platform->g->pd); 487 nvhost_unregister_client_domain(dev_to_genpd(&dev->dev));
492 488
493 /* deinitialise tegra specific scaling quirks */ 489 /* deinitialise tegra specific scaling quirks */
494 gk20a_tegra_scale_exit(dev); 490 gk20a_tegra_scale_exit(dev);
diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c
index d3d793d1..c998b10b 100644
--- a/drivers/gpu/nvgpu/vgpu/vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/vgpu.c
@@ -311,7 +311,17 @@ static int vgpu_pm_initialise_domain(struct platform_device *pdev)
311{ 311{
312 struct gk20a_platform *platform = platform_get_drvdata(pdev); 312 struct gk20a_platform *platform = platform_get_drvdata(pdev);
313 struct dev_power_governor *pm_domain_gov = NULL; 313 struct dev_power_governor *pm_domain_gov = NULL;
314 struct generic_pm_domain *domain = &platform->g->pd; 314 struct gk20a_domain_data *vgpu_pd_data;
315 struct generic_pm_domain *domain;
316
317 vgpu_pd_data = (struct gk20a_domain_data *)kzalloc
318 (sizeof(struct gk20a_domain_data), GFP_KERNEL);
319
320 if (!vgpu_pd_data)
321 return -ENOMEM;
322
323 domain = &vgpu_pd_data->gpd;
324 vgpu_pd_data->gk20a = platform->g;
315 325
316 domain->name = "gpu"; 326 domain->name = "gpu";
317 327
@@ -432,11 +442,16 @@ int vgpu_probe(struct platform_device *dev)
432int vgpu_remove(struct platform_device *dev) 442int vgpu_remove(struct platform_device *dev)
433{ 443{
434 struct gk20a *g = get_gk20a(dev); 444 struct gk20a *g = get_gk20a(dev);
445 struct gk20a_domain_data *vgpu_gpd;
435 gk20a_dbg_fn(""); 446 gk20a_dbg_fn("");
436 447
437 if (g->remove_support) 448 if (g->remove_support)
438 g->remove_support(dev); 449 g->remove_support(dev);
439 450
451 vgpu_gpd = container_of(&g, struct gk20a_domain_data, gk20a);
452 vgpu_gpd->gk20a = NULL;
453 kfree(vgpu_gpd);
454
440 vgpu_comm_deinit(); 455 vgpu_comm_deinit();
441 gk20a_user_deinit(dev); 456 gk20a_user_deinit(dev);
442 gk20a_get_platform(dev)->g = NULL; 457 gk20a_get_platform(dev)->g = NULL;