video: tegra: dc: power optimize DC and host1x clk
[linux-2.6.git] / drivers / video / tegra / dc / dsi.c
index 4a9e507..f60184b 100644 (file)
@@ -1391,8 +1391,7 @@ 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_readl(dc, DC_CMD_INT_MASK);
-       tegra_dc_writel(dc, val | FRAME_END_INT, DC_CMD_INT_MASK);
+       val = tegra_dc_unmask_interrupt(dc, FRAME_END_INT);
 
        tegra_dsi_stop_dc_stream(dc, dsi);
 
@@ -1412,7 +1411,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_writel(dc, val, DC_CMD_INT_MASK);
+       tegra_dc_restore_interrupt(dc, val); /* potentially a race? */
 
        if (timeout == 0)
                dev_warn(&dc->ndev->dev,
@@ -2142,15 +2141,13 @@ static void tegra_dc_dsi_idle(struct tegra_dc *dc)
                tegra_dsi_host_suspend(dc);
 }
 
-int tegra_dsi_write_data(struct tegra_dc *dc,
+static int tegra_dsi_write_data_nosync(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)) {
@@ -2164,10 +2161,27 @@ 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,
@@ -2186,7 +2200,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(dc, dsi,
+                       err = tegra_dsi_write_data_nosync(dc, dsi,
                                                cur_cmd->pdata,
                                                cur_cmd->data_id,
                                                cur_cmd->sp_len_dly.data_len);
@@ -2311,9 +2325,8 @@ int tegra_dsi_start_host_cmd_v_blank_dcs(struct tegra_dc_dsi_data * dsi,
                return -EINVAL;
 
        mutex_lock(&dsi->lock);
-       tegra_dc_dsi_hold_host(dc);
-
        tegra_dc_io_start(dc);
+       tegra_dc_dsi_hold_host(dc);
 
 
        err = tegra_dsi_dcs_pkt_seq_ctrl_init(dsi, cmd);
@@ -2334,8 +2347,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_io_end(dc);
        tegra_dc_dsi_release_host(dc);
+       tegra_dc_io_end(dc);
        mutex_unlock(&dsi->lock);
        return err;
 
@@ -2350,9 +2363,8 @@ void tegra_dsi_stop_host_cmd_v_blank_dcs(struct tegra_dc_dsi_data * dsi)
        u32 cnt;
 
        mutex_lock(&dsi->lock);
-       tegra_dc_dsi_hold_host(dc);
-
        tegra_dc_io_start(dc);
+       tegra_dc_dsi_hold_host(dc);
 
        tegra_dsi_writel(dsi, TEGRA_DSI_DISABLE, DSI_INIT_SEQ_CONTROL);
 
@@ -2360,9 +2372,9 @@ void tegra_dsi_stop_host_cmd_v_blank_dcs(struct tegra_dc_dsi_data * dsi)
        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);
@@ -2778,9 +2790,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
@@ -2893,8 +2905,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_io_end(dc);
        tegra_dc_dsi_release_host(dc);
+       tegra_dc_io_end(dc);
        mutex_unlock(&dsi->lock);
 }
 
@@ -3377,8 +3389,8 @@ static void tegra_dc_dsi_disable(struct tegra_dc *dc)
        int err;
        struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
 
-       tegra_dc_io_start(dc);
        mutex_lock(&dsi->lock);
+       tegra_dc_io_start(dc);
 
        if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE)
                tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi);