aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-06 07:29:31 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-18 09:15:02 -0400
commit1521653c72596aaf1899c8d79a3f541f79ff238b (patch)
treeac36b818043b270996d952fae1ca515026e52b6a
parent6a03fca96e4d4d010be52e11fc7b8ab89da9d2cf (diff)
OMAPDSS: register only one display device per output
We have boards with multiple panel devices connected to the same physical output, of which only one panel can be enabled at one time. Examples of these are Overo, where you can use different daughter boards that have different LCDs, and 3430SDP which has an LCD and a DVI output and a physical switch to select the active display. These are supported by omapdss so that we add all the possible display devices at probe, but the displays are inactive until somebody enables one. At this point the panel driver starts using the DSS, thus reserving the physcal resource and excluding the other panels. This is problematic: - Panel drivers can't allocate their resources properly at probe(), because the resources can be shared with other panels. Thus they can be only reserved at enable time. - Managing this in omapdss is confusing. It's not natural to have child devices, which may not even exist (for example, a daughterboard that is not connected). Only some boards have multiple displays per output, and of those, only very few have possibility of switching the display during runtime. Because of the above points: - We don't want to make omapdss and all the panel drivers more complex just because some boards have complex setups. - Only few boards support runtime switching, and afaik even then it's not required. So we don't need to support runtime switching. Thus we'll change to a model where we will have only one display device per output and this cannot be (currently) changed at runtime. We'll still have the possibility to select the display from multiple options during boot with the default display option. This patch accomplishes the above by changing how the output drivers register the display device. Instead of registering all the devices given from the board file, we'll only register one. If the default display option is set, the output driver selects that display from its displays. If the default display is not set, or the default display is not one of the output's displays, the output driver selects the first display. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/video/omap2/dss/dpi.c47
-rw-r--r--drivers/video/omap2/dss/dsi.c51
-rw-r--r--drivers/video/omap2/dss/dss.h1
-rw-r--r--drivers/video/omap2/dss/hdmi.c57
-rw-r--r--drivers/video/omap2/dss/rfbi.c47
-rw-r--r--drivers/video/omap2/dss/sdi.c47
-rw-r--r--drivers/video/omap2/dss/venc.c47
7 files changed, 231 insertions, 66 deletions
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 703fc1d8ec80..6f9a199a68a2 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -371,10 +371,14 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
371 return 0; 371 return 0;
372} 372}
373 373
374static void __init dpi_probe_pdata(struct platform_device *pdev) 374static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev)
375{ 375{
376 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 376 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
377 int i, r; 377 const char *def_disp_name = dss_get_default_display_name();
378 struct omap_dss_device *def_dssdev;
379 int i;
380
381 def_dssdev = NULL;
378 382
379 for (i = 0; i < pdata->num_devices; ++i) { 383 for (i = 0; i < pdata->num_devices; ++i) {
380 struct omap_dss_device *dssdev = pdata->devices[i]; 384 struct omap_dss_device *dssdev = pdata->devices[i];
@@ -382,16 +386,39 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
382 if (dssdev->type != OMAP_DISPLAY_TYPE_DPI) 386 if (dssdev->type != OMAP_DISPLAY_TYPE_DPI)
383 continue; 387 continue;
384 388
385 r = dpi_init_display(dssdev); 389 if (def_dssdev == NULL)
386 if (r) { 390 def_dssdev = dssdev;
387 DSSERR("device %s init failed: %d\n", dssdev->name, r); 391
388 continue; 392 if (def_disp_name != NULL &&
393 strcmp(dssdev->name, def_disp_name) == 0) {
394 def_dssdev = dssdev;
395 break;
389 } 396 }
397 }
390 398
391 r = omap_dss_register_device(dssdev, &pdev->dev); 399 return def_dssdev;
392 if (r) 400}
393 DSSERR("device %s register failed: %d\n", 401
394 dssdev->name, r); 402static void __init dpi_probe_pdata(struct platform_device *pdev)
403{
404 struct omap_dss_device *dssdev;
405 int r;
406
407 dssdev = dpi_find_dssdev(pdev);
408
409 if (!dssdev)
410 return;
411
412 r = dpi_init_display(dssdev);
413 if (r) {
414 DSSERR("device %s init failed: %d\n", dssdev->name, r);
415 return;
416 }
417
418 r = omap_dss_register_device(dssdev, &pdev->dev);
419 if (r) {
420 DSSERR("device %s register failed: %d\n", dssdev->name, r);
421 return;
395 } 422 }
396} 423}
397 424
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index f7078fc90459..ee9ae526f5c1 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -5006,11 +5006,15 @@ static void dsi_put_clocks(struct platform_device *dsidev)
5006 clk_put(dsi->sys_clk); 5006 clk_put(dsi->sys_clk);
5007} 5007}
5008 5008
5009static void __init dsi_probe_pdata(struct platform_device *dsidev) 5009static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *pdev)
5010{ 5010{
5011 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5011 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
5012 struct omap_dss_board_info *pdata = dsidev->dev.platform_data; 5012 struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
5013 int i, r; 5013 const char *def_disp_name = dss_get_default_display_name();
5014 struct omap_dss_device *def_dssdev;
5015 int i;
5016
5017 def_dssdev = NULL;
5014 5018
5015 for (i = 0; i < pdata->num_devices; ++i) { 5019 for (i = 0; i < pdata->num_devices; ++i) {
5016 struct omap_dss_device *dssdev = pdata->devices[i]; 5020 struct omap_dss_device *dssdev = pdata->devices[i];
@@ -5021,16 +5025,39 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
5021 if (dssdev->phy.dsi.module != dsi->module_id) 5025 if (dssdev->phy.dsi.module != dsi->module_id)
5022 continue; 5026 continue;
5023 5027
5024 r = dsi_init_display(dssdev); 5028 if (def_dssdev == NULL)
5025 if (r) { 5029 def_dssdev = dssdev;
5026 DSSERR("device %s init failed: %d\n", dssdev->name, r); 5030
5027 continue; 5031 if (def_disp_name != NULL &&
5032 strcmp(dssdev->name, def_disp_name) == 0) {
5033 def_dssdev = dssdev;
5034 break;
5028 } 5035 }
5036 }
5029 5037
5030 r = omap_dss_register_device(dssdev, &dsidev->dev); 5038 return def_dssdev;
5031 if (r) 5039}
5032 DSSERR("device %s register failed: %d\n", 5040
5033 dssdev->name, r); 5041static void __init dsi_probe_pdata(struct platform_device *dsidev)
5042{
5043 struct omap_dss_device *dssdev;
5044 int r;
5045
5046 dssdev = dsi_find_dssdev(dsidev);
5047
5048 if (!dssdev)
5049 return;
5050
5051 r = dsi_init_display(dssdev);
5052 if (r) {
5053 DSSERR("device %s init failed: %d\n", dssdev->name, r);
5054 return;
5055 }
5056
5057 r = omap_dss_register_device(dssdev, &dsidev->dev);
5058 if (r) {
5059 DSSERR("device %s register failed: %d\n", dssdev->name, r);
5060 return;
5034 } 5061 }
5035} 5062}
5036 5063
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 7bac8ee078ad..a977826d850c 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -175,6 +175,7 @@ struct seq_file;
175struct platform_device; 175struct platform_device;
176 176
177/* core */ 177/* core */
178const char *dss_get_default_display_name(void);
178struct bus_type *dss_get_bus(void); 179struct bus_type *dss_get_bus(void);
179struct regulator *dss_get_vdds_dsi(void); 180struct regulator *dss_get_vdds_dsi(void);
180struct regulator *dss_get_vdds_sdi(void); 181struct regulator *dss_get_vdds_sdi(void);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index bb07143a2d79..76d100b975e0 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -901,32 +901,61 @@ int hdmi_audio_config(struct omap_dss_audio *audio)
901 901
902#endif 902#endif
903 903
904static void __init hdmi_probe_pdata(struct platform_device *pdev) 904static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev)
905{ 905{
906 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 906 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
907 int r, i; 907 const char *def_disp_name = dss_get_default_display_name();
908 struct omap_dss_device *def_dssdev;
909 int i;
910
911 def_dssdev = NULL;
908 912
909 for (i = 0; i < pdata->num_devices; ++i) { 913 for (i = 0; i < pdata->num_devices; ++i) {
910 struct omap_dss_device *dssdev = pdata->devices[i]; 914 struct omap_dss_device *dssdev = pdata->devices[i];
911 struct omap_dss_hdmi_data *priv = dssdev->data;
912 915
913 if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI) 916 if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
914 continue; 917 continue;
915 918
916 hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio; 919 if (def_dssdev == NULL)
917 hdmi.ls_oe_gpio = priv->ls_oe_gpio; 920 def_dssdev = dssdev;
918 hdmi.hpd_gpio = priv->hpd_gpio;
919 921
920 r = hdmi_init_display(dssdev); 922 if (def_disp_name != NULL &&
921 if (r) { 923 strcmp(dssdev->name, def_disp_name) == 0) {
922 DSSERR("device %s init failed: %d\n", dssdev->name, r); 924 def_dssdev = dssdev;
923 continue; 925 break;
924 } 926 }
927 }
928
929 return def_dssdev;
930}
931
932static void __init hdmi_probe_pdata(struct platform_device *pdev)
933{
934 struct omap_dss_device *dssdev;
935 struct omap_dss_hdmi_data *priv;
936 int r;
925 937
926 r = omap_dss_register_device(dssdev, &pdev->dev); 938 dssdev = hdmi_find_dssdev(pdev);
927 if (r) 939
928 DSSERR("device %s register failed: %d\n", 940 if (!dssdev)
929 dssdev->name, r); 941 return;
942
943 priv = dssdev->data;
944
945 hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
946 hdmi.ls_oe_gpio = priv->ls_oe_gpio;
947 hdmi.hpd_gpio = priv->hpd_gpio;
948
949 r = hdmi_init_display(dssdev);
950 if (r) {
951 DSSERR("device %s init failed: %d\n", dssdev->name, r);
952 return;
953 }
954
955 r = omap_dss_register_device(dssdev, &pdev->dev);
956 if (r) {
957 DSSERR("device %s register failed: %d\n", dssdev->name, r);
958 return;
930 } 959 }
931} 960}
932 961
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 845b4e70a28e..1127037cb9d5 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -942,10 +942,14 @@ static int __init rfbi_init_display(struct omap_dss_device *dssdev)
942 return 0; 942 return 0;
943} 943}
944 944
945static void __init rfbi_probe_pdata(struct platform_device *pdev) 945static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev)
946{ 946{
947 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 947 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
948 int i, r; 948 const char *def_disp_name = dss_get_default_display_name();
949 struct omap_dss_device *def_dssdev;
950 int i;
951
952 def_dssdev = NULL;
949 953
950 for (i = 0; i < pdata->num_devices; ++i) { 954 for (i = 0; i < pdata->num_devices; ++i) {
951 struct omap_dss_device *dssdev = pdata->devices[i]; 955 struct omap_dss_device *dssdev = pdata->devices[i];
@@ -953,16 +957,39 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
953 if (dssdev->type != OMAP_DISPLAY_TYPE_DBI) 957 if (dssdev->type != OMAP_DISPLAY_TYPE_DBI)
954 continue; 958 continue;
955 959
956 r = rfbi_init_display(dssdev); 960 if (def_dssdev == NULL)
957 if (r) { 961 def_dssdev = dssdev;
958 DSSERR("device %s init failed: %d\n", dssdev->name, r); 962
959 continue; 963 if (def_disp_name != NULL &&
964 strcmp(dssdev->name, def_disp_name) == 0) {
965 def_dssdev = dssdev;
966 break;
960 } 967 }
968 }
969
970 return def_dssdev;
971}
972
973static void __init rfbi_probe_pdata(struct platform_device *pdev)
974{
975 struct omap_dss_device *dssdev;
976 int r;
977
978 dssdev = rfbi_find_dssdev(pdev);
961 979
962 r = omap_dss_register_device(dssdev, &pdev->dev); 980 if (!dssdev)
963 if (r) 981 return;
964 DSSERR("device %s register failed: %d\n", 982
965 dssdev->name, r); 983 r = rfbi_init_display(dssdev);
984 if (r) {
985 DSSERR("device %s init failed: %d\n", dssdev->name, r);
986 return;
987 }
988
989 r = omap_dss_register_device(dssdev, &pdev->dev);
990 if (r) {
991 DSSERR("device %s register failed: %d\n", dssdev->name, r);
992 return;
966 } 993 }
967} 994}
968 995
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index c9a9045e19f2..0aaa7f35874c 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -195,10 +195,14 @@ static int __init sdi_init_display(struct omap_dss_device *dssdev)
195 return 0; 195 return 0;
196} 196}
197 197
198static void __init sdi_probe_pdata(struct platform_device *pdev) 198static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev)
199{ 199{
200 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 200 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
201 int i, r; 201 const char *def_disp_name = dss_get_default_display_name();
202 struct omap_dss_device *def_dssdev;
203 int i;
204
205 def_dssdev = NULL;
202 206
203 for (i = 0; i < pdata->num_devices; ++i) { 207 for (i = 0; i < pdata->num_devices; ++i) {
204 struct omap_dss_device *dssdev = pdata->devices[i]; 208 struct omap_dss_device *dssdev = pdata->devices[i];
@@ -206,16 +210,39 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
206 if (dssdev->type != OMAP_DISPLAY_TYPE_SDI) 210 if (dssdev->type != OMAP_DISPLAY_TYPE_SDI)
207 continue; 211 continue;
208 212
209 r = sdi_init_display(dssdev); 213 if (def_dssdev == NULL)
210 if (r) { 214 def_dssdev = dssdev;
211 DSSERR("device %s init failed: %d\n", dssdev->name, r); 215
212 continue; 216 if (def_disp_name != NULL &&
217 strcmp(dssdev->name, def_disp_name) == 0) {
218 def_dssdev = dssdev;
219 break;
213 } 220 }
221 }
214 222
215 r = omap_dss_register_device(dssdev, &pdev->dev); 223 return def_dssdev;
216 if (r) 224}
217 DSSERR("device %s register failed: %d\n", 225
218 dssdev->name, r); 226static void __init sdi_probe_pdata(struct platform_device *pdev)
227{
228 struct omap_dss_device *dssdev;
229 int r;
230
231 dssdev = sdi_find_dssdev(pdev);
232
233 if (!dssdev)
234 return;
235
236 r = sdi_init_display(dssdev);
237 if (r) {
238 DSSERR("device %s init failed: %d\n", dssdev->name, r);
239 return;
240 }
241
242 r = omap_dss_register_device(dssdev, &pdev->dev);
243 if (r) {
244 DSSERR("device %s register failed: %d\n", dssdev->name, r);
245 return;
219 } 246 }
220} 247}
221 248
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 60bfc5801636..b9c0a8f468d2 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -735,10 +735,14 @@ static void venc_put_clocks(void)
735 clk_put(venc.tv_dac_clk); 735 clk_put(venc.tv_dac_clk);
736} 736}
737 737
738static void __init venc_probe_pdata(struct platform_device *pdev) 738static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev)
739{ 739{
740 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 740 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
741 int r, i; 741 const char *def_disp_name = dss_get_default_display_name();
742 struct omap_dss_device *def_dssdev;
743 int i;
744
745 def_dssdev = NULL;
742 746
743 for (i = 0; i < pdata->num_devices; ++i) { 747 for (i = 0; i < pdata->num_devices; ++i) {
744 struct omap_dss_device *dssdev = pdata->devices[i]; 748 struct omap_dss_device *dssdev = pdata->devices[i];
@@ -746,16 +750,39 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
746 if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) 750 if (dssdev->type != OMAP_DISPLAY_TYPE_VENC)
747 continue; 751 continue;
748 752
749 r = venc_init_display(dssdev); 753 if (def_dssdev == NULL)
750 if (r) { 754 def_dssdev = dssdev;
751 DSSERR("device %s init failed: %d\n", dssdev->name, r); 755
752 continue; 756 if (def_disp_name != NULL &&
757 strcmp(dssdev->name, def_disp_name) == 0) {
758 def_dssdev = dssdev;
759 break;
753 } 760 }
761 }
762
763 return def_dssdev;
764}
765
766static void __init venc_probe_pdata(struct platform_device *pdev)
767{
768 struct omap_dss_device *dssdev;
769 int r;
770
771 dssdev = venc_find_dssdev(pdev);
772
773 if (!dssdev)
774 return;
775
776 r = venc_init_display(dssdev);
777 if (r) {
778 DSSERR("device %s init failed: %d\n", dssdev->name, r);
779 return;
780 }
754 781
755 r = omap_dss_register_device(dssdev, &pdev->dev); 782 r = omap_dss_register_device(dssdev, &pdev->dev);
756 if (r) 783 if (r) {
757 DSSERR("device %s register failed: %d\n", 784 DSSERR("device %s register failed: %d\n", dssdev->name, r);
758 dssdev->name, r); 785 return;
759 } 786 }
760} 787}
761 788