Revert "video: tegra: dc: power optimize DC and host1x clk"
Peter Zu [Thu, 23 Aug 2012 19:13:01 +0000 (12:13 -0700)]
This reverts commit ced6edaf188e05194fc08b39ac0a89d1b56e94a5.

Change-Id: I0831dc5a623d8926e72f5dfef8e92b8e7dd81ea7
Signed-off-by: Peter Zu <pzu@nvidia.com>
Reviewed-on: http://git-master/r/126958
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Wen Yi <wyi@nvidia.com>
Reviewed-by: Jon Mayo <jmayo@nvidia.com>
GVS: Gerrit_Virtual_Submit

drivers/video/tegra/dc/dc.c
drivers/video/tegra/dc/dc_priv.h
drivers/video/tegra/dc/dsi.c
drivers/video/tegra/dc/hdmi.c
drivers/video/tegra/dc/lut.c
drivers/video/tegra/dc/nvsd.c
drivers/video/tegra/dc/rgb.c
drivers/video/tegra/dc/window.c

index 14c86b1..da7f291 100644 (file)
@@ -134,8 +134,8 @@ static void _dump_regs(struct tegra_dc *dc, void *data,
        char buff[256];
 
        mutex_lock(&dc->lock);
-       tegra_dc_io_start(dc);
        tegra_dc_hold_dc_out(dc);
+       tegra_dc_io_start(dc);
 
        DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0);
        DUMP_REG(DC_CMD_DISPLAY_COMMAND);
@@ -285,8 +285,8 @@ static void _dump_regs(struct tegra_dc *dc, void *data,
        DUMP_REG(DC_COM_PM1_DUTY_CYCLE);
        DUMP_REG(DC_DISP_SD_CONTROL);
 
-       tegra_dc_release_dc_out(dc);
        tegra_dc_io_end(dc);
+       tegra_dc_release_dc_out(dc);
        mutex_unlock(&dc->lock);
 }
 
@@ -503,13 +503,11 @@ int tegra_dc_get_stride(struct tegra_dc *dc, unsigned win)
                return 0;
        BUG_ON(win > DC_N_WINDOWS);
        mutex_lock(&dc->lock);
-       tegra_dc_io_start(dc);
        tegra_dc_hold_dc_out(dc);
        tegra_dc_writel(dc, WINDOW_A_SELECT << win,
                DC_CMD_DISPLAY_WINDOW_HEADER);
        stride = tegra_dc_readl(dc, DC_WIN_LINE_STRIDE);
        tegra_dc_release_dc_out(dc);
-       tegra_dc_io_end(dc);
        mutex_unlock(&dc->lock);
        return GET_LINE_STRIDE(stride);
 }
@@ -558,7 +556,6 @@ static void tegra_dc_set_scaling_filter(struct tegra_dc *dc)
        unsigned i;
        unsigned v0 = 128;
        unsigned v1 = 0;
-
        /* linear horizontal and vertical filters */
        for (i = 0; i < 16; i++) {
                tegra_dc_writel(dc, (v1 << 16) | (v0 << 8),
@@ -571,11 +568,9 @@ static void tegra_dc_set_scaling_filter(struct tegra_dc *dc)
        }
 }
 
-/* disable_irq() blocks until handler completes, calling this function while
- * holding dc->lock can deadlock. */
-static inline void disable_dc_irq(const struct tegra_dc *dc)
+static inline void disable_dc_irq(unsigned int irq)
 {
-       disable_irq(dc->irq);
+       disable_irq(irq);
 }
 
 u32 tegra_dc_get_syncpt_id(const struct tegra_dc *dc, int i)
@@ -589,13 +584,11 @@ u32 tegra_dc_incr_syncpt_max(struct tegra_dc *dc, int i)
        u32 max;
 
        mutex_lock(&dc->lock);
-       tegra_dc_io_start(dc);
        tegra_dc_hold_dc_out(dc);
        max = nvhost_syncpt_incr_max_ext(dc->ndev,
                dc->syncpt[i].id, ((dc->enabled) ? 1 : 0));
        dc->syncpt[i].max = max;
        tegra_dc_release_dc_out(dc);
-       tegra_dc_io_end(dc);
        mutex_unlock(&dc->lock);
 
        return max;
@@ -605,14 +598,12 @@ void tegra_dc_incr_syncpt_min(struct tegra_dc *dc, int i, u32 val)
 {
        mutex_lock(&dc->lock);
        if (dc->enabled) {
-               tegra_dc_io_start(dc);
                tegra_dc_hold_dc_out(dc);
                while (dc->syncpt[i].min < val) {
                        dc->syncpt[i].min++;
                        nvhost_syncpt_cpu_incr_ext(dc->ndev, dc->syncpt[i].id);
                }
                tegra_dc_release_dc_out(dc);
-               tegra_dc_io_end(dc);
        }
        mutex_unlock(&dc->lock);
 }
