diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/omap2/omapfb/omapfb-ioctl.c | 125 | ||||
-rw-r--r-- | drivers/video/omap2/omapfb/omapfb-main.c | 71 | ||||
-rw-r--r-- | drivers/video/omap2/omapfb/omapfb-sysfs.c | 37 | ||||
-rw-r--r-- | drivers/video/omap2/omapfb/omapfb.h | 9 |
4 files changed, 179 insertions, 63 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 9c7361871d78..6635bd75affa 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c | |||
@@ -34,12 +34,37 @@ | |||
34 | 34 | ||
35 | #include "omapfb.h" | 35 | #include "omapfb.h" |
36 | 36 | ||
37 | static u8 get_mem_idx(struct omapfb_info *ofbi) | ||
38 | { | ||
39 | if (ofbi->id == ofbi->region->id) | ||
40 | return 0; | ||
41 | |||
42 | return OMAPFB_MEM_IDX_ENABLED | ofbi->region->id; | ||
43 | } | ||
44 | |||
45 | static struct omapfb2_mem_region *get_mem_region(struct omapfb_info *ofbi, | ||
46 | u8 mem_idx) | ||
47 | { | ||
48 | struct omapfb2_device *fbdev = ofbi->fbdev; | ||
49 | |||
50 | if (mem_idx & OMAPFB_MEM_IDX_ENABLED) | ||
51 | mem_idx &= OMAPFB_MEM_IDX_MASK; | ||
52 | else | ||
53 | mem_idx = ofbi->id; | ||
54 | |||
55 | if (mem_idx >= fbdev->num_fbs) | ||
56 | return NULL; | ||
57 | |||
58 | return &fbdev->regions[mem_idx]; | ||
59 | } | ||
60 | |||
37 | static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) | 61 | static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) |
38 | { | 62 | { |
39 | struct omapfb_info *ofbi = FB2OFB(fbi); | 63 | struct omapfb_info *ofbi = FB2OFB(fbi); |
40 | struct omapfb2_device *fbdev = ofbi->fbdev; | 64 | struct omapfb2_device *fbdev = ofbi->fbdev; |
41 | struct omap_overlay *ovl; | 65 | struct omap_overlay *ovl; |
42 | struct omap_overlay_info info; | 66 | struct omap_overlay_info old_info; |
67 | struct omapfb2_mem_region *old_rg, *new_rg; | ||
43 | int r = 0; | 68 | int r = 0; |
44 | 69 | ||
45 | DBG("omapfb_setup_plane\n"); | 70 | DBG("omapfb_setup_plane\n"); |
@@ -52,7 +77,14 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) | |||
52 | /* XXX uses only the first overlay */ | 77 | /* XXX uses only the first overlay */ |
53 | ovl = ofbi->overlays[0]; | 78 | ovl = ofbi->overlays[0]; |
54 | 79 | ||
55 | if (pi->enabled && !ofbi->region.size) { | 80 | old_rg = ofbi->region; |
81 | new_rg = get_mem_region(ofbi, pi->mem_idx); | ||
82 | if (!new_rg) { | ||
83 | r = -EINVAL; | ||
84 | goto out; | ||
85 | } | ||
86 | |||
87 | if (pi->enabled && !new_rg->size) { | ||
56 | /* | 88 | /* |
57 | * This plane's memory was freed, can't enable it | 89 | * This plane's memory was freed, can't enable it |
58 | * until it's reallocated. | 90 | * until it's reallocated. |
@@ -61,27 +93,60 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) | |||
61 | goto out; | 93 | goto out; |
62 | } | 94 | } |
63 | 95 | ||
64 | ovl->get_overlay_info(ovl, &info); | 96 | ovl->get_overlay_info(ovl, &old_info); |
65 | 97 | ||
66 | info.pos_x = pi->pos_x; | 98 | if (old_rg != new_rg) { |
67 | info.pos_y = pi->pos_y; | 99 | ofbi->region = new_rg; |
68 | info.out_width = pi->out_width; | 100 | set_fb_fix(fbi); |
69 | info.out_height = pi->out_height; | 101 | } |
70 | info.enabled = pi->enabled; | ||
71 | 102 | ||
72 | r = ovl->set_overlay_info(ovl, &info); | 103 | if (pi->enabled) { |
73 | if (r) | 104 | struct omap_overlay_info info; |
74 | goto out; | 105 | |
106 | r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y, | ||
107 | pi->out_width, pi->out_height); | ||
108 | if (r) | ||
109 | goto undo; | ||
75 | 110 | ||
76 | if (ovl->manager) { | 111 | ovl->get_overlay_info(ovl, &info); |
77 | r = ovl->manager->apply(ovl->manager); | 112 | |
113 | if (!info.enabled) { | ||
114 | info.enabled = pi->enabled; | ||
115 | r = ovl->set_overlay_info(ovl, &info); | ||
116 | if (r) | ||
117 | goto undo; | ||
118 | } | ||
119 | } else { | ||
120 | struct omap_overlay_info info; | ||
121 | |||
122 | ovl->get_overlay_info(ovl, &info); | ||
123 | |||
124 | info.enabled = pi->enabled; | ||
125 | info.pos_x = pi->pos_x; | ||
126 | info.pos_y = pi->pos_y; | ||
127 | info.out_width = pi->out_width; | ||
128 | info.out_height = pi->out_height; | ||
129 | |||
130 | r = ovl->set_overlay_info(ovl, &info); | ||
78 | if (r) | 131 | if (r) |
79 | goto out; | 132 | goto undo; |
80 | } | 133 | } |
81 | 134 | ||
82 | out: | 135 | if (ovl->manager) |
83 | if (r) | 136 | ovl->manager->apply(ovl->manager); |
84 | dev_err(fbdev->dev, "setup_plane failed\n"); | 137 | |
138 | return 0; | ||
139 | |||
140 | undo: | ||
141 | if (old_rg != new_rg) { | ||
142 | ofbi->region = old_rg; | ||
143 | set_fb_fix(fbi); | ||
144 | } | ||
145 | |||
146 | ovl->set_overlay_info(ovl, &old_info); | ||
147 | out: | ||
148 | dev_err(fbdev->dev, "setup_plane failed\n"); | ||
149 | |||
85 | return r; | 150 | return r; |
86 | } | 151 | } |
87 | 152 | ||
@@ -92,8 +157,8 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) | |||
92 | if (ofbi->num_overlays != 1) { | 157 | if (ofbi->num_overlays != 1) { |
93 | memset(pi, 0, sizeof(*pi)); | 158 | memset(pi, 0, sizeof(*pi)); |
94 | } else { | 159 | } else { |
95 | struct omap_overlay_info *ovli; | ||
96 | struct omap_overlay *ovl; | 160 | struct omap_overlay *ovl; |
161 | struct omap_overlay_info *ovli; | ||
97 | 162 | ||
98 | ovl = ofbi->overlays[0]; | 163 | ovl = ofbi->overlays[0]; |
99 | ovli = &ovl->info; | 164 | ovli = &ovl->info; |
@@ -103,6 +168,7 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) | |||
103 | pi->enabled = ovli->enabled; | 168 | pi->enabled = ovli->enabled; |
104 | pi->channel_out = 0; /* xxx */ | 169 | pi->channel_out = 0; /* xxx */ |
105 | pi->mirror = 0; | 170 | pi->mirror = 0; |
171 | pi->mem_idx = get_mem_idx(ofbi); | ||
106 | pi->out_width = ovli->out_width; | 172 | pi->out_width = ovli->out_width; |
107 | pi->out_height = ovli->out_height; | 173 | pi->out_height = ovli->out_height; |
108 | } | 174 | } |
@@ -123,11 +189,24 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) | |||
123 | 189 | ||
124 | size = PAGE_ALIGN(mi->size); | 190 | size = PAGE_ALIGN(mi->size); |
125 | 191 | ||
126 | rg = &ofbi->region; | 192 | rg = ofbi->region; |
127 | 193 | ||
128 | for (i = 0; i < ofbi->num_overlays; i++) { | 194 | if (atomic_read(&rg->map_count)) |
129 | if (ofbi->overlays[i]->info.enabled) | 195 | return -EBUSY; |
130 | return -EBUSY; | 196 | |
197 | for (i = 0; i < fbdev->num_fbs; i++) { | ||
198 | struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]); | ||
199 | int j; | ||
200 | |||
201 | if (ofbi2->region != rg) | ||
202 | continue; | ||
203 | |||
204 | for (j = 0; j < ofbi2->num_overlays; j++) { | ||
205 | if (ofbi2->overlays[j]->info.enabled) { | ||
206 | r = -EBUSY; | ||
207 | return r; | ||
208 | } | ||
209 | } | ||
131 | } | 210 | } |
132 | 211 | ||
133 | if (rg->size != size || rg->type != mi->type) { | 212 | if (rg->size != size || rg->type != mi->type) { |
@@ -146,7 +225,7 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) | |||
146 | struct omapfb_info *ofbi = FB2OFB(fbi); | 225 | struct omapfb_info *ofbi = FB2OFB(fbi); |
147 | struct omapfb2_mem_region *rg; | 226 | struct omapfb2_mem_region *rg; |
148 | 227 | ||
149 | rg = &ofbi->region; | 228 | rg = ofbi->region; |
150 | memset(mi, 0, sizeof(*mi)); | 229 | memset(mi, 0, sizeof(*mi)); |
151 | 230 | ||
152 | mi->size = rg->size; | 231 | mi->size = rg->size; |
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index ccccf3d71a39..4a0588022b33 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c | |||
@@ -157,7 +157,7 @@ static void fill_fb(struct fb_info *fbi) | |||
157 | 157 | ||
158 | static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot) | 158 | static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot) |
159 | { | 159 | { |
160 | const struct vrfb *vrfb = &ofbi->region.vrfb; | 160 | const struct vrfb *vrfb = &ofbi->region->vrfb; |
161 | unsigned offset; | 161 | unsigned offset; |
162 | 162 | ||
163 | switch (rot) { | 163 | switch (rot) { |
@@ -185,27 +185,27 @@ static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot) | |||
185 | static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot) | 185 | static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot) |
186 | { | 186 | { |
187 | if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { | 187 | if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { |
188 | return ofbi->region.vrfb.paddr[rot] | 188 | return ofbi->region->vrfb.paddr[rot] |
189 | + omapfb_get_vrfb_offset(ofbi, rot); | 189 | + omapfb_get_vrfb_offset(ofbi, rot); |
190 | } else { | 190 | } else { |
191 | return ofbi->region.paddr; | 191 | return ofbi->region->paddr; |
192 | } | 192 | } |
193 | } | 193 | } |
194 | 194 | ||
195 | static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi) | 195 | static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi) |
196 | { | 196 | { |
197 | if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) | 197 | if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) |
198 | return ofbi->region.vrfb.paddr[0]; | 198 | return ofbi->region->vrfb.paddr[0]; |
199 | else | 199 | else |
200 | return ofbi->region.paddr; | 200 | return ofbi->region->paddr; |
201 | } | 201 | } |
202 | 202 | ||
203 | static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi) | 203 | static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi) |
204 | { | 204 | { |
205 | if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) | 205 | if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) |
206 | return ofbi->region.vrfb.vaddr[0]; | 206 | return ofbi->region->vrfb.vaddr[0]; |
207 | else | 207 | else |
208 | return ofbi->region.vaddr; | 208 | return ofbi->region->vaddr; |
209 | } | 209 | } |
210 | 210 | ||
211 | static struct omapfb_colormode omapfb_colormodes[] = { | 211 | static struct omapfb_colormode omapfb_colormodes[] = { |
@@ -450,7 +450,7 @@ static int check_vrfb_fb_size(unsigned long region_size, | |||
450 | static int check_fb_size(const struct omapfb_info *ofbi, | 450 | static int check_fb_size(const struct omapfb_info *ofbi, |
451 | struct fb_var_screeninfo *var) | 451 | struct fb_var_screeninfo *var) |
452 | { | 452 | { |
453 | unsigned long max_frame_size = ofbi->region.size; | 453 | unsigned long max_frame_size = ofbi->region->size; |
454 | int bytespp = var->bits_per_pixel >> 3; | 454 | int bytespp = var->bits_per_pixel >> 3; |
455 | unsigned long line_size = var->xres_virtual * bytespp; | 455 | unsigned long line_size = var->xres_virtual * bytespp; |
456 | 456 | ||
@@ -497,7 +497,7 @@ static int check_fb_size(const struct omapfb_info *ofbi, | |||
497 | static int setup_vrfb_rotation(struct fb_info *fbi) | 497 | static int setup_vrfb_rotation(struct fb_info *fbi) |
498 | { | 498 | { |
499 | struct omapfb_info *ofbi = FB2OFB(fbi); | 499 | struct omapfb_info *ofbi = FB2OFB(fbi); |
500 | struct omapfb2_mem_region *rg = &ofbi->region; | 500 | struct omapfb2_mem_region *rg = ofbi->region; |
501 | struct vrfb *vrfb = &rg->vrfb; | 501 | struct vrfb *vrfb = &rg->vrfb; |
502 | struct fb_var_screeninfo *var = &fbi->var; | 502 | struct fb_var_screeninfo *var = &fbi->var; |
503 | struct fb_fix_screeninfo *fix = &fbi->fix; | 503 | struct fb_fix_screeninfo *fix = &fbi->fix; |
@@ -558,9 +558,9 @@ static int setup_vrfb_rotation(struct fb_info *fbi) | |||
558 | return r; | 558 | return r; |
559 | 559 | ||
560 | /* used by open/write in fbmem.c */ | 560 | /* used by open/write in fbmem.c */ |
561 | fbi->screen_base = ofbi->region.vrfb.vaddr[0]; | 561 | fbi->screen_base = ofbi->region->vrfb.vaddr[0]; |
562 | 562 | ||
563 | fix->smem_start = ofbi->region.vrfb.paddr[0]; | 563 | fix->smem_start = ofbi->region->vrfb.paddr[0]; |
564 | 564 | ||
565 | switch (var->nonstd) { | 565 | switch (var->nonstd) { |
566 | case OMAPFB_COLOR_YUV422: | 566 | case OMAPFB_COLOR_YUV422: |
@@ -599,7 +599,7 @@ void set_fb_fix(struct fb_info *fbi) | |||
599 | struct fb_fix_screeninfo *fix = &fbi->fix; | 599 | struct fb_fix_screeninfo *fix = &fbi->fix; |
600 | struct fb_var_screeninfo *var = &fbi->var; | 600 | struct fb_var_screeninfo *var = &fbi->var; |
601 | struct omapfb_info *ofbi = FB2OFB(fbi); | 601 | struct omapfb_info *ofbi = FB2OFB(fbi); |
602 | struct omapfb2_mem_region *rg = &ofbi->region; | 602 | struct omapfb2_mem_region *rg = ofbi->region; |
603 | 603 | ||
604 | DBG("set_fb_fix\n"); | 604 | DBG("set_fb_fix\n"); |
605 | 605 | ||
@@ -688,7 +688,7 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var) | |||
688 | return -EINVAL; | 688 | return -EINVAL; |
689 | 689 | ||
690 | /* When no memory is allocated ignore the size check */ | 690 | /* When no memory is allocated ignore the size check */ |
691 | if (ofbi->region.size != 0 && check_fb_size(ofbi, var)) | 691 | if (ofbi->region->size != 0 && check_fb_size(ofbi, var)) |
692 | return -EINVAL; | 692 | return -EINVAL; |
693 | 693 | ||
694 | if (var->xres + var->xoffset > var->xres_virtual) | 694 | if (var->xres + var->xoffset > var->xres_virtual) |
@@ -856,7 +856,7 @@ static void omapfb_calc_addr(const struct omapfb_info *ofbi, | |||
856 | } | 856 | } |
857 | 857 | ||
858 | /* setup overlay according to the fb */ | 858 | /* setup overlay according to the fb */ |
859 | static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, | 859 | int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, |
860 | u16 posx, u16 posy, u16 outw, u16 outh) | 860 | u16 posx, u16 posy, u16 outw, u16 outh) |
861 | { | 861 | { |
862 | int r = 0; | 862 | int r = 0; |
@@ -892,7 +892,7 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, | |||
892 | yres = var->yres; | 892 | yres = var->yres; |
893 | } | 893 | } |
894 | 894 | ||
895 | if (ofbi->region.size) | 895 | if (ofbi->region->size) |
896 | omapfb_calc_addr(ofbi, var, fix, rotation, | 896 | omapfb_calc_addr(ofbi, var, fix, rotation, |
897 | &data_start_p, &data_start_v); | 897 | &data_start_p, &data_start_v); |
898 | 898 | ||
@@ -971,7 +971,7 @@ int omapfb_apply_changes(struct fb_info *fbi, int init) | |||
971 | 971 | ||
972 | DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id); | 972 | DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id); |
973 | 973 | ||
974 | if (ofbi->region.size == 0) { | 974 | if (ofbi->region->size == 0) { |
975 | /* the fb is not available. disable the overlay */ | 975 | /* the fb is not available. disable the overlay */ |
976 | omapfb_overlay_enable(ovl, 0); | 976 | omapfb_overlay_enable(ovl, 0); |
977 | if (!init && ovl->manager) | 977 | if (!init && ovl->manager) |
@@ -1071,16 +1071,16 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var, | |||
1071 | 1071 | ||
1072 | static void mmap_user_open(struct vm_area_struct *vma) | 1072 | static void mmap_user_open(struct vm_area_struct *vma) |
1073 | { | 1073 | { |
1074 | struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data; | 1074 | struct omapfb2_mem_region *rg = vma->vm_private_data; |
1075 | 1075 | ||
1076 | atomic_inc(&ofbi->map_count); | 1076 | atomic_inc(&rg->map_count); |
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | static void mmap_user_close(struct vm_area_struct *vma) | 1079 | static void mmap_user_close(struct vm_area_struct *vma) |
1080 | { | 1080 | { |
1081 | struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data; | 1081 | struct omapfb2_mem_region *rg = vma->vm_private_data; |
1082 | 1082 | ||
1083 | atomic_dec(&ofbi->map_count); | 1083 | atomic_dec(&rg->map_count); |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | static struct vm_operations_struct mmap_user_ops = { | 1086 | static struct vm_operations_struct mmap_user_ops = { |
@@ -1092,6 +1092,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) | |||
1092 | { | 1092 | { |
1093 | struct omapfb_info *ofbi = FB2OFB(fbi); | 1093 | struct omapfb_info *ofbi = FB2OFB(fbi); |
1094 | struct fb_fix_screeninfo *fix = &fbi->fix; | 1094 | struct fb_fix_screeninfo *fix = &fbi->fix; |
1095 | struct omapfb2_mem_region *rg; | ||
1095 | unsigned long off; | 1096 | unsigned long off; |
1096 | unsigned long start; | 1097 | unsigned long start; |
1097 | u32 len; | 1098 | u32 len; |
@@ -1102,6 +1103,8 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) | |||
1102 | return -EINVAL; | 1103 | return -EINVAL; |
1103 | off = vma->vm_pgoff << PAGE_SHIFT; | 1104 | off = vma->vm_pgoff << PAGE_SHIFT; |
1104 | 1105 | ||
1106 | rg = ofbi->region; | ||
1107 | |||
1105 | start = omapfb_get_region_paddr(ofbi); | 1108 | start = omapfb_get_region_paddr(ofbi); |
1106 | len = fix->smem_len; | 1109 | len = fix->smem_len; |
1107 | if (off >= len) | 1110 | if (off >= len) |
@@ -1117,12 +1120,12 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) | |||
1117 | vma->vm_flags |= VM_IO | VM_RESERVED; | 1120 | vma->vm_flags |= VM_IO | VM_RESERVED; |
1118 | vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); | 1121 | vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); |
1119 | vma->vm_ops = &mmap_user_ops; | 1122 | vma->vm_ops = &mmap_user_ops; |
1120 | vma->vm_private_data = ofbi; | 1123 | vma->vm_private_data = rg; |
1121 | if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, | 1124 | if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, |
1122 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) | 1125 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) |
1123 | return -EAGAIN; | 1126 | return -EAGAIN; |
1124 | /* vm_ops.open won't be called for mmap itself. */ | 1127 | /* vm_ops.open won't be called for mmap itself. */ |
1125 | atomic_inc(&ofbi->map_count); | 1128 | atomic_inc(&rg->map_count); |
1126 | return 0; | 1129 | return 0; |
1127 | } | 1130 | } |
1128 | 1131 | ||
@@ -1312,7 +1315,9 @@ static void omapfb_free_fbmem(struct fb_info *fbi) | |||
1312 | struct omapfb2_device *fbdev = ofbi->fbdev; | 1315 | struct omapfb2_device *fbdev = ofbi->fbdev; |
1313 | struct omapfb2_mem_region *rg; | 1316 | struct omapfb2_mem_region *rg; |
1314 | 1317 | ||
1315 | rg = &ofbi->region; | 1318 | rg = ofbi->region; |
1319 | |||
1320 | WARN_ON(atomic_read(&rg->map_count)); | ||
1316 | 1321 | ||
1317 | if (rg->paddr) | 1322 | if (rg->paddr) |
1318 | if (omap_vram_free(rg->paddr, rg->size)) | 1323 | if (omap_vram_free(rg->paddr, rg->size)) |
@@ -1367,8 +1372,15 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size, | |||
1367 | void __iomem *vaddr; | 1372 | void __iomem *vaddr; |
1368 | int r; | 1373 | int r; |
1369 | 1374 | ||
1370 | rg = &ofbi->region; | 1375 | rg = ofbi->region; |
1371 | memset(rg, 0, sizeof(*rg)); | 1376 | |
1377 | rg->paddr = 0; | ||
1378 | rg->vaddr = NULL; | ||
1379 | memset(&rg->vrfb, 0, sizeof rg->vrfb); | ||
1380 | rg->size = 0; | ||
1381 | rg->type = 0; | ||
1382 | rg->alloc = false; | ||
1383 | rg->map = false; | ||
1372 | 1384 | ||
1373 | size = PAGE_ALIGN(size); | 1385 | size = PAGE_ALIGN(size); |
1374 | 1386 | ||
@@ -1621,7 +1633,7 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev) | |||
1621 | for (i = 0; i < fbdev->num_fbs; i++) { | 1633 | for (i = 0; i < fbdev->num_fbs; i++) { |
1622 | struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); | 1634 | struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); |
1623 | struct omapfb2_mem_region *rg; | 1635 | struct omapfb2_mem_region *rg; |
1624 | rg = &ofbi->region; | 1636 | rg = ofbi->region; |
1625 | 1637 | ||
1626 | DBG("region%d phys %08x virt %p size=%lu\n", | 1638 | DBG("region%d phys %08x virt %p size=%lu\n", |
1627 | i, | 1639 | i, |
@@ -1638,7 +1650,7 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type) | |||
1638 | struct omapfb_info *ofbi = FB2OFB(fbi); | 1650 | struct omapfb_info *ofbi = FB2OFB(fbi); |
1639 | struct omapfb2_device *fbdev = ofbi->fbdev; | 1651 | struct omapfb2_device *fbdev = ofbi->fbdev; |
1640 | struct omap_dss_device *display = fb2display(fbi); | 1652 | struct omap_dss_device *display = fb2display(fbi); |
1641 | struct omapfb2_mem_region *rg = &ofbi->region; | 1653 | struct omapfb2_mem_region *rg = ofbi->region; |
1642 | unsigned long old_size = rg->size; | 1654 | unsigned long old_size = rg->size; |
1643 | unsigned long old_paddr = rg->paddr; | 1655 | unsigned long old_paddr = rg->paddr; |
1644 | int old_type = rg->type; | 1656 | int old_type = rg->type; |
@@ -1721,7 +1733,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi) | |||
1721 | fbi->flags = FBINFO_FLAG_DEFAULT; | 1733 | fbi->flags = FBINFO_FLAG_DEFAULT; |
1722 | fbi->pseudo_palette = fbdev->pseudo_palette; | 1734 | fbi->pseudo_palette = fbdev->pseudo_palette; |
1723 | 1735 | ||
1724 | if (ofbi->region.size == 0) { | 1736 | if (ofbi->region->size == 0) { |
1725 | clear_fb_info(fbi); | 1737 | clear_fb_info(fbi); |
1726 | return 0; | 1738 | return 0; |
1727 | } | 1739 | } |
@@ -1883,6 +1895,9 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) | |||
1883 | ofbi->fbdev = fbdev; | 1895 | ofbi->fbdev = fbdev; |
1884 | ofbi->id = i; | 1896 | ofbi->id = i; |
1885 | 1897 | ||
1898 | ofbi->region = &fbdev->regions[i]; | ||
1899 | ofbi->region->id = i; | ||
1900 | |||
1886 | /* assign these early, so that fb alloc can use them */ | 1901 | /* assign these early, so that fb alloc can use them */ |
1887 | ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : | 1902 | ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : |
1888 | OMAP_DSS_ROT_DMA; | 1903 | OMAP_DSS_ROT_DMA; |
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c index 5179219128bd..dea1aa46a7db 100644 --- a/drivers/video/omap2/omapfb/omapfb-sysfs.c +++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c | |||
@@ -64,7 +64,7 @@ static ssize_t store_rotate_type(struct device *dev, | |||
64 | if (rot_type == ofbi->rotation_type) | 64 | if (rot_type == ofbi->rotation_type) |
65 | goto out; | 65 | goto out; |
66 | 66 | ||
67 | if (ofbi->region.size) { | 67 | if (ofbi->region->size) { |
68 | r = -EBUSY; | 68 | r = -EBUSY; |
69 | goto out; | 69 | goto out; |
70 | } | 70 | } |
@@ -408,7 +408,7 @@ static ssize_t show_size(struct device *dev, | |||
408 | struct fb_info *fbi = dev_get_drvdata(dev); | 408 | struct fb_info *fbi = dev_get_drvdata(dev); |
409 | struct omapfb_info *ofbi = FB2OFB(fbi); | 409 | struct omapfb_info *ofbi = FB2OFB(fbi); |
410 | 410 | ||
411 | return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region.size); | 411 | return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size); |
412 | } | 412 | } |
413 | 413 | ||
414 | static ssize_t store_size(struct device *dev, struct device_attribute *attr, | 414 | static ssize_t store_size(struct device *dev, struct device_attribute *attr, |
@@ -416,6 +416,8 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr, | |||
416 | { | 416 | { |
417 | struct fb_info *fbi = dev_get_drvdata(dev); | 417 | struct fb_info *fbi = dev_get_drvdata(dev); |
418 | struct omapfb_info *ofbi = FB2OFB(fbi); | 418 | struct omapfb_info *ofbi = FB2OFB(fbi); |
419 | struct omapfb2_device *fbdev = ofbi->fbdev; | ||
420 | struct omapfb2_mem_region *rg; | ||
419 | unsigned long size; | 421 | unsigned long size; |
420 | int r; | 422 | int r; |
421 | int i; | 423 | int i; |
@@ -425,15 +427,30 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr, | |||
425 | if (!lock_fb_info(fbi)) | 427 | if (!lock_fb_info(fbi)) |
426 | return -ENODEV; | 428 | return -ENODEV; |
427 | 429 | ||
428 | for (i = 0; i < ofbi->num_overlays; i++) { | 430 | rg = ofbi->region; |
429 | if (ofbi->overlays[i]->info.enabled) { | 431 | |
430 | r = -EBUSY; | 432 | if (atomic_read(&rg->map_count)) { |
431 | goto out; | 433 | r = -EBUSY; |
434 | goto out; | ||
435 | } | ||
436 | |||
437 | for (i = 0; i < fbdev->num_fbs; i++) { | ||
438 | struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]); | ||
439 | int j; | ||
440 | |||
441 | if (ofbi2->region != rg) | ||
442 | continue; | ||
443 | |||
444 | for (j = 0; j < ofbi2->num_overlays; j++) { | ||
445 | if (ofbi2->overlays[j]->info.enabled) { | ||
446 | r = -EBUSY; | ||
447 | goto out; | ||
448 | } | ||
432 | } | 449 | } |
433 | } | 450 | } |
434 | 451 | ||
435 | if (size != ofbi->region.size) { | 452 | if (size != ofbi->region->size) { |
436 | r = omapfb_realloc_fbmem(fbi, size, ofbi->region.type); | 453 | r = omapfb_realloc_fbmem(fbi, size, ofbi->region->type); |
437 | if (r) { | 454 | if (r) { |
438 | dev_err(dev, "realloc fbmem failed\n"); | 455 | dev_err(dev, "realloc fbmem failed\n"); |
439 | goto out; | 456 | goto out; |
@@ -453,7 +470,7 @@ static ssize_t show_phys(struct device *dev, | |||
453 | struct fb_info *fbi = dev_get_drvdata(dev); | 470 | struct fb_info *fbi = dev_get_drvdata(dev); |
454 | struct omapfb_info *ofbi = FB2OFB(fbi); | 471 | struct omapfb_info *ofbi = FB2OFB(fbi); |
455 | 472 | ||
456 | return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region.paddr); | 473 | return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr); |
457 | } | 474 | } |
458 | 475 | ||
459 | static ssize_t show_virt(struct device *dev, | 476 | static ssize_t show_virt(struct device *dev, |
@@ -462,7 +479,7 @@ static ssize_t show_virt(struct device *dev, | |||
462 | struct fb_info *fbi = dev_get_drvdata(dev); | 479 | struct fb_info *fbi = dev_get_drvdata(dev); |
463 | struct omapfb_info *ofbi = FB2OFB(fbi); | 480 | struct omapfb_info *ofbi = FB2OFB(fbi); |
464 | 481 | ||
465 | return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region.vaddr); | 482 | return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr); |
466 | } | 483 | } |
467 | 484 | ||
468 | static struct device_attribute omapfb_attrs[] = { | 485 | static struct device_attribute omapfb_attrs[] = { |
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h index c9866be0460a..02f1ba9b228c 100644 --- a/drivers/video/omap2/omapfb/omapfb.h +++ b/drivers/video/omap2/omapfb/omapfb.h | |||
@@ -44,6 +44,7 @@ extern unsigned int omapfb_debug; | |||
44 | #define OMAPFB_MAX_OVL_PER_FB 3 | 44 | #define OMAPFB_MAX_OVL_PER_FB 3 |
45 | 45 | ||
46 | struct omapfb2_mem_region { | 46 | struct omapfb2_mem_region { |
47 | int id; | ||
47 | u32 paddr; | 48 | u32 paddr; |
48 | void __iomem *vaddr; | 49 | void __iomem *vaddr; |
49 | struct vrfb vrfb; | 50 | struct vrfb vrfb; |
@@ -51,13 +52,13 @@ struct omapfb2_mem_region { | |||
51 | u8 type; /* OMAPFB_PLANE_MEM_* */ | 52 | u8 type; /* OMAPFB_PLANE_MEM_* */ |
52 | bool alloc; /* allocated by the driver */ | 53 | bool alloc; /* allocated by the driver */ |
53 | bool map; /* kernel mapped by the driver */ | 54 | bool map; /* kernel mapped by the driver */ |
55 | atomic_t map_count; | ||
54 | }; | 56 | }; |
55 | 57 | ||
56 | /* appended to fb_info */ | 58 | /* appended to fb_info */ |
57 | struct omapfb_info { | 59 | struct omapfb_info { |
58 | int id; | 60 | int id; |
59 | struct omapfb2_mem_region region; | 61 | struct omapfb2_mem_region *region; |
60 | atomic_t map_count; | ||
61 | int num_overlays; | 62 | int num_overlays; |
62 | struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB]; | 63 | struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB]; |
63 | struct omapfb2_device *fbdev; | 64 | struct omapfb2_device *fbdev; |
@@ -76,6 +77,7 @@ struct omapfb2_device { | |||
76 | 77 | ||
77 | unsigned num_fbs; | 78 | unsigned num_fbs; |
78 | struct fb_info *fbs[10]; | 79 | struct fb_info *fbs[10]; |
80 | struct omapfb2_mem_region regions[10]; | ||
79 | 81 | ||
80 | unsigned num_displays; | 82 | unsigned num_displays; |
81 | struct omap_dss_device *displays[10]; | 83 | struct omap_dss_device *displays[10]; |
@@ -117,6 +119,9 @@ int omapfb_update_window(struct fb_info *fbi, | |||
117 | int dss_mode_to_fb_mode(enum omap_color_mode dssmode, | 119 | int dss_mode_to_fb_mode(enum omap_color_mode dssmode, |
118 | struct fb_var_screeninfo *var); | 120 | struct fb_var_screeninfo *var); |
119 | 121 | ||
122 | int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, | ||
123 | u16 posx, u16 posy, u16 outw, u16 outh); | ||
124 | |||
120 | /* find the display connected to this fb, if any */ | 125 | /* find the display connected to this fb, if any */ |
121 | static inline struct omap_dss_device *fb2display(struct fb_info *fbi) | 126 | static inline struct omap_dss_device *fb2display(struct fb_info *fbi) |
122 | { | 127 | { |