blob: 6782773801220c1cf4f8bb9d5535e2e14c13b5f6 [file] [log] [blame]
Shashank Mittal402d0972010-09-29 10:09:52 -07001/*
2 * * Copyright (c) 2010, 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
30#include <debug.h>
31#include <kernel/thread.h>
32#include <i2c_qup.h>
33#include <platform/iomap.h>
34#include <platform/gpio_hw.h>
35#include <platform/clock.h>
36#include <platform/pmic.h>
37
38#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
39
40static struct qup_i2c_dev *dev = NULL;
41
42uint8_t expander_read(uint8_t addr)
43{
44 uint8_t ret = 0;
45 /* Create a i2c_msg buffer, that is used to put the controller into read
46 mode and then to read some data. */
47 struct i2c_msg msg_buf[] = {
48 {CORE_GPIO_EXPANDER_I2C_ADDRESS, I2C_M_WR, 1, &addr},
49 {CORE_GPIO_EXPANDER_I2C_ADDRESS, I2C_M_RD, 1, &ret}
50 };
51
52 qup_i2c_xfer(dev, msg_buf, 2);
53
54 return ret;
55}
56
57uint8_t expander_write(uint8_t addr, uint8_t val)
58{
59 uint8_t data_buf[] = { addr, val };
60
61 /* Create a i2c_msg buffer, that is used to put the controller into write
62 mode and then to write some data. */
63 struct i2c_msg msg_buf[] = { {CORE_GPIO_EXPANDER_I2C_ADDRESS,
64 I2C_M_WR, 2, data_buf}
65 };
66
67 qup_i2c_xfer(dev, msg_buf, 1);
68
69 /* Double check that the write worked. */
70 if (val != expander_read(addr)) {
71 return -1;
72 }
73
74 return 0;
75}
76
77void panel_poweron(void)
78{
79 panel_backlight(1);
80 lcdc_on();
81}
82
83void panel_backlight(int on)
84{
85}
86
87static int display_common_power(int on)
88{
89}
90
91static int lcd_power_on()
92{
93 uint8_t buffer = 0x0, mask = 0x0, prev_val = 0x0;
94 int ret = 0;
95
96 /* Configure LDO L2 TEST Bank 2, to Range Select 0 */
97 buffer = (0x80); /* Write mode */
98 buffer |= (PM8901_LDO_TEST_BANK(2)); /* Test Bank 2 */
99 mask = buffer | LDO_TEST_RANGE_SELECT_MASK;
100
101 if ((ret = pm8901_test_bank_read(&prev_val,
102 PM8901_LDO_TEST_BANK(2),
103 PM8901_LDO_L2_TEST_BANK))) {
104 return ret;
105 }
106 if ((ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2_TEST_BANK,
107 prev_val))) {
108 return ret;
109 }
110
111 /* Configure LDO L2 TEST Bank 4, for High Range Mode */
112 buffer = (0x80); /* Write mode */
113 buffer |= (PM8901_LDO_TEST_BANK(4)); /* Test Bank 4 */
114 buffer |= (0x01); /* Put into High Range Mode */
115 mask = buffer | LDO_TEST_OUTPUT_RANGE_MASK;
116
117 if ((ret = pm8901_test_bank_read(&prev_val,
118 PM8901_LDO_TEST_BANK(4),
119 PM8901_LDO_L2_TEST_BANK))) {
120 return ret;
121 }
122 if ((ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2_TEST_BANK,
123 prev_val))) {
124 return ret;
125 }
126
127 /* Configure LDO L2 TEST Bank 5, for XO_EN<3-0> to 1 */
128 buffer = (0x80); /* Write mode */
129 buffer |= (PM8901_LDO_TEST_BANK(5)); /* Test Bank 5 */
130 buffer |= (0x0F); /* Enable XO_EN */
131 mask = buffer | LDO_TEST_XO_EN_ALL_MASK;
132
133 if ((ret = pm8901_test_bank_read(&prev_val,
134 PM8901_LDO_TEST_BANK(5),
135 PM8901_LDO_L2_TEST_BANK))) {
136 return ret;
137 }
138 if ((ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2_TEST_BANK,
139 prev_val))) {
140 return ret;
141 }
142
143 /* Enable LDO L2 at Max Voltage (should be around 3.3v) */
144 buffer = (0x1 << PM8901_LDO_CTL_ENABLE__S);
145 /* Disable Pull Down */
146 buffer |= (0x0 << PM8901_LDO_CTL_PULL_DOWN__S);
147 /* Put LDO into normal mode instead of low power mode */
148 buffer |= (0x0 << PM8901_LDO_CTL_MODE__S);
149 /* Write a 31 into the Voltage Programming value to obtain 3.3v VREG =
150 1.75V + X * 100mV */
151 buffer |= (0x1F);
152 mask = buffer | LDO_CTL_ENABLE_MASK |
153 LDO_CTL_PULL_DOWN_MASK |
154 LDO_CTL_NORMAL_POWER_MODE_MASK | LDO_CTL_VOLTAGE_SET_MASK;
155
156 /* Do a normal read here, as to not destroy the value in LDO control */
157 if ((ret = pm8901_read(&prev_val, 1, PM8901_LDO_L2))) {
158 return ret;
159 }
160 /* Configure the LDO2 for 3.3v */
161 ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2, prev_val);
162 return ret;
163}
164
165/* Configures the GPIO that are needed to enable LCD.
166 * This function also configures the PMIC for PWM control of the LCD backlight.
167 */
168static void lcd_gpio_cfg(uint8_t on)
169{
170 uint32_t func;
171 uint32_t pull;
172 uint32_t dir;
173 uint32_t enable = 0; /* not used in gpio_tlmm_config */
174 uint32_t drv;
175 if (on) {
176 func = 1; /* Configure GPIO for LCDC function */
177 pull = GPIO_NO_PULL;
178 dir = 1; /* doesn't matter since it is not configured as
179 GPIO */
180 drv = GPIO_16MA;
181 } else {
182 /* As discussed in the MSM8660 FFA HW SW Control Doc configure these
183 GPIO as input and pull down. */
184 func = 0; /* GPIO */
185 pull = GPIO_PULL_DOWN;
186 dir = 0; /* Input */
187 drv = 0; /* does not matter configured as input */
188 }
189
190 gpio_tlmm_config(0, func, dir, pull, drv, enable); /* lcdc_pclk */
191 gpio_tlmm_config(1, func, dir, pull, drv, enable); /* lcdc_hsync */
192 gpio_tlmm_config(2, func, dir, pull, drv, enable); /* lcdc_vsync */
193 gpio_tlmm_config(3, func, dir, pull, drv, enable); /* lcdc_den */
194 gpio_tlmm_config(4, func, dir, pull, drv, enable); /* lcdc_red7 */
195 gpio_tlmm_config(5, func, dir, pull, drv, enable); /* lcdc_red6 */
196 gpio_tlmm_config(6, func, dir, pull, drv, enable); /* lcdc_red5 */
197 gpio_tlmm_config(7, func, dir, pull, drv, enable); /* lcdc_red4 */
198 gpio_tlmm_config(8, func, dir, pull, drv, enable); /* lcdc_red3 */
199 gpio_tlmm_config(9, func, dir, pull, drv, enable); /* lcdc_red2 */
200 gpio_tlmm_config(10, func, dir, pull, drv, enable); /* lcdc_red1 */
201 gpio_tlmm_config(11, func, dir, pull, drv, enable); /* lcdc_red0 */
202 gpio_tlmm_config(12, func, dir, pull, drv, enable); /* lcdc_rgn7 */
203 gpio_tlmm_config(13, func, dir, pull, drv, enable); /* lcdc_rgn6 */
204 gpio_tlmm_config(14, func, dir, pull, drv, enable); /* lcdc_rgn5 */
205 gpio_tlmm_config(15, func, dir, pull, drv, enable); /* lcdc_rgn4 */
206 gpio_tlmm_config(16, func, dir, pull, drv, enable); /* lcdc_rgn3 */
207 gpio_tlmm_config(17, func, dir, pull, drv, enable); /* lcdc_rgn2 */
208 gpio_tlmm_config(18, func, dir, pull, drv, enable); /* lcdc_rgn1 */
209 gpio_tlmm_config(19, func, dir, pull, drv, enable); /* lcdc_rgn0 */
210 gpio_tlmm_config(20, func, dir, pull, drv, enable); /* lcdc_blu7 */
211 gpio_tlmm_config(21, func, dir, pull, drv, enable); /* lcdc_blu6 */
212 gpio_tlmm_config(22, func, dir, pull, drv, enable); /* lcdc_blu5 */
213 gpio_tlmm_config(23, func, dir, pull, drv, enable); /* lcdc_blu4 */
214 gpio_tlmm_config(24, func, dir, pull, drv, enable); /* lcdc_blu3 */
215 gpio_tlmm_config(25, func, dir, pull, drv, enable); /* lcdc_blu2 */
216 gpio_tlmm_config(26, func, dir, pull, drv, enable); /* lcdc_blu1 */
217 gpio_tlmm_config(27, func, dir, pull, drv, enable); /* lcdc_blu0 */
218}
219
220/* Backlight duty cycle init is used to configure the PMIC8058 for
221 * PWM output and drive those pins.
222 */
223static void bl_duty_cycle_init(void)
224{
225 /* Disable backlight LPG channels before configuring them and dedicated
226 PMIC GPIOs */
227 pm8058_write_one(0x00, LPG_BANK_ENABLE);
228
229 /* Configure PM8058 GPIO24 as a PWM driver (LPG ch0) for chain 1 of 6 LEDs */
230 pm8058_write_one(0x81, GPIO24_GPIO_CNTRL); /* Write, Bank0, VIN0, Mode
231 selection enabled */
232 pm8058_write_one(0x98, GPIO24_GPIO_CNTRL); /* Write, Bank1, OutOn/InOff,
233 CMOS, Don't Invert Output */
234 pm8058_write_one(0xAA, GPIO24_GPIO_CNTRL); /* Write, Bank2, GPIO no pull */
235 pm8058_write_one(0xB4, GPIO24_GPIO_CNTRL); /* Write, Bank3, high drv
236 strength */
237 pm8058_write_one(0xC6, GPIO24_GPIO_CNTRL); /* Write, Bank4, Src: LPG_DRV1
238 (Spec. Fnc 2) */
239 pm8058_write_one(0xD8, GPIO24_GPIO_CNTRL); /* Write, Bank5, Interrupt
240 polarity noninversion */
241
242 /* Configure PM8058 GPIO25 as a PWM driver (LPG ch1) for chain 2 of 5 LEDs */
243 pm8058_write_one(0x81, GPIO25_GPIO_CNTRL); /* Write, Bank0, VIN0, Mode
244 selection enabled */
245 pm8058_write_one(0x98, GPIO25_GPIO_CNTRL); /* Write, Bank1, OutOn/InOff,
246 CMOS, Don't Invert Output */
247 pm8058_write_one(0xAA, GPIO25_GPIO_CNTRL); /* Write, Bank2, GPIO no pull */
248 pm8058_write_one(0xB4, GPIO25_GPIO_CNTRL); /* Write, Bank3, high drv
249 strength */
250 pm8058_write_one(0xC6, GPIO25_GPIO_CNTRL); /* Write, Bank4, Src: LPG_DRV2
251 (Spec. Fnc 2) */
252 pm8058_write_one(0xD8, GPIO25_GPIO_CNTRL); /* Write, Bank5, Interrupt
253 polarity noninversion */
254
255 /* Configure PM8058 LPG channel 0 as non-LUT PWM for PM8058 GPIO24 */
256 pm8058_write_one(0x0, LPG_BANK_SEL); /* Select LPG ch0 slice of control
257 regs */
258 pm8058_write_one(0x00, LPG_CTL_0); /* Disable PWM, PWM output, and LPG
259 ramp generator */
260 pm8058_write_one(0x40, LPG_CTL_1); /* Dont Toggle, Enable user PWM value,
261 no LUT high value idx */
262 pm8058_write_one(0x00, LPG_CTL_2); /* Dont Loop, no LUT low value index */
263 pm8058_write_one(0xDE, LPG_CTL_3); /* LS 8 bits of 9-bit PWM user value */
264 pm8058_write_one(0x7F, LPG_CTL_4); /* MSbit of 9-bit PWM user value,
265 19.2MHz, Dev 6, Expo M = 7 */
266 pm8058_write_one(0x01, LPG_CTL_5); /* PWM = 9bit, disable pause at high
267 value LUT index */
268 pm8058_write_one(0x00, LPG_CTL_6); /* Disable pause at low value LUT index
269 */
270 pm8058_write_one(0x0C, LPG_CTL_0); /* Enable PWM and PWM output, LPG ramp
271 generator remains disabled */
272
273 /* Configure PM8058 LPG chan 1 as PWM for PM8058 GPIO25 */
274 pm8058_write_one(0x1, LPG_BANK_SEL); /* Select LPG ch1 slice of control
275 regs */
276 pm8058_write_one(0x00, LPG_CTL_0); /* Disable PWM, PWM output, and LPG
277 ramp generator */
278 pm8058_write_one(0x40, LPG_CTL_1); /* Dont Toggle, Enable user PWM value,
279 no LUT high value idx */
280 pm8058_write_one(0x00, LPG_CTL_2); /* Dont Loop, no LUT low value index */
281 pm8058_write_one(0x00, LPG_CTL_3); /* LS 8 bits of 9-bit PWM user value */
282 pm8058_write_one(0x7F, LPG_CTL_4); /* MSbit of 9-bit PWM user value,
283 19.2MHz, Dev 6, Expo M = 7 */
284 pm8058_write_one(0x01, LPG_CTL_5); /* PWM = 9bit, disable pause at high
285 value LUT index */
286 pm8058_write_one(0x00, LPG_CTL_6); /* Disable pause at low value LUT index
287 */
288 pm8058_write_one(0x0C, LPG_CTL_0); /* Enable PWM and PWM output, LPG ramp
289 generator remains disabled */
290
291 /* Enable both LPG channels to enable backlight driver */
292 pm8058_write_one(0x03, LPG_BANK_ENABLE); /* Enable LPG ch0 (GPIO24) &
293 ch1 (GPIO25) */
294}
295
296void board_lcd_enable(void)
297{
298 dev = qup_i2c_init(GSBI8_BASE, 100000, 24000000);
299
300 /* Make sure dev is created and initialized properly */
301 if (!dev) {
302 while (1) ;
303 return;
304 }
305
306 /* Store current value of these registers as to not destroy their previous
307 state. */
308 uint8_t open_drain_a = expander_read(GPIO_EXPANDER_REG_OPEN_DRAIN_A);
309 uint8_t dir_b = expander_read(GPIO_EXPANDER_REG_DIR_B);
310 uint8_t dir_a = expander_read(GPIO_EXPANDER_REG_DIR_A);
311 uint8_t data_b = expander_read(GPIO_EXPANDER_REG_DATA_B);
312 uint8_t data_a = expander_read(GPIO_EXPANDER_REG_DATA_A);
313
314 /* Set the LVDS_SHUTDOWN_N to open drain and output low. */
315 dprintf(INFO, "Enable lvds_shutdown_n line for Open Drain.\n");
316 expander_write(GPIO_EXPANDER_REG_OPEN_DRAIN_A, 0x04 | open_drain_a);
317
318 dprintf(INFO, "Enable lvds_shutdown_n line for output.\n");
319 expander_write(GPIO_EXPANDER_REG_DIR_A, ~0x04 & dir_a);
320
321 dprintf(INFO, "Drive the LVDS_SHUTDOWN_N pin high here.\n");
322 expander_write(GPIO_EXPANDER_REG_DATA_A, 0x04 | data_a);
323
324 /* Turn on the VREG_L2B to 3.3V. */
325
326 /* Power on the appropiate PMIC LDO power rails */
327 if (lcd_power_on())
328 return;
329
330 /* Enable the GPIO as LCDC mode LCD. */
331 lcd_gpio_cfg(1);
332
333 /* Arbitrary delay */
334 udelay(20000);
335
336 /* Set the backlight duty cycle via the PM8058 LPG_DRV1 and LPG_DRV2 */
337 bl_duty_cycle_init();
338
339 dprintf(INFO, "Enable BACKLIGHT_EN line for output.\n");
340 expander_write(GPIO_EXPANDER_REG_DIR_B, ~0x10 & dir_b);
341
342 dprintf(INFO, "Drive BACKLIGHT_EN to high\n");
343 expander_write(GPIO_EXPANDER_REG_DATA_B, 0x10 | data_b);
344
345}
346
347void mdp_clock_init(void)
348{
Shashank Mittalc648e712010-10-06 18:37:42 -0700349 int uxo = pxo_is_27mhz();
Shashank Mittal402d0972010-09-29 10:09:52 -0700350 /* Set the MDP_AXI_CLK to 165MHz, use MX0 for now */
Shashank Mittalc648e712010-10-06 18:37:42 -0700351 config_mdp_axi_clk(uxo);
Shashank Mittal402d0972010-09-29 10:09:52 -0700352
353 /* Turn on the PLL2, to ramp up the MDP clock to max (200MHz) */
354 nt_pll_enable(PLL_2, 1);
355
356 config_mdp_clk(MDP_NS_VAL, MDP_MD_VAL,
357 MDP_CC_VAL, MDP_NS_REG, MDP_MD_REG, MDP_CC_REG);
358
359 config_pixel_clk(PIXEL_NS_VAL, PIXEL_MD_VAL,
360 PIXEL_CC_VAL, LCD_PIXEL_NS_REG,
361 LCD_PIXEL_MD_REG, LCD_PIXEL_CC_REG);
362}
363
364void lcdc_on(void)
365{
366 board_lcd_enable();
367}