@@ -630,7 +621,6 @@ tegra_dc_config_pwm(struct tegra_dc *dc, struct tegra_dc_pwm_params *cfg)
                return;
        }
 
-       tegra_dc_io_start(dc);
        tegra_dc_hold_dc_out(dc);
 
        ctrl = ((cfg->period << PM_PERIOD_SHIFT) |
@@ -666,7 +656,6 @@ tegra_dc_config_pwm(struct tegra_dc *dc, struct tegra_dc_pwm_params *cfg)
        }
        tegra_dc_writel(dc, cmd_state, DC_CMD_STATE_ACCESS);
        tegra_dc_release_dc_out(dc);
-       tegra_dc_io_end(dc);
        mutex_unlock(&dc->lock);
 }
 EXPORT_SYMBOL(tegra_dc_config_pwm);
@@ -815,8 +804,8 @@ void tegra_dc_enable_crc(struct tegra_dc *dc)
        u32 val;
 
        mutex_lock(&dc->lock);
-       tegra_dc_io_start(dc);
        tegra_dc_hold_dc_out(dc);
+       tegra_dc_io_start(dc);
 
        val = CRC_ALWAYS_ENABLE | CRC_INPUT_DATA_ACTIVE_DATA |
                CRC_ENABLE_ENABLE;
@@ -824,21 +813,19 @@ void tegra_dc_enable_crc(struct tegra_dc *dc)
        tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL);
        tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
        tegra_dc_release_dc_out(dc);
-       tegra_dc_io_end(dc);
        mutex_unlock(&dc->lock);
 }
 
 void tegra_dc_disable_crc(struct tegra_dc *dc)
 {
        mutex_lock(&dc->lock);
-       tegra_dc_io_start(dc);
        tegra_dc_hold_dc_out(dc);
        tegra_dc_writel(dc, 0x0, DC_COM_CRC_CONTROL);
        tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL);
        tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
 
-       tegra_dc_release_dc_out(dc);
        tegra_dc_io_end(dc);
+       tegra_dc_release_dc_out(dc);
        mutex_unlock(&dc->lock);
 }
 
@@ -856,11 +843,9 @@ u32 tegra_dc_read_checksum_latched(struct tegra_dc *dc)
        mdelay(TEGRA_CRC_LATCHED_DELAY);
 
        mutex_lock(&dc->lock);
-       tegra_dc_io_start(dc);
        tegra_dc_hold_dc_out(dc);
        crc = tegra_dc_readl(dc, DC_COM_CRC_CHECKSUM_LATCHED);
        tegra_dc_release_dc_out(dc);
-       tegra_dc_io_end(dc);
        mutex_unlock(&dc->lock);
 crc_error:
        return crc;
@@ -878,13 +863,13 @@ static bool tegra_dc_windows_are_dirty(struct tegra_dc *dc)
        return false;
 }
 
-static inline void enable_dc_irq(const struct tegra_dc *dc)
+static inline void enable_dc_irq(unsigned int irq)
 {
 #ifndef CONFIG_TEGRA_FPGA_PLATFORM
-       enable_irq(dc->irq);
+       enable_irq(irq);
 #else
        /* Always disable DC interrupts on FPGA. */
-       disable_irq(dc->irq);
+       disable_irq(irq);
 #endif
 }
 
@@ -900,7 +885,6 @@ static void tegra_dc_vblank(struct work_struct *work)
                return;
        }
 
-       tegra_dc_io_start(dc);
        tegra_dc_hold_dc_out(dc);
        /* use the new frame's bandwidth setting instead of max(current, new),
         * skip this if we're using tegra_dc_one_shot_worker() */
@@ -929,7 +913,6 @@ static void tegra_dc_vblank(struct work_struct *work)
                tegra_dc_mask_interrupt(dc, V_BLANK_INT);
 
        tegra_dc_release_dc_out(dc);
-       tegra_dc_io_end(dc);
        mutex_unlock(&dc->lock);
 
        /* Do the actual brightness update outside of the mutex */
@@ -952,11 +935,8 @@ static void tegra_dc_one_shot_worker(struct work_struct *work)
        /* memory client has gone idle */
        tegra_dc_clear_bandwidth(dc);
 
-       if (dc->out_ops->idle) {
-               tegra_dc_io_start(dc);
+       if (dc->out_ops->idle)
                dc->out_ops->idle(dc);
-               tegra_dc_io_end(dc);
-       }
 
        mutex_unlock(&dc->lock);
 }
