@@ -902,7 +902,8 @@ static void dss_apply_fifo_merge(bool use_fifo_merge)
902
902
dss_data .fifo_merge_dirty = true;
903
903
}
904
904
905
- static void dss_ovl_setup_fifo (struct omap_overlay * ovl )
905
+ static void dss_ovl_setup_fifo (struct omap_overlay * ovl ,
906
+ bool use_fifo_merge )
906
907
{
907
908
struct ovl_priv_data * op = get_ovl_priv (ovl );
908
909
struct omap_dss_device * dssdev ;
@@ -914,7 +915,16 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
914
915
915
916
dssdev = ovl -> manager -> device ;
916
917
917
- size = dispc_ovl_get_fifo_size (ovl -> id );
918
+ if (use_fifo_merge ) {
919
+ int i ;
920
+
921
+ size = 0 ;
922
+
923
+ for (i = 0 ; i < omap_dss_get_num_overlays (); ++ i )
924
+ size += dispc_ovl_get_fifo_size (i );
925
+ } else {
926
+ size = dispc_ovl_get_fifo_size (ovl -> id );
927
+ }
918
928
919
929
burst_size = dispc_ovl_get_burst_size (ovl -> id );
920
930
@@ -940,7 +950,8 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
940
950
dss_apply_ovl_fifo_thresholds (ovl , fifo_low , fifo_high );
941
951
}
942
952
943
- static void dss_mgr_setup_fifos (struct omap_overlay_manager * mgr )
953
+ static void dss_mgr_setup_fifos (struct omap_overlay_manager * mgr ,
954
+ bool use_fifo_merge )
944
955
{
945
956
struct omap_overlay * ovl ;
946
957
struct mgr_priv_data * mp ;
@@ -951,26 +962,102 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
951
962
return ;
952
963
953
964
list_for_each_entry (ovl , & mgr -> overlays , list )
954
- dss_ovl_setup_fifo (ovl );
965
+ dss_ovl_setup_fifo (ovl , use_fifo_merge );
955
966
}
956
967
957
- static void dss_setup_fifos (void )
968
+ static void dss_setup_fifos (bool use_fifo_merge )
958
969
{
959
970
const int num_mgrs = omap_dss_get_num_overlay_managers ();
960
971
struct omap_overlay_manager * mgr ;
961
972
int i ;
962
973
963
974
for (i = 0 ; i < num_mgrs ; ++ i ) {
964
975
mgr = omap_dss_get_overlay_manager (i );
965
- dss_mgr_setup_fifos (mgr );
976
+ dss_mgr_setup_fifos (mgr , use_fifo_merge );
966
977
}
967
978
}
968
979
980
+ static int get_num_used_managers (void )
981
+ {
982
+ const int num_mgrs = omap_dss_get_num_overlay_managers ();
983
+ struct omap_overlay_manager * mgr ;
984
+ struct mgr_priv_data * mp ;
985
+ int i ;
986
+ int enabled_mgrs ;
987
+
988
+ enabled_mgrs = 0 ;
989
+
990
+ for (i = 0 ; i < num_mgrs ; ++ i ) {
991
+ mgr = omap_dss_get_overlay_manager (i );
992
+ mp = get_mgr_priv (mgr );
993
+
994
+ if (!mp -> enabled )
995
+ continue ;
996
+
997
+ enabled_mgrs ++ ;
998
+ }
999
+
1000
+ return enabled_mgrs ;
1001
+ }
1002
+
1003
+ static int get_num_used_overlays (void )
1004
+ {
1005
+ const int num_ovls = omap_dss_get_num_overlays ();
1006
+ struct omap_overlay * ovl ;
1007
+ struct ovl_priv_data * op ;
1008
+ struct mgr_priv_data * mp ;
1009
+ int i ;
1010
+ int enabled_ovls ;
1011
+
1012
+ enabled_ovls = 0 ;
1013
+
1014
+ for (i = 0 ; i < num_ovls ; ++ i ) {
1015
+ ovl = omap_dss_get_overlay (i );
1016
+ op = get_ovl_priv (ovl );
1017
+
1018
+ if (!op -> enabled && !op -> enabling )
1019
+ continue ;
1020
+
1021
+ mp = get_mgr_priv (ovl -> manager );
1022
+
1023
+ if (!mp -> enabled )
1024
+ continue ;
1025
+
1026
+ enabled_ovls ++ ;
1027
+ }
1028
+
1029
+ return enabled_ovls ;
1030
+ }
1031
+
1032
+ static bool get_use_fifo_merge (void )
1033
+ {
1034
+ int enabled_mgrs = get_num_used_managers ();
1035
+ int enabled_ovls = get_num_used_overlays ();
1036
+
1037
+ if (!dss_has_feature (FEAT_FIFO_MERGE ))
1038
+ return false;
1039
+
1040
+ /*
1041
+ * In theory the only requirement for fifomerge is enabled_ovls <= 1.
1042
+ * However, if we have two managers enabled and set/unset the fifomerge,
1043
+ * we need to set the GO bits in particular sequence for the managers,
1044
+ * and wait in between.
1045
+ *
1046
+ * This is rather difficult as new apply calls can happen at any time,
1047
+ * so we simplify the problem by requiring also that enabled_mgrs <= 1.
1048
+ * In practice this shouldn't matter, because when only one overlay is
1049
+ * enabled, most likely only one output is enabled.
1050
+ */
1051
+
1052
+ return enabled_mgrs <= 1 && enabled_ovls <= 1 ;
1053
+ }
1054
+
969
1055
int dss_mgr_enable (struct omap_overlay_manager * mgr )
970
1056
{
971
1057
struct mgr_priv_data * mp = get_mgr_priv (mgr );
972
1058
unsigned long flags ;
973
1059
int r ;
1060
+ bool fifo_merge ;
974
1061
975
1062
mutex_lock (& apply_lock );
976
1063
@@ -988,11 +1075,23 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
988
1075
goto err ;
989
1076
}
990
1077
991
- dss_setup_fifos ();
1078
+ /* step 1: setup fifos/fifomerge before enabling the manager */
1079
+
1080
+ fifo_merge = get_use_fifo_merge ();
1081
+ dss_setup_fifos (fifo_merge );
1082
+ dss_apply_fifo_merge (fifo_merge );
992
1083
993
1084
dss_write_regs ();
994
1085
dss_set_go_bits ();
995
1086
1087
+ spin_unlock_irqrestore (& data_lock , flags );
1088
+
1089
+ /* wait until fifo config is in */
1090
+ wait_pending_extra_info_updates ();
1091
+
1092
+ /* step 2: enable the manager */
1093
+ spin_lock_irqsave (& data_lock , flags );
1094
+
996
1095
if (!mgr_manual_update (mgr ))
997
1096
mp -> updating = true;
998
1097
@@ -1017,6 +1116,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
1017
1116
{
1018
1117
struct mgr_priv_data * mp = get_mgr_priv (mgr );
1019
1118
unsigned long flags ;
1119
+ bool fifo_merge ;
1020
1120
1021
1121
mutex_lock (& apply_lock );
1022
1122
@@ -1031,8 +1131,16 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
1031
1131
mp -> updating = false;
1032
1132
mp -> enabled = false;
1033
1133
1134
+ fifo_merge = get_use_fifo_merge ();
1135
+ dss_setup_fifos (fifo_merge );
1136
+ dss_apply_fifo_merge (fifo_merge );
1137
+
1138
+ dss_write_regs ();
1139
+ dss_set_go_bits ();
1140
+
1034
1141
spin_unlock_irqrestore (& data_lock , flags );
1035
1142
1143
+ wait_pending_extra_info_updates ();
1036
1144
out :
1037
1145
mutex_unlock (& apply_lock );
1038
1146
}
@@ -1284,6 +1392,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1284
1392
{
1285
1393
struct ovl_priv_data * op = get_ovl_priv (ovl );
1286
1394
unsigned long flags ;
1395
+ bool fifo_merge ;
1287
1396
int r ;
1288
1397
1289
1398
mutex_lock (& apply_lock );
@@ -1309,7 +1418,22 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1309
1418
goto err2 ;
1310
1419
}
1311
1420
1312
- dss_setup_fifos ();
1421
+ /* step 1: configure fifos/fifomerge for currently enabled ovls */
1422
+
1423
+ fifo_merge = get_use_fifo_merge ();
1424
+ dss_setup_fifos (fifo_merge );
1425
+ dss_apply_fifo_merge (fifo_merge );
1426
+
1427
+ dss_write_regs ();
1428
+ dss_set_go_bits ();
1429
+
1430
+ spin_unlock_irqrestore (& data_lock , flags );
1431
+
1432
+ /* wait for fifo configs to go in */
1433
+ wait_pending_extra_info_updates ();
1434
+
1435
+ /* step 2: enable the overlay */
1436
+ spin_lock_irqsave (& data_lock , flags );
1313
1437
1314
1438
op -> enabling = false;
1315
1439
dss_apply_ovl_enable (ovl , true);
@@ -1319,6 +1443,9 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1319
1443
1320
1444
spin_unlock_irqrestore (& data_lock , flags );
1321
1445
1446
+ /* wait for overlay to be enabled */
1447
+ wait_pending_extra_info_updates ();
1448
+
1322
1449
mutex_unlock (& apply_lock );
1323
1450
1324
1451
return 0 ;
@@ -1334,6 +1461,7 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1334
1461
{
1335
1462
struct ovl_priv_data * op = get_ovl_priv (ovl );
1336
1463
unsigned long flags ;
1464
+ bool fifo_merge ;
1337
1465
int r ;
1338
1466
1339
1467
mutex_lock (& apply_lock );
@@ -1348,14 +1476,34 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1348
1476
goto err ;
1349
1477
}
1350
1478
1479
+ /* step 1: disable the overlay */
1351
1480
spin_lock_irqsave (& data_lock , flags );
1352
1481
1353
1482
dss_apply_ovl_enable (ovl , false);
1483
+
1354
1484
dss_write_regs ();
1355
1485
dss_set_go_bits ();
1356
1486
1357
1487
spin_unlock_irqrestore (& data_lock , flags );
1358
1488
1489
+ /* wait for the overlay to be disabled */
1490
+ wait_pending_extra_info_updates ();
1491
+
1492
+ /* step 2: configure fifos/fifomerge */
1493
+ spin_lock_irqsave (& data_lock , flags );
1494
+
1495
+ fifo_merge = get_use_fifo_merge ();
1496
+ dss_setup_fifos (fifo_merge );
1497
+ dss_apply_fifo_merge (fifo_merge );
1498
+
1499
+ dss_write_regs ();
1500
+ dss_set_go_bits ();
1501
+
1502
+ spin_unlock_irqrestore (& data_lock , flags );
1503
+
1504
+ /* wait for fifo config to go in */
1505
+ wait_pending_extra_info_updates ();
1506
+
1359
1507
mutex_unlock (& apply_lock );
1360
1508
1361
1509
return 0 ;
0 commit comments