diff options
-rw-r--r-- | drivers/video/omap2/dss/apply.c | 221 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 55 | ||||
-rw-r--r-- | drivers/video/omap2/dss/display.c | 10 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 8 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 10 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.c | 11 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.h | 3 |
7 files changed, 252 insertions, 66 deletions
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 052dc874cd3d..b0264a164652 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c | |||
@@ -105,6 +105,9 @@ static struct { | |||
105 | struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; | 105 | struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; |
106 | struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; | 106 | struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; |
107 | 107 | ||
108 | bool fifo_merge_dirty; | ||
109 | bool fifo_merge; | ||
110 | |||
108 | bool irq_enabled; | 111 | bool irq_enabled; |
109 | } dss_data; | 112 | } dss_data; |
110 | 113 | ||
@@ -585,11 +588,40 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) | |||
585 | } | 588 | } |
586 | } | 589 | } |
587 | 590 | ||
591 | static void dss_write_regs_common(void) | ||
592 | { | ||
593 | const int num_mgrs = omap_dss_get_num_overlay_managers(); | ||
594 | int i; | ||
595 | |||
596 | if (!dss_data.fifo_merge_dirty) | ||
597 | return; | ||
598 | |||
599 | for (i = 0; i < num_mgrs; ++i) { | ||
600 | struct omap_overlay_manager *mgr; | ||
601 | struct mgr_priv_data *mp; | ||
602 | |||
603 | mgr = omap_dss_get_overlay_manager(i); | ||
604 | mp = get_mgr_priv(mgr); | ||
605 | |||
606 | if (mp->enabled) { | ||
607 | if (dss_data.fifo_merge_dirty) { | ||
608 | dispc_enable_fifomerge(dss_data.fifo_merge); | ||
609 | dss_data.fifo_merge_dirty = false; | ||
610 | } | ||
611 | |||
612 | if (mp->updating) | ||
613 | mp->shadow_info_dirty = true; | ||
614 | } | ||
615 | } | ||
616 | } | ||
617 | |||
588 | static void dss_write_regs(void) | 618 | static void dss_write_regs(void) |
589 | { | 619 | { |
590 | const int num_mgrs = omap_dss_get_num_overlay_managers(); | 620 | const int num_mgrs = omap_dss_get_num_overlay_managers(); |
591 | int i; | 621 | int i; |
592 | 622 | ||
623 | dss_write_regs_common(); | ||
624 | |||
593 | for (i = 0; i < num_mgrs; ++i) { | 625 | for (i = 0; i < num_mgrs; ++i) { |
594 | struct omap_overlay_manager *mgr; | 626 | struct omap_overlay_manager *mgr; |
595 | struct mgr_priv_data *mp; | 627 | struct mgr_priv_data *mp; |
@@ -659,6 +691,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) | |||
659 | 691 | ||
660 | dss_mgr_write_regs(mgr); | 692 | dss_mgr_write_regs(mgr); |
661 | 693 | ||
694 | dss_write_regs_common(); | ||
695 | |||
662 | mp->updating = true; | 696 | mp->updating = true; |
663 | 697 | ||
664 | if (!dss_data.irq_enabled && need_isr()) | 698 | if (!dss_data.irq_enabled && need_isr()) |
@@ -859,11 +893,20 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl, | |||
859 | op->extra_info_dirty = true; | 893 | op->extra_info_dirty = true; |
860 | } | 894 | } |
861 | 895 | ||
862 | static void dss_ovl_setup_fifo(struct omap_overlay *ovl) | 896 | static void dss_apply_fifo_merge(bool use_fifo_merge) |
897 | { | ||
898 | if (dss_data.fifo_merge == use_fifo_merge) | ||
899 | return; | ||
900 | |||
901 | dss_data.fifo_merge = use_fifo_merge; | ||
902 | dss_data.fifo_merge_dirty = true; | ||
903 | } | ||
904 | |||
905 | static void dss_ovl_setup_fifo(struct omap_overlay *ovl, | ||
906 | bool use_fifo_merge) | ||
863 | { | 907 | { |
864 | struct ovl_priv_data *op = get_ovl_priv(ovl); | 908 | struct ovl_priv_data *op = get_ovl_priv(ovl); |
865 | struct omap_dss_device *dssdev; | 909 | struct omap_dss_device *dssdev; |
866 | u32 size, burst_size; | ||
867 | u32 fifo_low, fifo_high; | 910 | u32 fifo_low, fifo_high; |
868 | 911 | ||
869 | if (!op->enabled && !op->enabling) | 912 | if (!op->enabled && !op->enabling) |
@@ -871,33 +914,14 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl) | |||
871 | 914 | ||
872 | dssdev = ovl->manager->device; | 915 | dssdev = ovl->manager->device; |
873 | 916 | ||
874 | size = dispc_ovl_get_fifo_size(ovl->id); | 917 | dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high, |
875 | 918 | use_fifo_merge); | |
876 | burst_size = dispc_ovl_get_burst_size(ovl->id); | ||
877 | |||
878 | switch (dssdev->type) { | ||
879 | case OMAP_DISPLAY_TYPE_DPI: | ||
880 | case OMAP_DISPLAY_TYPE_DBI: | ||
881 | case OMAP_DISPLAY_TYPE_SDI: | ||
882 | case OMAP_DISPLAY_TYPE_VENC: | ||
883 | case OMAP_DISPLAY_TYPE_HDMI: | ||
884 | default_get_overlay_fifo_thresholds(ovl->id, size, | ||
885 | burst_size, &fifo_low, &fifo_high); | ||
886 | break; | ||
887 | #ifdef CONFIG_OMAP2_DSS_DSI | ||
888 | case OMAP_DISPLAY_TYPE_DSI: | ||
889 | dsi_get_overlay_fifo_thresholds(ovl->id, size, | ||
890 | burst_size, &fifo_low, &fifo_high); | ||
891 | break; | ||
892 | #endif | ||
893 | default: | ||
894 | BUG(); | ||
895 | } | ||
896 | 919 | ||
897 | dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); | 920 | dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); |
898 | } | 921 | } |
899 | 922 | ||
900 | static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) | 923 | static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr, |
924 | bool use_fifo_merge) | ||
901 | { | 925 | { |
902 | struct omap_overlay *ovl; | 926 | struct omap_overlay *ovl; |
903 | struct mgr_priv_data *mp; | 927 | struct mgr_priv_data *mp; |
@@ -908,19 +932,94 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) | |||
908 | return; | 932 | return; |
909 | 933 | ||
910 | list_for_each_entry(ovl, &mgr->overlays, list) | 934 | list_for_each_entry(ovl, &mgr->overlays, list) |
911 | dss_ovl_setup_fifo(ovl); | 935 | dss_ovl_setup_fifo(ovl, use_fifo_merge); |
936 | } | ||
937 | |||
938 | static void dss_setup_fifos(bool use_fifo_merge) | ||
939 | { | ||
940 | const int num_mgrs = omap_dss_get_num_overlay_managers(); | ||
941 | struct omap_overlay_manager *mgr; | ||
942 | int i; | ||
943 | |||
944 | for (i = 0; i < num_mgrs; ++i) { | ||
945 | mgr = omap_dss_get_overlay_manager(i); | ||
946 | dss_mgr_setup_fifos(mgr, use_fifo_merge); | ||
947 | } | ||
912 | } | 948 | } |
913 | 949 | ||
914 | static void dss_setup_fifos(void) | 950 | static int get_num_used_managers(void) |
915 | { | 951 | { |
916 | const int num_mgrs = omap_dss_get_num_overlay_managers(); | 952 | const int num_mgrs = omap_dss_get_num_overlay_managers(); |
917 | struct omap_overlay_manager *mgr; | 953 | struct omap_overlay_manager *mgr; |
954 | struct mgr_priv_data *mp; | ||
918 | int i; | 955 | int i; |
956 | int enabled_mgrs; | ||
957 | |||
958 | enabled_mgrs = 0; | ||
919 | 959 | ||
920 | for (i = 0; i < num_mgrs; ++i) { | 960 | for (i = 0; i < num_mgrs; ++i) { |
921 | mgr = omap_dss_get_overlay_manager(i); | 961 | mgr = omap_dss_get_overlay_manager(i); |
922 | dss_mgr_setup_fifos(mgr); | 962 | mp = get_mgr_priv(mgr); |
963 | |||
964 | if (!mp->enabled) | ||
965 | continue; | ||
966 | |||
967 | enabled_mgrs++; | ||
923 | } | 968 | } |
969 | |||
970 | return enabled_mgrs; | ||
971 | } | ||
972 | |||
973 | static int get_num_used_overlays(void) | ||
974 | { | ||
975 | const int num_ovls = omap_dss_get_num_overlays(); | ||
976 | struct omap_overlay *ovl; | ||
977 | struct ovl_priv_data *op; | ||
978 | struct mgr_priv_data *mp; | ||
979 | int i; | ||
980 | int enabled_ovls; | ||
981 | |||
982 | enabled_ovls = 0; | ||
983 | |||
984 | for (i = 0; i < num_ovls; ++i) { | ||
985 | ovl = omap_dss_get_overlay(i); | ||
986 | op = get_ovl_priv(ovl); | ||
987 | |||
988 | if (!op->enabled && !op->enabling) | ||
989 | continue; | ||
990 | |||
991 | mp = get_mgr_priv(ovl->manager); | ||
992 | |||
993 | if (!mp->enabled) | ||
994 | continue; | ||
995 | |||
996 | enabled_ovls++; | ||
997 | } | ||
998 | |||
999 | return enabled_ovls; | ||
1000 | } | ||
1001 | |||
1002 | static bool get_use_fifo_merge(void) | ||
1003 | { | ||
1004 | int enabled_mgrs = get_num_used_managers(); | ||
1005 | int enabled_ovls = get_num_used_overlays(); | ||
1006 | |||
1007 | if (!dss_has_feature(FEAT_FIFO_MERGE)) | ||
1008 | return false; | ||
1009 | |||
1010 | /* | ||
1011 | * In theory the only requirement for fifomerge is enabled_ovls <= 1. | ||
1012 | * However, if we have two managers enabled and set/unset the fifomerge, | ||
1013 | * we need to set the GO bits in particular sequence for the managers, | ||
1014 | * and wait in between. | ||
1015 | * | ||
1016 | * This is rather difficult as new apply calls can happen at any time, | ||
1017 | * so we simplify the problem by requiring also that enabled_mgrs <= 1. | ||
1018 | * In practice this shouldn't matter, because when only one overlay is | ||
1019 | * enabled, most likely only one output is enabled. | ||
1020 | */ | ||
1021 | |||
1022 | return enabled_mgrs <= 1 && enabled_ovls <= 1; | ||
924 | } | 1023 | } |
925 | 1024 | ||
926 | int dss_mgr_enable(struct omap_overlay_manager *mgr) | 1025 | int dss_mgr_enable(struct omap_overlay_manager *mgr) |
@@ -928,6 +1027,7 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) | |||
928 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | 1027 | struct mgr_priv_data *mp = get_mgr_priv(mgr); |
929 | unsigned long flags; | 1028 | unsigned long flags; |
930 | int r; | 1029 | int r; |
1030 | bool fifo_merge; | ||
931 | 1031 | ||
932 | mutex_lock(&apply_lock); | 1032 | mutex_lock(&apply_lock); |
933 | 1033 | ||
@@ -945,11 +1045,23 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) | |||
945 | goto err; | 1045 | goto err; |
946 | } | 1046 | } |
947 | 1047 | ||
948 | dss_setup_fifos(); | 1048 | /* step 1: setup fifos/fifomerge before enabling the manager */ |
1049 | |||
1050 | fifo_merge = get_use_fifo_merge(); | ||
1051 | dss_setup_fifos(fifo_merge); | ||
1052 | dss_apply_fifo_merge(fifo_merge); | ||
949 | 1053 | ||
950 | dss_write_regs(); | 1054 | dss_write_regs(); |
951 | dss_set_go_bits(); | 1055 | dss_set_go_bits(); |
952 | 1056 | ||
1057 | spin_unlock_irqrestore(&data_lock, flags); | ||
1058 | |||
1059 | /* wait until fifo config is in */ | ||
1060 | wait_pending_extra_info_updates(); | ||
1061 | |||
1062 | /* step 2: enable the manager */ | ||
1063 | spin_lock_irqsave(&data_lock, flags); | ||
1064 | |||
953 | if (!mgr_manual_update(mgr)) | 1065 | if (!mgr_manual_update(mgr)) |
954 | mp->updating = true; | 1066 | mp->updating = true; |
955 | 1067 | ||
@@ -974,6 +1086,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) | |||
974 | { | 1086 | { |
975 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | 1087 | struct mgr_priv_data *mp = get_mgr_priv(mgr); |
976 | unsigned long flags; | 1088 | unsigned long flags; |
1089 | bool fifo_merge; | ||
977 | 1090 | ||
978 | mutex_lock(&apply_lock); | 1091 | mutex_lock(&apply_lock); |
979 | 1092 | ||
@@ -988,8 +1101,16 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) | |||
988 | mp->updating = false; | 1101 | mp->updating = false; |
989 | mp->enabled = false; | 1102 | mp->enabled = false; |
990 | 1103 | ||
1104 | fifo_merge = get_use_fifo_merge(); | ||
1105 | dss_setup_fifos(fifo_merge); | ||
1106 | dss_apply_fifo_merge(fifo_merge); | ||
1107 | |||
1108 | dss_write_regs(); | ||
1109 | dss_set_go_bits(); | ||
1110 | |||
991 | spin_unlock_irqrestore(&data_lock, flags); | 1111 | spin_unlock_irqrestore(&data_lock, flags); |
992 | 1112 | ||
1113 | wait_pending_extra_info_updates(); | ||
993 | out: | 1114 | out: |
994 | mutex_unlock(&apply_lock); | 1115 | mutex_unlock(&apply_lock); |
995 | } | 1116 | } |
@@ -1241,6 +1362,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) | |||
1241 | { | 1362 | { |
1242 | struct ovl_priv_data *op = get_ovl_priv(ovl); | 1363 | struct ovl_priv_data *op = get_ovl_priv(ovl); |
1243 | unsigned long flags; | 1364 | unsigned long flags; |
1365 | bool fifo_merge; | ||
1244 | int r; | 1366 | int r; |
1245 | 1367 | ||
1246 | mutex_lock(&apply_lock); | 1368 | mutex_lock(&apply_lock); |
@@ -1266,7 +1388,22 @@ int dss_ovl_enable(struct omap_overlay *ovl) | |||
1266 | goto err2; | 1388 | goto err2; |
1267 | } | 1389 | } |
1268 | 1390 | ||
1269 | dss_setup_fifos(); | 1391 | /* step 1: configure fifos/fifomerge for currently enabled ovls */ |
1392 | |||
1393 | fifo_merge = get_use_fifo_merge(); | ||
1394 | dss_setup_fifos(fifo_merge); | ||
1395 | dss_apply_fifo_merge(fifo_merge); | ||
1396 | |||
1397 | dss_write_regs(); | ||
1398 | dss_set_go_bits(); | ||
1399 | |||
1400 | spin_unlock_irqrestore(&data_lock, flags); | ||
1401 | |||
1402 | /* wait for fifo configs to go in */ | ||
1403 | wait_pending_extra_info_updates(); | ||
1404 | |||
1405 | /* step 2: enable the overlay */ | ||
1406 | spin_lock_irqsave(&data_lock, flags); | ||
1270 | 1407 | ||
1271 | op->enabling = false; | 1408 | op->enabling = false; |
1272 | dss_apply_ovl_enable(ovl, true); | 1409 | dss_apply_ovl_enable(ovl, true); |
@@ -1276,6 +1413,9 @@ int dss_ovl_enable(struct omap_overlay *ovl) | |||
1276 | 1413 | ||
1277 | spin_unlock_irqrestore(&data_lock, flags); | 1414 | spin_unlock_irqrestore(&data_lock, flags); |
1278 | 1415 | ||
1416 | /* wait for overlay to be enabled */ | ||
1417 | wait_pending_extra_info_updates(); | ||
1418 | |||
1279 | mutex_unlock(&apply_lock); | 1419 | mutex_unlock(&apply_lock); |
1280 | 1420 | ||
1281 | return 0; | 1421 | return 0; |
@@ -1291,6 +1431,7 @@ int dss_ovl_disable(struct omap_overlay *ovl) | |||
1291 | { | 1431 | { |
1292 | struct ovl_priv_data *op = get_ovl_priv(ovl); | 1432 | struct ovl_priv_data *op = get_ovl_priv(ovl); |
1293 | unsigned long flags; | 1433 | unsigned long flags; |
1434 | bool fifo_merge; | ||
1294 | int r; | 1435 | int r; |
1295 | 1436 | ||
1296 | mutex_lock(&apply_lock); | 1437 | mutex_lock(&apply_lock); |
@@ -1305,14 +1446,34 @@ int dss_ovl_disable(struct omap_overlay *ovl) | |||
1305 | goto err; | 1446 | goto err; |
1306 | } | 1447 | } |
1307 | 1448 | ||
1449 | /* step 1: disable the overlay */ | ||
1308 | spin_lock_irqsave(&data_lock, flags); | 1450 | spin_lock_irqsave(&data_lock, flags); |
1309 | 1451 | ||
1310 | dss_apply_ovl_enable(ovl, false); | 1452 | dss_apply_ovl_enable(ovl, false); |
1453 | |||
1311 | dss_write_regs(); | 1454 | dss_write_regs(); |
1312 | dss_set_go_bits(); | 1455 | dss_set_go_bits(); |
1313 | 1456 | ||
1314 | spin_unlock_irqrestore(&data_lock, flags); | 1457 | spin_unlock_irqrestore(&data_lock, flags); |
1315 | 1458 | ||
1459 | /* wait for the overlay to be disabled */ | ||
1460 | wait_pending_extra_info_updates(); | ||
1461 | |||
1462 | /* step 2: configure fifos/fifomerge */ | ||
1463 | spin_lock_irqsave(&data_lock, flags); | ||
1464 | |||
1465 | fifo_merge = get_use_fifo_merge(); | ||
1466 | dss_setup_fifos(fifo_merge); | ||
1467 | dss_apply_fifo_merge(fifo_merge); | ||
1468 | |||
1469 | dss_write_regs(); | ||
1470 | dss_set_go_bits(); | ||
1471 | |||
1472 | spin_unlock_irqrestore(&data_lock, flags); | ||
1473 | |||
1474 | /* wait for fifo config to go in */ | ||
1475 | wait_pending_extra_info_updates(); | ||
1476 | |||
1316 | mutex_unlock(&apply_lock); | 1477 | mutex_unlock(&apply_lock); |
1317 | 1478 | ||
1318 | return 0; | 1479 | return 0; |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 6fa866a83f1c..ba45bbe14bf4 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -909,7 +909,7 @@ static void dispc_configure_burst_sizes(void) | |||
909 | dispc_ovl_set_burst_size(i, burst_size); | 909 | dispc_ovl_set_burst_size(i, burst_size); |
910 | } | 910 | } |
911 | 911 | ||
912 | u32 dispc_ovl_get_burst_size(enum omap_plane plane) | 912 | static u32 dispc_ovl_get_burst_size(enum omap_plane plane) |
913 | { | 913 | { |
914 | unsigned unit = dss_feat_get_burst_size_unit(); | 914 | unsigned unit = dss_feat_get_burst_size_unit(); |
915 | /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ | 915 | /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ |
@@ -1018,7 +1018,7 @@ static void dispc_read_plane_fifo_sizes(void) | |||
1018 | } | 1018 | } |
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | u32 dispc_ovl_get_fifo_size(enum omap_plane plane) | 1021 | static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) |
1022 | { | 1022 | { |
1023 | return dispc.fifo_size[plane]; | 1023 | return dispc.fifo_size[plane]; |
1024 | } | 1024 | } |
@@ -1039,13 +1039,13 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) | |||
1039 | dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); | 1039 | dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); |
1040 | dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); | 1040 | dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); |
1041 | 1041 | ||
1042 | DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", | 1042 | DSSDBG("fifo(%d) threshold (bytes), old %u/%u, new %u/%u\n", |
1043 | plane, | 1043 | plane, |
1044 | REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), | 1044 | REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), |
1045 | lo_start, lo_end), | 1045 | lo_start, lo_end) * unit, |
1046 | REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), | 1046 | REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), |
1047 | hi_start, hi_end), | 1047 | hi_start, hi_end) * unit, |
1048 | low, high); | 1048 | low * unit, high * unit); |
1049 | 1049 | ||
1050 | dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), | 1050 | dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), |
1051 | FLD_VAL(high, hi_start, hi_end) | | 1051 | FLD_VAL(high, hi_start, hi_end) | |
@@ -1054,10 +1054,53 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) | |||
1054 | 1054 | ||
1055 | void dispc_enable_fifomerge(bool enable) | 1055 | void dispc_enable_fifomerge(bool enable) |
1056 | { | 1056 | { |
1057 | if (!dss_has_feature(FEAT_FIFO_MERGE)) { | ||
1058 | WARN_ON(enable); | ||
1059 | return; | ||
1060 | } | ||
1061 | |||
1057 | DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); | 1062 | DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); |
1058 | REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); | 1063 | REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); |
1059 | } | 1064 | } |
1060 | 1065 | ||
1066 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, | ||
1067 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge) | ||
1068 | { | ||
1069 | /* | ||
1070 | * All sizes are in bytes. Both the buffer and burst are made of | ||
1071 | * buffer_units, and the fifo thresholds must be buffer_unit aligned. | ||
1072 | */ | ||
1073 | |||
1074 | unsigned buf_unit = dss_feat_get_buffer_size_unit(); | ||
1075 | unsigned ovl_fifo_size, total_fifo_size, burst_size; | ||
1076 | int i; | ||
1077 | |||
1078 | burst_size = dispc_ovl_get_burst_size(plane); | ||
1079 | ovl_fifo_size = dispc_ovl_get_fifo_size(plane); | ||
1080 | |||
1081 | if (use_fifomerge) { | ||
1082 | total_fifo_size = 0; | ||
1083 | for (i = 0; i < omap_dss_get_num_overlays(); ++i) | ||
1084 | total_fifo_size += dispc_ovl_get_fifo_size(i); | ||
1085 | } else { | ||
1086 | total_fifo_size = ovl_fifo_size; | ||
1087 | } | ||
1088 | |||
1089 | /* | ||
1090 | * We use the same low threshold for both fifomerge and non-fifomerge | ||
1091 | * cases, but for fifomerge we calculate the high threshold using the | ||
1092 | * combined fifo size | ||
1093 | */ | ||
1094 | |||
1095 | if (dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { | ||
1096 | *fifo_low = ovl_fifo_size - burst_size * 2; | ||
1097 | *fifo_high = total_fifo_size - burst_size; | ||
1098 | } else { | ||
1099 | *fifo_low = ovl_fifo_size - burst_size; | ||
1100 | *fifo_high = total_fifo_size - buf_unit; | ||
1101 | } | ||
1102 | } | ||
1103 | |||
1061 | static void dispc_ovl_set_fir(enum omap_plane plane, | 1104 | static void dispc_ovl_set_fir(enum omap_plane plane, |
1062 | int hinc, int vinc, | 1105 | int hinc, int vinc, |
1063 | enum omap_color_component color_comp) | 1106 | enum omap_color_component color_comp) |
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index be331dc5a61b..4424c198dbcd 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c | |||
@@ -279,16 +279,6 @@ void omapdss_default_get_resolution(struct omap_dss_device *dssdev, | |||
279 | } | 279 | } |
280 | EXPORT_SYMBOL(omapdss_default_get_resolution); | 280 | EXPORT_SYMBOL(omapdss_default_get_resolution); |
281 | 281 | ||
282 | void default_get_overlay_fifo_thresholds(enum omap_plane plane, | ||
283 | u32 fifo_size, u32 burst_size, | ||
284 | u32 *fifo_low, u32 *fifo_high) | ||
285 | { | ||
286 | unsigned buf_unit = dss_feat_get_buffer_size_unit(); | ||
287 | |||
288 | *fifo_high = fifo_size - buf_unit; | ||
289 | *fifo_low = fifo_size - burst_size; | ||
290 | } | ||
291 | |||
292 | int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) | 282 | int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) |
293 | { | 283 | { |
294 | switch (dssdev->type) { | 284 | switch (dssdev->type) { |
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 52b935977300..1c3e295c2e0a 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
@@ -4524,14 +4524,6 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) | |||
4524 | } | 4524 | } |
4525 | EXPORT_SYMBOL(omapdss_dsi_enable_te); | 4525 | EXPORT_SYMBOL(omapdss_dsi_enable_te); |
4526 | 4526 | ||
4527 | void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, | ||
4528 | u32 fifo_size, u32 burst_size, | ||
4529 | u32 *fifo_low, u32 *fifo_high) | ||
4530 | { | ||
4531 | *fifo_high = fifo_size - burst_size; | ||
4532 | *fifo_low = fifo_size - burst_size * 2; | ||
4533 | } | ||
4534 | |||
4535 | int dsi_init_display(struct omap_dss_device *dssdev) | 4527 | int dsi_init_display(struct omap_dss_device *dssdev) |
4536 | { | 4528 | { |
4537 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4529 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 32ff69fb3333..d4b3dff2ead3 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h | |||
@@ -202,9 +202,6 @@ void dss_uninit_device(struct platform_device *pdev, | |||
202 | struct omap_dss_device *dssdev); | 202 | struct omap_dss_device *dssdev); |
203 | bool dss_use_replication(struct omap_dss_device *dssdev, | 203 | bool dss_use_replication(struct omap_dss_device *dssdev, |
204 | enum omap_color_mode mode); | 204 | enum omap_color_mode mode); |
205 | void default_get_overlay_fifo_thresholds(enum omap_plane plane, | ||
206 | u32 fifo_size, u32 burst_size, | ||
207 | u32 *fifo_low, u32 *fifo_high); | ||
208 | 205 | ||
209 | /* manager */ | 206 | /* manager */ |
210 | int dss_init_overlay_managers(struct platform_device *pdev); | 207 | int dss_init_overlay_managers(struct platform_device *pdev); |
@@ -313,9 +310,6 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, | |||
313 | int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, | 310 | int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, |
314 | bool enable_hsdiv); | 311 | bool enable_hsdiv); |
315 | void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); | 312 | void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); |
316 | void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, | ||
317 | u32 fifo_size, u32 burst_size, | ||
318 | u32 *fifo_low, u32 *fifo_high); | ||
319 | void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); | 313 | void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); |
320 | void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); | 314 | void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); |
321 | struct platform_device *dsi_get_dsidev_from_id(int module); | 315 | struct platform_device *dsi_get_dsidev_from_id(int module); |
@@ -429,8 +423,8 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, | |||
429 | 423 | ||
430 | 424 | ||
431 | void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); | 425 | void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); |
432 | u32 dispc_ovl_get_fifo_size(enum omap_plane plane); | 426 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, |
433 | u32 dispc_ovl_get_burst_size(enum omap_plane plane); | 427 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge); |
434 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | 428 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, |
435 | bool ilace, bool replication); | 429 | bool ilace, bool replication); |
436 | int dispc_ovl_enable(enum omap_plane plane, bool enable); | 430 | int dispc_ovl_enable(enum omap_plane plane, bool enable); |
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index afcb59301c37..419419ad0493 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c | |||
@@ -370,7 +370,8 @@ static const struct omap_dss_features omap3430_dss_features = { | |||
370 | FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | | 370 | FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | |
371 | FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC | | 371 | FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC | |
372 | FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD | | 372 | FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD | |
373 | FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER, | 373 | FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE | |
374 | FEAT_OMAP3_DSI_FIFO_BUG, | ||
374 | 375 | ||
375 | .num_mgrs = 2, | 376 | .num_mgrs = 2, |
376 | .num_ovls = 3, | 377 | .num_ovls = 3, |
@@ -394,7 +395,8 @@ static const struct omap_dss_features omap3630_dss_features = { | |||
394 | FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | | 395 | FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | |
395 | FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG | | 396 | FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG | |
396 | FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD | | 397 | FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD | |
397 | FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER, | 398 | FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE | |
399 | FEAT_OMAP3_DSI_FIFO_BUG, | ||
398 | 400 | ||
399 | .num_mgrs = 2, | 401 | .num_mgrs = 2, |
400 | .num_ovls = 3, | 402 | .num_ovls = 3, |
@@ -419,7 +421,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = { | |||
419 | FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | | 421 | FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | |
420 | FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | | 422 | FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | |
421 | FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V | | 423 | FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V | |
422 | FEAT_ALPHA_FREE_ZORDER, | 424 | FEAT_ALPHA_FREE_ZORDER | FEAT_FIFO_MERGE, |
423 | 425 | ||
424 | .num_mgrs = 3, | 426 | .num_mgrs = 3, |
425 | .num_ovls = 4, | 427 | .num_ovls = 4, |
@@ -443,7 +445,8 @@ static const struct omap_dss_features omap4_dss_features = { | |||
443 | FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | | 445 | FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | |
444 | FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE | | 446 | FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE | |
445 | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR | | 447 | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR | |
446 | FEAT_PRELOAD | FEAT_FIR_COEF_V | FEAT_ALPHA_FREE_ZORDER, | 448 | FEAT_PRELOAD | FEAT_FIR_COEF_V | FEAT_ALPHA_FREE_ZORDER | |
449 | FEAT_FIFO_MERGE, | ||
447 | 450 | ||
448 | .num_mgrs = 3, | 451 | .num_mgrs = 3, |
449 | .num_ovls = 4, | 452 | .num_ovls = 4, |
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index cd833bbaac3d..5f9b82156778 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h | |||
@@ -58,6 +58,9 @@ enum dss_feat_id { | |||
58 | FEAT_FIR_COEF_V = 1 << 25, | 58 | FEAT_FIR_COEF_V = 1 << 25, |
59 | FEAT_ALPHA_FIXED_ZORDER = 1 << 26, | 59 | FEAT_ALPHA_FIXED_ZORDER = 1 << 26, |
60 | FEAT_ALPHA_FREE_ZORDER = 1 << 27, | 60 | FEAT_ALPHA_FREE_ZORDER = 1 << 27, |
61 | FEAT_FIFO_MERGE = 1 << 28, | ||
62 | /* An unknown HW bug causing the normal FIFO thresholds not to work */ | ||
63 | FEAT_OMAP3_DSI_FIFO_BUG = 1 << 29, | ||
61 | }; | 64 | }; |
62 | 65 | ||
63 | /* DSS register field id */ | 66 | /* DSS register field id */ |