@@ -966,13 +946,13 @@ static void tegra_dc_one_shot_worker(struct work_struct *work)
 static u64 tegra_dc_underflow_count(struct tegra_dc *dc, unsigned reg)
 {
        unsigned count = tegra_dc_readl(dc, reg);
-
        tegra_dc_writel(dc, 0, reg);
        return ((count & 0x80000000) == 0) ? count : 10000000000ll;
 }
 
 static void tegra_dc_underflow_handler(struct tegra_dc *dc)
 {
+       u32 val;
        int i;
 
        dc->stats.underflows++;
@@ -1035,7 +1015,8 @@ static void tegra_dc_underflow_handler(struct tegra_dc *dc)
        /* Clear the underflow mask now that we've checked it. */
        tegra_dc_writel(dc, dc->underflow_mask, DC_CMD_INT_STATUS);
        dc->underflow_mask = 0;
-       tegra_dc_unmask_interrupt(dc, ALL_UF_INT);
+       val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
+       tegra_dc_writel(dc, val | ALL_UF_INT, DC_CMD_INT_MASK);
        print_underflow_info(dc);
 }
 
@@ -1081,19 +1062,12 @@ static irqreturn_t tegra_dc_irq(int irq, void *ptr)
        unsigned long underflow_mask;
        u32 val;
 
-       mutex_lock(&dc->lock);
-       clk_enable(dc->clk);
-       tegra_dc_io_start(dc);
-       tegra_dc_hold_dc_out(dc);
-
        if (!nvhost_module_powered_ext(nvhost_get_parent(dc->ndev))) {
                WARN(1, "IRQ when DC not powered!\n");
+               tegra_dc_io_start(dc);
                status = tegra_dc_readl(dc, DC_CMD_INT_STATUS);
                tegra_dc_writel(dc, status, DC_CMD_INT_STATUS);
-               tegra_dc_release_dc_out(dc);
                tegra_dc_io_end(dc);
-               clk_disable(dc->clk);
-               mutex_unlock(&dc->lock);
                return IRQ_HANDLED;
        }
 
@@ -1123,11 +1097,6 @@ static irqreturn_t tegra_dc_irq(int irq, void *ptr)
        else
                tegra_dc_continuous_irq(dc, status);
 
-       tegra_dc_release_dc_out(dc);
-       tegra_dc_io_end(dc);
-       clk_disable(dc->clk);
-       mutex_unlock(&dc->lock);
-
        return IRQ_HANDLED;
 #else /* CONFIG_TEGRA_FPGA_PLATFORM */
        return IRQ_NONE;
@@ -1246,7 +1215,6 @@ static int tegra_dc_init(struct tegra_dc *dc)
 {
        int i;
 
-       tegra_dc_io_start(dc);
        tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
        if (dc->ndev->id == 0) {
                tegra_mc_set_priority(TEGRA_MC_CLIENT_DISPLAY0A,
@@ -1309,19 +1277,14 @@ static int tegra_dc_init(struct tegra_dc *dc)
 
        print_mode_info(dc, dc->mode);
 
-       if (dc->mode.pclk) {
-               if (tegra_dc_program_mode(dc, &dc->mode)) {
-                       tegra_dc_io_end(dc);
+       if (dc->mode.pclk)
+               if (tegra_dc_program_mode(dc, &dc->mode))
                        return -EINVAL;
-               }
-       }
 
        /* Initialize SD AFTER the modeset.
           nvsd_init handles the sd_settings = NULL case. */
        nvsd_init(dc, dc->out->sd_settings);
 
-       tegra_dc_io_end(dc);
-
        return 0;
 }
 
@@ -1334,22 +1297,20 @@ static bool _tegra_dc_controller_enable(struct tegra_dc *dc)
 
        tegra_dc_setup_clk(dc, dc->clk);
        tegra_dc_clk_enable(dc);
-       tegra_dc_io_start(dc);
 
        /* do not accept interrupts during initialization */
        tegra_dc_writel(dc, 0, DC_CMD_INT_MASK);
 
-       enable_dc_irq(dc);
+       enable_dc_irq(dc->irq);
 
        failed_init = tegra_dc_init(dc);
        if (failed_init) {
                tegra_dc_writel(dc, 0, DC_CMD_INT_MASK);
-               disable_irq_nosync(dc->irq);
+               disable_irq(dc->irq);
                tegra_dc_clear_bandwidth(dc);
                tegra_dc_clk_disable(dc);
                if (dc->out && dc->out->disable)
                        dc->out->disable();
-               tegra_dc_io_end(dc);
                return false;
        }
 
@@ -1369,7 +1330,6 @@ static bool _tegra_dc_controller_enable(struct tegra_dc *dc)
        if (dc->out->postpoweron)
                dc->out->postpoweron();
 
-       tegra_dc_io_end(dc);
        return true;
 }
 
@@ -1386,10 +1346,10 @@ static bool _tegra_dc_controller_reset_enable(struct tegra_dc *dc)
 
        if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) {
                mutex_lock(&tegra_dcs[1]->lock);
-               disable_irq_nosync(tegra_dcs[1]->irq);
+               disable_irq(tegra_dcs[1]->irq);
        } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) {
                mutex_lock(&tegra_dcs[0]->lock);
-               disable_irq_nosync(tegra_dcs[0]->irq);
+               disable_irq(tegra_dcs[0]->irq);
        }
 
        msleep(5);
