Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: dazjo/android_kernel_zte_msm7x27
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: e9eef05a80c7
Choose a base ref
...
head repository: dazjo/android_kernel_zte_msm7x27
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f2784b9134b9
Choose a head ref
  • 4 commits
  • 6 files changed
  • 3 contributors

Commits on Feb 1, 2013

  1. msm_fb: vsync events for legacy MDP 3.00 targets

    Pieced together from current code in CAF. This is very specific to
    MDP 3.00 targets that use the LCDC display controller, and it might
    break horribly and badly on anything else.
    
    Change-Id: I2b7086a17fd22a04d61d7962f4ea98ab1af00442
    grigorig authored and LalitMaganti committed Feb 1, 2013

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    aa26384 View commit details
  2. msm_fb: fixup MDP 3.00 vsync events

    This is the sum of several fixes and improvements to the MDP 3.00
    vsync event code.
    
    Make sure to never switch off MDP command clock twice; add timeout
    to the vsync wait completion and interpret the return value of the
    completion function correctly.
    
    Change-Id: Ic0a699c98a90e896a9ba185793cc7d9187bb6ec1
    grigorig authored and LalitMaganti committed Feb 1, 2013
    Copy the full SHA
    5667580 View commit details
  3. msm: display: fb blend setting via MSMFB_METADATA_SET ioctl

    MSMFB_METADATA_SET ioctl is added for the fb user to pass
    in additional infomation rather than using reserved
    fields.
    User can set pre-multiplied alpha for the frame buffer via this
    ioctl, overlay blend setting will take this into account.
    
    Change-Id: Ic2f6236d84691fb03174ec479874c6928489ea30
    Ken Zhang authored and LalitMaganti committed Feb 1, 2013
    Copy the full SHA
    3b04157 View commit details

Commits on Feb 5, 2013

  1. Copy the full SHA
    f2784b9 View commit details
Showing with 270 additions and 4 deletions.
  1. +92 −4 drivers/video/msm/mdp.c
  2. +23 −0 drivers/video/msm/mdp.h
  3. +71 −0 drivers/video/msm/mdp_dma_lcdc.c
  4. +58 −0 drivers/video/msm/msm_fb.c
  5. +5 −0 drivers/video/msm/msm_fb.h
  6. +21 −0 include/linux/msm_mdp.h
96 changes: 92 additions & 4 deletions drivers/video/msm/mdp.c
Original file line number Diff line number Diff line change
@@ -69,6 +69,8 @@ uint32 mdp_lcdc_underflow_cnt;
boolean mdp_current_clk_on = FALSE;
boolean mdp_is_in_isr = FALSE;

struct vsync vsync_cntrl;

/*
* legacy mdp_in_processing is only for DMA2-MDDI
* this applies to DMA2 block only
@@ -867,6 +869,12 @@ static int mdp_do_histogram(struct fb_info *info, struct mdp_histogram *hist)
}
#endif

/* vsync_isr_handler: Called from isr context*/
static void vsync_isr_handler(void)
{
vsync_cntrl.vsync_time = ktime_get();
}

/* Returns < 0 on error, 0 on timeout, or > 0 on successful wait */

