From: Hitesh K. Patel <[email protected]>

DPST bug fixes When the interrupt service routine was moved, the DPST specific 
interrupt handling code was left out. I put it back in.
Some kernel changes illuminated a bug where objects were being freed out of 
order and now caused a kernel error. I corrected the order.

Also Enable DPST for Medfield.

Signed-off-by: Thomas G Eaton <[email protected]>
Signed-off-by: Hitesh K. Patel <[email protected]>
---
 drivers/staging/mrst/drv/psb_bl.c        |   14 ++++++++-
 drivers/staging/mrst/drv/psb_dpst.c      |    1 -
 drivers/staging/mrst/drv/psb_drv.h       |    1 +
 drivers/staging/mrst/drv/psb_irq.c       |   45 ++++++++++++++++++++++++++++-
 drivers/staging/mrst/drv/psb_powermgmt.c |    2 +
 drivers/staging/mrst/drv/psb_umevents.c  |    4 +-
 6 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/mrst/drv/psb_bl.c 
b/drivers/staging/mrst/drv/psb_bl.c
index 5024185..7971ecb 100644
--- a/drivers/staging/mrst/drv/psb_bl.c
+++ b/drivers/staging/mrst/drv/psb_bl.c
@@ -100,10 +100,18 @@ int psb_set_brightness(struct backlight_device *bd)
                        REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 
MRST_BACKLIGHT_MODULATION_FREQ_SHIFT) |
                                  blc_pwm_ctl);
                } else if (IS_MDFLD(dev)) {
+                       u32 adjusted_level = 0;
+                       /* Adjust the backlight level with the percent in
+                        * dev_priv->blc_adj2;
+                        */
+                       adjusted_level = level * dev_priv->blc_adj2;
+                       adjusted_level = adjusted_level / BLC_ADJUSTMENT_MAX;
+
                        if ((dev_priv->dbi_panel_on) || 
(dev_priv->dpi_panel_on))
-                               mdfld_dsi_brightness_control(dev, 0, level);
+                               mdfld_dsi_brightness_control(dev, 0, 
adjusted_level);
+
                        if ((dev_priv->dbi_panel_on2) || 
(dev_priv->dpi_panel_on2))
-                               mdfld_dsi_brightness_control(dev, 2, level);
+                               mdfld_dsi_brightness_control(dev, 2, 
adjusted_level);
                }
                ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
        }
@@ -137,6 +145,8 @@ static int device_backlight_init(struct drm_device *dev)
        struct drm_psb_private *dev_priv = (struct drm_psb_private *) 
dev->dev_private;
 
        if (IS_MDFLD(dev))
