video: tegra: dc: power optimize DC and host1x clk
[linux-2.6.git] / drivers / video / tegra / dc / rgb.c
1 /*
2  * drivers/video/tegra/dc/rgb.c
3  *
4  * Copyright (C) 2010 Google, Inc.
5  * Author: Erik Gilling <konkers@android.com>
6  *
7  * Copyright (c) 2010-2012, NVIDIA CORPORATION, All rights reserved.
8  *
9  * This software is licensed under the terms of the GNU General Public
10  * License version 2, as published by the Free Software Foundation, and
11  * may be copied, distributed, and modified under those terms.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  */
19
20 #include <linux/kernel.h>
21
22 #include <mach/dc.h>
23
24 #include "dc_reg.h"
25 #include "dc_priv.h"
26
27
28 static const u32 tegra_dc_rgb_enable_partial_pintable[] = {
29         DC_COM_PIN_OUTPUT_ENABLE0,      0x00000000,
30         DC_COM_PIN_OUTPUT_ENABLE1,      0x00000000,
31         DC_COM_PIN_OUTPUT_ENABLE2,      0x00000000,
32         DC_COM_PIN_OUTPUT_ENABLE3,      0x00000000,
33         DC_COM_PIN_OUTPUT_POLARITY0,    0x00000000,
34         DC_COM_PIN_OUTPUT_POLARITY2,    0x00000000,
35         DC_COM_PIN_OUTPUT_DATA0,        0x00000000,
36         DC_COM_PIN_OUTPUT_DATA1,        0x00000000,
37         DC_COM_PIN_OUTPUT_DATA2,        0x00000000,
38         DC_COM_PIN_OUTPUT_DATA3,        0x00000000,
39 };
40
41 static const u32 tegra_dc_rgb_enable_pintable[] = {
42         DC_COM_PIN_OUTPUT_ENABLE0,      0x00000000,
43         DC_COM_PIN_OUTPUT_ENABLE1,      0x00000000,
44         DC_COM_PIN_OUTPUT_ENABLE2,      0x00000000,
45         DC_COM_PIN_OUTPUT_ENABLE3,      0x00000000,
46         DC_COM_PIN_OUTPUT_POLARITY0,    0x00000000,
47         DC_COM_PIN_OUTPUT_POLARITY1,    0x01000000,
48         DC_COM_PIN_OUTPUT_POLARITY2,    0x00000000,
49         DC_COM_PIN_OUTPUT_POLARITY3,    0x00000000,
50         DC_COM_PIN_OUTPUT_DATA0,        0x00000000,
51         DC_COM_PIN_OUTPUT_DATA1,        0x00000000,
52         DC_COM_PIN_OUTPUT_DATA2,        0x00000000,
53         DC_COM_PIN_OUTPUT_DATA3,        0x00000000,
54 };
55
56 static const u32 tegra_dc_rgb_enable_out_sel_pintable[] = {
57         DC_COM_PIN_OUTPUT_SELECT0,      0x00000000,
58         DC_COM_PIN_OUTPUT_SELECT1,      0x00000000,
59         DC_COM_PIN_OUTPUT_SELECT2,      0x00000000,
60 #ifdef CONFIG_TEGRA_SILICON_PLATFORM
61         DC_COM_PIN_OUTPUT_SELECT3,      0x00000000,
62 #else
63         /* The display panel sub-board used on FPGA platforms (panel 86)
64            is non-standard. It expects the Data Enable signal on the WR
65            pin instead of the DE pin. */
66         DC_COM_PIN_OUTPUT_SELECT3,      0x00200000,
67 #endif
68         DC_COM_PIN_OUTPUT_SELECT4,      0x00210222,
69         DC_COM_PIN_OUTPUT_SELECT5,      0x00002200,
70         DC_COM_PIN_OUTPUT_SELECT6,      0x00020000,
71 };
72
73 static const u32 tegra_dc_rgb_disable_pintable[] = {
74         DC_COM_PIN_OUTPUT_ENABLE0,      0x55555555,
75         DC_COM_PIN_OUTPUT_ENABLE1,      0x55150005,
76         DC_COM_PIN_OUTPUT_ENABLE2,      0x55555555,
77         DC_COM_PIN_OUTPUT_ENABLE3,      0x55555555,
78         DC_COM_PIN_OUTPUT_POLARITY0,    0x00000000,
79         DC_COM_PIN_OUTPUT_POLARITY1,    0x00000000,
80         DC_COM_PIN_OUTPUT_POLARITY2,    0x00000000,
81         DC_COM_PIN_OUTPUT_POLARITY3,    0x00000000,
82         DC_COM_PIN_OUTPUT_DATA0,        0xaaaaaaaa,
83         DC_COM_PIN_OUTPUT_DATA1,        0xaaaaaaaa,
84         DC_COM_PIN_OUTPUT_DATA2,        0xaaaaaaaa,
85         DC_COM_PIN_OUTPUT_DATA3,        0xaaaaaaaa,
86         DC_COM_PIN_OUTPUT_SELECT0,      0x00000000,
87         DC_COM_PIN_OUTPUT_SELECT1,      0x00000000,
88         DC_COM_PIN_OUTPUT_SELECT2,      0x00000000,
89         DC_COM_PIN_OUTPUT_SELECT3,      0x00000000,
90         DC_COM_PIN_OUTPUT_SELECT4,      0x00000000,
91         DC_COM_PIN_OUTPUT_SELECT5,      0x00000000,
92         DC_COM_PIN_OUTPUT_SELECT6,      0x00000000,
93 };
94
95 static void tegra_dc_rgb_enable(struct tegra_dc *dc)
96 {
97         int i;
98         u32 out_sel_pintable[ARRAY_SIZE(tegra_dc_rgb_enable_out_sel_pintable)];
99
100         tegra_dc_io_start(dc);
101         tegra_dc_writel(dc, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
102                         PW4_ENABLE | PM0_ENABLE | PM1_ENABLE,
103                         DC_CMD_DISPLAY_POWER_CONTROL);
104
105         tegra_dc_writel(dc, DISP_CTRL_MODE_C_DISPLAY, DC_CMD_DISPLAY_COMMAND);
106
107         if (dc->out->out_pins) {
108                 tegra_dc_set_out_pin_polars(dc, dc->out->out_pins,
109                         dc->out->n_out_pins);
110                 tegra_dc_write_table(dc, tegra_dc_rgb_enable_partial_pintable);
111         } else {
112                 tegra_dc_write_table(dc, tegra_dc_rgb_enable_pintable);
113         }
114
115         memcpy(out_sel_pintable, tegra_dc_rgb_enable_out_sel_pintable,
116                 sizeof(tegra_dc_rgb_enable_out_sel_pintable));
117
118         if (dc->out && dc->out->out_sel_configs) {
119                 u8 *out_sels = dc->out->out_sel_configs;
120                 for (i = 0; i < dc->out->n_out_sel_configs; i++) {
121                         switch (out_sels[i]) {
122                         case TEGRA_PIN_OUT_CONFIG_SEL_LM1_M1:
123                                 out_sel_pintable[5*2+1] =
124                                         (out_sel_pintable[5*2+1] &
125                                         ~PIN5_LM1_LCD_M1_OUTPUT_MASK) |
126                                         PIN5_LM1_LCD_M1_OUTPUT_M1;
127                                 break;
128                         case TEGRA_PIN_OUT_CONFIG_SEL_LM1_LD21:
129                                 out_sel_pintable[5*2+1] =
130                                         (out_sel_pintable[5*2+1] &
131                                         ~PIN5_LM1_LCD_M1_OUTPUT_MASK) |
132                                         PIN5_LM1_LCD_M1_OUTPUT_LD21;
133                                 break;
134                         case TEGRA_PIN_OUT_CONFIG_SEL_LM1_PM1:
135                                 out_sel_pintable[5*2+1] =
136                                         (out_sel_pintable[5*2+1] &
137                                         ~PIN5_LM1_LCD_M1_OUTPUT_MASK) |
138                                         PIN5_LM1_LCD_M1_OUTPUT_PM1;
139                                 break;
140                         default:
141                                 dev_err(&dc->ndev->dev,
142                                         "Invalid pin config[%d]: %d\n",
143                                          i, out_sels[i]);
144                                 break;
145                         }
146                 }
147         }
148
149         tegra_dc_write_table(dc, out_sel_pintable);
150
151         /* Inform DC register updated */
152         tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL);
153         tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
154         tegra_dc_io_end(dc);
155 }
156
157 static void tegra_dc_rgb_disable(struct tegra_dc *dc)
158 {
159         tegra_dc_io_start(dc);
160         tegra_dc_writel(dc, 0x00000000, DC_CMD_DISPLAY_POWER_CONTROL);
161
162         tegra_dc_write_table(dc, tegra_dc_rgb_disable_pintable);
163         tegra_dc_io_end(dc);
164 }
165
166 struct tegra_dc_out_ops tegra_dc_rgb_ops = {
167         .enable = tegra_dc_rgb_enable,
168         .disable = tegra_dc_rgb_disable,
169 };
170