blob: abdf2d13c3b9854bdd8d861337d6567966c80dbb [file] [log] [blame]
Kinson Chik1ac45ce2011-05-29 22:01:34 -07001/*
2 * * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29#include <debug.h>
Kinson Chike5c93432011-06-17 09:10:29 -070030#include <reg.h>
31#include <mipi_dsi.h>
Kinson Chikfe931032011-07-21 10:01:34 -070032#include <mdp4.h>
Kinson Chik1ac45ce2011-05-29 22:01:34 -070033#include <dev/pm8921.h>
Kinson Chike5c93432011-06-17 09:10:29 -070034#include <platform/iomap.h>
35#include <platform/clock.h>
36#include <target/display.h>
Kinson Chik1ac45ce2011-05-29 22:01:34 -070037
Kinson Chike5c93432011-06-17 09:10:29 -070038void panel_backlight_on(void)
Kinson Chik1ac45ce2011-05-29 22:01:34 -070039{
40 struct pm8921_gpio backlight_pwm = {
41 .direction = PM_GPIO_DIR_OUT,
42 .output_buffer = 0,
43 .output_value = 0,
44 .pull = PM_GPIO_PULL_NO,
45 .vin_sel = 2,
46 .out_strength = PM_GPIO_STRENGTH_HIGH,
47 .function = PM_GPIO_FUNC_1,
48 .inv_int_pol = 0,
49 };
50
51 int rc = pm8921_gpio_config(GPIO_24, &backlight_pwm);
52 if (rc) {
Kinson Chike5c93432011-06-17 09:10:29 -070053 dprintf(CRITICAL, "FAIL pm8921_gpio_config(): rc=%d.\n", rc);
Kinson Chik1ac45ce2011-05-29 22:01:34 -070054 }
55}
Kinson Chike5c93432011-06-17 09:10:29 -070056
57/* Pull DISP_RST_N high to get panel out of reset */
58void mipi_panel_reset(void){
59
60 struct pm8921_gpio gpio43_param = {
61 .direction = PM_GPIO_DIR_OUT,
62 .output_buffer = 0,
63 .output_value = 1,
64 .pull = PM_GPIO_PULL_UP0,
65 .vin_sel = 2,
66 .out_strength = PM_GPIO_STRENGTH_HIGH,
67 .function = PM_GPIO_FUNC_PAIRED,
68 .inv_int_pol = 0,
69 .disable_pin = 0,
70 };
71 pm8921_gpio_config(GPIO_43, &gpio43_param);
72}
73
74void mipi_dsi_panel_power_on(void){
75
76 /* Turn on LDO8 for lcd1 mipi vdd */
77 pm8921_ldo_set_voltage(LDO_8, LDO_VOLTAGE_3_0V);
78
79 /* Turn on LDO23 for lcd1 mipi vddio */
80 pm8921_ldo_set_voltage(LDO_23, LDO_VOLTAGE_1_8V);
81
82 /* Turn on LDO2 for vdda_mipi_dsi */
83 pm8921_ldo_set_voltage(LDO_2, LDO_VOLTAGE_1_2V);
84
85}
86
87static void mipi_dsi_calibration(void)
88{
Greg Grisco1073a5e2011-07-28 18:59:18 -070089 uint32_t i = 0;
Kinson Chike5c93432011-06-17 09:10:29 -070090 uint32_t term_cnt = 5000;
91 int32_t cal_busy = readl(MIPI_DSI_BASE + 0x550);
92
93 /* DSI1_DSIPHY_REGULATOR_CAL_PWR_CFG */
94 writel(0x01, MIPI_DSI_BASE + 0x0518);
95
96 /* DSI1_DSIPHY_CAL_SW_CFG2 */
97 writel(0x0, MIPI_DSI_BASE + 0x0534);
98 /* DSI1_DSIPHY_CAL_HW_CFG1 */
99 writel(0x5a, MIPI_DSI_BASE + 0x053c);
100 /* DSI1_DSIPHY_CAL_HW_CFG3 */
101 writel(0x10, MIPI_DSI_BASE + 0x0544);
102 /* DSI1_DSIPHY_CAL_HW_CFG4 */
103 writel(0x01, MIPI_DSI_BASE + 0x0548);
104 /* DSI1_DSIPHY_CAL_HW_CFG0 */
105 writel(0x01, MIPI_DSI_BASE + 0x0538);
106
107 /* DSI1_DSIPHY_CAL_HW_TRIGGER */
108 writel(0x01, MIPI_DSI_BASE + 0x0528);
Kinson Chikf91907f2011-07-15 10:06:48 -0700109
Kinson Chike5c93432011-06-17 09:10:29 -0700110 /* DSI1_DSIPHY_CAL_HW_TRIGGER */
111 writel(0x00, MIPI_DSI_BASE + 0x0528);
112
113 cal_busy = readl(MIPI_DSI_BASE + 0x550);
114 while (cal_busy & 0x10) {
115 i++;
116 if (i > term_cnt) {
117 dprintf(CRITICAL, "DSI1 PHY REGULATOR NOT READY,"
118 "exceeded polling TIMEOUT!\n");
119 break;
120 }
121 cal_busy = readl(MIPI_DSI_BASE + 0x550);
122 }
123}
124
125int mipi_dsi_phy_init(struct mipi_dsi_panel_config *pinfo){
126 struct mipi_dsi_phy_ctrl *pd;
127 uint32_t i, off = 0;
128
Kinson Chikf91907f2011-07-15 10:06:48 -0700129 writel(0x0001, MIPI_DSI_BASE + 0x128);/* start phy sw reset */
Kinson Chike5c93432011-06-17 09:10:29 -0700130 writel(0x0000, MIPI_DSI_BASE + 0x128);/* end phy w reset */
131 writel(0x0003, MIPI_DSI_BASE + 0x500);/* regulator_ctrl_0 */
132 writel(0x0001, MIPI_DSI_BASE + 0x504);/* regulator_ctrl_1 */
133 writel(0x0001, MIPI_DSI_BASE + 0x508);/* regulator_ctrl_2 */
134 writel(0x0000, MIPI_DSI_BASE + 0x50c);/* regulator_ctrl_3 */
135 writel(0x0100, MIPI_DSI_BASE + 0x510);/* regulator_ctrl_4 */
136
137 pd = (pinfo->dsi_phy_config);
138
139 off = 0x0480; /* strength 0 - 2 */
140 for (i = 0; i < 3; i++) {
141 writel(pd->strength[i], MIPI_DSI_BASE + off);
142 off += 4;
143 }
144
145 off = 0x0470; /* ctrl 0 - 3 */
146 for (i = 0; i < 4; i++) {
147 writel(pd->ctrl[i], MIPI_DSI_BASE + off);
148 off += 4;
149 }
150
151 off = 0x0500; /* regulator ctrl 0 - 4 */
152 for (i = 0; i < 5; i++) {
153 writel(pd->regulator[i], MIPI_DSI_BASE + off);
154 off += 4;
155 }
156 mipi_dsi_calibration();
157
158 off = 0x0204; /* pll ctrl 1 - 19, skip 0 */
159 for (i = 1; i < 20; i++) {
160 writel(pd->pll[i], MIPI_DSI_BASE + off);
161 off += 4;
162 }
163
164 /* pll ctrl 0 */
165 writel(pd->pll[0], MIPI_DSI_BASE + 0x200);
166 writel((pd->pll[0] | 0x01), MIPI_DSI_BASE + 0x200);
167
168 /* Check that PHY is ready */
169 while(!(readl(DSIPHY_PLL_RDY) & 0x01));
170
171 writel(0x202D, DSI_CLKOUT_TIMING_CTRL);
172
173 off = 0x0440; /* phy timing ctrl 0 - 11 */
174 for (i = 0; i < 12; i++) {
175 writel(pd->timing[i], MIPI_DSI_BASE + off);
176 off += 4;
177 }
178 return 0;
179}
180
181/* Calculations specific for the Toshiba MDT61 Panel */
182void mdp_setup_mdt61_video_dsi_config(void){
183 unsigned long hsync_period;
184 unsigned long vsync_period;
185
186 /* For MDT61 display width is 200 more than image width */
187 hsync_period = TSH_MDT61_DISPLAY_WIDTH + MIPI_HSYNC_BACK_PORCH_DCLK
188 + MIPI_HSYNC_FRONT_PORCH_DCLK + MIPI_HSYNC_PULSE_WIDTH;
189
190 vsync_period = (TSH_MDT61_MIPI_FB_HEIGHT + MIPI_VSYNC_BACK_PORCH_LINES
191 + MIPI_VSYNC_FRONT_PORCH_LINES + MIPI_VSYNC_PULSE_WIDTH) * hsync_period;
192
193 writel(hsync_period<<16 | MIPI_HSYNC_PULSE_WIDTH<<0, MDP_DSI_VIDEO_HSYNC_CTL);
194 writel(vsync_period, MDP_DSI_VIDEO_VSYNC_PERIOD);
195 writel(MIPI_VSYNC_PULSE_WIDTH * hsync_period, MDP_DSI_VIDEO_VSYNC_PULSE_WIDTH);
196 writel((MIPI_HSYNC_BACK_PORCH_DCLK + MIPI_HSYNC_PULSE_WIDTH + TSH_MDT61_DISPLAY_WIDTH - 1)<<16 |
197 (MIPI_HSYNC_BACK_PORCH_DCLK + MIPI_HSYNC_PULSE_WIDTH), MDP_DSI_VIDEO_DISPLAY_HCTL);
198 writel(hsync_period * (MIPI_VSYNC_BACK_PORCH_LINES + MIPI_VSYNC_PULSE_WIDTH),
199 MDP_DSI_VIDEO_DISPLAY_V_START);
200 writel(hsync_period *
201 (MIPI_VSYNC_BACK_PORCH_LINES + MIPI_VSYNC_PULSE_WIDTH + TSH_MDT61_MIPI_FB_HEIGHT) - 1,
202 MDP_DSI_VIDEO_DISPLAY_V_END);
203
204 /* Special Case for Toshiba 4in Panel */
205 writel((1<<31) |
206 (MIPI_HSYNC_BACK_PORCH_DCLK + MIPI_HSYNC_PULSE_WIDTH + TSH_MDT61_MIPI_FB_WIDTH - 1)<<16 |
207 MIPI_HSYNC_PULSE_WIDTH + MIPI_HSYNC_BACK_PORCH_DCLK, MDP_DSI_VIDEO_ACTIVE_HCTL);
208 writel(1<<31 | hsync_period * (MIPI_VSYNC_BACK_PORCH_LINES + MIPI_VSYNC_PULSE_WIDTH),
209 MDP_DSI_VIDEO_DISPLAY_V_START);
210 writel((TSH_MDT61_MIPI_FB_HEIGHT + MIPI_VSYNC_BACK_PORCH_LINES + MIPI_VSYNC_PULSE_WIDTH) *
211 hsync_period - 1, MDP_DSI_VIDEO_DISPLAY_V_END);
212
213 writel(0x00000001, MDP_DSI_VIDEO_EN); // MDP_DSI_EN ENABLE
214}
215
216void config_mdt61_dsi_video_mode(void)
217{
218
219 unsigned char dst_format = 3; /* RGB888 */
220 unsigned char traffic_mode = 1; /* non burst mode with sync start events */
221 unsigned char lane_en = 7; /* 3 Lanes -- Enables Data Lane0, 1, 2 */
222 unsigned long low_pwr_stop_mode = 0;
223 unsigned char eof_bllp_pwr = 0x8; /* Needed or else will have blank line at top of display */
224 unsigned char interleav = 0;
225
226 dprintf(SPEW, "DSI_Video_Mode - Dst Format: RGB888\n");
227 dprintf(SPEW, "Data Lane: 3 lane\n");
228 dprintf(SPEW, "Traffic mode: non burst mode with sync start events\n");
229
230 writel(0x00000000, MDP_DSI_VIDEO_EN);
231
232 writel(0x00000000, DSI_CLK_CTRL);
233 writel(0x00000000, DSI_CLK_CTRL);
234 writel(0x00000000, DSI_CLK_CTRL);
235 writel(0x00000000, DSI_CLK_CTRL);
236 writel(0x00000002, DSI_CLK_CTRL);
237 writel(0x00000006, DSI_CLK_CTRL);
238 writel(0x0000000e, DSI_CLK_CTRL);
239 writel(0x0000001e, DSI_CLK_CTRL);
240 writel(0x0000003e, DSI_CLK_CTRL);
241
242 writel(0, DSI_CTRL);
243
244 writel(0, DSI_ERR_INT_MASK0);
245
246 writel(0x02020202, DSI_INT_CTRL);
247
248 writel((MIPI_HSYNC_PULSE_WIDTH + MIPI_HSYNC_BACK_PORCH_DCLK + TSH_MDT61_DISPLAY_WIDTH)<<16 |
249 (MIPI_HSYNC_PULSE_WIDTH + MIPI_HSYNC_BACK_PORCH_DCLK), DSI_VIDEO_MODE_ACTIVE_H);
250
251 writel((MIPI_VSYNC_PULSE_WIDTH + MIPI_VSYNC_BACK_PORCH_LINES + TSH_MDT61_MIPI_FB_HEIGHT)<<16 |
252 (MIPI_VSYNC_PULSE_WIDTH + MIPI_VSYNC_BACK_PORCH_LINES), DSI_VIDEO_MODE_ACTIVE_V);
253
254 writel((MIPI_VSYNC_PULSE_WIDTH + MIPI_VSYNC_BACK_PORCH_LINES + TSH_MDT61_MIPI_FB_HEIGHT +
255 MIPI_VSYNC_FRONT_PORCH_LINES - 1)<<16 |
256 (MIPI_HSYNC_PULSE_WIDTH + MIPI_HSYNC_BACK_PORCH_DCLK + TSH_MDT61_DISPLAY_WIDTH +
257 MIPI_HSYNC_FRONT_PORCH_DCLK - 1), DSI_VIDEO_MODE_TOTAL);
258
259 writel((MIPI_HSYNC_PULSE_WIDTH)<<16 | 0, DSI_VIDEO_MODE_HSYNC);
260
261 writel(0<<16 | 0, DSI_VIDEO_MODE_VSYNC);
262
263 writel(MIPI_VSYNC_PULSE_WIDTH<<16 | 0, DSI_VIDEO_MODE_VSYNC_VPOS);
264
265 writel(1, DSI_EOT_PACKET_CTRL);
266
267 writel(low_pwr_stop_mode << 16 | eof_bllp_pwr << 12 | traffic_mode << 8
268 | dst_format << 4 | 0x0, DSI_VIDEO_MODE_CTRL);
269
270 writel(0x00010100, DSI_INT_CTRL);
271 writel(0x02010202, DSI_INT_CTRL);
272 writel(0x02030303, DSI_INT_CTRL);
273
274 writel(interleav << 30 | 0 << 24 | 0 << 20 | lane_en << 4
275 | 0x103, DSI_CTRL);
276}