+               dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
+               dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
                return 0;
 
        if (IS_MRST(dev)) {
diff --git a/drivers/staging/mrst/drv/psb_dpst.c 
b/drivers/staging/mrst/drv/psb_dpst.c
index 64fba2f..2bbd7b5 100644
--- a/drivers/staging/mrst/drv/psb_dpst.c
+++ b/drivers/staging/mrst/drv/psb_dpst.c
@@ -124,7 +124,6 @@ struct dpst_state *psb_dpst_init(struct kobject 
*parent_kobj)
        struct umevent_obj *working_umevent;
 
        state = kzalloc(sizeof(struct dpst_state), GFP_KERNEL);
-       printk(KERN_ALERT "after kzalloc\n");
        state->list = NULL;
        state->list = psb_dpst_device_pool_create_and_init(
                                                  parent_kobj,
diff --git a/drivers/staging/mrst/drv/psb_drv.h 
b/drivers/staging/mrst/drv/psb_drv.h
index 13f996b..b452c75 100644
--- a/drivers/staging/mrst/drv/psb_drv.h
+++ b/drivers/staging/mrst/drv/psb_drv.h
@@ -815,6 +815,7 @@ struct drm_psb_private {
        /* DPST Register Save */
        uint32_t saveHISTOGRAM_INT_CONTROL_REG;
        uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG;
+       uint32_t savePWM_CONTROL_LOGIC;
 
        /* MSI reg save */
 
diff --git a/drivers/staging/mrst/drv/psb_irq.c 
b/drivers/staging/mrst/drv/psb_irq.c
index 46b31d2..f32b61a 100644
--- a/drivers/staging/mrst/drv/psb_irq.c
+++ b/drivers/staging/mrst/drv/psb_irq.c
@@ -251,8 +251,49 @@ static void mid_pipe_event_handler(struct drm_device *dev, 
uint32_t pipe)
                DRM_ERROR("%s, can't clear the status bits in pipe_stat_reg, 
its value = 0x%x. \n",
                        __FUNCTION__, PSB_RVDC32(pipe_stat_reg));
 
-       if (pipe_stat_val & PIPE_DPST_EVENT_STATUS) {
+       if ((pipe_stat_val & PIPE_DPST_EVENT_STATUS) &&
+          (dev_priv->psb_dpst_state != NULL)) {
+               uint32_t pwm_reg = 0;
+               uint32_t hist_reg = 0;
+               u32 irqCtrl = 0;
+               struct dpst_guardband guardband_reg;
+               struct dpst_ie_histogram_control ie_hist_cont_reg;
 
+               hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
+
+               /* Determine if this is histogram or pwm interrupt */
+               if(hist_reg & HISTOGRAM_INT_CTRL_CLEAR) {
+                       /* Notify UM of histogram interrupt */
+                       psb_dpst_notify_change_um(DPST_EVENT_HIST_INTERRUPT,
+                       dev_priv->psb_dpst_state);
+
+                       /* disable dpst interrupts */
+                       guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
+                       guardband_reg.interrupt_enable = 0;
+                       guardband_reg.interrupt_status = 1;
+                       PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
+
+                       ie_hist_cont_reg.data = 
PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
+                       ie_hist_cont_reg.ie_histogram_enable = 0;
+                       PSB_WVDC32(ie_hist_cont_reg.data, 
HISTOGRAM_LOGIC_CONTROL);
+
+                       irqCtrl = PSB_RVDC32(PIPEASTAT);
+                       irqCtrl &= ~PIPE_DPST_EVENT_ENABLE;
+                       PSB_WVDC32(irqCtrl, PIPEASTAT);
+               }
+               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
+               if((pwm_reg & PWM_PHASEIN_INT_ENABLE) &&
+                  !(pwm_reg & PWM_PHASEIN_ENABLE)) {
+                       /* Notify UM of the phase complete */
+                       psb_dpst_notify_change_um(DPST_EVENT_PHASE_COMPLETE,
+                       dev_priv->psb_dpst_state);
+
+                       /* Temporarily get phase mngr ready to generate
+                        * another interrupt until this can be moved to
+                        * user mode */
+                       /* PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE,
+                                  PWM_CONTROL_LOGIC); */
+               }
        }
 
        if (pipe_stat_val & PIPE_VBLANK_STATUS) {
diff --git a/drivers/staging/mrst/drv/psb_powermgmt.c 
b/drivers/staging/mrst/drv/psb_powermgmt.c
index aa9bd76..decf38b 100644
--- a/drivers/staging/mrst/drv/psb_powermgmt.c
+++ b/drivers/staging/mrst/drv/psb_powermgmt.c
@@ -523,6 +523,7 @@ static int save_display_registers(struct drm_device *dev)
                /* DPST registers */
                 dev_priv->saveHISTOGRAM_INT_CONTROL_REG = 
PSB_RVDC32(HISTOGRAM_INT_CONTROL);
                 dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG = 
PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
+               dev_priv->savePWM_CONTROL_LOGIC = PSB_RVDC32(PWM_CONTROL_LOGIC);
 
 
        } else { /*PSB*/
@@ -716,6 +717,7 @@ static int restore_display_registers(struct drm_device *dev)
                /* DPST registers */
                 PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG, 
HISTOGRAM_INT_CONTROL);
                 PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG, 
HISTOGRAM_LOGIC_CONTROL);
+               PSB_WVDC32(dev_priv->savePWM_CONTROL_LOGIC, PWM_CONTROL_LOGIC);
 
 
        } else { /*PSB*/
diff --git a/drivers/staging/mrst/drv/psb_umevents.c 
b/drivers/staging/mrst/drv/psb_umevents.c
index 7ebc520..9b66863 100644
--- a/drivers/staging/mrst/drv/psb_umevents.c
+++ b/drivers/staging/mrst/drv/psb_umevents.c
@@ -371,9 +371,9 @@ void psb_umevent_destroy_list(struct umevent_list *list)
                                                   head);
                node_kill = node;
                node = umevent_obj_curr->head.next;
+               list_del(node_kill);
                psb_destroy_umevent_obj(umevent_obj_curr);
                umevent_obj_curr = NULL;
-               list_del(node_kill);
                i++;
        }
        kset_unregister(list->umevent_disp_pool);
@@ -413,9 +413,9 @@ void psb_umevent_remove_from_list(struct umevent_list *list,
        if (found_match == 1) {
                node_kill = node;
                node = umevent_obj_curr->head.next;
+               list_del(node_kill);
                psb_destroy_umevent_obj(umevent_obj_curr);
                umevent_obj_curr = NULL;
-               list_del(node_kill);
        }
 }
 /*EXPORT_SYMBOL(psb_umevent_remove_from_list); */
-- 
1.7.1

_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to