@@ -1401,14 +1361,14 @@ static bool _tegra_dc_controller_reset_enable(struct tegra_dc *dc)
 #endif
 
        if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) {
-               enable_dc_irq(tegra_dcs[1]);
+               enable_dc_irq(tegra_dcs[1]->irq);
                mutex_unlock(&tegra_dcs[1]->lock);
        } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) {
-               enable_dc_irq(tegra_dcs[0]);
+               enable_dc_irq(tegra_dcs[0]->irq);
                mutex_unlock(&tegra_dcs[0]->lock);
        }
 
-       enable_dc_irq(dc);
+       enable_dc_irq(dc->irq);
 
        if (tegra_dc_init(dc)) {
                dev_err(&dc->ndev->dev, "cannot initialize\n");
@@ -1466,16 +1426,16 @@ static int _tegra_dc_set_default_videomode(struct tegra_dc *dc)
 
 static bool _tegra_dc_enable(struct tegra_dc *dc)
 {
-       if (dc->enabled)
-               return true;
-
        if (dc->mode.pclk == 0)
                return false;
 
        if (!dc->out)
                return false;
 
+       tegra_dc_io_start(dc);
+
        if (!_tegra_dc_controller_enable(dc)) {
+               tegra_dc_io_end(dc);
                return false;
        }
        return true;
@@ -1496,8 +1456,6 @@ static void _tegra_dc_controller_disable(struct tegra_dc *dc)
 {
        unsigned i;
 
-       tegra_dc_hold_dc_out(dc);
-
        if (dc->out && dc->out->prepoweroff)
                dc->out->prepoweroff();
 
@@ -1505,14 +1463,11 @@ static void _tegra_dc_controller_disable(struct tegra_dc *dc)
                dc->out_ops->disable(dc);
 
        tegra_dc_writel(dc, 0, DC_CMD_INT_MASK);
-
-       disable_irq_nosync(dc->irq);
+       tegra_dc_writel(dc, 0, DC_CMD_INT_ENABLE);
+       disable_irq(dc->irq);
 
        tegra_dc_clear_bandwidth(dc);
-       if (dc->out_ops->release) /* ugly hack */
-               tegra_dc_release_dc_out(dc);
-       else
-               tegra_dc_clk_disable(dc);
+       tegra_dc_clk_disable(dc);
 
        if (dc->out && dc->out->disable)
                dc->out->disable();
@@ -1593,10 +1548,13 @@ static void _tegra_dc_disable(struct tegra_dc *dc)
                cancel_delayed_work_sync(&dc->one_shot_work);
        }
 
-       tegra_dc_io_start(dc);
+       tegra_dc_hold_dc_out(dc);
+
        _tegra_dc_controller_disable(dc);
        tegra_dc_io_end(dc);
 
+       tegra_dc_release_dc_out(dc);
+
        if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
                mutex_unlock(&dc->one_shot_lock);
 }
@@ -1623,7 +1581,6 @@ void tegra_dc_disable(struct tegra_dc *dc)
 #endif
 
        mutex_unlock(&dc->lock);
-       synchronize_irq(dc->irq);
        print_mode_info(dc, dc->mode);
 }
 
@@ -1689,14 +1646,12 @@ static void tegra_dc_underflow_worker(struct work_struct *work)
                to_delayed_work(work), struct tegra_dc, underflow_work);
 
        mutex_lock(&dc->lock);
-       tegra_dc_io_start(dc);
        tegra_dc_hold_dc_out(dc);
 
        if (dc->enabled) {
                tegra_dc_underflow_handler(dc);
        }
        tegra_dc_release_dc_out(dc);
-       tegra_dc_io_end(dc);
        mutex_unlock(&dc->lock);
 }
 
@@ -1857,21 +1812,20 @@ static int tegra_dc_probe(struct nvhost_device *ndev,
                dc->ext = NULL;
        }
 
+       mutex_lock(&dc->lock);
+       if (dc->pdata->flags & TEGRA_DC_FLAG_ENABLED) {
+               dc->enabled = _tegra_dc_enable(dc);
+               _tegra_dc_set_default_videomode(dc);
+       }
+       mutex_unlock(&dc->lock);
+
        /* interrupt handler must be registered before tegra_fb_register() */
