18 #include <linux/module.h>
20 #include <linux/slab.h>
24 #include <linux/wait.h>
29 #include <mach/board.h>
36 #define PRINT_BLIT_TIME 0
40 #define FULL_UPDATE_DONE 0x2
45 #define SUSPEND_RESUME 0x1
48 #define SHOW_UPDATES 0x8
50 #define DLOG(mask, fmt, args...) \
52 if (msmfb_debug_mask & mask) \
53 printk(KERN_INFO "msmfb: "fmt, ##args); \
56 static int msmfb_debug_mask;
104 unsigned long irq_flags;
115 spin_unlock_irqrestore(&msmfb->
update_lock, irq_flags);
119 static int msmfb_start_dma(
struct msmfb_info *msmfb)
123 unsigned long irq_flags;
125 s64 time_since_request;
129 time_since_request = ktime_to_ns(ktime_sub(
ktime_get(),
135 "request\n", time_since_request, us);
138 spin_unlock_irqrestore(&msmfb->
update_lock, irq_flags);
143 spin_unlock_irqrestore(&msmfb->
update_lock, irq_flags);
162 spin_unlock_irqrestore(&msmfb->
update_lock, irq_flags);
164 addr = ((msmfb->
xres * (yoffset +
y) + x) * 2);
165 mdp->
dma(mdp, addr + msmfb->
fb->fix.smem_start,
170 spin_unlock_irqrestore(&msmfb->
update_lock, irq_flags);
179 static void msmfb_handle_vsync_interrupt(
struct msmfb_callback *callback)
183 msmfb_start_dma(msmfb);
190 msmfb_start_dma(msmfb);
200 unsigned long irq_flags;
205 left, top, eright, ebottom, yoffset, pan_display);
213 spin_unlock_irqrestore(&msmfb->
update_lock, irq_flags);
225 spin_unlock_irqrestore(&msmfb->
update_lock, irq_flags);
232 (sleeping ==
AWAKE)) {
237 "rerequest vsync\n");
240 "waiting for frame start, %d %d\n",
255 if (left == 0 && top == 0 && eright == info->
var.xres &&
256 ebottom == info->
var.yres) {
266 if (left < msmfb->update_info.left)
268 if (top < msmfb->update_info.top)
278 spin_unlock_irqrestore(&msmfb->
update_lock, irq_flags);
297 msmfb_pan_update(info, left, top, eright, ebottom, 0, 0);
305 unsigned long irq_flags;
312 "not starting drawing\n");
318 spin_unlock_irqrestore(&msmfb->
update_lock, irq_flags);
327 if ((var->
xres != info->
var.xres) ||
328 (var->
yres != info->
var.yres) ||
346 msmfb_pan_update(info, var->
reserved[1] & 0xffff,
351 msmfb_pan_update(info, 0, 0, info->
var.xres, info->
var.yres,
360 msmfb_update(p, rect->
dx, rect->
dy, rect->
dx + rect->
width,
367 msmfb_update(p, area->
dx, area->
dy, area->
dx + area->
width,
374 msmfb_update(p, image->
dx, image->
dy, image->
dx + image->
width,
379 static int msmfb_blit(
struct fb_info *info,
390 for (i = 0; i < req_list.count; i++) {
395 ret = mdp->
blit(mdp, info, &
req);
405 static int msmfb_ioctl(
struct fb_info *p,
unsigned int cmd,
unsigned long arg)
415 ret = msmfb_blit(p, argp);
426 static struct fb_ops msmfb_ops = {
428 .fb_open = msmfb_open,
429 .fb_release = msmfb_release,
430 .fb_check_var = msmfb_check_var,
432 .fb_fillrect = msmfb_fillrect,
433 .fb_copyarea = msmfb_copyarea,
434 .fb_imageblit = msmfb_imageblit,
435 .fb_ioctl = msmfb_ioctl,
438 static unsigned PP[16];
442 #define BITS_PER_PIXEL 16
444 static void setup_fb_info(
struct msmfb_info *msmfb)
451 fb_info->
fix.ypanstep = 1;
453 fb_info->
fbops = &msmfb_ops;
458 fb_info->
fix.line_length = msmfb->
xres * 2;
460 fb_info->
var.xres = msmfb->
xres;
461 fb_info->
var.yres = msmfb->
yres;
462 fb_info->
var.width = msmfb->
panel->fb_data->width;
463 fb_info->
var.height = msmfb->
panel->fb_data->height;
464 fb_info->
var.xres_virtual = msmfb->
xres;
465 fb_info->
var.yres_virtual = msmfb->
yres * 2;
467 fb_info->
var.accel_flags = 0;
469 fb_info->
var.yoffset = 0;
477 fb_info->
fix.reserved[0] = 0x5444;
478 fb_info->
fix.reserved[1] = 0x5055;
484 fb_info->
var.reserved[0] = 0x54445055;
485 fb_info->
var.reserved[1] = 0;
490 fb_info->
var.red.offset = 11;
491 fb_info->
var.red.length = 5;
492 fb_info->
var.red.msb_right = 0;
493 fb_info->
var.green.offset = 5;
494 fb_info->
var.green.length = 6;
495 fb_info->
var.green.msb_right = 0;
496 fb_info->
var.blue.offset = 0;
497 fb_info->
var.blue.length = 5;
498 fb_info->
var.blue.msb_right = 0;
504 for (r = 1; r < 16; r++)
514 unsigned char *fbram;
522 if (resource->
end - resource->
start < size) {
527 fb->
fix.smem_start = resource->
start;
528 fb->
fix.smem_len = resource_size(resource);
529 fbram =
ioremap(resource->
start, resource_size(resource));
546 pr_err(
"msmfb_probe: no platform data\n");
550 pr_err(
"msmfb_probe: no fb_data\n");
559 msmfb->
panel = panel;
563 ret = setup_fbmem(msmfb, pdev);
565 goto error_setup_fbmem;
567 setup_fb_info(msmfb);
573 msmfb->
black = kzalloc(msmfb->
fb->var.bits_per_pixel*msmfb->
xres,
585 msmfb->
fake_vsync.function = msmfb_fake_vsync;
589 goto error_register_framebuffer;
595 error_register_framebuffer:
604 .probe = msmfb_probe,
605 .driver = {.name =
"msm_panel"},
609 static int msmfb_add_mdp_device(
struct device *
dev,
619 static void msmfb_remove_mdp_device(
struct device *dev,
623 if (dev != &mdp->
dev)
630 .add_dev = &msmfb_add_mdp_device,
631 .remove_dev = &msmfb_remove_mdp_device,
634 static int __init msmfb_init(
void)