Merge "USB: EHCI: msm: Add support for EHCI based Host Controller" into msm-3.0
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index a094ba5..ad71007 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -971,12 +971,54 @@
#ifdef CONFIG_USB_MSM_OTG_72K
static struct msm_otg_platform_data msm_otg_pdata;
#else
+#ifdef CONFIG_MSM_BUS_SCALING
+/* Bandwidth requests (zero) if no vote placed */
+static struct msm_bus_vectors usb_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+
+/* Bus bandwidth requests in Bytes/sec */
+static struct msm_bus_vectors usb_max_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 60000000, /* At least 480Mbps on bus. */
+ .ib = 960000000, /* MAX bursts rate */
+ },
+};
+
+static struct msm_bus_paths usb_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(usb_init_vectors),
+ usb_init_vectors,
+ },
+ {
+ ARRAY_SIZE(usb_max_vectors),
+ usb_max_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata usb_bus_scale_pdata = {
+ usb_bus_scale_usecases,
+ ARRAY_SIZE(usb_bus_scale_usecases),
+ .name = "usb",
+};
+#endif
+
static struct msm_otg_platform_data msm_otg_pdata = {
.mode = USB_OTG,
.otg_control = OTG_PMIC_CONTROL,
.phy_type = SNPS_28NM_INTEGRATED_PHY,
.pmic_id_irq = PM8038_USB_ID_IN_IRQ(PM8038_IRQ_BASE),
.power_budget = 750,
+#ifdef CONFIG_MSM_BUS_SCALING
+ .bus_scale_table = &usb_bus_scale_pdata,
+#endif
};
#endif
diff --git a/drivers/mfd/wcd9310-core.c b/drivers/mfd/wcd9310-core.c
index e0d4b45..d1d9132 100644
--- a/drivers/mfd/wcd9310-core.c
+++ b/drivers/mfd/wcd9310-core.c
@@ -267,15 +267,6 @@
static int tabla_reset(struct tabla *tabla)
{
int ret;
- struct pm_gpio param = {
- .direction = PM_GPIO_DIR_OUT,
- .output_buffer = PM_GPIO_OUT_BUF_CMOS,
- .output_value = 1,
- .pull = PM_GPIO_PULL_NO,
- .vin_sel = PM_GPIO_VIN_S4,
- .out_strength = PM_GPIO_STRENGTH_MED,
- .function = PM_GPIO_FUNC_NORMAL,
- };
if (tabla->reset_gpio) {
ret = gpio_request(tabla->reset_gpio, "CDC_RESET");
@@ -286,10 +277,6 @@
return ret;
}
- ret = pm8xxx_gpio_config(tabla->reset_gpio, ¶m);
- if (ret)
- pr_err("%s: Failed to configure gpio\n", __func__);
-
gpio_direction_output(tabla->reset_gpio, 1);
msleep(20);
gpio_direction_output(tabla->reset_gpio, 0);
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 3c848fa..ef357db 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -4062,6 +4062,11 @@
static void hdmi_msm_hpd_off(void)
{
+ if (!hdmi_msm_state->hpd_initialized) {
+ DEV_DBG("%s: HPD is already OFF, returning\n", __func__);
+ return;
+ }
+
DEV_DBG("%s: (timer, clk, 5V, core, IRQ off)\n", __func__);
del_timer(&hdmi_msm_state->hpd_state_timer);
disable_irq(hdmi_msm_state->irq);
@@ -4087,6 +4092,12 @@
static int hdmi_msm_hpd_on(bool trigger_handler)
{
static int phy_reset_done;
+ uint32 hpd_ctrl;
+
+ if (hdmi_msm_state->hpd_initialized) {
+ DEV_DBG("%s: HPD is already ON, returning\n", __func__);
+ return 0;
+ }
hdmi_msm_clk(1);
hdmi_msm_state->pd->core_power(1, 1);
@@ -4104,36 +4115,34 @@
HDMI_OUTP(0x0208, 0x0001001B);
/* Check HPD State */
- if (!hdmi_msm_state->hpd_initialized) {
- uint32 hpd_ctrl;
- enable_irq(hdmi_msm_state->irq);
+ enable_irq(hdmi_msm_state->irq);
- /* set timeout to 4.1ms (max) for hardware debounce */
- hpd_ctrl = (HDMI_INP(0x0258) & ~0xFFF) | 0xFFF;
+ /* set timeout to 4.1ms (max) for hardware debounce */
+ hpd_ctrl = (HDMI_INP(0x0258) & ~0xFFF) | 0xFFF;
- /* Toggle HPD circuit to trigger HPD sense */
- HDMI_OUTP(0x0258, ~(1 << 28) & hpd_ctrl);
- HDMI_OUTP(0x0258, (1 << 28) | hpd_ctrl);
+ /* Toggle HPD circuit to trigger HPD sense */
+ HDMI_OUTP(0x0258, ~(1 << 28) & hpd_ctrl);
+ HDMI_OUTP(0x0258, (1 << 28) | hpd_ctrl);
- DEV_DBG("%s: (clk, 5V, core, IRQ on) <trigger:%s>\n", __func__,
- trigger_handler ? "true" : "false");
+ DEV_DBG("%s: (clk, 5V, core, IRQ on) <trigger:%s>\n", __func__,
+ trigger_handler ? "true" : "false");
- if (trigger_handler) {
- /* Set HPD state machine: ensure at least 2 readouts */
- mutex_lock(&hdmi_msm_state_mutex);
- hdmi_msm_state->hpd_stable = 0;
- hdmi_msm_state->hpd_prev_state = TRUE;
- mutex_lock(&external_common_state_hpd_mutex);
- external_common_state->hpd_state = FALSE;
- mutex_unlock(&external_common_state_hpd_mutex);
- hdmi_msm_state->hpd_cable_chg_detected = TRUE;
- mutex_unlock(&hdmi_msm_state_mutex);
- mod_timer(&hdmi_msm_state->hpd_state_timer,
- jiffies + HZ/2);
- }
-
- hdmi_msm_state->hpd_initialized = TRUE;
+ if (trigger_handler) {
+ /* Set HPD state machine: ensure at least 2 readouts */
+ mutex_lock(&hdmi_msm_state_mutex);
+ hdmi_msm_state->hpd_stable = 0;
+ hdmi_msm_state->hpd_prev_state = TRUE;
+ mutex_lock(&external_common_state_hpd_mutex);
+ external_common_state->hpd_state = FALSE;
+ mutex_unlock(&external_common_state_hpd_mutex);
+ hdmi_msm_state->hpd_cable_chg_detected = TRUE;
+ mutex_unlock(&hdmi_msm_state_mutex);
+ mod_timer(&hdmi_msm_state->hpd_state_timer,
+ jiffies + HZ/2);
}
+
+ hdmi_msm_state->hpd_initialized = TRUE;
+
hdmi_msm_set_mode(TRUE);
return 0;
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 5f7c6a9..d8987e2 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -86,6 +86,9 @@
struct workqueue_struct *mdp_dma_wq; /*mdp dma wq */
struct workqueue_struct *mdp_vsync_wq; /*mdp vsync wq */
+struct workqueue_struct *mdp_hist_wq; /*mdp histogram wq */
+struct work_struct mdp_histogram_worker;
+
static struct workqueue_struct *mdp_pipe_ctrl_wq; /* mdp mdp pipe ctrl wq */
static struct delayed_work mdp_pipe_ctrl_worker;
@@ -237,20 +240,112 @@
#ifdef CONFIG_FB_MSM_MDP40
unsigned int mdp_hist_frame_cnt;
-struct completion mdp_hist_comp;
-boolean mdp_is_hist_start = FALSE;
#else
static unsigned int mdp_hist_frame_cnt;
-static struct completion mdp_hist_comp;
-static boolean mdp_is_hist_start = FALSE;
#endif
+struct completion mdp_hist_comp;
static DEFINE_MUTEX(mdp_hist_mutex);
static boolean mdp_is_hist_data = FALSE;
+static boolean mdp_is_hist_start = FALSE;
+boolean mdp_is_hist_valid = FALSE;
+static boolean mdp_is_hist_init = FALSE;
+static uint32 mdp_hist_r[128];
+static uint32 mdp_hist_g[128];
+static uint32 mdp_hist_b[128];
+
+void __mdp_histogram_kickoff()
+{
+ char *mdp_hist_base;
+
+ if (mdp_rev >= MDP_REV_40)
+ mdp_hist_base = MDP_BASE + 0x95000;
+ else if (mdp_rev >= MDP_REV_30 && mdp_rev <= MDP_REV_31)
+ mdp_hist_base = MDP_BASE + 0x94000;
+ else {
+ pr_err("%s(): Unsupported MDP rev. %u\n", __func__, mdp_rev);
+ return ;
+ }
+
+ if (mdp_is_hist_data == TRUE) {
+ MDP_OUTP(mdp_hist_base + 0x004, mdp_hist_frame_cnt);
+ MDP_OUTP(mdp_hist_base, 1);
+ }
+}
+
+void __mdp_histogram_reset()
+{
+ char *mdp_hist_base;
+
+ if (mdp_rev >= MDP_REV_40)
+ mdp_hist_base = MDP_BASE + 0x95000;
+ else if (mdp_rev >= MDP_REV_30 && mdp_rev <= MDP_REV_31)
+ mdp_hist_base = MDP_BASE + 0x94000;
+ else {
+ pr_err("%s(): Unsupported MDP rev %u\n", __func__, mdp_rev);
+ return ;
+ }
+
+ MDP_OUTP(mdp_hist_base + 0x00C, 1);
+}
+
+static void mdp_hist_read_work(struct work_struct *data)
+{
+ char *mdp_hist_base;
+ uint32 r_data_offset = 0x100, g_data_offset = 0x200;
+ uint32 b_data_offset = 0x300;
+ int num_bins, i = 0;
+
+ if (mdp_rev >= MDP_REV_42) {
+ mdp_hist_base = MDP_BASE + 0x95000;
+ r_data_offset = 0x400;
+ g_data_offset = 0x800;
+ b_data_offset = 0xc00;
+ num_bins = 128;
+ } else if (mdp_rev >= MDP_REV_40 && mdp_rev <= MDP_REV_41) {
+ mdp_hist_base = MDP_BASE + 0x95000;
+ num_bins = 32;
+ } else if (mdp_rev >= MDP_REV_30 && mdp_rev <= MDP_REV_31) {
+ mdp_hist_base = MDP_BASE + 0x94000;
+ num_bins = 32;
+ } else {
+ pr_err("%s(): Unsupported MDP rev %u\n", __func__, mdp_rev);
+ return ;
+ }
+
+ mutex_lock(&mdp_hist_mutex);
+ if (mdp_is_hist_data == FALSE) {
+ pr_debug("%s, Histogram disabled before read.\n", __func__);
+ goto error;
+ }
+
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ for (i = 0; i < num_bins; i++) {
+ mdp_hist_r[i] = inpdw(mdp_hist_base + r_data_offset + (4*i));
+ mdp_hist_g[i] = inpdw(mdp_hist_base + g_data_offset + (4*i));
+ mdp_hist_b[i] = inpdw(mdp_hist_base + b_data_offset + (4*i));
+ }
+
+ __mdp_histogram_kickoff();
+
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+ /* if read was triggered by an underrun, don't wake up readers*/
+ if (mdp_is_hist_valid && mdp_is_hist_init) {
+ complete(&mdp_hist_comp);
+ } else {
+ if (mdp_is_hist_valid == FALSE)
+ mdp_is_hist_valid = TRUE;
+
+ if (mdp_is_hist_init == FALSE)
+ mdp_is_hist_init = TRUE;
+ }
+error:
+ mutex_unlock(&mdp_hist_mutex);
+}
/*should hold mdp_hist_mutex before calling this function*/
int _mdp_histogram_ctrl(boolean en)
{
- unsigned long flag;
unsigned long hist_base;
uint32_t status;
@@ -266,34 +361,40 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
mdp_hist_frame_cnt = 1;
mdp_enable_irq(MDP_HISTOGRAM_TERM);
- spin_lock_irqsave(&mdp_spin_lock, flag);
- if (mdp_rev >= MDP_REV_40) {
- MDP_OUTP(MDP_BASE + hist_base + 0x10, 1);
- MDP_OUTP(MDP_BASE + hist_base + 0x1c, INTR_HIST_DONE);
- }
- spin_unlock_irqrestore(&mdp_spin_lock, flag);
- MDP_OUTP(MDP_BASE + hist_base + 0x4, mdp_hist_frame_cnt);
- MDP_OUTP(MDP_BASE + hist_base, 1);
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ INIT_COMPLETION(mdp_hist_comp);
+
+ /*Clear the interrupts before enabling them*/
+ MDP_OUTP(MDP_BASE + hist_base + 0x18, INTR_HIST_DONE |
+ INTR_HIST_RESET_SEQ_DONE);
+ MDP_OUTP(MDP_BASE + hist_base + 0x10, 1);
+ MDP_OUTP(MDP_BASE + hist_base + 0x1c, INTR_HIST_DONE |
+ INTR_HIST_RESET_SEQ_DONE);
+
mdp_is_hist_data = TRUE;
+ mdp_is_hist_valid = TRUE;
+ mdp_is_hist_init = FALSE;
+
+ __mdp_histogram_reset();
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
} else {
if (!mdp_is_hist_data)
return -EINVAL;
mdp_is_hist_data = FALSE;
+ mdp_is_hist_valid = FALSE;
+ mdp_is_hist_init = FALSE;
+
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ status = inpdw(MDP_BASE + hist_base + 0x1C);
+ status &= ~(INTR_HIST_DONE | INTR_HIST_RESET_SEQ_DONE);
+ MDP_OUTP(MDP_BASE + hist_base + 0x1C, status);
+ MDP_OUTP(MDP_BASE + hist_base + 0x18, INTR_HIST_DONE |
+ INTR_HIST_RESET_SEQ_DONE);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
complete(&mdp_hist_comp);
- if (mdp_rev >= MDP_REV_40) {
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
- status = inpdw(MDP_BASE + hist_base + 0x1C);
- status &= ~INTR_HIST_DONE;
- MDP_OUTP(MDP_BASE + hist_base + 0x1C, status);
-
- MDP_OUTP(MDP_BASE + hist_base + 0x18, INTR_HIST_DONE);
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF,
- FALSE);
- }
-
mdp_disable_irq(MDP_HISTOGRAM_TERM);
}
@@ -307,6 +408,10 @@
if (mdp_is_hist_start)
ret = _mdp_histogram_ctrl(en);
mutex_unlock(&mdp_hist_mutex);
+
+ if (en == false)
+ flush_workqueue(mdp_hist_wq);
+
return ret;
}
@@ -361,6 +466,10 @@
ret = _mdp_histogram_ctrl(FALSE);
+ mutex_unlock(&mdp_hist_mutex);
+ flush_workqueue(mdp_hist_wq);
+ return ret;
+
mdp_hist_stop_err:
mutex_unlock(&mdp_hist_mutex);
return ret;
@@ -369,55 +478,26 @@
/*call from within mdp_hist_mutex*/
static int _mdp_copy_hist_data(struct mdp_histogram *hist)
{
- char *mdp_hist_base;
- uint32 r_data_offset = 0x100, g_data_offset = 0x200;
- uint32 b_data_offset = 0x300;
int ret = 0;
- if (mdp_rev >= MDP_REV_42) {
- mdp_hist_base = MDP_BASE + 0x95000;
- r_data_offset = 0x400;
- g_data_offset = 0x800;
- b_data_offset = 0xc00;
- } else if (mdp_rev >= MDP_REV_40 && mdp_rev <= MDP_REV_41) {
- mdp_hist_base = MDP_BASE + 0x95000;
- } else if (mdp_rev >= MDP_REV_30 && mdp_rev <= MDP_REV_31) {
- mdp_hist_base = MDP_BASE + 0x94000;
- } else {
- pr_err("%s(): Unsupported MDP rev %u\n", __func__, mdp_rev);
- return -EPERM;
- }
-
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
if (hist->r) {
- ret = copy_to_user(hist->r, mdp_hist_base + r_data_offset,
- hist->bin_cnt * 4);
+ ret = copy_to_user(hist->r, mdp_hist_r, hist->bin_cnt * 4);
if (ret)
goto hist_err;
}
if (hist->g) {
- ret = copy_to_user(hist->g, mdp_hist_base + g_data_offset,
- hist->bin_cnt * 4);
+ ret = copy_to_user(hist->g, mdp_hist_g, hist->bin_cnt * 4);
if (ret)
goto hist_err;
}
if (hist->b) {
- ret = copy_to_user(hist->b, mdp_hist_base + b_data_offset,
- hist->bin_cnt * 4);
+ ret = copy_to_user(hist->b, mdp_hist_b, hist->bin_cnt * 4);
if (ret)
goto hist_err;
}
-
- if (mdp_is_hist_start == TRUE) {
- MDP_OUTP(mdp_hist_base + 0x004,
- mdp_hist_frame_cnt);
- MDP_OUTP(mdp_hist_base, 1);
- }
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
return 0;
-
hist_err:
- printk(KERN_ERR "%s: invalid hist buffer\n", __func__);
+ pr_err("%s: invalid hist buffer\n", __func__);
return ret;
}
@@ -435,17 +515,17 @@
mutex_lock(&mdp_hist_mutex);
if (!mdp_is_hist_data) {
- ret = -EINVAL;
- goto error;
- }
-
- if (!mdp_is_hist_start) {
- printk(KERN_ERR "%s histogram not started\n", __func__);
+ pr_err("%s - histogram not ready\n", __func__);
ret = -EPERM;
goto error;
}
- INIT_COMPLETION(mdp_hist_comp);
+ if (!mdp_is_hist_start) {
+ pr_err("%s histogram not started\n", __func__);
+ ret = -EPERM;
+ goto error;
+ }
+
mdp_hist_frame_cnt = hist->frame_cnt;
mutex_unlock(&mdp_hist_mutex);
@@ -455,8 +535,9 @@
}
mutex_lock(&mdp_hist_mutex);
- if (mdp_is_hist_data)
+ if (mdp_is_hist_data && mdp_is_hist_init)
ret = _mdp_copy_hist_data(hist);
+
error:
mutex_unlock(&mdp_hist_mutex);
return ret;
@@ -818,7 +899,7 @@
#ifndef CONFIG_FB_MSM_MDP40
irqreturn_t mdp_isr(int irq, void *ptr)
{
- uint32 mdp_interrupt = 0;
+ uint32 hist_interrupt, mdp_interrupt = 0;
struct mdp_dma_data *dma;
unsigned long flag;
@@ -853,24 +934,34 @@
}
#ifndef CONFIG_FB_MSM_MDP22
if (mdp_interrupt & MDP_HIST_DONE) {
+ hist_interrupt = inp32(MDP_DMA_P_HIST_INTR_STATUS);
outp32(MDP_BASE + 0x94018, 0x3);
outp32(MDP_INTR_CLEAR, MDP_HIST_DONE);
- complete(&mdp_hist_comp);
+ if (hist_interrupt & INTR_HIST_RESET_SEQ_DONE)
+ __mdp_histogram_kickoff();
+
+ if (hist_interrupt & INTR_HIST_DONE) {
+ if (waitqueue_active(&mdp_hist_comp.wait)) {
+ if (!queue_work(mdp_hist_wq,
+ &mdp_histogram_worker)) {
+ pr_err("%s: can't queue hist_read\n",
+ __func__);
+ }
+ } else
+ __mdp_histogram_reset();
+ }
}
/* LCDC UnderFlow */
if (mdp_interrupt & LCDC_UNDERFLOW) {
mdp_lcdc_underflow_cnt++;
/*when underflow happens HW resets all the histogram
- registers that were set before so restore them back
- to normal.*/
+ registers that were set before so restore them back
+ to normal.*/
MDP_OUTP(MDP_BASE + 0x94010, 1);
- MDP_OUTP(MDP_BASE + 0x9401c, 2);
- if (mdp_is_hist_start == TRUE) {
- MDP_OUTP(MDP_BASE + 0x94004,
- mdp_hist_frame_cnt);
- MDP_OUTP(MDP_BASE + 0x94000, 1);
- }
+ MDP_OUTP(MDP_BASE + 0x9401c, INTR_HIST_DONE);
+ mdp_is_hist_valid = FALSE;
+ __mdp_histogram_reset();
}
/* LCDC Frame Start */
@@ -969,6 +1060,8 @@
spin_lock_init(&mdp_spin_lock);
mdp_dma_wq = create_singlethread_workqueue("mdp_dma_wq");
mdp_vsync_wq = create_singlethread_workqueue("mdp_vsync_wq");
+ mdp_hist_wq = create_singlethread_workqueue("mdp_hist_wq");
+ INIT_WORK(&mdp_histogram_worker, mdp_hist_read_work);
mdp_pipe_ctrl_wq = create_singlethread_workqueue("mdp_pipe_ctrl_wq");
INIT_DELAYED_WORK(&mdp_pipe_ctrl_worker,
mdp_pipe_ctrl_workqueue_handler);
@@ -1009,8 +1102,6 @@
mutex_init(&dma_wb_data.ov_mutex);
#endif
-
-
#ifndef CONFIG_FB_MSM_MDP22
init_completion(&mdp_hist_comp);
#endif
@@ -1128,7 +1219,6 @@
}
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
#endif
- mdp_histogram_ctrl(TRUE);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
ret = panel_next_on(pdev);
@@ -1141,6 +1231,7 @@
mdp4_mddi_overlay_restore();
#endif
+ mdp_histogram_ctrl(TRUE);
return ret;
}
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index 35a1453..3d3668e 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -44,6 +44,10 @@
extern int mdp_rev;
extern struct mdp_csc_cfg mdp_csc_convert[4];
+extern struct workqueue_struct *mdp_hist_wq;
+extern struct work_struct mdp_histogram_worker;
+extern boolean mdp_is_hist_valid;
+
#define MDP4_REVISION_V1 0
#define MDP4_REVISION_V2 1
#define MDP4_REVISION_V2_1 2
@@ -606,6 +610,10 @@
#define MDP_EBI2_LCD0 (msm_mdp_base + 0x003c)
#define MDP_EBI2_LCD1 (msm_mdp_base + 0x0040)
#define MDP_EBI2_PORTMAP_MODE (msm_mdp_base + 0x005c)
+
+#define MDP_DMA_P_HIST_INTR_STATUS (msm_mdp_base + 0x94014)
+#define MDP_DMA_P_HIST_INTR_CLEAR (msm_mdp_base + 0x94018)
+#define MDP_DMA_P_HIST_INTR_ENABLE (msm_mdp_base + 0x9401C)
#endif
#define MDP_FULL_BYPASS_WORD43 (msm_mdp_base + 0x101ac)
@@ -733,6 +741,8 @@
int mdp_start_histogram(struct fb_info *info);
int mdp_stop_histogram(struct fb_info *info);
int mdp_histogram_ctrl(boolean en);
+void __mdp_histogram_kickoff(void);
+void __mdp_histogram_reset(void);
void mdp_footswitch_ctrl(boolean on);
#ifdef CONFIG_FB_MSM_MDP303
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index b72350d..77e8cd1 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -20,7 +20,6 @@
extern struct mdp_dma_data dma_wb_data;
extern unsigned int mdp_hist_frame_cnt;
extern struct completion mdp_hist_comp;
-extern boolean mdp_is_hist_start;
extern boolean mdp_is_in_isr;
extern uint32 mdp_intr_mask;
extern spinlock_t mdp_spin_lock;
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index 2876d9f..d8a55ed 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -296,12 +296,6 @@
bits = mdp_intr_mask;
outpdw(MDP_BASE + 0x0050, bits);/* enable specififed interrupts */
- /* histogram */
- MDP_OUTP(MDP_BASE + 0x95010, 1); /* auto clear HIST */
-
- /* enable histogram interrupts */
- outpdw(MDP_BASE + 0x9501c, INTR_HIST_DONE);
-
/* For the max read pending cmd config below, if the MDP clock */
/* is less than the AXI clock, then we must use 3 pending */
/* pending requests. Otherwise, we should use 8 pending requests. */
@@ -386,11 +380,8 @@
that histogram works.*/
MDP_OUTP(MDP_BASE + 0x95010, 1);
outpdw(MDP_BASE + 0x9501c, INTR_HIST_DONE);
- if (mdp_is_hist_start == TRUE) {
- MDP_OUTP(MDP_BASE + 0x95004,
- mdp_hist_frame_cnt);
- MDP_OUTP(MDP_BASE + 0x95000, 1);
- }
+ mdp_is_hist_valid = FALSE;
+ __mdp_histogram_reset();
}
if (isr & INTR_EXTERNAL_INTF_UDERRUN)
@@ -569,16 +560,18 @@
outpdw(MDP_DMA_P_HIST_INTR_CLEAR, isr);
mb();
isr &= mask;
+ if (isr & INTR_HIST_RESET_SEQ_DONE)
+ __mdp_histogram_kickoff();
+
if (isr & INTR_HIST_DONE) {
- if (waitqueue_active(&(mdp_hist_comp.wait))) {
- complete(&mdp_hist_comp);
- } else {
- if (mdp_is_hist_start == TRUE) {
- MDP_OUTP(MDP_BASE + 0x95004,
- mdp_hist_frame_cnt);
- MDP_OUTP(MDP_BASE + 0x95000, 1);
+ if (waitqueue_active(&mdp_hist_comp.wait)) {
+ if (!queue_work(mdp_hist_wq,
+ &mdp_histogram_worker)) {
+ pr_err("%s - can't queue hist_read\n",
+ __func__);
}
- }
+ } else
+ __mdp_histogram_reset();
}
}
diff --git a/drivers/video/msm/mdp_hw_init.c b/drivers/video/msm/mdp_hw_init.c
index 8f8b4d3..ff3ad41 100644
--- a/drivers/video/msm/mdp_hw_init.c
+++ b/drivers/video/msm/mdp_hw_init.c
@@ -635,8 +635,6 @@
MDP_OUTP(MDP_BASE + 0xE0000, 0);
MDP_OUTP(MDP_BASE + 0x100, 0xffffffff);
MDP_OUTP(MDP_BASE + 0x90070, 0);
- MDP_OUTP(MDP_BASE + 0x94010, 1);
- MDP_OUTP(MDP_BASE + 0x9401c, 2);
#endif
/*