-       if (request_threaded_irq(irq, NULL, tegra_dc_irq, IRQF_ONESHOT,
+       if (request_irq(irq, tegra_dc_irq, 0,
                        dev_name(&ndev->dev), dc)) {
                dev_err(&ndev->dev, "request_irq %d failed\n", irq);
                ret = -EBUSY;
                goto err_put_emc_clk;
        }
-       disable_dc_irq(dc);
-
-       mutex_lock(&dc->lock);
-       if (dc->pdata->flags & TEGRA_DC_FLAG_ENABLED) {
-               _tegra_dc_set_default_videomode(dc);
-               dc->enabled = _tegra_dc_enable(dc);
-       }
-       mutex_unlock(&dc->lock);
 
        tegra_dc_create_debugfs(dc);
 
@@ -1895,11 +1849,9 @@ static int tegra_dc_probe(struct nvhost_device *ndev,
                        dc->pdata->fb->yres = mode->v_active;
                }
 
-               tegra_dc_io_start(dc);
                dc->fb = tegra_fb_register(ndev, dc, dc->pdata->fb, fb_mem);
                if (IS_ERR_OR_NULL(dc->fb))
                        dc->fb = NULL;
-               tegra_dc_io_end(dc);
        }
 
        if (dc->out && dc->out->hotplug_init)
@@ -1950,12 +1902,8 @@ static int tegra_dc_remove(struct nvhost_device *ndev)
        if (dc->ext)
                tegra_dc_ext_unregister(dc->ext);
 
-       mutex_lock(&dc->lock);
        if (dc->enabled)
                _tegra_dc_disable(dc);
-       dc->enabled = false;
-       mutex_unlock(&dc->lock);
-       synchronize_irq(dc->irq); /* wait for IRQ handlers to finish */
 
 #ifdef CONFIG_SWITCH
        switch_dev_unregister(&dc->modeset_switch);
@@ -1982,7 +1930,6 @@ static int tegra_dc_suspend(struct nvhost_device *ndev, pm_message_t state)
        tegra_dc_ext_disable(dc->ext);
 
        mutex_lock(&dc->lock);
-       tegra_dc_io_start(dc);
 
        if (dc->out_ops && dc->out_ops->suspend)
                dc->out_ops->suspend(dc);
@@ -2002,9 +1949,7 @@ static int tegra_dc_suspend(struct nvhost_device *ndev, pm_message_t state)
                        msleep(100);
        }
 
-       tegra_dc_io_end(dc);
        mutex_unlock(&dc->lock);
-       synchronize_irq(dc->irq); /* wait for IRQ handlers to finish */
 
        return 0;
 }
@@ -2020,9 +1965,8 @@ static int tegra_dc_resume(struct nvhost_device *ndev)
        dc->suspended = false;
 
        if (dc->enabled) {
-               dc->enabled = false;
+               _tegra_dc_enable(dc);
                _tegra_dc_set_default_videomode(dc);
-               dc->enabled = _tegra_dc_enable(dc);
        }
 
        if (dc->out && dc->out->hotplug_init)
index 7521158..759d64d 100644 (file)
@@ -325,26 +325,21 @@ static inline bool tegra_dc_is_yuv_planar(int fmt)
        return false;
 }
 
-static inline u32 tegra_dc_unmask_interrupt(struct tegra_dc *dc, u32 int_val)
+static inline void tegra_dc_unmask_interrupt(struct tegra_dc *dc, u32 int_val)
 {
        u32 val;
 
        val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
-       tegra_dc_writel(dc, val | int_val, DC_CMD_INT_MASK);
-       return val;
+       val |= int_val;
+       tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
 }
 
-static inline u32 tegra_dc_mask_interrupt(struct tegra_dc *dc, u32 int_val)
+static inline void tegra_dc_mask_interrupt(struct tegra_dc *dc, u32 int_val)
 {
        u32 val;
 
        val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
-       tegra_dc_writel(dc, val & ~int_val, DC_CMD_INT_MASK);
-       return val;
-}
-
-static inline void tegra_dc_restore_interrupt(struct tegra_dc *dc, u32 val)
-{
+       val &= ~int_val;
        tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
 }
 
