23 #include <linux/module.h>
25 #include <linux/slab.h>
29 #include <linux/device.h>
31 #include <linux/omapfb.h>
40 #define MODULE_NAME "omapfb"
42 #define OMAPFB_PLANE_XRES_MIN 8
43 #define OMAPFB_PLANE_YRES_MIN 8
45 static char *def_mode;
46 static char *def_vram;
48 static int def_rotate;
49 static bool def_mirror;
50 static bool auto_update;
51 static unsigned int auto_update_freq;
58 static bool omapfb_test_pattern;
67 static void draw_pixel(
struct fb_info *fbi,
int x,
int y,
unsigned color)
73 const unsigned line_len = fix->
line_length / bytespp;
75 int r = (color >> 16) & 0xff;
76 int g = (color >> 8) & 0xff;
77 int b = (color >> 0) & 0xff;
81 p += y * line_len +
x;
90 p += (y * line_len +
x) * 3;
97 p += y * line_len +
x;
102 static void fill_fb(
struct fb_info *fbi)
113 DBG(
"fill_fb %dx%d, line_len %d bytes\n", w, h, fbi->
fix.line_length);
115 for (y = 0; y <
h; y++) {
116 for (x = 0; x <
w; x++) {
117 if (x < 20 && y < 20)
118 draw_pixel(fbi, x, y, 0xffffff);
119 else if (x < 20 && (y > 20 && y < h - 20))
120 draw_pixel(fbi, x, y, 0xff);
121 else if (y < 20 && (x > 20 && x < w - 20))
122 draw_pixel(fbi, x, y, 0xff00);
123 else if (x > w - 20 && (y > 20 && y < h - 20))
124 draw_pixel(fbi, x, y, 0xff0000);
125 else if (y > h - 20 && (x > 20 && x < w - 20))
126 draw_pixel(fbi, x, y, 0xffff00);
127 else if (x == 20 || x == w - 20 ||
128 y == 20 || y == h - 20)
129 draw_pixel(fbi, x, y, 0xffffff);
130 else if (x == y || w - x == h - y)
131 draw_pixel(fbi, x, y, 0xff00ff);
132 else if (w - x == y || x == h - y)
133 draw_pixel(fbi, x, y, 0x00ffff);
134 else if (x > 20 && y > 20 && x < w - 20 && y < h - 20) {
136 unsigned r = 0, g = 0, b = 0;
140 b = (y % 32) * 256 / 32;
142 g = (y % 64) * 256 / 64;
144 r = (y % 32) * 256 / 32;
153 c = (r << 16) | (g << 8) | (b << 0);
154 draw_pixel(fbi, x, y, c);
156 draw_pixel(fbi, x, y, 0);
163 static unsigned omapfb_get_vrfb_offset(
const struct omapfb_info *ofbi,
int rot)
191 static u32 omapfb_get_region_rot_paddr(
const struct omapfb_info *ofbi,
int rot)
195 + omapfb_get_vrfb_offset(ofbi, rot);
197 return ofbi->
region->paddr;
201 static u32 omapfb_get_region_paddr(
const struct omapfb_info *ofbi)
204 return ofbi->
region->vrfb.paddr[0];
206 return ofbi->
region->paddr;
212 return ofbi->
region->vrfb.vaddr[0];
214 return ofbi->
region->vaddr;
220 .bits_per_pixel = 16,
224 .bits_per_pixel = 16,
228 .bits_per_pixel = 16,
229 .red = { .length = 4, .offset = 8, .msb_right = 0 },
230 .green = { .length = 4, .offset = 4, .msb_right = 0 },
231 .blue = { .length = 4, .offset = 0, .msb_right = 0 },
232 .transp = { .length = 4, .offset = 12, .msb_right = 0 },
235 .bits_per_pixel = 16,
236 .red = { .length = 5, .offset = 11, .msb_right = 0 },
237 .green = { .length = 6, .offset = 5, .msb_right = 0 },
238 .blue = { .length = 5, .offset = 0, .msb_right = 0 },
239 .transp = { .length = 0, .offset = 0, .msb_right = 0 },
242 .bits_per_pixel = 24,
243 .red = { .length = 8, .offset = 16, .msb_right = 0 },
244 .green = { .length = 8, .offset = 8, .msb_right = 0 },
245 .blue = { .length = 8, .offset = 0, .msb_right = 0 },
246 .transp = { .length = 0, .offset = 0, .msb_right = 0 },
249 .bits_per_pixel = 32,
250 .red = { .length = 8, .offset = 16, .msb_right = 0 },
251 .green = { .length = 8, .offset = 8, .msb_right = 0 },
252 .blue = { .length = 8, .offset = 0, .msb_right = 0 },
253 .transp = { .length = 0, .offset = 0, .msb_right = 0 },
256 .bits_per_pixel = 32,
257 .red = { .length = 8, .offset = 16, .msb_right = 0 },
258 .green = { .length = 8, .offset = 8, .msb_right = 0 },
259 .blue = { .length = 8, .offset = 0, .msb_right = 0 },
260 .transp = { .length = 8, .offset = 24, .msb_right = 0 },
263 .bits_per_pixel = 32,
264 .red = { .length = 8, .offset = 24, .msb_right = 0 },
265 .green = { .length = 8, .offset = 16, .msb_right = 0 },
266 .blue = { .length = 8, .offset = 8, .msb_right = 0 },
267 .transp = { .length = 8, .offset = 0, .msb_right = 0 },
270 .bits_per_pixel = 32,
271 .red = { .length = 8, .offset = 24, .msb_right = 0 },
272 .green = { .length = 8, .offset = 16, .msb_right = 0 },
273 .blue = { .length = 8, .offset = 8, .msb_right = 0 },
274 .transp = { .length = 0, .offset = 0, .msb_right = 0 },
289 var->
red.length == 0 ||
290 var->
blue.length == 0 ||
291 var->
green.length == 0)
295 cmp_component(&var->
red, &color->
red) &&
297 cmp_component(&var->
blue, &color->
blue) &&
320 for (i = 0; i <
ARRAY_SIZE(omapfb_colormodes); ++
i) {
323 assign_colormode_to_var(var, m);
333 for (i = 0; i <
ARRAY_SIZE(omapfb_colormodes); ++
i) {
335 if (cmp_var_to_colormode(var, m)) {
336 assign_colormode_to_var(var, m);
373 for (i = 0; i <
ARRAY_SIZE(omapfb_colormodes); ++
i) {
376 assign_colormode_to_var(var, m);
402 if (var->
xres < xres_min)
403 var->
xres = xres_min;
404 if (var->
yres < yres_min)
405 var->
yres = yres_min;
406 if (var->
xres > xres_max)
407 var->
xres = xres_max;
408 if (var->
yres > yres_max)
409 var->
yres = yres_max;
419 static void shrink_height(
unsigned long max_frame_size,
422 DBG(
"can't fit FB into memory, reducing y\n");
433 static void shrink_width(
unsigned long max_frame_size,
436 DBG(
"can't fit FB into memory, reducing x\n");
447 static int check_vrfb_fb_size(
unsigned long region_size,
453 return min_phys_size > region_size ? -
EINVAL : 0;
456 static int check_fb_size(
const struct omapfb_info *ofbi,
459 unsigned long max_frame_size = ofbi->
region->size;
465 if (check_vrfb_fb_size(max_frame_size, var))
470 if (check_vrfb_fb_size(max_frame_size, var)) {
471 DBG(
"cannot fit FB to memory\n");
478 DBG(
"max frame size %lu, line size %lu\n", max_frame_size, line_size);
481 shrink_height(max_frame_size, var);
484 shrink_width(max_frame_size, var);
489 DBG(
"cannot fit FB to memory\n");
503 static int setup_vrfb_rotation(
struct fb_info *fbi)
507 struct vrfb *vrfb = &rg->
vrfb;
519 DBG(
"setup_vrfb_rotation\n");
521 r = fb_mode_to_dss_mode(var, &mode);
538 else if (bytespp != vrfb->
bytespp)
544 if (vrfb->
vaddr[0] && reconf) {
550 DBG(
"setup_vrfb_rotation: reset fb\n");
593 for (i = 0; i <
ARRAY_SIZE(omapfb_colormodes); ++
i) {
595 if (dssmode == mode->
dssmode) {
596 assign_colormode_to_var(var, mode);
636 fix->
smem_start = omapfb_get_region_paddr(ofbi);
675 DBG(
"check_fb_var %d\n", ofbi->
id);
679 r = fb_mode_to_dss_mode(var, &mode);
681 DBG(
"cannot convert var to omap dss mode\n");
686 if ((ofbi->
overlays[i]->supported_modes & mode) == 0) {
687 DBG(
"invalid mode\n");
695 if (check_fb_res_bounds(var))
699 if (ofbi->
region->size != 0 && check_fb_size(ofbi, var))
707 DBG(
"xres = %d, yres = %d, vxres = %d, vyres = %d\n",
711 if (display && display->
driver->get_dimensions) {
713 display->
driver->get_dimensions(display, &w, &h);
723 if (display && display->
driver->get_timings) {
725 display->
driver->get_timings(display, &timings);
763 static int omapfb_open(
struct fb_info *fbi,
int user)
768 static int omapfb_release(
struct fb_info *fbi,
int user)
814 static void omapfb_calc_addr(
const struct omapfb_info *ofbi,
823 data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation);
825 data_start_p = omapfb_get_region_paddr(ofbi);
828 offset = calc_rotation_offset_vrfb(var, fix, rotation);
830 offset = calc_rotation_offset_dma(var, fix, rotation);
835 DBG(
"offset %d, %d = %d\n",
838 DBG(
"paddr %x\n", data_start_p);
840 *paddr = data_start_p;
852 u32 data_start_p = 0;
857 int rotation = var->
rotate;
866 rotation = (rotation + ofbi->
rotation[
i]) % 4;
870 DBG(
"setup_overlay %d, posx %d, posy %d, outw %d, outh %d\n", ofbi->
id,
871 posx, posy, outw, outh);
882 omapfb_calc_addr(ofbi, var, fix, rotation, &data_start_p);
884 r = fb_mode_to_dss_mode(var, &mode);
886 DBG(
"fb_mode_to_dss_mode failed");
910 info.
paddr = data_start_p;
926 DBG(
"ovl->setup_overlay_info failed\n");
933 DBG(
"setup_overlay failed\n");
949 if (omapfb_test_pattern)
958 DBG(
"apply_changes, fb %d, ovl %d\n", ofbi->
id, ovl->
id);
960 if (ofbi->
region->size == 0) {
962 omapfb_overlay_enable(ovl, 0);
1004 DBG(
"apply_changes failed\n");
1015 DBG(
"check_var(%d)\n",
FB2OFB(fbi)->
id);
1017 omapfb_get_mem_region(ofbi->
region);
1021 omapfb_put_mem_region(ofbi->
region);
1027 static int omapfb_set_par(
struct fb_info *fbi)
1034 omapfb_get_mem_region(ofbi->
region);
1038 r = setup_vrfb_rotation(fbi);
1045 omapfb_put_mem_region(ofbi->
region);
1057 DBG(
"pan_display(%d)\n",
FB2OFB(fbi)->
id);
1064 new_var.xoffset = var->
xoffset;
1065 new_var.yoffset = var->
yoffset;
1069 omapfb_get_mem_region(ofbi->
region);
1073 omapfb_put_mem_region(ofbi->
region);
1082 omapfb_get_mem_region(rg);
1084 omapfb_put_mem_region(rg);
1091 omapfb_get_mem_region(rg);
1093 omapfb_put_mem_region(rg);
1096 static struct vm_operations_struct mmap_user_ops = {
1097 .open = mmap_user_open,
1098 .close = mmap_user_close,
1107 unsigned long start;
1117 rg = omapfb_get_mem_region(ofbi->
region);
1119 start = omapfb_get_region_paddr(ofbi);
1128 DBG(
"user mmap region start %lx, len %d, off %lx\n", start, len, off);
1133 vma->
vm_ops = &mmap_user_ops;
1145 omapfb_put_mem_region(rg);
1150 omapfb_put_mem_region(ofbi->
region);
1197 pal = ((red >> (16 - var->
red.length)) <<
1199 ((green >> (16 - var->
green.length)) <<
1200 var->
green.offset) |
1201 (blue >> (16 - var->
blue.length));
1216 return _setcolreg(info, regno, red, green, blue, transp, 1);
1228 green = cmap->
green;
1231 index = cmap->
start;
1233 for (count = 0; count < cmap->
len; count++) {
1236 r = _setcolreg(info, index++, *red++, *green++, *blue++, trans,
1237 count == cmap->
len - 1);
1245 static int omapfb_blank(
int blank,
struct fb_info *fbi)
1258 d = get_display_data(fbdev, display);
1265 if (display->
driver->resume)
1266 r = display->
driver->resume(display);
1287 if (display->
driver->suspend)
1288 r = display->
driver->suspend(display);
1297 omapfb_unlock(fbdev);
1305 size_t count, loff_t *ppos)
1307 DBG(
"omapfb_write %d, %lu\n", count, (
unsigned long)*ppos);
1313 static struct fb_ops omapfb_ops = {
1315 .fb_open = omapfb_open,
1316 .fb_release = omapfb_release,
1320 .fb_blank = omapfb_blank,
1322 .fb_check_var = omapfb_check_var,
1323 .fb_set_par = omapfb_set_par,
1324 .fb_pan_display = omapfb_pan_display,
1325 .fb_mmap = omapfb_mmap,
1326 .fb_setcolreg = omapfb_setcolreg,
1327 .fb_setcmap = omapfb_setcmap,
1331 static void omapfb_free_fbmem(
struct fb_info *fbi)
1350 if (rg->
vrfb.vaddr[0]) {
1363 static void clear_fb_info(
struct fb_info *fbi)
1374 DBG(
"free all fbmem\n");
1376 for (i = 0; i < fbdev->
num_fbs; i++) {
1378 omapfb_free_fbmem(fbi);
1385 static int omapfb_alloc_fbmem(
struct fb_info *fbi,
unsigned long size,
1386 unsigned long paddr)
1407 DBG(
"allocating %lu bytes for fb %d\n", size, ofbi->
id);
1410 DBG(
"reserving %lu bytes at %lx for fb %d\n", size, paddr,
1416 dev_err(fbdev->
dev,
"failed to allocate framebuffer\n");
1424 dev_err(fbdev->
dev,
"failed to ioremap framebuffer\n");
1429 DBG(
"allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr);
1433 dev_err(fbdev->
dev,
"vrfb create ctx failed\n");
1449 static int omapfb_alloc_fbmem_display(
struct fb_info *fbi,
unsigned long size,
1450 unsigned long paddr)
1457 display = fb2display(fbi);
1462 switch (omapfb_get_recommended_bpp(fbdev, display)) {
1477 display->
driver->get_resolution(display, &w, &h);
1483 DBG(
"adjusting fb mem size for VRFB, %u -> %lu\n",
1484 w * h * bytespp, size);
1486 size = w * h * bytespp;
1493 return omapfb_alloc_fbmem(fbi, size, paddr);
1497 unsigned long *sizes,
unsigned long *
paddrs)
1501 unsigned long paddr = 0;
1504 start = (
char *)param;
1517 if (fbnum >= max_entries)
1535 paddrs[fbnum] =
paddr;
1536 sizes[fbnum] =
size;
1555 unsigned long vram_sizes[10];
1556 unsigned long vram_paddrs[10];
1558 memset(&vram_sizes, 0,
sizeof(vram_sizes));
1559 memset(&vram_paddrs, 0,
sizeof(vram_paddrs));
1561 if (def_vram && omapfb_parse_vram_param(def_vram, 10,
1562 vram_sizes, vram_paddrs)) {
1563 dev_err(fbdev->
dev,
"failed to parse vram parameter\n");
1565 memset(&vram_sizes, 0,
sizeof(vram_sizes));
1566 memset(&vram_paddrs, 0,
sizeof(vram_paddrs));
1569 for (i = 0; i < fbdev->
num_fbs; i++) {
1572 if (i == 0 || vram_sizes[i] != 0) {
1573 r = omapfb_alloc_fbmem_display(fbdev->
fbs[i],
1574 vram_sizes[i], vram_paddrs[i]);
1581 for (i = 0; i < fbdev->
num_fbs; i++) {
1586 DBG(
"region%d phys %08x virt %p size=%lu\n",
1596 static void omapfb_clear_fb(
struct fb_info *fbi)
1601 .width = fbi->
var.xres_virtual,
1602 .height = fbi->
var.yres_virtual,
1617 unsigned long old_paddr = rg->
paddr;
1618 int old_type = rg->
type;
1626 if (old_size == size && old_type == type)
1629 if (display && display->
driver->sync)
1630 display->
driver->sync(display);
1632 omapfb_free_fbmem(fbi);
1639 r = omapfb_alloc_fbmem(fbi, size, 0);
1643 omapfb_alloc_fbmem(fbi, old_size, old_paddr);
1651 if (old_size == size)
1654 if (old_size == 0) {
1655 DBG(
"initializing fb %d\n", ofbi->
id);
1656 r = omapfb_fb_init(fbdev, fbi);
1658 DBG(
"omapfb_fb_init failed\n");
1663 DBG(
"omapfb_apply_changes failed\n");
1668 memcpy(&new_var, &fbi->
var,
sizeof(new_var));
1674 r = setup_vrfb_rotation(fbi);
1679 omapfb_clear_fb(fbi);
1683 omapfb_free_fbmem(fbi);
1698 auto_update_work.work);
1704 if (!dssdrv || !dssdrv->
update)
1708 dssdrv->
sync(dssdev);
1711 dssdrv->
update(dssdev, 0, 0, w, h);
1713 freq = auto_update_freq;
1731 dev_err(fbdev->
dev,
"Failed to create workqueue for "
1739 d = get_display_data(fbdev, display);
1753 d = get_display_data(fbdev, display);
1768 fbi->
fbops = &omapfb_ops;
1772 if (ofbi->
region->size == 0) {
1780 var->
rotate = def_rotate;
1786 display->
driver->get_resolution(display, &w, &h);
1801 switch (omapfb_get_recommended_bpp(fbdev, display)) {
1829 r = setup_vrfb_rotation(fbi);
1835 dev_err(fbdev->
dev,
"unable to allocate color map memory\n");
1851 DBG(
"free_resources\n");
1856 for (i = 0; i < fbdev->
num_fbs; i++)
1860 omapfb_free_all_fbmem(fbdev);
1862 for (i = 0; i < fbdev->
num_fbs; i++) {
1863 fbinfo_cleanup(fbdev, fbdev->
fbs[i]);
1870 if (fbdev->
displays[i].auto_update_work_enabled)
1874 dssdev->
driver->disable(dssdev);
1889 static int omapfb_create_framebuffers(
struct omapfb2_device *fbdev)
1895 DBG(
"create %d framebuffers\n", CONFIG_FB_OMAP2_NUM_FBS);
1898 for (i = 0; i < CONFIG_FB_OMAP2_NUM_FBS; i++) {
1907 "unable to allocate memory for plane info\n");
1913 fbdev->
fbs[
i] = fbi;
1926 ofbi->
mirror = def_mirror;
1931 DBG(
"fb_infos allocated\n");
1942 r = omapfb_allocate_all_fbs(fbdev);
1944 dev_err(fbdev->
dev,
"failed to allocate fbmem\n");
1948 DBG(
"fbmems allocated\n");
1951 for (i = 0; i < fbdev->
num_fbs; i++) {
1955 omapfb_get_mem_region(ofbi->
region);
1956 r = omapfb_fb_init(fbdev, fbi);
1957 omapfb_put_mem_region(ofbi->
region);
1960 dev_err(fbdev->
dev,
"failed to setup fb_info\n");
1965 for (i = 0; i < fbdev->
num_fbs; i++) {
1969 if (ofbi->
region->size == 0)
1972 omapfb_clear_fb(fbi);
1975 DBG(
"fb_infos initialized\n");
1977 for (i = 0; i < fbdev->
num_fbs; i++) {
1981 "registering framebuffer %d failed\n", i);
1986 DBG(
"framebuffers registered\n");
1988 for (i = 0; i < fbdev->
num_fbs; i++) {
1992 omapfb_get_mem_region(ofbi->
region);
1994 omapfb_put_mem_region(ofbi->
region);
1997 dev_err(fbdev->
dev,
"failed to change mode\n");
2011 r = omapfb_overlay_enable(ovl, 1);
2015 "failed to enable overlay\n");
2021 DBG(
"create_framebuffers done\n");
2026 static int omapfb_mode_to_timings(
const char *mode_str,
2035 #ifdef CONFIG_OMAP2_DSS_VENC
2036 if (
strcmp(mode_str,
"pal") == 0) {
2040 }
else if (
strcmp(mode_str,
"ntsc") == 0) {
2068 if (fbops ==
NULL) {
2081 if (display->
driver->get_timings) {
2082 display->
driver->get_timings(display, timings);
2135 r = omapfb_mode_to_timings(mode_str, display, &timings, &bpp);
2139 d = get_display_data(fbdev, display);
2142 if (display->
driver->check_timings) {
2143 r = display->
driver->check_timings(display, &timings);
2148 if (display->
driver->get_timings) {
2149 display->
driver->get_timings(display, &temp_timings);
2151 if (temp_timings.x_res != timings.
x_res ||
2152 temp_timings.y_res != timings.
y_res)
2157 if (display->
driver->set_timings)
2158 display->
driver->set_timings(display, &timings);
2163 static int omapfb_get_recommended_bpp(
struct omapfb2_device *fbdev,
2170 d = get_display_data(fbdev, dssdev);
2175 return dssdev->
driver->get_recommended_bpp(dssdev);
2188 while (!r && (this_opt =
strsep(&options,
",")) !=
NULL) {
2189 char *
p, *display_str, *mode_str;
2193 p =
strchr(this_opt,
':');
2200 display_str = this_opt;
2206 display_str) == 0) {
2217 r = omapfb_set_def_mode(fbdev, display, mode_str);
2227 static void fb_videomode_to_omap_timings(
struct fb_videomode *m,
2231 if (display->
driver->get_timings) {
2232 display->
driver->get_timings(display, t);
2262 int r,
i, best_xres, best_idx, len;
2264 if (!display->
driver->read_edid)
2270 r = display->
driver->read_edid(display, edid, len);
2290 if (m->pixclock == 0)
2294 if (m->xres == 2880 || m->xres == 1440)
2297 fb_videomode_to_omap_timings(m, display, &t);
2299 r = display->
driver->check_timings(display, &t);
2300 if (r == 0 && best_xres < m->xres) {
2301 best_xres = m->xres;
2306 if (best_xres == 0) {
2311 fb_videomode_to_omap_timings(&specs->
modedb[best_idx], display,
2332 r = dssdrv->
enable(dssdev);
2334 dev_warn(fbdev->
dev,
"Failed to enable display '%s'\n",
2339 d = get_display_data(fbdev, dssdev);
2362 r = dssdrv->
update(dssdev, 0, 0, w, h);
2365 "Failed to update display\n");
2385 DBG(
"omapfb_probe\n");
2388 dev_err(&pdev->
dev,
"probed for an unknown device\n");
2394 if (fbdev ==
NULL) {
2404 dev_warn(&pdev->
dev,
"VRFB is not supported on this hardware, "
2405 "ignoring the module parameter vrfb=y\n");
2412 platform_set_drvdata(pdev, fbdev);
2423 dev_warn(&pdev->
dev,
"no driver for display: %s\n",
2459 def_display = ovl_device;
2461 dev_warn(&pdev->
dev,
"cannot find default display\n");
2465 if (def_mode &&
strlen(def_mode) > 0) {
2466 if (omapfb_parse_def_modes(fbdev))
2467 dev_warn(&pdev->
dev,
"cannot parse default modes\n");
2468 }
else if (def_display && def_display->
driver->set_timings &&
2469 def_display->
driver->check_timings) {
2472 r = omapfb_find_best_mode(def_display, &t);
2475 def_display->
driver->set_timings(def_display, &t);
2478 r = omapfb_create_framebuffers(fbdev);
2485 r = mgr->
apply(mgr);
2487 dev_warn(fbdev->
dev,
"failed to apply dispc config\n");
2490 DBG(
"mgr->apply'ed\n");
2493 r = omapfb_init_display(fbdev, def_display);
2496 "failed to initialize default "
2502 DBG(
"create sysfs for fbs\n");
2505 dev_err(fbdev->
dev,
"failed to create sysfs entries\n");
2512 omapfb_free_resources(fbdev);
2514 dev_err(&pdev->
dev,
"failed to setup omapfb\n");
2526 omapfb_free_resources(fbdev);
2539 static int __init omapfb_init(
void)
2541 DBG(
"omapfb_init\n");
2551 static void __exit omapfb_exit(
void)
2553 DBG(
"omapfb_exit\n");