123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- /* Copyright (c) 2012, The Linux Foundation. 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/kernel.h>
- #include <linux/sched.h>
- #include <linux/time.h>
- #include <linux/init.h>
- #include <linux/interrupt.h>
- #include <linux/spinlock.h>
- #include <linux/hrtimer.h>
- #include <linux/clk.h>
- #include <linux/io.h>
- #include <linux/debugfs.h>
- #include <linux/delay.h>
- #include <linux/mutex.h>
- #include <linux/pm_runtime.h>
- #include <linux/regulator/consumer.h>
- #include <linux/semaphore.h>
- #include <linux/uaccess.h>
- #include <asm/system.h>
- #include <asm/mach-types.h>
- #include <mach/clk.h>
- #include <mach/hardware.h>
- #include "msm_fb.h"
- struct mdp_ccs mdp_ccs_rgb2yuv;
- struct mdp_ccs mdp_ccs_yuv2rgb;
- static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
- static int pdev_list_cnt;
- static int ebi2_host_resource_initialized;
- static struct msm_panel_common_pdata *ebi2_host_pdata;
- static int ebi2_host_probe(struct platform_device *pdev);
- static int ebi2_host_remove(struct platform_device *pdev);
- static int ebi2_host_runtime_suspend(struct device *dev)
- {
- dev_dbg(dev, "pm_runtime: suspending...\n");
- return 0;
- }
- static int ebi2_host_runtime_resume(struct device *dev)
- {
- dev_dbg(dev, "pm_runtime: resuming...\n");
- return 0;
- }
- static const struct dev_pm_ops ebi2_host_dev_pm_ops = {
- .runtime_suspend = ebi2_host_runtime_suspend,
- .runtime_resume = ebi2_host_runtime_resume,
- };
- static struct platform_driver ebi2_host_driver = {
- .probe = ebi2_host_probe,
- .remove = ebi2_host_remove,
- .shutdown = NULL,
- .driver = {
- /*
- * Simulate mdp hw
- */
- .name = "mdp",
- .pm = &ebi2_host_dev_pm_ops,
- },
- };
- void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
- boolean isr)
- {
- return;
- }
- int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req)
- {
- return 0;
- }
- int mdp_start_histogram(struct fb_info *info)
- {
- return 0;
- }
- int mdp_stop_histogram(struct fb_info *info)
- {
- return 0;
- }
- void mdp_refresh_screen(unsigned long data)
- {
- return;
- }
- static int ebi2_host_off(struct platform_device *pdev)
- {
- int ret;
- ret = panel_next_off(pdev);
- return ret;
- }
- static int ebi2_host_on(struct platform_device *pdev)
- {
- int ret;
- ret = panel_next_on(pdev);
- return ret;
- }
- static int ebi2_host_probe(struct platform_device *pdev)
- {
- struct platform_device *msm_fb_dev = NULL;
- struct msm_fb_data_type *mfd;
- struct msm_fb_panel_data *pdata = NULL;
- int rc;
- if ((pdev->id == 0) && (pdev->num_resources > 0)) {
- ebi2_host_pdata = pdev->dev.platform_data;
- ebi2_host_resource_initialized = 1;
- return 0;
- }
- ebi2_host_resource_initialized = 1;
- if (!ebi2_host_resource_initialized)
- return -EPERM;
- mfd = 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;
- msm_fb_dev = platform_device_alloc("msm_fb", pdev->id);
- if (!msm_fb_dev)
- return -ENOMEM;
- /* link to the latest pdev */
- mfd->pdev = msm_fb_dev;
- if (ebi2_host_pdata) {
- mfd->mdp_rev = ebi2_host_pdata->mdp_rev;
- mfd->mem_hid = ebi2_host_pdata->mem_hid;
- }
- /* add panel data */
- if (platform_device_add_data
- (msm_fb_dev, pdev->dev.platform_data,
- sizeof(struct msm_fb_panel_data))) {
- pr_err("ebi2_host_probe: platform_device_add_data failed!\n");
- rc = -ENOMEM;
- goto ebi2_host_probe_err;
- }
- /* data chain */
- pdata = msm_fb_dev->dev.platform_data;
- pdata->on = ebi2_host_on;
- pdata->off = ebi2_host_off;
- pdata->next = pdev;
- /* set driver data */
- platform_set_drvdata(msm_fb_dev, mfd);
- rc = platform_device_add(msm_fb_dev);
- if (rc)
- goto ebi2_host_probe_err;
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
- pdev_list[pdev_list_cnt++] = pdev;
- return 0;
- ebi2_host_probe_err:
- platform_device_put(msm_fb_dev);
- return rc;
- }
- void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty,
- boolean sync)
- {
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- struct fb_info *fbi = mfd->fbi;
- struct msm_panel_info *panel_info = &mfd->panel_info;
- MDPIBUF *iBuf;
- int bpp = info->var.bits_per_pixel / 8;
- int yres, remainder;
- if (panel_info->mode2_yres != 0) {
- yres = panel_info->mode2_yres;
- remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
- } else {
- yres = panel_info->yres;
- remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
- }
- if (!remainder)
- remainder = PAGE_SIZE;
- down(&mfd->sem);
- iBuf = &mfd->ibuf;
- /* use virtual address */
- iBuf->buf = (uint8 *) fbi->screen_base;
- if (fbi->var.yoffset < yres) {
- iBuf->buf += fbi->var.xoffset * bpp;
- } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
- iBuf->buf += fbi->var.xoffset * bpp + yres *
- fbi->fix.line_length + PAGE_SIZE - remainder;
- } else {
- iBuf->buf += fbi->var.xoffset * bpp + 2 * yres *
- fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
- }
- iBuf->ibuf_width = info->var.xres_virtual;
- iBuf->bpp = bpp;
- iBuf->vsync_enable = sync;
- if (dirty) {
- /*
- * ToDo: dirty region check inside var.xoffset+xres
- * <-> var.yoffset+yres
- */
- iBuf->dma_x = dirty->xoffset % info->var.xres;
- iBuf->dma_y = dirty->yoffset % info->var.yres;
- iBuf->dma_w = dirty->width;
- iBuf->dma_h = dirty->height;
- } else {
- iBuf->dma_x = 0;
- iBuf->dma_y = 0;
- iBuf->dma_w = info->var.xres;
- iBuf->dma_h = info->var.yres;
- }
- mfd->ibuf_flushed = FALSE;
- up(&mfd->sem);
- }
- void mdp_dma_pan_update(struct fb_info *info)
- {
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- MDPIBUF *iBuf;
- int i, j;
- uint32 data;
- uint8 *src;
- struct msm_fb_panel_data *pdata =
- (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
- struct fb_info *fbi = mfd->fbi;
- iBuf = &mfd->ibuf;
- invalidate_caches((unsigned long)fbi->screen_base,
- (unsigned long)info->fix.smem_len,
- (unsigned long)info->fix.smem_start);
- pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w,
- iBuf->dma_h);
- for (i = 0; i < iBuf->dma_h; i++) {
- src = iBuf->buf + (fbi->fix.line_length * (iBuf->dma_y + i))
- + (iBuf->dma_x * iBuf->bpp);
- for (j = 0; j < iBuf->dma_w; j++) {
- data = (uint32)(*src++ >> 2) << 12;
- data |= (uint32)(*src++ >> 2) << 6;
- data |= (uint32)(*src++ >> 2);
- data = ((data&0x1FF)<<16) | ((data&0x3FE00)>>9);
- outpdw(mfd->data_port, data);
- }
- }
- }
- static int ebi2_host_remove(struct platform_device *pdev)
- {
- pm_runtime_disable(&pdev->dev);
- return 0;
- }
- static int ebi2_host_register_driver(void)
- {
- return platform_driver_register(&ebi2_host_driver);
- }
- static int __init ebi2_host_driver_init(void)
- {
- int ret;
- ret = ebi2_host_register_driver();
- if (ret) {
- pr_err("ebi2_host_register_driver() failed!\n");
- return ret;
- }
- return 0;
- }
- module_init(ebi2_host_driver_init);
|