int mdp_ppp_pipe_wait(void)
@@ -1205,6 +1213,8 @@ irqreturn_t mdp_isr(int irq, void *ptr)
{
uint32 hist_interrupt, mdp_interrupt = 0;
struct mdp_dma_data *dma;
int vsync_isr, disabled_clocks;
unsigned long flag;

mdp_is_in_isr = TRUE;
do {
@@ -1221,6 +1231,31 @@ irqreturn_t mdp_isr(int irq, void *ptr)
if (!mdp_interrupt)
break;

/*Primary Vsync interrupt*/
if (mdp_interrupt & MDP_PRIM_RDPTR) {
spin_lock_irqsave(&mdp_spin_lock, flag);
vsync_isr = vsync_cntrl.vsync_irq_enabled;
disabled_clocks = vsync_cntrl.disabled_clocks;
if ((!vsync_isr && !vsync_cntrl.disabled_clocks)
|| (!vsync_isr && vsync_cntrl.vsync_dma_enabled)) {
mdp_intr_mask &= ~MDP_PRIM_RDPTR;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
mdp_disable_irq_nosync(MDP_VSYNC_TERM);
vsync_cntrl.disabled_clocks = 1;
} else if (vsync_isr) {
vsync_isr_handler();
}
vsync_cntrl.vsync_dma_enabled = 0;
spin_unlock_irqrestore(&mdp_spin_lock, flag);

complete(&vsync_cntrl.vsync_comp);
if (!vsync_isr && !disabled_clocks)
mdp_pipe_ctrl(MDP_CMD_BLOCK,
MDP_BLOCK_POWER_OFF, TRUE);

complete_all(&vsync_cntrl.vsync_wait);
}

/* DMA3 TV-Out Start */
if (mdp_interrupt & TV_OUT_DMA3_START) {
/* let's disable TV out interrupt */
@@ -1266,17 +1301,34 @@ irqreturn_t mdp_isr(int irq, void *ptr)
__mdp_histogram_reset();
}


/* LCDC Frame Start */
if (mdp_interrupt & LCDC_FRAME_START) {
/* let's disable LCDC interrupt */
mdp_intr_mask &= ~LCDC_FRAME_START;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);

dma = &dma2_data;
spin_lock_irqsave(&mdp_spin_lock, flag);
vsync_isr = vsync_cntrl.vsync_irq_enabled;
disabled_clocks = vsync_cntrl.disabled_clocks;
/* let's disable LCDC interrupt */
if (dma->waiting) {
dma->waiting = FALSE;
complete(&dma->comp);
}

if (!vsync_isr && !disabled_clocks) {
mdp_intr_mask &= ~LCDC_FRAME_START;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
mdp_disable_irq_nosync(MDP_VSYNC_TERM);
vsync_cntrl.disabled_clocks = 1;
} else {
vsync_isr_handler();
}
spin_unlock_irqrestore(&mdp_spin_lock, flag);

if (!vsync_isr && !disabled_clocks)
mdp_pipe_ctrl(MDP_CMD_BLOCK,
MDP_BLOCK_POWER_OFF, TRUE);

complete_all(&vsync_cntrl.vsync_wait);
}

/* DMA2 LCD-Out Complete */
@@ -1376,6 +1428,7 @@ static void mdp_drv_init(void)
dma2_data.busy = FALSE;
dma2_data.waiting = FALSE;
init_completion(&dma2_data.comp);
init_completion(&vsync_cntrl.vsync_comp);
init_MUTEX(&dma2_data.mutex);
mutex_init(&dma2_data.ov_mutex);

@@ -1410,6 +1463,9 @@ static void mdp_drv_init(void)
for (i = 0; i < MDP_MAX_BLOCK; i++) {
atomic_set(&mdp_block_power_cnt[i], 0);
}
vsync_cntrl.disabled_clocks = 1;
init_completion(&vsync_cntrl.vsync_wait);
atomic_set(&vsync_cntrl.vsync_resume, 1);

#ifdef MSM_FB_ENABLE_DBGFS
{
@@ -1496,6 +1552,10 @@ static int mdp_off(struct platform_device *pdev)

mdp_histogram_ctrl(FALSE);

atomic_set(&vsync_cntrl.suspend, 1);
atomic_set(&vsync_cntrl.vsync_resume, 0);
complete_all(&vsync_cntrl.vsync_wait);

mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
ret = panel_next_off(pdev);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
@@ -1830,6 +1890,7 @@ static int mdp_probe(struct platform_device *pdev)
/* link to the latest pdev */
mfd->pdev = msm_fb_dev;
mfd->mdp_rev = mdp_rev;
mfd->vsync_init = NULL;

if (mdp_pdata) {
if (mdp_pdata->cont_splash_enabled) {
@@ -2059,6 +2120,9 @@ static int mdp_probe(struct platform_device *pdev)
}
#else
mfd->dma = &dma2_data;
mfd->vsync_init = mdp_dma_lcdc_vsync_init;
mfd->vsync_ctrl = mdp_dma_lcdc_vsync_ctrl;
mfd->vsync_show = mdp_dma_lcdc_show_event;
spin_lock_irqsave(&mdp_spin_lock, flag);
mdp_intr_mask &= ~MDP_DMA_P_DONE;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
@@ -2148,6 +2212,30 @@ static int mdp_probe(struct platform_device *pdev)

pdev_list[pdev_list_cnt++] = pdev;
mdp4_extn_disp = 0;

if (mfd->vsync_init != NULL) {
mfd->vsync_init(0);

if (!mfd->vsync_sysfs_created) {
mfd->dev_attr.attr.name = "vsync_event";
mfd->dev_attr.attr.mode = S_IRUGO;
mfd->dev_attr.show = mfd->vsync_show;
sysfs_attr_init(&mfd->dev_attr.attr);

rc = sysfs_create_file(&mfd->fbi->dev->kobj,
&mfd->dev_attr.attr);
if (rc) {
pr_err("%s: sysfs creation failed, ret=%d\n",
__func__, rc);
return rc;
}

kobject_uevent(&mfd->fbi->dev->kobj, KOBJ_ADD);
pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__);
mfd->vsync_sysfs_created = 1;
}
}

return 0;

mdp_probe_err:
23 changes: 23 additions & 0 deletions drivers/video/msm/mdp.h
Original file line number Diff line number Diff line change
@@ -105,6 +105,22 @@ extern struct mdp_ccs mdp_ccs_yuv2rgb ;
extern struct mdp_ccs mdp_ccs_rgb2yuv ;
extern unsigned char hdmi_prim_display;

struct vsync {
ktime_t vsync_time;
struct completion vsync_comp;
struct device *dev;
struct work_struct vsync_work;
int vsync_irq_enabled;
int vsync_dma_enabled;
int disabled_clocks;
struct completion vsync_wait;
atomic_t suspend;
atomic_t vsync_resume;
int sysfs_created;
};

extern struct vsync vsync_cntrl;

/*
* MDP Image Structure
*/
@@ -268,6 +284,7 @@ struct mdp_hist_lut_info {
#endif
#define MDP_HISTOGRAM_TERM 0x80
#define MDP_OVERLAY2_TERM 0x100
#define MDP_VSYNC_TERM 0x1000

#define ACTIVE_START_X_EN BIT(31)
#define ACTIVE_START_Y_EN BIT(31)
@@ -287,6 +304,7 @@ struct mdp_hist_lut_info {
#define MDP_PPP_DONE BIT(0)
#define TV_OUT_DMA3_DONE BIT(6)
#define TV_ENC_UNDERRUN BIT(7)
#define MDP_PRIM_RDPTR BIT(8)
#define TV_OUT_DMA3_START BIT(13)
#define MDP_HIST_DONE BIT(20)

@@ -755,6 +773,11 @@ static inline int mdp_bus_scale_update_request(uint32_t index)
return 0;
}
#endif
void mdp_dma_lcdc_vsync_init(int cndx);
void mdp_dma_vsync_ctrl(int enable);
void mdp_dma_lcdc_vsync_ctrl(int enable);
ssize_t mdp_dma_lcdc_show_event(struct device *dev,
struct device_attribute *attr, char *buf);

#ifdef MDP_HW_VSYNC
void mdp_hw_vsync_clk_enable(struct msm_fb_data_type *mfd);
71 changes: 71 additions & 0 deletions drivers/video/msm/mdp_dma_lcdc.c
Original file line number Diff line number Diff line change
@@ -61,6 +61,32 @@ int first_pixel_start_x;
int first_pixel_start_y;
static bool firstupdate = TRUE; ////LCD_LUYA_20100610_01

ssize_t mdp_dma_lcdc_show_event(struct device *dev,
struct device_attribute *attr, char *buf)
{
ssize_t ret = 0;

if (atomic_read(&vsync_cntrl.suspend) > 0 ||
atomic_read(&vsync_cntrl.vsync_resume) == 0)
return 0;

INIT_COMPLETION(vsync_cntrl.vsync_wait);

ret = wait_for_completion_interruptible_timeout(&vsync_cntrl.vsync_wait,
msecs_to_jiffies(VSYNC_PERIOD * 4));
if (ret <= 0) {
ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu",
ktime_to_ns(ktime_get()));
buf[strlen(buf) + 1] = '\0';
return ret;
}

ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu",
ktime_to_ns(vsync_cntrl.vsync_time));
buf[strlen(buf) + 1] = '\0';
return ret;
}

int mdp_lcdc_on(struct platform_device *pdev)
{
int lcdc_width;
@@ -116,6 +142,9 @@ int mdp_lcdc_on(struct platform_device *pdev)
fbi = mfd->fbi;
var = &fbi->var;

vsync_cntrl.dev = mfd->fbi->dev;
atomic_set(&vsync_cntrl.suspend, 0);

/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);

@@ -357,12 +386,54 @@ int mdp_lcdc_off(struct platform_device *pdev)

ret = panel_next_off(pdev);

atomic_set(&vsync_cntrl.suspend, 1);
atomic_set(&vsync_cntrl.vsync_resume, 0);
complete_all(&vsync_cntrl.vsync_wait);

/* delay to make sure the last frame finishes */
msleep(20); ////ZTE_LCD_LUYA_20100629_001

return ret;
}