index f60184b..4a9e507 100644 (file)
@@ -1391,7 +1391,8 @@ static void tegra_dsi_stop_dc_stream_at_frame_end(struct tegra_dc *dc,
        INIT_COMPLETION(dc->frame_end_complete);
 
        /* unmask frame end interrupt */
-       val = tegra_dc_unmask_interrupt(dc, FRAME_END_INT);
+       val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
+       tegra_dc_writel(dc, val | FRAME_END_INT, DC_CMD_INT_MASK);
 
        tegra_dsi_stop_dc_stream(dc, dsi);
 
@@ -1411,7 +1412,7 @@ static void tegra_dsi_stop_dc_stream_at_frame_end(struct tegra_dc *dc,
        tegra_dsi_soft_reset(dsi);
 
        /* reinstate interrupt mask */
-       tegra_dc_restore_interrupt(dc, val); /* potentially a race? */
+       tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
 
        if (timeout == 0)
                dev_warn(&dc->ndev->dev,
@@ -2141,13 +2142,15 @@ static void tegra_dc_dsi_idle(struct tegra_dc *dc)
                tegra_dsi_host_suspend(dc);
 }
 
-static int tegra_dsi_write_data_nosync(struct tegra_dc *dc,
+int tegra_dsi_write_data(struct tegra_dc *dc,
                        struct tegra_dc_dsi_data *dsi,
                        u8 *pdata, u8 data_id, u16 data_len)
 {
        int err = 0;
        struct dsi_status *init_status;
 
+       tegra_dc_io_start(dc);
+
        init_status = tegra_dsi_prepare_host_transmission(
                                dc, dsi, DSI_LP_OP_WRITE);
        if (IS_ERR_OR_NULL(init_status)) {
@@ -2161,27 +2164,10 @@ fail:
        err = tegra_dsi_restore_state(dc, dsi, init_status);
        if (err < 0)
                dev_err(&dc->ndev->dev, "Failed to restore prev state\n");
-
-       return err;
-}
-
-int tegra_dsi_write_data(struct tegra_dc *dc,
-                       struct tegra_dc_dsi_data *dsi,
-                       u8 *pdata, u8 data_id, u16 data_len)
-{
-       int err;
-
-       tegra_dc_io_start(dc);
-       tegra_dc_dsi_hold_host(dc);
-
-       err = tegra_dsi_write_data_nosync(dc, dsi, pdata, data_id, data_len);
-
-       tegra_dc_dsi_release_host(dc);
        tegra_dc_io_end(dc);
 
        return err;
 }
-
 EXPORT_SYMBOL(tegra_dsi_write_data);
 
 static int tegra_dsi_send_panel_cmd(struct tegra_dc *dc,
@@ -2200,7 +2186,7 @@ static int tegra_dsi_send_panel_cmd(struct tegra_dc *dc,
                if (cur_cmd->cmd_type == TEGRA_DSI_DELAY_MS)
                        mdelay(cur_cmd->sp_len_dly.delay_ms);
                else {
-                       err = tegra_dsi_write_data_nosync(dc, dsi,
+                       err = tegra_dsi_write_data(dc, dsi,
                                                cur_cmd->pdata,
                                                cur_cmd->data_id,
                                                cur_cmd->sp_len_dly.data_len);
@@ -2325,9 +2311,10 @@ int tegra_dsi_start_host_cmd_v_blank_dcs(struct tegra_dc_dsi_data * dsi,
                return -EINVAL;
 
        mutex_lock(&dsi->lock);
-       tegra_dc_io_start(dc);
        tegra_dc_dsi_hold_host(dc);
 
+       tegra_dc_io_start(dc);
+
 
        err = tegra_dsi_dcs_pkt_seq_ctrl_init(dsi, cmd);
        if (err < 0) {
@@ -2347,8 +2334,8 @@ int tegra_dsi_start_host_cmd_v_blank_dcs(struct tegra_dc_dsi_data * dsi,
        tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_CONTROL);
 
 fail:
-       tegra_dc_dsi_release_host(dc);
        tegra_dc_io_end(dc);
+       tegra_dc_dsi_release_host(dc);
        mutex_unlock(&dsi->lock);
        return err;
 
@@ -2363,18 +2350,19 @@ void tegra_dsi_stop_host_cmd_v_blank_dcs(struct tegra_dc_dsi_data * dsi)
        u32 cnt;
 
        mutex_lock(&dsi->lock);
-       tegra_dc_io_start(dc);
        tegra_dc_dsi_hold_host(dc);
 
+       tegra_dc_io_start(dc);
+
        tegra_dsi_writel(dsi, TEGRA_DSI_DISABLE, DSI_INIT_SEQ_CONTROL);
 
        /* clear seq data registers */
        for (cnt = 0; cnt < 8; cnt++)
                tegra_dsi_writel(dsi, 0, DSI_INIT_SEQ_DATA_0 + cnt);
 
-       tegra_dc_dsi_release_host(dc);
        tegra_dc_io_end(dc);
 
+       tegra_dc_dsi_release_host(dc);
        mutex_unlock(&dsi->lock);
 }
 EXPORT_SYMBOL(tegra_dsi_stop_host_cmd_v_blank_dcs);
@@ -2790,9 +2778,9 @@ static void tegra_dc_dsi_enable(struct tegra_dc *dc)
        u32 val;
 
        mutex_lock(&dsi->lock);
-       tegra_dc_io_start(dc);
        tegra_dc_dsi_hold_host(dc);
 
+       tegra_dc_io_start(dc);
        /* Stop DC stream before configuring DSI registers
         * to avoid visible glitches on panel during transition
         * from bootloader to kernel driver
@@ -2905,8 +2893,8 @@ static void tegra_dc_dsi_enable(struct tegra_dc *dc)
        if (dsi->status.driven == DSI_DRIVEN_MODE_DC)
                tegra_dsi_start_dc_stream(dc, dsi);
 fail:
-       tegra_dc_dsi_release_host(dc);
        tegra_dc_io_end(dc);
+       tegra_dc_dsi_release_host(dc);
        mutex_unlock(&dsi->lock);
 }
 
@@ -3389,8 +3377,8 @@ static void tegra_dc_dsi_disable(struct tegra_dc *dc)
        int err;
        struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
 
-       mutex_lock(&dsi->lock);
        tegra_dc_io_start(dc);
+       mutex_lock(&dsi->lock);
 
        if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE)
                tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi);
index 9f5968f..55d9163 100644 (file)
@@ -1462,7 +1462,10 @@ static void tegra_dc_hdmi_detect_worker(struct work_struct *work)
                container_of(to_delayed_work(work), struct tegra_dc_hdmi_data, work);
        struct tegra_dc *dc = hdmi->dc;
 
+       tegra_dc_enable(dc);
+       msleep(5);
        if (!tegra_dc_hdmi_detect(dc)) {
+               tegra_dc_disable(dc);
                tegra_fb_update_monspecs(dc->fb, NULL, NULL);
 
                dc->connected = false;
@@ -1620,11 +1623,21 @@ static int tegra_dc_hdmi_init(struct tegra_dc *dc)
        }
 #endif
 
+       /* TODO: support non-hotplug */
+       if (request_irq(gpio_to_irq(dc->out->hotplug_gpio), tegra_dc_hdmi_irq,
+                       IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+                       dev_name(&dc->ndev->dev), dc)) {
+               dev_err(&dc->ndev->dev, "hdmi: request_irq %d failed\n",
+                       gpio_to_irq(dc->out->hotplug_gpio));
+               err = -EBUSY;
+               goto err_put_clock;
+       }
+
        hdmi->edid = tegra_edid_create(dc->out->dcc_bus);
        if (IS_ERR_OR_NULL(hdmi->edid)) {
                dev_err(&dc->ndev->dev, "hdmi: can't create edid\n");
                err = PTR_ERR(hdmi->edid);
-               goto err_put_clock;
+               goto err_free_irq;
        }
 
 #ifdef CONFIG_TEGRA_NVHDCP
@@ -1679,23 +1692,14 @@ static int tegra_dc_hdmi_init(struct tegra_dc *dc)
 
        tegra_dc_hdmi_debug_create(hdmi);
 
-       /* TODO: support non-hotplug */
-       if (request_irq(gpio_to_irq(dc->out->hotplug_gpio), tegra_dc_hdmi_irq,
-               IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-               dev_name(&dc->ndev->dev), dc)) {
-               dev_err(&dc->ndev->dev, "hdmi: request_irq %d failed\n",
-                       gpio_to_irq(dc->out->hotplug_gpio));
-               err = -EBUSY;
-               goto err_nvhdcp_destroy;
-       }
-
        return 0;
 
-err_nvhdcp_destroy:
-       if (hdmi->nvhdcp)
-               tegra_nvhdcp_destroy(hdmi->nvhdcp);
+#ifdef CONFIG_TEGRA_NVHDCP
 err_edid_destroy:
        tegra_edid_destroy(hdmi->edid);
+#endif
+err_free_irq:
+       free_irq(gpio_to_irq(dc->out->hotplug_gpio), dc);
 err_put_clock:
 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
        if (!IS_ERR_OR_NULL(hdmi->hda2hdmi_clk))
index 2dfecfc..7ce8fc6 100644 (file)
@@ -109,7 +109,6 @@ static int tegra_dc_update_winlut(struct tegra_dc *dc, int win_idx, int fbovr)
        mutex_unlock(&dc->lock);
 
        tegra_dc_update_windows(&win, 1);
-       tegra_dc_sync_windows(&win, 1);
 
        return 0;
 }
index 2f33431..6e76ee0 100644 (file)
@@ -174,9 +174,7 @@ static bool nvsd_phase_in_adjustments(struct tegra_dc *dc,
                        /* Set manual k value */
                        man_k = SD_MAN_K_R(cur_k) |
                                SD_MAN_K_G(cur_k) | SD_MAN_K_B(cur_k);
-                       tegra_dc_io_start(dc);
                        tegra_dc_writel(dc, man_k, DC_DISP_SD_MAN_K_VALUES);
-                       tegra_dc_io_end(dc);
                        /* Set manual brightness value */
                        atomic_set(sd_brightness, cur_sd_brightness);
                }
@@ -273,7 +271,6 @@ static void nvsd_cmd_handler(struct tegra_dc_sd_settings *settings,
                                val &= ~SD_BIN_WIDTH_MASK;
                                val |= bw;
                        }
-
                        tegra_dc_writel(dc, val, DC_DISP_SD_CONTROL);
 
                        nvsd_phase_in_luts(settings, dc);
@@ -354,7 +351,6 @@ void nvsd_init(struct tegra_dc *dc, struct tegra_dc_sd_settings *settings)
        u32 bw_idx = 0;
        /* TODO: check if HW says SD's available */
 
-       tegra_dc_io_start(dc);
        /* If SD's not present or disabled, clear the register and return. */
        if (!settings || settings->enable == 0) {
                /* clear the brightness val, too. */
@@ -366,7 +362,6 @@ void nvsd_init(struct tegra_dc *dc, struct tegra_dc_sd_settings *settings)
                if (settings)
                        settings->phase_settings_step = 0;
                tegra_dc_writel(dc, 0, DC_DISP_SD_CONTROL);
-               tegra_dc_io_end(dc);
                return;
        }
 
@@ -492,7 +487,6 @@ void nvsd_init(struct tegra_dc *dc, struct tegra_dc_sd_settings *settings)
        /* Finally, Write SD Control */
        tegra_dc_writel(dc, val, DC_DISP_SD_CONTROL);
        dev_dbg(&dc->ndev->dev, "  SD_CONTROL: 0x%08x\n", val);
-       tegra_dc_io_end(dc);
 
        /* set the brightness pointer */
        sd_brightness = settings->sd_brightness;
@@ -816,11 +810,9 @@ static ssize_t nvsd_settings_store(struct kobject *kobj,
                                return -ENODEV;
                        }
 
-                       tegra_dc_io_start(dc);
                        tegra_dc_hold_dc_out(dc);
                        nvsd_init(dc, sd_settings);
                        tegra_dc_release_dc_out(dc);
-                       tegra_dc_io_end(dc);
 
                        mutex_unlock(&dc->lock);
 
index 36dbbdf..b4097d9 100644 (file)
@@ -97,7 +97,6 @@ static void tegra_dc_rgb_enable(struct tegra_dc *dc)
        int i;
        u32 out_sel_pintable[ARRAY_SIZE(tegra_dc_rgb_enable_out_sel_pintable)];
 
-       tegra_dc_io_start(dc);
        tegra_dc_writel(dc, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
                        PW4_ENABLE | PM0_ENABLE | PM1_ENABLE,
                        DC_CMD_DISPLAY_POWER_CONTROL);
@@ -151,16 +150,13 @@ static void tegra_dc_rgb_enable(struct tegra_dc *dc)
        /* Inform DC register updated */
        tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL);
        tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
-       tegra_dc_io_end(dc);
 }
 
 static void tegra_dc_rgb_disable(struct tegra_dc *dc)
 {
-       tegra_dc_io_start(dc);
        tegra_dc_writel(dc, 0x00000000, DC_CMD_DISPLAY_POWER_CONTROL);
 
        tegra_dc_write_table(dc, tegra_dc_rgb_disable_pintable);
-       tegra_dc_io_end(dc);
 }
 
 struct tegra_dc_out_ops tegra_dc_rgb_ops = {
index 48fef11..0b4350d 100644 (file)
@@ -31,16 +31,11 @@ static bool tegra_dc_windows_are_clean(struct tegra_dc_win *windows[],
                                             int n)
 {
        int i;
-       struct tegra_dc *dc = windows[0]->dc;
 
-       mutex_lock(&dc->lock);
        for (i = 0; i < n; i++) {
-               if (windows[i]->dirty) {
-                       mutex_unlock(&dc->lock);
+               if (windows[i]->dirty)
                        return false;
-               }
        }
-       mutex_unlock(&dc->lock);
 
        return true;
 }
@@ -105,7 +100,6 @@ static void tegra_dc_set_blending(struct tegra_dc *dc,
 {
        unsigned long mask = BIT(DC_N_WINDOWS) - 1;
 
-       tegra_dc_io_start(dc);
        while (mask) {
                int idx = get_topmost_window(blend->z, &mask);
 
@@ -122,7 +116,6 @@ static void tegra_dc_set_blending(struct tegra_dc *dc,
                tegra_dc_writel(dc, blend_3win(idx, mask, blend->flags),
                                DC_WIN_BLEND_3WIN_XY);
        }
-       tegra_dc_io_end(dc);
 }
 
 /* does not support syncing windows on multiple dcs in one call */
@@ -148,8 +141,6 @@ int tegra_dc_sync_windows(struct tegra_dc_win *windows[], int n)
        trace_printk("%s:After wait_event_interruptible_timeout\n",
                windows[0]->dc->ndev->name);
 #endif
-       /* tegra_dc_io_start() done in update_windows */
-       tegra_dc_io_end(windows[0]->dc);
        return ret;
 }
 EXPORT_SYMBOL(tegra_dc_sync_windows);
@@ -201,8 +192,7 @@ static inline u32 compute_initial_dda(fixed20_12 in)
        return dfixed_frac(in);
 }
 
-/* Does not support updating windows on multiple dcs in one call.
- * Requires a matching sync_windows to avoid leaking ref-count on clocks. */
+/* does not support updating windows on multiple dcs in one call */
 int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
 {
        struct tegra_dc *dc;
@@ -229,7 +219,6 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
                return -EFAULT;
        }
 
-       tegra_dc_io_start(dc);
        tegra_dc_hold_dc_out(dc);
 
        if (no_vsync)
@@ -435,7 +424,6 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
        trace_printk("%s:update_mask=%#lx\n", dc->ndev->name, update_mask);
 
        tegra_dc_release_dc_out(dc);
-       /* tegra_dc_io_end() is called in tegra_dc_sync_windows() */
        mutex_unlock(&dc->lock);
        if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
                mutex_unlock(&dc->one_shot_lock);