aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/msm/msm_fb.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-07-06 16:34:27 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-07-06 16:34:27 -0700
commit8eb26942ae6eea7976273e554ab7c4fb2a128e17 (patch)
treefe9f62c3c9786ca39c71738108942fb0c04a24b5 /drivers/staging/msm/msm_fb.c
parentstaging: comedi: remove COMEDI_DEVICE_CREATE macro, expand all callers (diff)
downloadlinux-dev-8eb26942ae6eea7976273e554ab7c4fb2a128e17.tar.xz
linux-dev-8eb26942ae6eea7976273e554ab7c4fb2a128e17.zip
Staging: msm: delete the driver
It doesn't build anymore, no one is working on it, and, according to the developers, there's a different one that is working and in the real part of the kernel already. Acked-by: David Brown <davidb@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/msm/msm_fb.c')
-rw-r--r--drivers/staging/msm/msm_fb.c2353
1 files changed, 0 insertions, 2353 deletions
diff --git a/drivers/staging/msm/msm_fb.c b/drivers/staging/msm/msm_fb.c
deleted file mode 100644
index e60f8f97ead8..000000000000
--- a/drivers/staging/msm/msm_fb.c
+++ /dev/null
@@ -1,2353 +0,0 @@
-/*
- *
- * Core MSM framebuffer driver.
- *
- * Copyright (C) 2007 Google Incorporated
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/fb.h>
-#include "msm_mdp.h"
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <mach/board.h>
-#include <linux/uaccess.h>
-
-#include <linux/workqueue.h>
-#include <linux/string.h>
-#include <linux/proc_fs.h>
-#include <linux/vmalloc.h>
-#include <linux/debugfs.h>
-#include <linux/console.h>
-#include <linux/leds.h>
-#include <asm/dma-mapping.h>
-
-
-#define MSM_FB_C
-#include "msm_fb.h"
-#include "mddihosti.h"
-#include "tvenc.h"
-#include "mdp.h"
-#include "mdp4.h"
-
-#ifdef CONFIG_FB_MSM_LOGO
-#define INIT_IMAGE_FILE "/logo.rle"
-extern int load_565rle_image(char *filename);
-#endif
-
-
-#define pgprot_noncached(prot) \
- __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
-#define pgprot_writecombine(prot) \
- __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
-#define pgprot_device(prot) \
- __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_DEV_NONSHARED)
-#define pgprot_writethroughcache(prot) \
- __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_WRITETHROUGH)
-#define pgprot_writebackcache(prot) \
- __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_WRITEBACK)
-#define pgprot_writebackwacache(prot) \
- __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_WRITEALLOC)
-
-static unsigned char *fbram;
-static unsigned char *fbram_phys;
-static int fbram_size;
-
-static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
-static int pdev_list_cnt;
-
-int vsync_mode = 1;
-
-#define MAX_FBI_LIST 32
-static struct fb_info *fbi_list[MAX_FBI_LIST];
-static int fbi_list_index;
-
-static struct msm_fb_data_type *mfd_list[MAX_FBI_LIST];
-static int mfd_list_index;
-
-static u32 msm_fb_pseudo_palette[16] = {
- 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
-};
-
-u32 msm_fb_debug_enabled;
-/* Setting msm_fb_msg_level to 8 prints out ALL messages */
-u32 msm_fb_msg_level = 7;
-
-/* Setting mddi_msg_level to 8 prints out ALL messages */
-u32 mddi_msg_level = 5;
-
-extern int32 mdp_block_power_cnt[MDP_MAX_BLOCK];
-extern unsigned long mdp_timer_duration;
-
-static int msm_fb_register(struct msm_fb_data_type *mfd);
-static int msm_fb_open(struct fb_info *info, int user);
-static int msm_fb_release(struct fb_info *info, int user);
-static int msm_fb_pan_display(struct fb_var_screeninfo *var,
- struct fb_info *info);
-static int msm_fb_stop_sw_refresher(struct msm_fb_data_type *mfd);
-int msm_fb_resume_sw_refresher(struct msm_fb_data_type *mfd);
-static int msm_fb_check_var(struct fb_var_screeninfo *var,
- struct fb_info *info);
-static int msm_fb_set_par(struct fb_info *info);
-static int msm_fb_blank_sub(int blank_mode, struct fb_info *info,
- boolean op_enable);
-static int msm_fb_suspend_sub(struct msm_fb_data_type *mfd);
-static int msm_fb_resume_sub(struct msm_fb_data_type *mfd);
-static int msm_fb_ioctl(struct fb_info *info, unsigned int cmd,
- unsigned long arg);
-static int msm_fb_mmap(struct fb_info *info, struct vm_area_struct * vma);
-
-#ifdef MSM_FB_ENABLE_DBGFS
-
-#define MSM_FB_MAX_DBGFS 1024
-#define MAX_BACKLIGHT_BRIGHTNESS 255
-
-int msm_fb_debugfs_file_index;
-struct dentry *msm_fb_debugfs_root;
-struct dentry *msm_fb_debugfs_file[MSM_FB_MAX_DBGFS];
-
-struct dentry *msm_fb_get_debugfs_root(void)
-{
- if (msm_fb_debugfs_root == NULL)
- msm_fb_debugfs_root = debugfs_create_dir("msm_fb", NULL);
-
- return msm_fb_debugfs_root;
-}
-
-void msm_fb_debugfs_file_create(struct dentry *root, const char *name,
- u32 *var)
-{
- if (msm_fb_debugfs_file_index >= MSM_FB_MAX_DBGFS)
- return;
-
- msm_fb_debugfs_file[msm_fb_debugfs_file_index++] =
- debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var);
-}
-#endif
-
-int msm_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-
- if (!mfd->cursor_update)
- return -ENODEV;
-
- return mfd->cursor_update(info, cursor);
-}
-
-static int msm_fb_resource_initialized;
-
-#ifndef CONFIG_FB_BACKLIGHT
-static int lcd_backlight_registered;
-
-static void msm_fb_set_bl_brightness(struct led_classdev *led_cdev,
- enum led_brightness value)
-{
- struct msm_fb_data_type *mfd = dev_get_drvdata(led_cdev->dev->parent);
- int bl_lvl;
-
- if (value > MAX_BACKLIGHT_BRIGHTNESS)
- value = MAX_BACKLIGHT_BRIGHTNESS;
-
- /* This maps android backlight level 0 to 255 into
- driver backlight level 0 to bl_max with rounding */
- bl_lvl = (2 * value * mfd->panel_info.bl_max + MAX_BACKLIGHT_BRIGHTNESS)
- /(2 * MAX_BACKLIGHT_BRIGHTNESS);
-
- if (!bl_lvl && value)
- bl_lvl = 1;
-
- msm_fb_set_backlight(mfd, bl_lvl, 1);
-}
-
-static struct led_classdev backlight_led = {
- .name = "lcd-backlight",
- .brightness = MAX_BACKLIGHT_BRIGHTNESS,
- .brightness_set = msm_fb_set_bl_brightness,
-};
-#endif
-
-static struct msm_fb_platform_data *msm_fb_pdata;
-
-int msm_fb_detect_client(const char *name)
-{
- int ret = -EPERM;
-#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
- u32 id;
-#endif
-
- if (msm_fb_pdata && msm_fb_pdata->detect_client) {
- ret = msm_fb_pdata->detect_client(name);
-
- /* if it's non mddi panel, we need to pre-scan
- mddi client to see if we can disable mddi host */
-
-#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
- if (!ret && msm_fb_pdata->mddi_prescan)
- id = mddi_get_client_id();
-#endif
- }
-
- return ret;
-}
-
-static int msm_fb_probe(struct platform_device *pdev)
-{
- struct msm_fb_data_type *mfd;
- int rc;
-
- MSM_FB_DEBUG("msm_fb_probe\n");
-
- if ((pdev->id == 0) && (pdev->num_resources > 0)) {
- msm_fb_pdata = pdev->dev.platform_data;
- fbram_size =
- pdev->resource[0].end - pdev->resource[0].start + 1;
- fbram_phys = (char *)pdev->resource[0].start;
- fbram = ioremap((unsigned long)fbram_phys, fbram_size);
-
- if (!fbram) {
- printk(KERN_ERR "fbram ioremap failed!\n");
- return -ENOMEM;
- }
- MSM_FB_INFO("msm_fb_probe: phy_Addr = 0x%x virt = 0x%x\n",
- (int)fbram_phys, (int)fbram);
-
- msm_fb_resource_initialized = 1;
- return 0;
- }
-
- if (!msm_fb_resource_initialized)
- return -EPERM;
-
- mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
-
- if (!mfd)
- return -ENODEV;
-
- if (mfd->key != MFD_KEY)
- return -EINVAL;
-
- if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
- return -ENOMEM;
-
- mfd->panel_info.frame_count = 0;
- mfd->bl_level = mfd->panel_info.bl_max;
-
- if (mfd->panel_info.type == LCDC_PANEL)
- mfd->allow_set_offset =
- msm_fb_pdata->allow_set_offset != NULL ?
- msm_fb_pdata->allow_set_offset() : 0;
- else
- mfd->allow_set_offset = 0;
-
- rc = msm_fb_register(mfd);
- if (rc)
- return rc;
-
-#ifdef CONFIG_FB_BACKLIGHT
- msm_fb_config_backlight(mfd);
-#else
- /* android supports only one lcd-backlight/lcd for now */
- if (!lcd_backlight_registered) {
- if (led_classdev_register(&pdev->dev, &backlight_led))
- printk(KERN_ERR "led_classdev_register failed\n");
- else
- lcd_backlight_registered = 1;
- }
-#endif
-
- pdev_list[pdev_list_cnt++] = pdev;
- return 0;
-}
-
-static int msm_fb_remove(struct platform_device *pdev)
-{
- struct msm_fb_data_type *mfd;
-
- MSM_FB_DEBUG("msm_fb_remove\n");
-
- mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
-
- if (!mfd)
- return -ENODEV;
-
- if (mfd->key != MFD_KEY)
- return -EINVAL;
-
- if (msm_fb_suspend_sub(mfd))
- printk(KERN_ERR "msm_fb_remove: can't stop the device %d\n", mfd->index);
-
- if (mfd->channel_irq != 0)
- free_irq(mfd->channel_irq, (void *)mfd);
-
- if (mfd->vsync_width_boundary)
- vfree(mfd->vsync_width_boundary);
-
- if (mfd->vsync_resync_timer.function)
- del_timer(&mfd->vsync_resync_timer);
-
- if (mfd->refresh_timer.function)
- del_timer(&mfd->refresh_timer);
-
- if (mfd->dma_hrtimer.function)
- hrtimer_cancel(&mfd->dma_hrtimer);
-
- /* remove /dev/fb* */
- unregister_framebuffer(mfd->fbi);
-
-#ifdef CONFIG_FB_BACKLIGHT
- /* remove /sys/class/backlight */
- backlight_device_unregister(mfd->fbi->bl_dev);
-#else
- if (lcd_backlight_registered) {
- lcd_backlight_registered = 0;
- led_classdev_unregister(&backlight_led);
- }
-#endif
-
-#ifdef MSM_FB_ENABLE_DBGFS
- if (mfd->sub_dir)
- debugfs_remove(mfd->sub_dir);
-#endif
-
- return 0;
-}
-
-#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
-static int msm_fb_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct msm_fb_data_type *mfd;
- int ret = 0;
-
- MSM_FB_DEBUG("msm_fb_suspend\n");
-
- mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
-
- if ((!mfd) || (mfd->key != MFD_KEY))
- return 0;
-
- console_lock();
- fb_set_suspend(mfd->fbi, 1);
-
- ret = msm_fb_suspend_sub(mfd);
- if (ret != 0) {
- printk(KERN_ERR "msm_fb: failed to suspend! %d\n", ret);
- fb_set_suspend(mfd->fbi, 0);
- } else {
- pdev->dev.power.power_state = state;
- }
-
- console_unlock();
- return ret;
-}
-#else
-#define msm_fb_suspend NULL
-#endif
-
-static int msm_fb_suspend_sub(struct msm_fb_data_type *mfd)
-{
- int ret = 0;
-
- if ((!mfd) || (mfd->key != MFD_KEY))
- return 0;
-
- /*
- * suspend this channel
- */
- mfd->suspend.sw_refreshing_enable = mfd->sw_refreshing_enable;
- mfd->suspend.op_enable = mfd->op_enable;
- mfd->suspend.panel_power_on = mfd->panel_power_on;
-
- if (mfd->op_enable) {
- ret =
- msm_fb_blank_sub(FB_BLANK_POWERDOWN, mfd->fbi,
- mfd->suspend.op_enable);
- if (ret) {
- MSM_FB_INFO
- ("msm_fb_suspend: can't turn off display!\n");
- return ret;
- }
- mfd->op_enable = FALSE;
- }
- /*
- * try to power down
- */
- mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
-
- /*
- * detach display channel irq if there's any
- * or wait until vsync-resync completes
- */
- if ((mfd->dest == DISPLAY_LCD)) {
- if (mfd->panel_info.lcd.vsync_enable) {
- if (mfd->panel_info.lcd.hw_vsync_mode) {
- if (mfd->channel_irq != 0)
- disable_irq(mfd->channel_irq);
- } else {
- volatile boolean vh_pending;
- do {
- vh_pending = mfd->vsync_handler_pending;
- } while (vh_pending);
- }
- }
- }
-
- return 0;
-}
-
-#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
-static int msm_fb_resume(struct platform_device *pdev)
-{
- /* This resume function is called when interrupt is enabled.
- */
- int ret = 0;
- struct msm_fb_data_type *mfd;
-
- MSM_FB_DEBUG("msm_fb_resume\n");
-
- mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
-
- if ((!mfd) || (mfd->key != MFD_KEY))
- return 0;
-
- console_lock();
- ret = msm_fb_resume_sub(mfd);
- pdev->dev.power.power_state = PMSG_ON;
- fb_set_suspend(mfd->fbi, 1);
- console_unlock();
-
- return ret;
-}
-#else
-#define msm_fb_resume NULL
-#endif
-
-static int msm_fb_resume_sub(struct msm_fb_data_type *mfd)
-{
- int ret = 0;
-
- if ((!mfd) || (mfd->key != MFD_KEY))
- return 0;
-
- /* attach display channel irq if there's any */
- if (mfd->channel_irq != 0)
- enable_irq(mfd->channel_irq);
-
- /* resume state var recover */
- mfd->sw_refreshing_enable = mfd->suspend.sw_refreshing_enable;
- mfd->op_enable = mfd->suspend.op_enable;
-
- if (mfd->suspend.panel_power_on) {
- ret =
- msm_fb_blank_sub(FB_BLANK_UNBLANK, mfd->fbi,
- mfd->op_enable);
- if (ret)
- MSM_FB_INFO("msm_fb_resume: can't turn on display!\n");
- }
-
- return ret;
-}
-
-static struct platform_driver msm_fb_driver = {
- .probe = msm_fb_probe,
- .remove = msm_fb_remove,
-#ifndef CONFIG_HAS_EARLYSUSPEND
- .suspend = msm_fb_suspend,
- .resume = msm_fb_resume,
-#endif
- .shutdown = NULL,
- .driver = {
- /* Driver name must match the device name added in platform.c. */
- .name = "msm_fb",
- },
-};
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void msmfb_early_suspend(struct early_suspend *h)
-{
- struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
- early_suspend);
- msm_fb_suspend_sub(mfd);
-}
-
-static void msmfb_early_resume(struct early_suspend *h)
-{
- struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
- early_suspend);
- msm_fb_resume_sub(mfd);
-}
-#endif
-
-void msm_fb_set_backlight(struct msm_fb_data_type *mfd, __u32 bkl_lvl, u32 save)
-{
- struct msm_fb_panel_data *pdata;
-
- pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
-
- if ((pdata) && (pdata->set_backlight)) {
- down(&mfd->sem);
- if ((bkl_lvl != mfd->bl_level) || (!save)) {
- u32 old_lvl;
-
- old_lvl = mfd->bl_level;
- mfd->bl_level = bkl_lvl;
- pdata->set_backlight(mfd);
-
- if (!save)
- mfd->bl_level = old_lvl;
- }
- up(&mfd->sem);
- }
-}
-
-static int msm_fb_blank_sub(int blank_mode, struct fb_info *info,
- boolean op_enable)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- struct msm_fb_panel_data *pdata = NULL;
- int ret = 0;
-
- if (!op_enable)
- return -EPERM;
-
- pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
- if ((!pdata) || (!pdata->on) || (!pdata->off)) {
- printk(KERN_ERR "msm_fb_blank_sub: no panel operation detected!\n");
- return -ENODEV;
- }
-
- switch (blank_mode) {
- case FB_BLANK_UNBLANK:
- if (!mfd->panel_power_on) {
- mdelay(100);
- ret = pdata->on(mfd->pdev);
- if (ret == 0) {
- mfd->panel_power_on = TRUE;
-
- msm_fb_set_backlight(mfd,
- mfd->bl_level, 0);
-
-/* ToDo: possible conflict with android which doesn't expect sw refresher */
-/*
- if (!mfd->hw_refresh)
- {
- if ((ret = msm_fb_resume_sw_refresher(mfd)) != 0)
- {
- MSM_FB_INFO("msm_fb_blank_sub: msm_fb_resume_sw_refresher failed = %d!\n",ret);
- }
- }
-*/
- }
- }
- break;
-
- case FB_BLANK_VSYNC_SUSPEND:
- case FB_BLANK_HSYNC_SUSPEND:
- case FB_BLANK_NORMAL:
- case FB_BLANK_POWERDOWN:
- default:
- if (mfd->panel_power_on) {
- int curr_pwr_state;
-
- mfd->op_enable = FALSE;
- curr_pwr_state = mfd->panel_power_on;
- mfd->panel_power_on = FALSE;
-
- mdelay(100);
- ret = pdata->off(mfd->pdev);
- if (ret)
- mfd->panel_power_on = curr_pwr_state;
-
- msm_fb_set_backlight(mfd, 0, 0);
- mfd->op_enable = TRUE;
- }
- break;
- }
-
- return ret;
-}
-
-static void msm_fb_fillrect(struct fb_info *info,
- const struct fb_fillrect *rect)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-
- cfb_fillrect(info, rect);
- if (!mfd->hw_refresh && (info->var.yoffset == 0) &&
- !mfd->sw_currently_refreshing) {
- struct fb_var_screeninfo var;
-
- var = info->var;
- var.reserved[0] = 0x54445055;
- var.reserved[1] = (rect->dy << 16) | (rect->dx);
- var.reserved[2] = ((rect->dy + rect->height) << 16) |
- (rect->dx + rect->width);
-
- msm_fb_pan_display(&var, info);
- }
-}
-
-static void msm_fb_copyarea(struct fb_info *info,
- const struct fb_copyarea *area)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-
- cfb_copyarea(info, area);
- if (!mfd->hw_refresh && (info->var.yoffset == 0) &&
- !mfd->sw_currently_refreshing) {
- struct fb_var_screeninfo var;
-
- var = info->var;
- var.reserved[0] = 0x54445055;
- var.reserved[1] = (area->dy << 16) | (area->dx);
- var.reserved[2] = ((area->dy + area->height) << 16) |
- (area->dx + area->width);
-
- msm_fb_pan_display(&var, info);
- }
-}
-
-static void msm_fb_imageblit(struct fb_info *info, const struct fb_image *image)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-
- cfb_imageblit(info, image);
- if (!mfd->hw_refresh && (info->var.yoffset == 0) &&
- !mfd->sw_currently_refreshing) {
- struct fb_var_screeninfo var;
-
- var = info->var;
- var.reserved[0] = 0x54445055;
- var.reserved[1] = (image->dy << 16) | (image->dx);
- var.reserved[2] = ((image->dy + image->height) << 16) |
- (image->dx + image->width);
-
- msm_fb_pan_display(&var, info);
- }
-}
-
-static int msm_fb_blank(int blank_mode, struct fb_info *info)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- return msm_fb_blank_sub(blank_mode, info, mfd->op_enable);
-}
-
-static int msm_fb_set_lut(struct fb_cmap *cmap, struct fb_info *info)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-
- if (!mfd->lut_update)
- return -ENODEV;
-
- mfd->lut_update(info, cmap);
- return 0;
-}
-
-/*
- * Custom Framebuffer mmap() function for MSM driver.
- * Differs from standard mmap() function by allowing for customized
- * page-protection.
- */
-static int msm_fb_mmap(struct fb_info *info, struct vm_area_struct * vma)
-{
- /* Get frame buffer memory range. */
- unsigned long start = info->fix.smem_start;
- u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
- unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- if (off >= len) {
- /* memory mapped io */
- off -= len;
- if (info->var.accel_flags) {
- mutex_unlock(&info->lock);
- return -EINVAL;
- }
- start = info->fix.mmio_start;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
- }
-
- /* Set VM flags. */
- start &= PAGE_MASK;
- if ((vma->vm_end - vma->vm_start + off) > len)
- return -EINVAL;
- off += start;
- vma->vm_pgoff = off >> PAGE_SHIFT;
- /* This is an IO map - tell maydump to skip this VMA */
- vma->vm_flags |= VM_IO | VM_RESERVED;
-
- /* Set VM page protection */
- if (mfd->mdp_fb_page_protection == MDP_FB_PAGE_PROTECTION_WRITECOMBINE)
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
- else if (mfd->mdp_fb_page_protection ==
- MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE)
- vma->vm_page_prot = pgprot_writethroughcache(vma->vm_page_prot);
- else if (mfd->mdp_fb_page_protection ==
- MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE)
- vma->vm_page_prot = pgprot_writebackcache(vma->vm_page_prot);
- else if (mfd->mdp_fb_page_protection ==
- MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE)
- vma->vm_page_prot = pgprot_writebackwacache(vma->vm_page_prot);
- else
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- /* Remap the frame buffer I/O range */
- if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot))
- return -EAGAIN;
-
- return 0;
-}
-
-static struct fb_ops msm_fb_ops = {
- .owner = THIS_MODULE,
- .fb_open = msm_fb_open,
- .fb_release = msm_fb_release,
- .fb_read = NULL,
- .fb_write = NULL,
- .fb_cursor = NULL,
- .fb_check_var = msm_fb_check_var, /* vinfo check */
- .fb_set_par = msm_fb_set_par, /* set the video mode according to info->var */
- .fb_setcolreg = NULL, /* set color register */
- .fb_blank = msm_fb_blank, /* blank display */
- .fb_pan_display = msm_fb_pan_display, /* pan display */
- .fb_fillrect = msm_fb_fillrect, /* Draws a rectangle */
- .fb_copyarea = msm_fb_copyarea, /* Copy data from area to another */
- .fb_imageblit = msm_fb_imageblit, /* Draws a image to the display */
- .fb_rotate = NULL,
- .fb_sync = NULL, /* wait for blit idle, optional */
- .fb_ioctl = msm_fb_ioctl, /* perform fb specific ioctl (optional) */
- .fb_mmap = msm_fb_mmap,
-};
-
-static int msm_fb_register(struct msm_fb_data_type *mfd)
-{
- int ret = -ENODEV;
- int bpp;
- struct msm_panel_info *panel_info = &mfd->panel_info;
- struct fb_info *fbi = mfd->fbi;
- struct fb_fix_screeninfo *fix;
- struct fb_var_screeninfo *var;
- int *id;
- int fbram_offset;
-
- /*
- * fb info initialization
- */
- fix = &fbi->fix;
- var = &fbi->var;
-
- fix->type_aux = 0; /* if type == FB_TYPE_INTERLEAVED_PLANES */
- fix->visual = FB_VISUAL_TRUECOLOR; /* True Color */
- fix->ywrapstep = 0; /* No support */
- fix->mmio_start = 0; /* No MMIO Address */
- fix->mmio_len = 0; /* No MMIO Address */
- fix->accel = FB_ACCEL_NONE;/* FB_ACCEL_MSM needes to be added in fb.h */
-
- var->xoffset = 0, /* Offset from virtual to visible */
- var->yoffset = 0, /* resolution */
- var->grayscale = 0, /* No graylevels */
- var->nonstd = 0, /* standard pixel format */
- var->activate = FB_ACTIVATE_VBL, /* activate it at vsync */
- var->height = -1, /* height of picture in mm */
- var->width = -1, /* width of picture in mm */
- var->accel_flags = 0, /* acceleration flags */
- var->sync = 0, /* see FB_SYNC_* */
- var->rotate = 0, /* angle we rotate counter clockwise */
- mfd->op_enable = FALSE;
-
- switch (mfd->fb_imgType) {
- case MDP_RGB_565:
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->xpanstep = 1;
- fix->ypanstep = 1;
- var->vmode = FB_VMODE_NONINTERLACED;
- var->blue.offset = 0;
- var->green.offset = 5;
- var->red.offset = 11;
- var->blue.length = 5;
- var->green.length = 6;
- var->red.length = 5;
- var->blue.msb_right = 0;
- var->green.msb_right = 0;
- var->red.msb_right = 0;
- var->transp.offset = 0;
- var->transp.length = 0;
- bpp = 2;
- break;
-
- case MDP_RGB_888:
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->xpanstep = 1;
- fix->ypanstep = 1;
- var->vmode = FB_VMODE_NONINTERLACED;
- var->blue.offset = 0;
- var->green.offset = 8;
- var->red.offset = 16;
- var->blue.length = 8;
- var->green.length = 8;
- var->red.length = 8;
- var->blue.msb_right = 0;
- var->green.msb_right = 0;
- var->red.msb_right = 0;
- var->transp.offset = 0;
- var->transp.length = 0;
- bpp = 3;
- break;
-
- case MDP_ARGB_8888:
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->xpanstep = 1;
- fix->ypanstep = 1;
- var->vmode = FB_VMODE_NONINTERLACED;
- var->blue.offset = 0;
- var->green.offset = 8;
- var->red.offset = 16;
- var->blue.length = 8;
- var->green.length = 8;
- var->red.length = 8;
- var->blue.msb_right = 0;
- var->green.msb_right = 0;
- var->red.msb_right = 0;
- var->transp.offset = 24;
- var->transp.length = 8;
- bpp = 3;
- break;
-
- case MDP_YCRYCB_H2V1:
- /* ToDo: need to check TV-Out YUV422i framebuffer format */
- /* we might need to create new type define */
- fix->type = FB_TYPE_INTERLEAVED_PLANES;
- fix->xpanstep = 2;
- fix->ypanstep = 1;
- var->vmode = FB_VMODE_NONINTERLACED;
-
- /* how about R/G/B offset? */
- var->blue.offset = 0;
- var->green.offset = 5;
- var->red.offset = 11;
- var->blue.length = 5;
- var->green.length = 6;
- var->red.length = 5;
- var->blue.msb_right = 0;
- var->green.msb_right = 0;
- var->red.msb_right = 0;
- var->transp.offset = 0;
- var->transp.length = 0;
- bpp = 2;
- break;
-
- default:
- MSM_FB_ERR("msm_fb_init: fb %d unknown image type!\n",
- mfd->index);
- return ret;
- }
-
- /* The adreno GPU hardware requires that the pitch be aligned to
- 32 pixels for color buffers, so for the cases where the GPU
- is writing directly to fb0, the framebuffer pitch
- also needs to be 32 pixel aligned */
-
- if (mfd->index == 0)
- fix->line_length = ALIGN(panel_info->xres * bpp, 32);
- else
- fix->line_length = panel_info->xres * bpp;
-
- fix->smem_len = fix->line_length * panel_info->yres * mfd->fb_page;
-
- mfd->var_xres = panel_info->xres;
- mfd->var_yres = panel_info->yres;
-
- var->pixclock = mfd->panel_info.clk_rate;
- mfd->var_pixclock = var->pixclock;
-
- var->xres = panel_info->xres;
- var->yres = panel_info->yres;
- var->xres_virtual = panel_info->xres;
- var->yres_virtual = panel_info->yres * mfd->fb_page;
- var->bits_per_pixel = bpp * 8, /* FrameBuffer color depth */
- /*
- * id field for fb app
- */
- id = (int *)&mfd->panel;
-
-#if defined(CONFIG_FB_MSM_MDP22)
- snprintf(fix->id, sizeof(fix->id), "msmfb22_%x", (__u32) *id);
-#elif defined(CONFIG_FB_MSM_MDP30)
- snprintf(fix->id, sizeof(fix->id), "msmfb30_%x", (__u32) *id);
-#elif defined(CONFIG_FB_MSM_MDP31)
- snprintf(fix->id, sizeof(fix->id), "msmfb31_%x", (__u32) *id);
-#elif defined(CONFIG_FB_MSM_MDP40)
- snprintf(fix->id, sizeof(fix->id), "msmfb40_%x", (__u32) *id);
-#else
- error CONFIG_FB_MSM_MDP undefined !
-#endif
- fbi->fbops = &msm_fb_ops;
- fbi->flags = FBINFO_FLAG_DEFAULT;
- fbi->pseudo_palette = msm_fb_pseudo_palette;
-
- mfd->ref_cnt = 0;
- mfd->sw_currently_refreshing = FALSE;
- mfd->sw_refreshing_enable = TRUE;
- mfd->panel_power_on = FALSE;
-
- mfd->pan_waiting = FALSE;
- init_completion(&mfd->pan_comp);
- init_completion(&mfd->refresher_comp);
- sema_init(&mfd->sem, 1);
-
- fbram_offset = PAGE_ALIGN((int)fbram)-(int)fbram;
- fbram += fbram_offset;
- fbram_phys += fbram_offset;
- fbram_size -= fbram_offset;
-
- if (fbram_size < fix->smem_len) {
- printk(KERN_ERR "error: no more framebuffer memory!\n");
- return -ENOMEM;
- }
-
- fbi->screen_base = fbram;
- fbi->fix.smem_start = (unsigned long)fbram_phys;
-
- memset(fbi->screen_base, 0x0, fix->smem_len);
-
- mfd->op_enable = TRUE;
- mfd->panel_power_on = FALSE;
-
- /* cursor memory allocation */
- if (mfd->cursor_update) {
- mfd->cursor_buf = dma_alloc_coherent(NULL,
- MDP_CURSOR_SIZE,
- (dma_addr_t *) &mfd->cursor_buf_phys,
- GFP_KERNEL);
- if (!mfd->cursor_buf)
- mfd->cursor_update = 0;
- }
-
- if (mfd->lut_update) {
- ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
- if (ret)
- printk(KERN_ERR "%s: fb_alloc_cmap() failed!\n",
- __func__);
- }
-
- if (register_framebuffer(fbi) < 0) {
- if (mfd->lut_update)
- fb_dealloc_cmap(&fbi->cmap);
-
- if (mfd->cursor_buf)
- dma_free_coherent(NULL,
- MDP_CURSOR_SIZE,
- mfd->cursor_buf,
- (dma_addr_t) mfd->cursor_buf_phys);
-
- mfd->op_enable = FALSE;
- return -EPERM;
- }
-
- fbram += fix->smem_len;
- fbram_phys += fix->smem_len;
- fbram_size -= fix->smem_len;
-
- MSM_FB_INFO
- ("FrameBuffer[%d] %dx%d size=%d bytes is registered successfully!\n",
- mfd->index, fbi->var.xres, fbi->var.yres, fbi->fix.smem_len);
-
-#ifdef CONFIG_FB_MSM_LOGO
- if (!load_565rle_image(INIT_IMAGE_FILE)) ; /* Flip buffer */
-#endif
- ret = 0;
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
- mfd->early_suspend.suspend = msmfb_early_suspend;
- mfd->early_suspend.resume = msmfb_early_resume;
- mfd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 2;
- register_early_suspend(&mfd->early_suspend);
-#endif
-
-#ifdef MSM_FB_ENABLE_DBGFS
- {
- struct dentry *root;
- struct dentry *sub_dir;
- char sub_name[2];
-
- root = msm_fb_get_debugfs_root();
- if (root != NULL) {
- sub_name[0] = (char)(mfd->index + 0x30);
- sub_name[1] = '\0';
- sub_dir = debugfs_create_dir(sub_name, root);
- } else {
- sub_dir = NULL;
- }
-
- mfd->sub_dir = sub_dir;
-
- if (sub_dir) {
- msm_fb_debugfs_file_create(sub_dir, "op_enable",
- (u32 *) &mfd->op_enable);
- msm_fb_debugfs_file_create(sub_dir, "panel_power_on",
- (u32 *) &mfd->
- panel_power_on);
- msm_fb_debugfs_file_create(sub_dir, "ref_cnt",
- (u32 *) &mfd->ref_cnt);
- msm_fb_debugfs_file_create(sub_dir, "fb_imgType",
- (u32 *) &mfd->fb_imgType);
- msm_fb_debugfs_file_create(sub_dir,
- "sw_currently_refreshing",
- (u32 *) &mfd->
- sw_currently_refreshing);
- msm_fb_debugfs_file_create(sub_dir,
- "sw_refreshing_enable",
- (u32 *) &mfd->
- sw_refreshing_enable);
-
- msm_fb_debugfs_file_create(sub_dir, "xres",
- (u32 *) &mfd->panel_info.
- xres);
- msm_fb_debugfs_file_create(sub_dir, "yres",
- (u32 *) &mfd->panel_info.
- yres);
- msm_fb_debugfs_file_create(sub_dir, "bpp",
- (u32 *) &mfd->panel_info.
- bpp);
- msm_fb_debugfs_file_create(sub_dir, "type",
- (u32 *) &mfd->panel_info.
- type);
- msm_fb_debugfs_file_create(sub_dir, "wait_cycle",
- (u32 *) &mfd->panel_info.
- wait_cycle);
- msm_fb_debugfs_file_create(sub_dir, "pdest",
- (u32 *) &mfd->panel_info.
- pdest);
- msm_fb_debugfs_file_create(sub_dir, "backbuff",
- (u32 *) &mfd->panel_info.
- fb_num);
- msm_fb_debugfs_file_create(sub_dir, "clk_rate",
- (u32 *) &mfd->panel_info.
- clk_rate);
- msm_fb_debugfs_file_create(sub_dir, "frame_count",
- (u32 *) &mfd->panel_info.
- frame_count);
-
-
- switch (mfd->dest) {
- case DISPLAY_LCD:
- msm_fb_debugfs_file_create(sub_dir,
- "vsync_enable",
- (u32 *)&mfd->panel_info.lcd.vsync_enable);
- msm_fb_debugfs_file_create(sub_dir,
- "refx100",
- (u32 *) &mfd->panel_info.lcd. refx100);
- msm_fb_debugfs_file_create(sub_dir,
- "v_back_porch",
- (u32 *) &mfd->panel_info.lcd.v_back_porch);
- msm_fb_debugfs_file_create(sub_dir,
- "v_front_porch",
- (u32 *) &mfd->panel_info.lcd.v_front_porch);
- msm_fb_debugfs_file_create(sub_dir,
- "v_pulse_width",
- (u32 *) &mfd->panel_info.lcd.v_pulse_width);
- msm_fb_debugfs_file_create(sub_dir,
- "hw_vsync_mode",
- (u32 *) &mfd->panel_info.lcd.hw_vsync_mode);
- msm_fb_debugfs_file_create(sub_dir,
- "vsync_notifier_period", (u32 *)
- &mfd->panel_info.lcd.vsync_notifier_period);
- break;
-
- case DISPLAY_LCDC:
- msm_fb_debugfs_file_create(sub_dir,
- "h_back_porch",
- (u32 *) &mfd->panel_info.lcdc.h_back_porch);
- msm_fb_debugfs_file_create(sub_dir,
- "h_front_porch",
- (u32 *) &mfd->panel_info.lcdc.h_front_porch);
- msm_fb_debugfs_file_create(sub_dir,
- "h_pulse_width",
- (u32 *) &mfd->panel_info.lcdc.h_pulse_width);
- msm_fb_debugfs_file_create(sub_dir,
- "v_back_porch",
- (u32 *) &mfd->panel_info.lcdc.v_back_porch);
- msm_fb_debugfs_file_create(sub_dir,
- "v_front_porch",
- (u32 *) &mfd->panel_info.lcdc.v_front_porch);
- msm_fb_debugfs_file_create(sub_dir,
- "v_pulse_width",
- (u32 *) &mfd->panel_info.lcdc.v_pulse_width);
- msm_fb_debugfs_file_create(sub_dir,
- "border_clr",
- (u32 *) &mfd->panel_info.lcdc.border_clr);
- msm_fb_debugfs_file_create(sub_dir,
- "underflow_clr",
- (u32 *) &mfd->panel_info.lcdc.underflow_clr);
- msm_fb_debugfs_file_create(sub_dir,
- "hsync_skew",
- (u32 *) &mfd->panel_info.lcdc.hsync_skew);
- break;
-
- default:
- break;
- }
- }
- }
-#endif /* MSM_FB_ENABLE_DBGFS */
-
- return ret;
-}
-
-static int msm_fb_open(struct fb_info *info, int user)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-
- if (!mfd->ref_cnt) {
- mdp_set_dma_pan_info(info, NULL, TRUE);
-
- if (msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable)) {
- printk(KERN_ERR "msm_fb_open: can't turn on display!\n");
- return -1;
- }
- }
-
- mfd->ref_cnt++;
- return 0;
-}
-
-static int msm_fb_release(struct fb_info *info, int user)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- int ret = 0;
-
- if (!mfd->ref_cnt) {
- MSM_FB_INFO("msm_fb_release: try to close unopened fb %d!\n",
- mfd->index);
- return -EINVAL;
- }
-
- mfd->ref_cnt--;
-
- if (!mfd->ref_cnt) {
- if ((ret =
- msm_fb_blank_sub(FB_BLANK_POWERDOWN, info,
- mfd->op_enable)) != 0) {
- printk(KERN_ERR "msm_fb_release: can't turn off display!\n");
- return ret;
- }
- }
-
- return ret;
-}
-
-DEFINE_SEMAPHORE(msm_fb_pan_sem);
-
-static int msm_fb_pan_display(struct fb_var_screeninfo *var,
- struct fb_info *info)
-{
- struct mdp_dirty_region dirty;
- struct mdp_dirty_region *dirtyPtr = NULL;
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-
- if ((!mfd->op_enable) || (!mfd->panel_power_on))
- return -EPERM;
-
- if (var->xoffset > (info->var.xres_virtual - info->var.xres))
- return -EINVAL;
-
- if (var->yoffset > (info->var.yres_virtual - info->var.yres))
- return -EINVAL;
-
- if (info->fix.xpanstep)
- info->var.xoffset =
- (var->xoffset / info->fix.xpanstep) * info->fix.xpanstep;
-
- if (info->fix.ypanstep)
- info->var.yoffset =
- (var->yoffset / info->fix.ypanstep) * info->fix.ypanstep;
-
- /* "UPDT" */
- if (var->reserved[0] == 0x54445055) {
- dirty.xoffset = var->reserved[1] & 0xffff;
- dirty.yoffset = (var->reserved[1] >> 16) & 0xffff;
-
- if ((var->reserved[2] & 0xffff) <= dirty.xoffset)
- return -EINVAL;
- if (((var->reserved[2] >> 16) & 0xffff) <= dirty.yoffset)
- return -EINVAL;
-
- dirty.width = (var->reserved[2] & 0xffff) - dirty.xoffset;
- dirty.height =
- ((var->reserved[2] >> 16) & 0xffff) - dirty.yoffset;
- info->var.yoffset = var->yoffset;
-
- if (dirty.xoffset < 0)
- return -EINVAL;
-
- if (dirty.yoffset < 0)
- return -EINVAL;
-
- if ((dirty.xoffset + dirty.width) > info->var.xres)
- return -EINVAL;
-
- if ((dirty.yoffset + dirty.height) > info->var.yres)
- return -EINVAL;
-
- if ((dirty.width <= 0) || (dirty.height <= 0))
- return -EINVAL;
-
- dirtyPtr = &dirty;
- }
-
- /* Flip */
- /* A constant value is used to indicate that we should change the DMA
- output buffer instead of just panning */
-
- if (var->reserved[0] == 0x466c6970) {
- unsigned long length, address;
- struct file *p_src_file;
- struct mdp_img imgdata;
- int bpp;
-
- if (mfd->allow_set_offset) {
- imgdata.memory_id = var->reserved[1];
- imgdata.priv = var->reserved[2];
-
- /* If there is no memory ID then we want to reset back
- to the original fb visibility */
- if (var->reserved[1]) {
- if (var->reserved[4] == MDP_BLIT_SRC_GEM) {
- panic("waaaaaaaaaaaaaah");
- if ( /*get_gem_img(&imgdata,
- (unsigned long *) &address,
- &length)*/ -1 < 0) {
- return -1;
- }
- } else {
- /*get_img(&imgdata, info, &address,
- &length, &p_src_file);*/
- panic("waaaaaah");
- }
- mfd->ibuf.visible_swapped = TRUE;
- } else {
- /* Flip back to the original address
- adjusted for xoffset and yoffset */
-
- bpp = info->var.bits_per_pixel / 8;
- address = (unsigned long) info->fix.smem_start;
- address += info->var.xoffset * bpp +
- info->var.yoffset * info->fix.line_length;
-
- mfd->ibuf.visible_swapped = FALSE;
- }
-
- mdp_set_offset_info(info, address,
- (var->activate == FB_ACTIVATE_VBL));
-
- mfd->dma_fnc(mfd);
- return 0;
- } else
- return -EINVAL;
- }
-
- down(&msm_fb_pan_sem);
- mdp_set_dma_pan_info(info, dirtyPtr,
- (var->activate == FB_ACTIVATE_VBL));
- mdp_dma_pan_update(info);
- up(&msm_fb_pan_sem);
-
- ++mfd->panel_info.frame_count;
- return 0;
-}
-
-static int msm_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-
- if (var->rotate != FB_ROTATE_UR)
- return -EINVAL;
- if (var->grayscale != info->var.grayscale)
- return -EINVAL;
-
- switch (var->bits_per_pixel) {
- case 16:
- if ((var->green.offset != 5) ||
- !((var->blue.offset == 11)
- || (var->blue.offset == 0)) ||
- !((var->red.offset == 11)
- || (var->red.offset == 0)) ||
- (var->blue.length != 5) ||
- (var->green.length != 6) ||
- (var->red.length != 5) ||
- (var->blue.msb_right != 0) ||
- (var->green.msb_right != 0) ||
- (var->red.msb_right != 0) ||
- (var->transp.offset != 0) ||
- (var->transp.length != 0))
- return -EINVAL;
- break;
-
- case 24:
- if ((var->blue.offset != 0) ||
- (var->green.offset != 8) ||
- (var->red.offset != 16) ||
- (var->blue.length != 8) ||
- (var->green.length != 8) ||
- (var->red.length != 8) ||
- (var->blue.msb_right != 0) ||
- (var->green.msb_right != 0) ||
- (var->red.msb_right != 0) ||
- !(((var->transp.offset == 0) &&
- (var->transp.length == 0)) ||
- ((var->transp.offset == 24) &&
- (var->transp.length == 8))))
- return -EINVAL;
- break;
-
- default:
- return -EINVAL;
- }
-
- if ((var->xres_virtual <= 0) || (var->yres_virtual <= 0))
- return -EINVAL;
-
- if (info->fix.smem_len <
- (var->xres_virtual*var->yres_virtual*(var->bits_per_pixel/8)))
- return -EINVAL;
-
- if ((var->xres == 0) || (var->yres == 0))
- return -EINVAL;
-
- if ((var->xres > mfd->panel_info.xres) ||
- (var->yres > mfd->panel_info.yres))
- return -EINVAL;
-
- if (var->xoffset > (var->xres_virtual - var->xres))
- return -EINVAL;
-
- if (var->yoffset > (var->yres_virtual - var->yres))
- return -EINVAL;
-
- return 0;
-}
-
-static int msm_fb_set_par(struct fb_info *info)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- struct fb_var_screeninfo *var = &info->var;
- int old_imgType;
- int blank = 0;
-
- old_imgType = mfd->fb_imgType;
- switch (var->bits_per_pixel) {
- case 16:
- if (var->red.offset == 0)
- mfd->fb_imgType = MDP_BGR_565;
- else
- mfd->fb_imgType = MDP_RGB_565;
- break;
-
- case 24:
- if ((var->transp.offset == 0) && (var->transp.length == 0))
- mfd->fb_imgType = MDP_RGB_888;
- else if ((var->transp.offset == 24) &&
- (var->transp.length == 8)) {
- mfd->fb_imgType = MDP_ARGB_8888;
- info->var.bits_per_pixel = 32;
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- if ((mfd->var_pixclock != var->pixclock) ||
- (mfd->hw_refresh && ((mfd->fb_imgType != old_imgType) ||
- (mfd->var_pixclock != var->pixclock) ||
- (mfd->var_xres != var->xres) ||
- (mfd->var_yres != var->yres)))) {
- mfd->var_xres = var->xres;
- mfd->var_yres = var->yres;
- mfd->var_pixclock = var->pixclock;
- blank = 1;
- }
-
- if (blank) {
- msm_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable);
- msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable);
- }
-
- return 0;
-}
-
-static int msm_fb_stop_sw_refresher(struct msm_fb_data_type *mfd)
-{
- if (mfd->hw_refresh)
- return -EPERM;
-
- if (mfd->sw_currently_refreshing) {
- down(&mfd->sem);
- mfd->sw_currently_refreshing = FALSE;
- up(&mfd->sem);
-
- /* wait until the refresher finishes the last job */
- wait_for_completion_killable(&mfd->refresher_comp);
- }
-
- return 0;
-}
-
-int msm_fb_resume_sw_refresher(struct msm_fb_data_type *mfd)
-{
- boolean do_refresh;
-
- if (mfd->hw_refresh)
- return -EPERM;
-
- down(&mfd->sem);
- if ((!mfd->sw_currently_refreshing) && (mfd->sw_refreshing_enable)) {
- do_refresh = TRUE;
- mfd->sw_currently_refreshing = TRUE;
- } else {
- do_refresh = FALSE;
- }
- up(&mfd->sem);
-
- if (do_refresh)
- mdp_refresh_screen((unsigned long)mfd);
-
- return 0;
-}
-
-void mdp_ppp_put_img(struct file *p_src_file, struct file *p_dst_file)
-{
-#ifdef CONFIG_ANDROID_PMEM
- if (p_src_file)
- put_pmem_file(p_src_file);
- if (p_dst_file)
- put_pmem_file(p_dst_file);
-#endif
-}
-
-int mdp_blit(struct fb_info *info, struct mdp_blit_req *req)
-{
- int ret;
- struct file *p_src_file = 0, *p_dst_file = 0;
- if (unlikely(req->src_rect.h == 0 || req->src_rect.w == 0)) {
- printk(KERN_ERR "mpd_ppp: src img of zero size!\n");
- return -EINVAL;
- }
- if (unlikely(req->dst_rect.h == 0 || req->dst_rect.w == 0))
- return 0;
-
- ret = mdp_ppp_blit(info, req, &p_src_file, &p_dst_file);
- mdp_ppp_put_img(p_src_file, p_dst_file);
- return ret;
-}
-
-typedef void (*msm_dma_barrier_function_pointer) (void *, size_t);
-
-static inline void msm_fb_dma_barrier_for_rect(struct fb_info *info,
- struct mdp_img *img, struct mdp_rect *rect,
- msm_dma_barrier_function_pointer dma_barrier_fp
- )
-{
- /*
- * Compute the start and end addresses of the rectangles.
- * NOTE: As currently implemented, the data between
- * the end of one row and the start of the next is
- * included in the address range rather than
- * doing multiple calls for each row.
- */
-
- char * const pmem_start = info->screen_base;
-/* int bytes_per_pixel = mdp_get_bytes_per_pixel(img->format);
- unsigned long start = (unsigned long)pmem_start + img->offset +
- (img->width * rect->y + rect->x) * bytes_per_pixel;
- size_t size = ((rect->h - 1) * img->width + rect->w) * bytes_per_pixel;
- (*dma_barrier_fp) ((void *) start, size);
-*/
- panic("waaaaah");
-}
-
-static inline void msm_dma_nc_pre(void)
-{
- dmb();
-}
-static inline void msm_dma_wt_pre(void)
-{
- dmb();
-}
-static inline void msm_dma_todevice_wb_pre(void *start, size_t size)
-{
- #warning this
-// dma_cache_pre_ops(start, size, DMA_TO_DEVICE);
-}
-
-static inline void msm_dma_fromdevice_wb_pre(void *start, size_t size)
-{
- #warning this
-// dma_cache_pre_ops(start, size, DMA_FROM_DEVICE);
-}
-
-static inline void msm_dma_nc_post(void)
-{
- dmb();
-}
-
-static inline void msm_dma_fromdevice_wt_post(void *start, size_t size)
-{
- #warning this
-// dma_cache_post_ops(start, size, DMA_FROM_DEVICE);
-}
-
-static inline void msm_dma_todevice_wb_post(void *start, size_t size)
-{
- #warning this
-// dma_cache_post_ops(start, size, DMA_TO_DEVICE);
-}
-
-static inline void msm_dma_fromdevice_wb_post(void *start, size_t size)
-{
- #warning this
-// dma_cache_post_ops(start, size, DMA_FROM_DEVICE);
-}
-
-/*
- * Do the write barriers required to guarantee data is committed to RAM
- * (from CPU cache or internal buffers) before a DMA operation starts.
- * NOTE: As currently implemented, the data between
- * the end of one row and the start of the next is
- * included in the address range rather than
- * doing multiple calls for each row.
-*/
-static void msm_fb_ensure_memory_coherency_before_dma(struct fb_info *info,
- struct mdp_blit_req *req_list,
- int req_list_count)
-{
-#ifdef CONFIG_ARCH_QSD8X50
- int i;
-
- /*
- * Normally, do the requested barriers for each address
- * range that corresponds to a rectangle.
- *
- * But if at least one write barrier is requested for data
- * going to or from the device but no address range is
- * needed for that barrier, then do the barrier, but do it
- * only once, no matter how many requests there are.
- */
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- switch (mfd->mdp_fb_page_protection) {
- default:
- case MDP_FB_PAGE_PROTECTION_NONCACHED:
- case MDP_FB_PAGE_PROTECTION_WRITECOMBINE:
- /*
- * The following barrier is only done at most once,
- * since further calls would be redundant.
- */
- for (i = 0; i < req_list_count; i++) {
- if (!(req_list[i].flags
- & MDP_NO_DMA_BARRIER_START)) {
- msm_dma_nc_pre();
- break;
- }
- }
- break;
-
- case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE:
- /*
- * The following barrier is only done at most once,
- * since further calls would be redundant.
- */
- for (i = 0; i < req_list_count; i++) {
- if (!(req_list[i].flags
- & MDP_NO_DMA_BARRIER_START)) {
- msm_dma_wt_pre();
- break;
- }
- }
- break;
-
- case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE:
- case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE:
- for (i = 0; i < req_list_count; i++) {
- if (!(req_list[i].flags &
- MDP_NO_DMA_BARRIER_START)) {
-
- msm_fb_dma_barrier_for_rect(info,
- &(req_list[i].src),
- &(req_list[i].src_rect),
- msm_dma_todevice_wb_pre
- );
-
- msm_fb_dma_barrier_for_rect(info,
- &(req_list[i].dst),
- &(req_list[i].dst_rect),
- msm_dma_todevice_wb_pre
- );
- }
- }
- break;
- }
-#else
- dmb();
-#endif
-}
-
-
-/*
- * Do the write barriers required to guarantee data will be re-read from RAM by
- * the CPU after a DMA operation ends.
- * NOTE: As currently implemented, the data between
- * the end of one row and the start of the next is
- * included in the address range rather than
- * doing multiple calls for each row.
-*/
-static void msm_fb_ensure_memory_coherency_after_dma(struct fb_info *info,
- struct mdp_blit_req *req_list,
- int req_list_count)
-{
-#ifdef CONFIG_ARCH_QSD8X50
- int i;
-
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- switch (mfd->mdp_fb_page_protection) {
- default:
- case MDP_FB_PAGE_PROTECTION_NONCACHED:
- case MDP_FB_PAGE_PROTECTION_WRITECOMBINE:
- /*
- * The following barrier is only done at most once,
- * since further calls would be redundant.
- */
- for (i = 0; i < req_list_count; i++) {
- if (!(req_list[i].flags
- & MDP_NO_DMA_BARRIER_END)) {
- msm_dma_nc_post();
- break;
- }
- }
- break;
-
- case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE:
- for (i = 0; i < req_list_count; i++) {
- if (!(req_list[i].flags &
- MDP_NO_DMA_BARRIER_END)) {
-
- msm_fb_dma_barrier_for_rect(info,
- &(req_list[i].dst),
- &(req_list[i].dst_rect),
- msm_dma_fromdevice_wt_post
- );
- }
- }
- break;
- case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE:
- case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE:
- for (i = 0; i < req_list_count; i++) {
- if (!(req_list[i].flags &
- MDP_NO_DMA_BARRIER_END)) {
-
- msm_fb_dma_barrier_for_rect(info,
- &(req_list[i].dst),
- &(req_list[i].dst_rect),
- msm_dma_fromdevice_wb_post
- );
- }
- }
- break;
- }
-#else
- dmb();
-#endif
-}
-
-#ifdef CONFIG_MDP_PPP_ASYNC_OP
-void msm_fb_ensure_mem_coherency_after_dma(struct fb_info *info,
- struct mdp_blit_req *req_list, int req_list_count)
-{
- BUG_ON(!info);
-
- /*
- * Ensure that CPU cache and other internal CPU state is
- * updated to reflect any change in memory modified by MDP blit
- * DMA.
- */
- msm_fb_ensure_memory_coherency_after_dma(info,
- req_list, req_list_count);
-}
-
-static int msmfb_async_blit(struct fb_info *info, void __user *p)
-{
- /*
- * CAUTION: The names of the struct types intentionally *DON'T* match
- * the names of the variables declared -- they appear to be swapped.
- * Read the code carefully and you should see that the variable names
- * make sense.
- */
- const int MAX_LIST_WINDOW = 16;
- struct mdp_blit_req req_list[MAX_LIST_WINDOW];
- struct mdp_blit_req_list req_list_header;
-
- int count, i, req_list_count;
-
- /* Get the count size for the total BLIT request. */
- if (copy_from_user(&req_list_header, p, sizeof(req_list_header)))
- return -EFAULT;
- p += sizeof(req_list_header);
- count = req_list_header.count;
- while (count > 0) {
- /*
- * Access the requests through a narrow window to decrease copy
- * overhead and make larger requests accessible to the
- * coherency management code.
- * NOTE: The window size is intended to be larger than the
- * typical request size, but not require more than 2
- * kbytes of stack storage.
- */
- req_list_count = count;
- if (req_list_count > MAX_LIST_WINDOW)
- req_list_count = MAX_LIST_WINDOW;
- if (copy_from_user(&req_list, p,
- sizeof(struct mdp_blit_req)*req_list_count))
- return -EFAULT;
-
- /*
- * Ensure that any data CPU may have previously written to
- * internal state (but not yet committed to memory) is
- * guaranteed to be committed to memory now.
- */
- msm_fb_ensure_memory_coherency_before_dma(info,
- req_list, req_list_count);
-
- /*
- * Do the blit DMA, if required -- returning early only if
- * there is a failure.
- */
- for (i = 0; i < req_list_count; i++) {
- if (!(req_list[i].flags & MDP_NO_BLIT)) {
- int ret = 0;
- struct mdp_ppp_djob *job = NULL;
-
- if (unlikely(req_list[i].src_rect.h == 0 ||
- req_list[i].src_rect.w == 0)) {
- MSM_FB_ERR("mpd_ppp: "
- "src img of zero size!\n");
- return -EINVAL;
- }
-
- if (unlikely(req_list[i].dst_rect.h == 0 ||
- req_list[i].dst_rect.w == 0))
- continue;
-
- /* create a new display job */
- job = mdp_ppp_new_djob();
- if (unlikely(!job))
- return -ENOMEM;
-
- job->info = info;
- memcpy(&job->req, &req_list[i],
- sizeof(struct mdp_blit_req));
-
- /* Do the actual blit. */
- ret = mdp_ppp_blit(info, &job->req,
- &job->p_src_file, &job->p_dst_file);
-
- /*
- * Note that early returns don't guarantee
- * memory coherency.
- */
- if (ret || mdp_ppp_get_ret_code()) {
- mdp_ppp_clear_curr_djob();
- return ret;
- }
- }
- }
-
- /* Go to next window of requests. */
- count -= req_list_count;
- p += sizeof(struct mdp_blit_req)*req_list_count;
- }
- return 0;
-}
-#else
-
-/*
- * NOTE: The userspace issues blit operations in a sequence, the sequence
- * start with a operation marked START and ends in an operation marked
- * END. It is guaranteed by the userspace that all the blit operations
- * between START and END are only within the regions of areas designated
- * by the START and END operations and that the userspace doesn't modify
- * those areas. Hence it would be enough to perform barrier/cache operations
- * only on the START and END operations.
- */
-static int msmfb_blit(struct fb_info *info, void __user *p)
-{
- /*
- * CAUTION: The names of the struct types intentionally *DON'T* match
- * the names of the variables declared -- they appear to be swapped.
- * Read the code carefully and you should see that the variable names
- * make sense.
- */
- const int MAX_LIST_WINDOW = 16;
- struct mdp_blit_req req_list[MAX_LIST_WINDOW];
- struct mdp_blit_req_list req_list_header;
-
- int count, i, req_list_count;
-
- /* Get the count size for the total BLIT request. */
- if (copy_from_user(&req_list_header, p, sizeof(req_list_header)))
- return -EFAULT;
- p += sizeof(req_list_header);
- count = req_list_header.count;
- while (count > 0) {
- /*
- * Access the requests through a narrow window to decrease copy
- * overhead and make larger requests accessible to the
- * coherency management code.
- * NOTE: The window size is intended to be larger than the
- * typical request size, but not require more than 2
- * kbytes of stack storage.
- */
- req_list_count = count;
- if (req_list_count > MAX_LIST_WINDOW)
- req_list_count = MAX_LIST_WINDOW;
- if (copy_from_user(&req_list, p,
- sizeof(struct mdp_blit_req)*req_list_count))
- return -EFAULT;
-
- /*
- * Ensure that any data CPU may have previously written to
- * internal state (but not yet committed to memory) is
- * guaranteed to be committed to memory now.
- */
- msm_fb_ensure_memory_coherency_before_dma(info,
- req_list, req_list_count);
-
- /*
- * Do the blit DMA, if required -- returning early only if
- * there is a failure.
- */
- for (i = 0; i < req_list_count; i++) {
- if (!(req_list[i].flags & MDP_NO_BLIT)) {
- /* Do the actual blit. */
- int ret = mdp_blit(info, &(req_list[i]));
-
- /*
- * Note that early returns don't guarantee
- * memory coherency.
- */
- if (ret)
- return ret;
- }
- }
-
- /*
- * Ensure that CPU cache and other internal CPU state is
- * updated to reflect any change in memory modified by MDP blit
- * DMA.
- */
- msm_fb_ensure_memory_coherency_after_dma(info,
- req_list,
- req_list_count);
-
- /* Go to next window of requests. */
- count -= req_list_count;
- p += sizeof(struct mdp_blit_req)*req_list_count;
- }
- return 0;
-}
-#endif
-
-#ifdef CONFIG_FB_MSM_OVERLAY
-static int msmfb_overlay_get(struct fb_info *info, void __user *p)
-{
- struct mdp_overlay req;
- int ret;
-
- if (copy_from_user(&req, p, sizeof(req)))
- return -EFAULT;
-
- ret = mdp4_overlay_get(info, &req);
- if (ret) {
- printk(KERN_ERR "%s: ioctl failed \n",
- __func__);
- return ret;
- }
- if (copy_to_user(p, &req, sizeof(req))) {
- printk(KERN_ERR "%s: copy2user failed \n",
- __func__);
- return -EFAULT;
- }
-
- return 0;
-}
-
-static int msmfb_overlay_set(struct fb_info *info, void __user *p)
-{
- struct mdp_overlay req;
- int ret;
-
- if (copy_from_user(&req, p, sizeof(req)))
- return -EFAULT;
-
- ret = mdp4_overlay_set(info, &req);
- if (ret) {
- printk(KERN_ERR "%s:ioctl failed \n",
- __func__);
- return ret;
- }
-
- if (copy_to_user(p, &req, sizeof(req))) {
- printk(KERN_ERR "%s: copy2user failed \n",
- __func__);
- return -EFAULT;
- }
-
- return 0;
-}
-
-static int msmfb_overlay_unset(struct fb_info *info, unsigned long *argp)
-{
- int ret, ndx;
-
- ret = copy_from_user(&ndx, argp, sizeof(ndx));
- if (ret) {
- printk(KERN_ERR "%s:msmfb_overlay_unset ioctl failed \n",
- __func__);
- return ret;
- }
-
- return mdp4_overlay_unset(info, ndx);
-}
-
-static int msmfb_overlay_play(struct fb_info *info, unsigned long *argp)
-{
- int ret;
- struct msmfb_overlay_data req;
- struct file *p_src_file = 0;
-
- ret = copy_from_user(&req, argp, sizeof(req));
- if (ret) {
- printk(KERN_ERR "%s:msmfb_overlay_play ioctl failed \n",
- __func__);
- return ret;
- }
-
- ret = mdp4_overlay_play(info, &req, &p_src_file);
-
- if (p_src_file)
- put_pmem_file(p_src_file);
-
- return ret;
-}
-
-#endif
-
-DEFINE_SEMAPHORE(msm_fb_ioctl_ppp_sem);
-DEFINE_MUTEX(msm_fb_ioctl_lut_sem);
-DEFINE_MUTEX(msm_fb_ioctl_hist_sem);
-
-/* Set color conversion matrix from user space */
-
-#ifndef CONFIG_FB_MSM_MDP40
-static void msmfb_set_color_conv(struct mdp_ccs *p)
-{
- int i;
-
- if (p->direction == MDP_CCS_RGB2YUV) {
- /* MDP cmd block enable */
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
-
- /* RGB->YUV primary forward matrix */
- for (i = 0; i < MDP_CCS_SIZE; i++)
- writel(p->ccs[i], MDP_CSC_PFMVn(i));
-
- #ifdef CONFIG_FB_MSM_MDP31
- for (i = 0; i < MDP_BV_SIZE; i++)
- writel(p->bv[i], MDP_CSC_POST_BV2n(i));
- #endif
-
- /* MDP cmd block disable */
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
- } else {
- /* MDP cmd block enable */
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
-
- /* YUV->RGB primary reverse matrix */
- for (i = 0; i < MDP_CCS_SIZE; i++)
- writel(p->ccs[i], MDP_CSC_PRMVn(i));
- for (i = 0; i < MDP_BV_SIZE; i++)
- writel(p->bv[i], MDP_CSC_PRE_BV1n(i));
-
- /* MDP cmd block disable */
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
- }
-}
-#endif
-
-
-static int msm_fb_ioctl(struct fb_info *info, unsigned int cmd,
- unsigned long arg)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- void __user *argp = (void __user *)arg;
- struct fb_cursor cursor;
- struct fb_cmap cmap;
- struct mdp_histogram hist;
-#ifndef CONFIG_FB_MSM_MDP40
- struct mdp_ccs ccs_matrix;
-#endif
- struct mdp_page_protection fb_page_protection;
- int ret = 0;
-
- if (!mfd->op_enable)
- return -EPERM;
-
- switch (cmd) {
-#ifdef CONFIG_FB_MSM_OVERLAY
- case MSMFB_OVERLAY_GET:
- down(&msm_fb_ioctl_ppp_sem);
- ret = msmfb_overlay_get(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
- break;
- case MSMFB_OVERLAY_SET:
- down(&msm_fb_ioctl_ppp_sem);
- ret = msmfb_overlay_set(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
- break;
- case MSMFB_OVERLAY_UNSET:
- down(&msm_fb_ioctl_ppp_sem);
- ret = msmfb_overlay_unset(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
- break;
- case MSMFB_OVERLAY_PLAY:
- down(&msm_fb_ioctl_ppp_sem);
- ret = msmfb_overlay_play(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
- break;
-#endif
- case MSMFB_BLIT:
- down(&msm_fb_ioctl_ppp_sem);
-#ifdef CONFIG_MDP_PPP_ASYNC_OP
- ret = msmfb_async_blit(info, argp);
- mdp_ppp_wait(); /* Wait for all blits to be finished. */
-#else
- ret = msmfb_blit(info, argp);
-#endif
- up(&msm_fb_ioctl_ppp_sem);
-
- break;
-
- /* Ioctl for setting ccs matrix from user space */
- case MSMFB_SET_CCS_MATRIX:
-#ifndef CONFIG_FB_MSM_MDP40
- ret = copy_from_user(&ccs_matrix, argp, sizeof(ccs_matrix));
- if (ret) {
- printk(KERN_ERR
- "%s:MSMFB_SET_CCS_MATRIX ioctl failed \n",
- __func__);
- return ret;
- }
-
- down(&msm_fb_ioctl_ppp_sem);
- if (ccs_matrix.direction == MDP_CCS_RGB2YUV)
- mdp_ccs_rgb2yuv = ccs_matrix;
- else
- mdp_ccs_yuv2rgb = ccs_matrix;
-
- msmfb_set_color_conv(&ccs_matrix) ;
- up(&msm_fb_ioctl_ppp_sem);
-#else
- ret = -EINVAL;
-#endif
-
- break;
-
- /* Ioctl for getting ccs matrix to user space */
- case MSMFB_GET_CCS_MATRIX:
-#ifndef CONFIG_FB_MSM_MDP40
- ret = copy_from_user(&ccs_matrix, argp, sizeof(ccs_matrix)) ;
- if (ret) {
- printk(KERN_ERR
- "%s:MSMFB_GET_CCS_MATRIX ioctl failed \n",
- __func__);
- return ret;
- }
-
- down(&msm_fb_ioctl_ppp_sem);
- if (ccs_matrix.direction == MDP_CCS_RGB2YUV)
- ccs_matrix = mdp_ccs_rgb2yuv;
- else
- ccs_matrix = mdp_ccs_yuv2rgb;
-
- ret = copy_to_user(argp, &ccs_matrix, sizeof(ccs_matrix));
-
- if (ret) {
- printk(KERN_ERR
- "%s:MSMFB_GET_CCS_MATRIX ioctl failed \n",
- __func__);
- return ret ;
- }
- up(&msm_fb_ioctl_ppp_sem);
-#else
- ret = -EINVAL;
-#endif
-
- break;
-
-#ifdef CONFIG_MDP_PPP_ASYNC_OP
- case MSMFB_ASYNC_BLIT:
- down(&msm_fb_ioctl_ppp_sem);
- ret = msmfb_async_blit(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
- break;
-
- case MSMFB_BLIT_FLUSH:
- down(&msm_fb_ioctl_ppp_sem);
- mdp_ppp_wait();
- up(&msm_fb_ioctl_ppp_sem);
- break;
-#endif
-
- case MSMFB_GRP_DISP:
-#ifdef CONFIG_FB_MSM_MDP22
- {
- unsigned long grp_id;
-
- ret = copy_from_user(&grp_id, argp, sizeof(grp_id));
- if (ret)
- return ret;
-
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
- writel(grp_id, MDP_FULL_BYPASS_WORD43);
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF,
- FALSE);
- break;
- }
-#else
- return -EFAULT;
-#endif
- case MSMFB_SUSPEND_SW_REFRESHER:
- if (!mfd->panel_power_on)
- return -EPERM;
-
- mfd->sw_refreshing_enable = FALSE;
- ret = msm_fb_stop_sw_refresher(mfd);
- break;
-
- case MSMFB_RESUME_SW_REFRESHER:
- if (!mfd->panel_power_on)
- return -EPERM;
-
- mfd->sw_refreshing_enable = TRUE;
- ret = msm_fb_resume_sw_refresher(mfd);
- break;
-
- case MSMFB_CURSOR:
- ret = copy_from_user(&cursor, argp, sizeof(cursor));
- if (ret)
- return ret;
-
- ret = msm_fb_cursor(info, &cursor);
- break;
-
- case MSMFB_SET_LUT:
- ret = copy_from_user(&cmap, argp, sizeof(cmap));
- if (ret)
- return ret;
-
- mutex_lock(&msm_fb_ioctl_lut_sem);
- ret = msm_fb_set_lut(&cmap, info);
- mutex_unlock(&msm_fb_ioctl_lut_sem);
- break;
-
- case MSMFB_HISTOGRAM:
- if (!mfd->do_histogram)
- return -ENODEV;
-
- ret = copy_from_user(&hist, argp, sizeof(hist));
- if (ret)
- return ret;
-
- mutex_lock(&msm_fb_ioctl_hist_sem);
- ret = mfd->do_histogram(info, &hist);
- mutex_unlock(&msm_fb_ioctl_hist_sem);
- break;
-
- case MSMFB_GET_PAGE_PROTECTION:
- fb_page_protection.page_protection
- = mfd->mdp_fb_page_protection;
- ret = copy_to_user(argp, &fb_page_protection,
- sizeof(fb_page_protection));
- if (ret)
- return ret;
- break;
-
- case MSMFB_SET_PAGE_PROTECTION:
-#ifdef CONFIG_ARCH_QSD8X50
- ret = copy_from_user(&fb_page_protection, argp,
- sizeof(fb_page_protection));
- if (ret)
- return ret;
-
- /* Validate the proposed page protection settings. */
- switch (fb_page_protection.page_protection) {
- case MDP_FB_PAGE_PROTECTION_NONCACHED:
- case MDP_FB_PAGE_PROTECTION_WRITECOMBINE:
- case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE:
- /* Write-back cache (read allocate) */
- case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE:
- /* Write-back cache (write allocate) */
- case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE:
- mfd->mdp_fb_page_protection =
- fb_page_protection.page_protection;
- break;
- default:
- ret = -EINVAL;
- break;
- }
-#else
- /*
- * Don't allow caching until 7k DMA cache operations are
- * available.
- */
- ret = -EINVAL;
-#endif
- break;
-
- default:
- MSM_FB_INFO("MDP: unknown ioctl (cmd=%d) received!\n", cmd);
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static int msm_fb_register_driver(void)
-{
- return platform_driver_register(&msm_fb_driver);
-}
-
-void msm_fb_add_device(struct platform_device *pdev)
-{
- struct msm_fb_panel_data *pdata;
- struct platform_device *this_dev = NULL;
- struct fb_info *fbi;
- struct msm_fb_data_type *mfd = NULL;
- u32 type, id, fb_num;
-
- if (!pdev)
- return;
- id = pdev->id;
-
- pdata = pdev->dev.platform_data;
- if (!pdata)
- return;
- type = pdata->panel_info.type;
- fb_num = pdata->panel_info.fb_num;
-
- if (fb_num <= 0)
- return;
-
- if (fbi_list_index >= MAX_FBI_LIST) {
- printk(KERN_ERR "msm_fb: no more framebuffer info list!\n");
- return;
- }
- /*
- * alloc panel device data
- */
- this_dev = msm_fb_device_alloc(pdata, type, id);
-
- if (!this_dev) {
- printk(KERN_ERR
- "%s: msm_fb_device_alloc failed!\n", __func__);
- return;
- }
-
- /*
- * alloc framebuffer info + par data
- */
- fbi = framebuffer_alloc(sizeof(struct msm_fb_data_type), NULL);
- if (fbi == NULL) {
- platform_device_put(this_dev);
- printk(KERN_ERR "msm_fb: can't alloca framebuffer info data!\n");
- return;
- }
-
- mfd = (struct msm_fb_data_type *)fbi->par;
- mfd->key = MFD_KEY;
- mfd->fbi = fbi;
- mfd->panel.type = type;
- mfd->panel.id = id;
- mfd->fb_page = fb_num;
- mfd->index = fbi_list_index;
- mfd->mdp_fb_page_protection = MDP_FB_PAGE_PROTECTION_WRITECOMBINE;
-
- /* link to the latest pdev */
- mfd->pdev = this_dev;
-
- mfd_list[mfd_list_index++] = mfd;
- fbi_list[fbi_list_index++] = fbi;
-
- /*
- * set driver data
- */
- platform_set_drvdata(this_dev, mfd);
-
- if (platform_device_add(this_dev)) {
- printk(KERN_ERR "msm_fb: platform_device_add failed!\n");
- platform_device_put(this_dev);
- framebuffer_release(fbi);
- fbi_list_index--;
- return;
- }
-}
-EXPORT_SYMBOL(msm_fb_add_device);
-
-int __init msm_fb_init(void)
-{
- int rc = -ENODEV;
-
- if (msm_fb_register_driver())
- return rc;
-
-#ifdef MSM_FB_ENABLE_DBGFS
- {
- struct dentry *root;
-
- if ((root = msm_fb_get_debugfs_root()) != NULL) {
- msm_fb_debugfs_file_create(root,
- "msm_fb_msg_printing_level",
- (u32 *) &msm_fb_msg_level);
- msm_fb_debugfs_file_create(root,
- "mddi_msg_printing_level",
- (u32 *) &mddi_msg_level);
- msm_fb_debugfs_file_create(root, "msm_fb_debug_enabled",
- (u32 *) &msm_fb_debug_enabled);
- }
- }
-#endif
-
- return 0;
-}
-
-module_init(msm_fb_init);