summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gk20a.c
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 /drivers/gpu/nvgpu/gk20a/gk20a.c
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>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c137
1 files changed, 129 insertions, 8 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