mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
1299d2f5a3
This patch will queue multiple surfaces and commit those surfaces into mdp at same instance so that surfaces will be blended and displayed at same time. Hardware vsync event is delivered to the user space frame work via uevent. Both queue and commit are controlled by frame work and synchonized with vsync event. Therefore frame rate will match with vsync rate. Change-Id: If630a6d94fd38483ee313f575b1a71ed8bd65a52 Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
194 lines
4.5 KiB
C
194 lines
4.5 KiB
C
/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 and
|
|
* only version 2 as published by the Free Software Foundation.
|
|
*
|
|
* 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 "msm_fb.h"
|
|
#include "mipi_dsi.h"
|
|
#include "mipi_orise.h"
|
|
#include "mdp4.h"
|
|
|
|
|
|
static struct mipi_dsi_panel_platform_data *mipi_orise_pdata;
|
|
|
|
static struct dsi_buf orise_tx_buf;
|
|
static struct dsi_buf orise_rx_buf;
|
|
|
|
static char enter_sleep[2] = {0x10, 0x00}; /* DTYPE_DCS_WRITE */
|
|
static char exit_sleep[2] = {0x11, 0x00}; /* DTYPE_DCS_WRITE */
|
|
static char display_off[2] = {0x28, 0x00}; /* DTYPE_DCS_WRITE */
|
|
static char display_on[2] = {0x29, 0x00}; /* DTYPE_DCS_WRITE */
|
|
|
|
static struct dsi_cmd_desc orise_video_on_cmds[] = {
|
|
{DTYPE_DCS_WRITE, 1, 0, 0, 10,
|
|
sizeof(exit_sleep), exit_sleep},
|
|
{DTYPE_DCS_WRITE, 1, 0, 0, 10,
|
|
sizeof(display_on), display_on},
|
|
};
|
|
|
|
static struct dsi_cmd_desc orise_cmd_on_cmds[] = {
|
|
{DTYPE_DCS_WRITE, 1, 0, 0, 10,
|
|
sizeof(exit_sleep), exit_sleep},
|
|
{DTYPE_DCS_WRITE, 1, 0, 0, 10,
|
|
sizeof(display_on), display_on},
|
|
};
|
|
|
|
static struct dsi_cmd_desc orise_display_off_cmds[] = {
|
|
{DTYPE_DCS_WRITE, 1, 0, 0, 10,
|
|
sizeof(display_off), display_off},
|
|
{DTYPE_DCS_WRITE, 1, 0, 0, 120,
|
|
sizeof(enter_sleep), enter_sleep}
|
|
};
|
|
|
|
static int mipi_orise_lcd_on(struct platform_device *pdev)
|
|
{
|
|
struct msm_fb_data_type *mfd;
|
|
struct mipi_panel_info *mipi;
|
|
struct msm_panel_info *pinfo;
|
|
|
|
mfd = platform_get_drvdata(pdev);
|
|
if (!mfd)
|
|
return -ENODEV;
|
|
if (mfd->key != MFD_KEY)
|
|
return -EINVAL;
|
|
|
|
pinfo = &mfd->panel_info;
|
|
mipi = &mfd->panel_info.mipi;
|
|
|
|
if (mipi->mode == DSI_VIDEO_MODE) {
|
|
mipi_dsi_cmds_tx(&orise_tx_buf, orise_video_on_cmds,
|
|
ARRAY_SIZE(orise_video_on_cmds));
|
|
} else {
|
|
mipi_dsi_cmds_tx(&orise_tx_buf, orise_cmd_on_cmds,
|
|
ARRAY_SIZE(orise_cmd_on_cmds));
|
|
|
|
mipi_dsi_cmd_bta_sw_trigger(); /* clean up ack_err_status */
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mipi_orise_lcd_off(struct platform_device *pdev)
|
|
{
|
|
struct msm_fb_data_type *mfd;
|
|
|
|
mfd = platform_get_drvdata(pdev);
|
|
|
|
if (!mfd)
|
|
return -ENODEV;
|
|
if (mfd->key != MFD_KEY)
|
|
return -EINVAL;
|
|
|
|
mipi_dsi_cmds_tx(&orise_tx_buf, orise_display_off_cmds,
|
|
ARRAY_SIZE(orise_display_off_cmds));
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
static int __devinit mipi_orise_lcd_probe(struct platform_device *pdev)
|
|
{
|
|
struct msm_fb_data_type *mfd;
|
|
struct mipi_panel_info *mipi;
|
|
struct platform_device *current_pdev;
|
|
static struct mipi_dsi_phy_ctrl *phy_settings;
|
|
|
|
if (pdev->id == 0) {
|
|
mipi_orise_pdata = pdev->dev.platform_data;
|
|
|
|
if (mipi_orise_pdata
|
|
&& mipi_orise_pdata->phy_ctrl_settings) {
|
|
phy_settings = (mipi_orise_pdata->phy_ctrl_settings);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
current_pdev = msm_fb_add_device(pdev);
|
|
|
|
if (current_pdev) {
|
|
mfd = platform_get_drvdata(current_pdev);
|
|
if (!mfd)
|
|
return -ENODEV;
|
|
if (mfd->key != MFD_KEY)
|
|
return -EINVAL;
|
|
|
|
mipi = &mfd->panel_info.mipi;
|
|
|
|
if (phy_settings != NULL)
|
|
mipi->dsi_phy_db = phy_settings;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static struct platform_driver this_driver = {
|
|
.probe = mipi_orise_lcd_probe,
|
|
.driver = {
|
|
.name = "mipi_orise",
|
|
},
|
|
};
|
|
|
|
static struct msm_fb_panel_data orise_panel_data = {
|
|
.on = mipi_orise_lcd_on,
|
|
.off = mipi_orise_lcd_off,
|
|
};
|
|
|
|
static int ch_used[3];
|
|
|
|
int mipi_orise_device_register(struct msm_panel_info *pinfo,
|
|
u32 channel, u32 panel)
|
|
{
|
|
struct platform_device *pdev = NULL;
|
|
int ret;
|
|
|
|
if ((channel >= 3) || ch_used[channel])
|
|
return -ENODEV;
|
|
|
|
ch_used[channel] = TRUE;
|
|
|
|
pdev = platform_device_alloc("mipi_orise", (panel << 8)|channel);
|
|
if (!pdev)
|
|
return -ENOMEM;
|
|
|
|
orise_panel_data.panel_info = *pinfo;
|
|
|
|
ret = platform_device_add_data(pdev, &orise_panel_data,
|
|
sizeof(orise_panel_data));
|
|
if (ret) {
|
|
printk(KERN_ERR
|
|
"%s: platform_device_add_data failed!\n", __func__);
|
|
goto err_device_put;
|
|
}
|
|
|
|
ret = platform_device_add(pdev);
|
|
if (ret) {
|
|
printk(KERN_ERR
|
|
"%s: platform_device_register failed!\n", __func__);
|
|
goto err_device_put;
|
|
}
|
|
|
|
return 0;
|
|
|
|
err_device_put:
|
|
platform_device_put(pdev);
|
|
return ret;
|
|
}
|
|
|
|
static int __init mipi_orise_lcd_init(void)
|
|
{
|
|
mipi_dsi_buf_alloc(&orise_tx_buf, DSI_BUF_SIZE);
|
|
mipi_dsi_buf_alloc(&orise_rx_buf, DSI_BUF_SIZE);
|
|
|
|
return platform_driver_register(&this_driver);
|
|
}
|
|
|
|
module_init(mipi_orise_lcd_init);
|