forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/gpu/drm/omapdrm/dss/dss.c
....@@ -1,21 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2009 Nokia Corporation
34 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
45 *
56 * Some code and ideas taken from drivers/video/omap/ driver
67 * by Imre Deak.
7
- *
8
- * This program is free software; you can redistribute it and/or modify it
9
- * under the terms of the GNU General Public License version 2 as published by
10
- * the Free Software Foundation.
11
- *
12
- * This program is distributed in the hope that it will be useful, but WITHOUT
13
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15
- * more details.
16
- *
17
- * You should have received a copy of the GNU General Public License along with
18
- * this program. If not, see <http://www.gnu.org/licenses/>.
198 */
209
2110 #define DSS_SUBSYS_NAME "DSS"
....@@ -394,9 +383,6 @@
394383
395384 dss_dump_clocks(dss, s);
396385 dispc_dump_clocks(dss->dispc, s);
397
-#ifdef CONFIG_OMAP2_DSS_DSI
398
- dsi_dump_clocks(s);
399
-#endif
400386 return 0;
401387 }
402388
....@@ -681,12 +667,6 @@
681667 return dss->feat->fck_freq_max;
682668 }
683669
684
-enum omap_dss_output_id dss_get_supported_outputs(struct dss_device *dss,
685
- enum omap_channel channel)
686
-{
687
- return dss->feat->outputs[channel];
688
-}
689
-
690670 static int dss_setup_default_clock(struct dss_device *dss)
691671 {
692672 unsigned long max_dss_fck, prate;
....@@ -943,7 +923,6 @@
943923 void *data)
944924 {
945925 struct dss_debugfs_entry *entry;
946
- struct dentry *d;
947926
948927 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
949928 if (!entry)
....@@ -951,15 +930,9 @@
951930
952931 entry->show_fn = show_fn;
953932 entry->data = data;
933
+ entry->dentry = debugfs_create_file(name, 0444, dss->debugfs.root,
934
+ entry, &dss_debug_fops);
954935
955
- d = debugfs_create_file(name, 0444, dss->debugfs.root, entry,
956
- &dss_debug_fops);
957
- if (IS_ERR(d)) {
958
- kfree(entry);
959
- return ERR_PTR(PTR_ERR(d));
960
- }
961
-
962
- entry->dentry = d;
963936 return entry;
964937 }
965938
....@@ -1178,41 +1151,14 @@
11781151 .has_lcd_clk_src = true,
11791152 };
11801153
1181
-static int dss_init_ports(struct dss_device *dss)
1154
+static void __dss_uninit_ports(struct dss_device *dss, unsigned int num_ports)
11821155 {
11831156 struct platform_device *pdev = dss->pdev;
11841157 struct device_node *parent = pdev->dev.of_node;
11851158 struct device_node *port;
1186
- int i;
1159
+ unsigned int i;
11871160
1188
- for (i = 0; i < dss->feat->num_ports; i++) {
1189
- port = of_graph_get_port_by_id(parent, i);
1190
- if (!port)
1191
- continue;
1192
-
1193
- switch (dss->feat->ports[i]) {
1194
- case OMAP_DISPLAY_TYPE_DPI:
1195
- dpi_init_port(dss, pdev, port, dss->feat->model);
1196
- break;
1197
- case OMAP_DISPLAY_TYPE_SDI:
1198
- sdi_init_port(dss, pdev, port);
1199
- break;
1200
- default:
1201
- break;
1202
- }
1203
- }
1204
-
1205
- return 0;
1206
-}
1207
-
1208
-static void dss_uninit_ports(struct dss_device *dss)
1209
-{
1210
- struct platform_device *pdev = dss->pdev;
1211
- struct device_node *parent = pdev->dev.of_node;
1212
- struct device_node *port;
1213
- int i;
1214
-
1215
- for (i = 0; i < dss->feat->num_ports; i++) {
1161
+ for (i = 0; i < num_ports; i++) {
12161162 port = of_graph_get_port_by_id(parent, i);
12171163 if (!port)
12181164 continue;
....@@ -1227,7 +1173,53 @@
12271173 default:
12281174 break;
12291175 }
1176
+ of_node_put(port);
12301177 }
1178
+}
1179
+
1180
+static int dss_init_ports(struct dss_device *dss)
1181
+{
1182
+ struct platform_device *pdev = dss->pdev;
1183
+ struct device_node *parent = pdev->dev.of_node;
1184
+ struct device_node *port;
1185
+ unsigned int i;
1186
+ int r;
1187
+
1188
+ for (i = 0; i < dss->feat->num_ports; i++) {
1189
+ port = of_graph_get_port_by_id(parent, i);
1190
+ if (!port)
1191
+ continue;
1192
+
1193
+ switch (dss->feat->ports[i]) {
1194
+ case OMAP_DISPLAY_TYPE_DPI:
1195
+ r = dpi_init_port(dss, pdev, port, dss->feat->model);
1196
+ if (r)
1197
+ goto error;
1198
+ break;
1199
+
1200
+ case OMAP_DISPLAY_TYPE_SDI:
1201
+ r = sdi_init_port(dss, pdev, port);
1202
+ if (r)
1203
+ goto error;
1204
+ break;
1205
+
1206
+ default:
1207
+ break;
1208
+ }
1209
+ of_node_put(port);
1210
+ }
1211
+
1212
+ return 0;
1213
+
1214
+error:
1215
+ of_node_put(port);
1216
+ __dss_uninit_ports(dss, i);
1217
+ return r;
1218
+}
1219
+
1220
+static void dss_uninit_ports(struct dss_device *dss)
1221
+{
1222
+ __dss_uninit_ports(dss, dss->feat->num_ports);
12311223 }
12321224
12331225 static int dss_video_pll_probe(struct dss_device *dss)
....@@ -1315,6 +1307,7 @@
13151307 static int dss_bind(struct device *dev)
13161308 {
13171309 struct dss_device *dss = dev_get_drvdata(dev);
1310
+ struct platform_device *drm_pdev;
13181311 int r;
13191312
13201313 r = component_bind_all(dev, NULL);
....@@ -1323,14 +1316,25 @@
13231316
13241317 pm_set_vt_switch(0);
13251318
1326
- omapdss_gather_components(dev);
13271319 omapdss_set_dss(dss);
1320
+
1321
+ drm_pdev = platform_device_register_simple("omapdrm", 0, NULL, 0);
1322
+ if (IS_ERR(drm_pdev)) {
1323
+ component_unbind_all(dev, NULL);
1324
+ return PTR_ERR(drm_pdev);
1325
+ }
1326
+
1327
+ dss->drm_pdev = drm_pdev;
13281328
13291329 return 0;
13301330 }
13311331
13321332 static void dss_unbind(struct device *dev)
13331333 {
1334
+ struct dss_device *dss = dev_get_drvdata(dev);
1335
+
1336
+ platform_device_unregister(dss->drm_pdev);
1337
+
13341338 omapdss_set_dss(NULL);
13351339
13361340 component_unbind_all(dev, NULL);
....@@ -1347,9 +1351,15 @@
13471351 return dev == child;
13481352 }
13491353
1354
+struct dss_component_match_data {
1355
+ struct device *dev;
1356
+ struct component_match **match;
1357
+};
1358
+
13501359 static int dss_add_child_component(struct device *dev, void *data)
13511360 {
1352
- struct component_match **match = data;
1361
+ struct dss_component_match_data *cmatch = data;
1362
+ struct component_match **match = cmatch->match;
13531363
13541364 /*
13551365 * HACK
....@@ -1360,7 +1370,17 @@
13601370 if (strstr(dev_name(dev), "rfbi"))
13611371 return 0;
13621372
1363
- component_match_add(dev->parent, match, dss_component_compare, dev);
1373
+ /*
1374
+ * Handle possible interconnect target modules defined within the DSS.
1375
+ * The DSS components can be children of an interconnect target module
1376
+ * after the device tree has been updated for the module data.
1377
+ * See also omapdss_boot_init() for compatible fixup.
1378
+ */
1379
+ if (strstr(dev_name(dev), "target-module"))
1380
+ return device_for_each_child(dev, cmatch,
1381
+ dss_add_child_component);
1382
+
1383
+ component_match_add(cmatch->dev, match, dss_component_compare, dev);
13641384
13651385 return 0;
13661386 }
....@@ -1403,6 +1423,7 @@
14031423 static int dss_probe(struct platform_device *pdev)
14041424 {
14051425 const struct soc_device_attribute *soc;
1426
+ struct dss_component_match_data cmatch;
14061427 struct component_match *match = NULL;
14071428 struct resource *dss_mem;
14081429 struct dss_device *dss;
....@@ -1474,13 +1495,24 @@
14741495 dss);
14751496
14761497 /* Add all the child devices as components. */
1477
- device_for_each_child(&pdev->dev, &match, dss_add_child_component);
1478
-
1479
- r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
1498
+ r = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
14801499 if (r)
14811500 goto err_uninit_debugfs;
14821501
1502
+ omapdss_gather_components(&pdev->dev);
1503
+
1504
+ cmatch.dev = &pdev->dev;
1505
+ cmatch.match = &match;
1506
+ device_for_each_child(&pdev->dev, &cmatch, dss_add_child_component);
1507
+
1508
+ r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
1509
+ if (r)
1510
+ goto err_of_depopulate;
1511
+
14831512 return 0;
1513
+
1514
+err_of_depopulate:
1515
+ of_platform_depopulate(&pdev->dev);
14841516
14851517 err_uninit_debugfs:
14861518 dss_debugfs_remove_file(dss->debugfs.clk);
....@@ -1509,6 +1541,8 @@
15091541 static int dss_remove(struct platform_device *pdev)
15101542 {
15111543 struct dss_device *dss = platform_get_drvdata(pdev);
1544
+
1545
+ of_platform_depopulate(&pdev->dev);
15121546
15131547 component_master_del(&pdev->dev, &dss_component_ops);
15141548
....@@ -1539,12 +1573,10 @@
15391573
15401574 DSSDBG("shutdown\n");
15411575
1542
- for_each_dss_dev(dssdev) {
1543
- if (!dssdev->driver)
1544
- continue;
1545
-
1546
- if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
1547
- dssdev->driver->disable(dssdev);
1576
+ for_each_dss_output(dssdev) {
1577
+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE &&
1578
+ dssdev->ops && dssdev->ops->disable)
1579
+ dssdev->ops->disable(dssdev);
15481580 }
15491581 }
15501582
....@@ -1585,6 +1617,7 @@
15851617 static const struct dev_pm_ops dss_pm_ops = {
15861618 .runtime_suspend = dss_runtime_suspend,
15871619 .runtime_resume = dss_runtime_resume,
1620
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
15881621 };
15891622
15901623 struct platform_driver omap_dsshw_driver = {
....@@ -1598,3 +1631,40 @@
15981631 .suppress_bind_attrs = true,
15991632 },
16001633 };
1634
+
1635
+/* INIT */
1636
+static struct platform_driver * const omap_dss_drivers[] = {
1637
+ &omap_dsshw_driver,
1638
+ &omap_dispchw_driver,
1639
+#ifdef CONFIG_OMAP2_DSS_DSI
1640
+ &omap_dsihw_driver,
1641
+#endif
1642
+#ifdef CONFIG_OMAP2_DSS_VENC
1643
+ &omap_venchw_driver,
1644
+#endif
1645
+#ifdef CONFIG_OMAP4_DSS_HDMI
1646
+ &omapdss_hdmi4hw_driver,
1647
+#endif
1648
+#ifdef CONFIG_OMAP5_DSS_HDMI
1649
+ &omapdss_hdmi5hw_driver,
1650
+#endif
1651
+};
1652
+
1653
+static int __init omap_dss_init(void)
1654
+{
1655
+ return platform_register_drivers(omap_dss_drivers,
1656
+ ARRAY_SIZE(omap_dss_drivers));
1657
+}
1658
+
1659
+static void __exit omap_dss_exit(void)
1660
+{
1661
+ platform_unregister_drivers(omap_dss_drivers,
1662
+ ARRAY_SIZE(omap_dss_drivers));
1663
+}
1664
+
1665
+module_init(omap_dss_init);
1666
+module_exit(omap_dss_exit);
1667
+
1668
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
1669
+MODULE_DESCRIPTION("OMAP2/3/4/5 Display Subsystem");
1670
+MODULE_LICENSE("GPL v2");