diff options
author | Andy Gross <andy.gross@ti.com> | 2012-12-19 15:53:38 -0500 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2013-02-16 17:38:04 -0500 |
commit | 238083ad5d67d1c9ba6e7158a027e834a48bb23b (patch) | |
tree | a7434626b1874beb0b69f9cf336e1134bb7c97e1 | |
parent | 4836d15789c85224662d3e037694d15ec9901631 (diff) |
drm/omap: Add OMAP5 support
Add support for OMAP5 processor. The main differences are that the OMAP5
has 2 containers, one for 1D and one for 2D. Each container is 128MiB in
size.
Signed-off-by: Andy Gross <andy.gross@ti.com>
Signed-off-by: Rob Clark <rob@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/omapdrm/omap_dmm_priv.h | 5 | ||||
-rw-r--r-- | drivers/staging/omapdrm/omap_dmm_tiler.c | 127 | ||||
-rw-r--r-- | drivers/staging/omapdrm/tcm.h | 2 |
3 files changed, 90 insertions, 44 deletions
diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h b/drivers/staging/omapdrm/omap_dmm_priv.h index 273ec12c028a..58bcd6ae0255 100644 --- a/drivers/staging/omapdrm/omap_dmm_priv.h +++ b/drivers/staging/omapdrm/omap_dmm_priv.h | |||
@@ -118,6 +118,11 @@ struct pat { | |||
118 | #define DESCR_SIZE 128 | 118 | #define DESCR_SIZE 128 |
119 | #define REFILL_BUFFER_SIZE ((4 * 128 * 256) + (3 * DESCR_SIZE)) | 119 | #define REFILL_BUFFER_SIZE ((4 * 128 * 256) + (3 * DESCR_SIZE)) |
120 | 120 | ||
121 | /* For OMAP5, a fixed offset is added to all Y coordinates for 1D buffers. | ||
122 | * This is used in programming to address the upper portion of the LUT | ||
123 | */ | ||
124 | #define OMAP5_LUT_OFFSET 128 | ||
125 | |||
121 | struct dmm; | 126 | struct dmm; |
122 | 127 | ||
123 | struct dmm_txn { | 128 | struct dmm_txn { |
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index c42c5e500e02..391021537105 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c | |||
@@ -213,6 +213,11 @@ static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area, | |||
213 | txn->last_pat->next_pa = (uint32_t)pat_pa; | 213 | txn->last_pat->next_pa = (uint32_t)pat_pa; |
214 | 214 | ||
215 | pat->area = *area; | 215 | pat->area = *area; |
216 | |||
217 | /* adjust Y coordinates based off of container parameters */ | ||
218 | pat->area.y0 += engine->tcm->y_offset; | ||
219 | pat->area.y1 += engine->tcm->y_offset; | ||
220 | |||
216 | pat->ctrl = (struct pat_ctrl){ | 221 | pat->ctrl = (struct pat_ctrl){ |
217 | .start = 1, | 222 | .start = 1, |
218 | .lut_id = engine->tcm->lut_id, | 223 | .lut_id = engine->tcm->lut_id, |
@@ -622,6 +627,11 @@ static int omap_dmm_probe(struct platform_device *dev) | |||
622 | omap_dmm->lut_width = ((pat_geom >> 16) & 0xF) << 5; | 627 | omap_dmm->lut_width = ((pat_geom >> 16) & 0xF) << 5; |
623 | omap_dmm->lut_height = ((pat_geom >> 24) & 0xF) << 5; | 628 | omap_dmm->lut_height = ((pat_geom >> 24) & 0xF) << 5; |
624 | 629 | ||
630 | /* increment LUT by one if on OMAP5 */ | ||
631 | /* LUT has twice the height, and is split into a separate container */ | ||
632 | if (omap_dmm->lut_height != omap_dmm->container_height) | ||
633 | omap_dmm->num_lut++; | ||
634 | |||
625 | /* initialize DMM registers */ | 635 | /* initialize DMM registers */ |
626 | writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__0); | 636 | writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__0); |
627 | writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__1); | 637 | writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__1); |
@@ -701,6 +711,9 @@ static int omap_dmm_probe(struct platform_device *dev) | |||
701 | } | 711 | } |
702 | 712 | ||
703 | /* init containers */ | 713 | /* init containers */ |
714 | /* Each LUT is associated with a TCM (container manager). We use the | ||
715 | lut_id to denote the lut_id used to identify the correct LUT for | ||
716 | programming during reill operations */ | ||
704 | for (i = 0; i < omap_dmm->num_lut; i++) { | 717 | for (i = 0; i < omap_dmm->num_lut; i++) { |
705 | omap_dmm->tcm[i] = sita_init(omap_dmm->container_width, | 718 | omap_dmm->tcm[i] = sita_init(omap_dmm->container_width, |
706 | omap_dmm->container_height, | 719 | omap_dmm->container_height, |
@@ -717,13 +730,23 @@ static int omap_dmm_probe(struct platform_device *dev) | |||
717 | 730 | ||
718 | /* assign access mode containers to applicable tcm container */ | 731 | /* assign access mode containers to applicable tcm container */ |
719 | /* OMAP 4 has 1 container for all 4 views */ | 732 | /* OMAP 4 has 1 container for all 4 views */ |
733 | /* OMAP 5 has 2 containers, 1 for 2D and 1 for 1D */ | ||
720 | containers[TILFMT_8BIT] = omap_dmm->tcm[0]; | 734 | containers[TILFMT_8BIT] = omap_dmm->tcm[0]; |
721 | containers[TILFMT_16BIT] = omap_dmm->tcm[0]; | 735 | containers[TILFMT_16BIT] = omap_dmm->tcm[0]; |
722 | containers[TILFMT_32BIT] = omap_dmm->tcm[0]; | 736 | containers[TILFMT_32BIT] = omap_dmm->tcm[0]; |
723 | containers[TILFMT_PAGE] = omap_dmm->tcm[0]; | 737 | |
738 | if (omap_dmm->container_height != omap_dmm->lut_height) { | ||
739 | /* second LUT is used for PAGE mode. Programming must use | ||
740 | y offset that is added to all y coordinates. LUT id is still | ||
741 | 0, because it is the same LUT, just the upper 128 lines */ | ||
742 | containers[TILFMT_PAGE] = omap_dmm->tcm[1]; | ||
743 | omap_dmm->tcm[1]->y_offset = OMAP5_LUT_OFFSET; | ||
744 | omap_dmm->tcm[1]->lut_id = 0; | ||
745 | } else { | ||
746 | containers[TILFMT_PAGE] = omap_dmm->tcm[0]; | ||
747 | } | ||
724 | 748 | ||
725 | area = (struct tcm_area) { | 749 | area = (struct tcm_area) { |
726 | .is2d = true, | ||
727 | .tcm = NULL, | 750 | .tcm = NULL, |
728 | .p1.x = omap_dmm->container_width - 1, | 751 | .p1.x = omap_dmm->container_width - 1, |
729 | .p1.y = omap_dmm->container_height - 1, | 752 | .p1.y = omap_dmm->container_height - 1, |
@@ -835,64 +858,81 @@ int tiler_map_show(struct seq_file *s, void *arg) | |||
835 | int h_adj; | 858 | int h_adj; |
836 | int w_adj; | 859 | int w_adj; |
837 | unsigned long flags; | 860 | unsigned long flags; |
861 | int lut_idx; | ||
862 | |||
838 | 863 | ||
839 | if (!omap_dmm) { | 864 | if (!omap_dmm) { |
840 | /* early return if dmm/tiler device is not initialized */ | 865 | /* early return if dmm/tiler device is not initialized */ |
841 | return 0; | 866 | return 0; |
842 | } | 867 | } |
843 | 868 | ||
844 | h_adj = omap_dmm->lut_height / ydiv; | 869 | h_adj = omap_dmm->container_height / ydiv; |
845 | w_adj = omap_dmm->lut_width / xdiv; | 870 | w_adj = omap_dmm->container_width / xdiv; |
846 | 871 | ||
847 | map = kzalloc(h_adj * sizeof(*map), GFP_KERNEL); | 872 | map = kmalloc(h_adj * sizeof(*map), GFP_KERNEL); |
848 | global_map = kzalloc((w_adj + 1) * h_adj, GFP_KERNEL); | 873 | global_map = kmalloc((w_adj + 1) * h_adj, GFP_KERNEL); |
849 | 874 | ||
850 | if (!map || !global_map) | 875 | if (!map || !global_map) |
851 | goto error; | 876 | goto error; |
852 | 877 | ||
853 | memset(global_map, ' ', (w_adj + 1) * h_adj); | 878 | for (lut_idx = 0; lut_idx < omap_dmm->num_lut; lut_idx++) { |
854 | for (i = 0; i < omap_dmm->lut_height; i++) { | 879 | memset(map, 0, sizeof(h_adj * sizeof(*map))); |
855 | map[i] = global_map + i * (w_adj + 1); | 880 | memset(global_map, ' ', (w_adj + 1) * h_adj); |
856 | map[i][w_adj] = 0; | ||
857 | } | ||
858 | spin_lock_irqsave(&list_lock, flags); | ||
859 | 881 | ||
860 | list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) { | 882 | for (i = 0; i < omap_dmm->container_height; i++) { |
861 | if (block->fmt != TILFMT_PAGE) { | 883 | map[i] = global_map + i * (w_adj + 1); |
862 | fill_map(map, xdiv, ydiv, &block->area, *m2dp, true); | 884 | map[i][w_adj] = 0; |
863 | if (!*++a2dp) | 885 | } |
864 | a2dp = a2d; | 886 | |
865 | if (!*++m2dp) | 887 | spin_lock_irqsave(&list_lock, flags); |
866 | m2dp = m2d; | 888 | |
867 | map_2d_info(map, xdiv, ydiv, nice, &block->area); | 889 | list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) { |
868 | } else { | 890 | if (block->area.tcm == omap_dmm->tcm[lut_idx]) { |
869 | bool start = read_map_pt(map, xdiv, ydiv, | 891 | if (block->fmt != TILFMT_PAGE) { |
870 | &block->area.p0) | 892 | fill_map(map, xdiv, ydiv, &block->area, |
871 | == ' '; | 893 | *m2dp, true); |
872 | bool end = read_map_pt(map, xdiv, ydiv, &block->area.p1) | 894 | if (!*++a2dp) |
873 | == ' '; | 895 | a2dp = a2d; |
874 | tcm_for_each_slice(a, block->area, p) | 896 | if (!*++m2dp) |
875 | fill_map(map, xdiv, ydiv, &a, '=', true); | 897 | m2dp = m2d; |
876 | fill_map_pt(map, xdiv, ydiv, &block->area.p0, | 898 | map_2d_info(map, xdiv, ydiv, nice, |
899 | &block->area); | ||
900 | } else { | ||
901 | bool start = read_map_pt(map, xdiv, | ||
902 | ydiv, &block->area.p0) == ' '; | ||
903 | bool end = read_map_pt(map, xdiv, ydiv, | ||
904 | &block->area.p1) == ' '; | ||
905 | |||
906 | tcm_for_each_slice(a, block->area, p) | ||
907 | fill_map(map, xdiv, ydiv, &a, | ||
908 | '=', true); | ||
909 | fill_map_pt(map, xdiv, ydiv, | ||
910 | &block->area.p0, | ||
877 | start ? '<' : 'X'); | 911 | start ? '<' : 'X'); |
878 | fill_map_pt(map, xdiv, ydiv, &block->area.p1, | 912 | fill_map_pt(map, xdiv, ydiv, |
913 | &block->area.p1, | ||
879 | end ? '>' : 'X'); | 914 | end ? '>' : 'X'); |
880 | map_1d_info(map, xdiv, ydiv, nice, &block->area); | 915 | map_1d_info(map, xdiv, ydiv, nice, |
916 | &block->area); | ||
917 | } | ||
918 | } | ||
881 | } | 919 | } |
882 | } | ||
883 | 920 | ||
884 | spin_unlock_irqrestore(&list_lock, flags); | 921 | spin_unlock_irqrestore(&list_lock, flags); |
885 | 922 | ||
886 | if (s) { | 923 | if (s) { |
887 | seq_printf(s, "BEGIN DMM TILER MAP\n"); | 924 | seq_printf(s, "CONTAINER %d DUMP BEGIN\n", lut_idx); |
888 | for (i = 0; i < 128; i++) | 925 | for (i = 0; i < 128; i++) |
889 | seq_printf(s, "%03d:%s\n", i, map[i]); | 926 | seq_printf(s, "%03d:%s\n", i, map[i]); |
890 | seq_printf(s, "END TILER MAP\n"); | 927 | seq_printf(s, "CONTAINER %d DUMP END\n", lut_idx); |
891 | } else { | 928 | } else { |
892 | dev_dbg(omap_dmm->dev, "BEGIN DMM TILER MAP\n"); | 929 | dev_dbg(omap_dmm->dev, "CONTAINER %d DUMP BEGIN\n", |
893 | for (i = 0; i < 128; i++) | 930 | lut_idx); |
894 | dev_dbg(omap_dmm->dev, "%03d:%s\n", i, map[i]); | 931 | for (i = 0; i < 128; i++) |
895 | dev_dbg(omap_dmm->dev, "END TILER MAP\n"); | 932 | dev_dbg(omap_dmm->dev, "%03d:%s\n", i, map[i]); |
933 | dev_dbg(omap_dmm->dev, "CONTAINER %d DUMP END\n", | ||
934 | lut_idx); | ||
935 | } | ||
896 | } | 936 | } |
897 | 937 | ||
898 | error: | 938 | error: |
@@ -913,7 +953,6 @@ static int omap_dmm_resume(struct device *dev) | |||
913 | return -ENODEV; | 953 | return -ENODEV; |
914 | 954 | ||
915 | area = (struct tcm_area) { | 955 | area = (struct tcm_area) { |
916 | .is2d = true, | ||
917 | .tcm = NULL, | 956 | .tcm = NULL, |
918 | .p1.x = omap_dmm->container_width - 1, | 957 | .p1.x = omap_dmm->container_width - 1, |
919 | .p1.y = omap_dmm->container_height - 1, | 958 | .p1.y = omap_dmm->container_height - 1, |
diff --git a/drivers/staging/omapdrm/tcm.h b/drivers/staging/omapdrm/tcm.h index d273e3ee0b4c..a8d5ce47686f 100644 --- a/drivers/staging/omapdrm/tcm.h +++ b/drivers/staging/omapdrm/tcm.h | |||
@@ -59,6 +59,8 @@ struct tcm { | |||
59 | u16 width, height; /* container dimensions */ | 59 | u16 width, height; /* container dimensions */ |
60 | int lut_id; /* Lookup table identifier */ | 60 | int lut_id; /* Lookup table identifier */ |
61 | 61 | ||
62 | unsigned int y_offset; /* offset to use for y coordinates */ | ||
63 | |||
62 | /* 'pvt' structure shall contain any tcm details (attr) along with | 64 | /* 'pvt' structure shall contain any tcm details (attr) along with |
63 | linked list of allocated areas and mutex for mutually exclusive access | 65 | linked list of allocated areas and mutex for mutually exclusive access |
64 | to the list. It may also contain copies of width and height to notice | 66 | to the list. It may also contain copies of width and height to notice |