void mdp_dma_lcdc_vsync_init(int cndx)
{
/* nothing to do */
}

void mdp_dma_lcdc_vsync_ctrl(int enable)
{
unsigned long flag;
int disabled_clocks;

if (vsync_cntrl.vsync_irq_enabled == enable)
return;

spin_lock_irqsave(&mdp_spin_lock, flag);
if (!enable)
INIT_COMPLETION(vsync_cntrl.vsync_wait);

vsync_cntrl.vsync_irq_enabled = enable;
if (!enable)
vsync_cntrl.disabled_clocks = 0;
disabled_clocks = vsync_cntrl.disabled_clocks;
spin_unlock_irqrestore(&mdp_spin_lock, flag);

if (enable && disabled_clocks) {
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
spin_lock_irqsave(&mdp_spin_lock, flag);
outp32(MDP_INTR_CLEAR, LCDC_FRAME_START);
mdp_intr_mask |= LCDC_FRAME_START;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
mdp_enable_irq(MDP_VSYNC_TERM);
spin_unlock_irqrestore(&mdp_spin_lock, flag);
}

if (vsync_cntrl.vsync_irq_enabled &&
atomic_read(&vsync_cntrl.suspend) == 0)
atomic_set(&vsync_cntrl.vsync_resume, 1);
}

void mdp_lcdc_update(struct msm_fb_data_type *mfd)
{
struct fb_info *fbi = mfd->fbi;
Loading