ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / panel-lgd-wxga-7-0.c
1 /*
2  * arch/arm/mach-tegra/panel-lgd-wxga-7-0.c
3  *
4  * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <linux/delay.h>
20 #include <linux/gpio.h>
21 #include <linux/tegra_pwm_bl.h>
22 #include <linux/regulator/consumer.h>
23 #include <linux/pwm_backlight.h>
24 #include <linux/max8831_backlight.h>
25 #include <linux/leds.h>
26 #include <linux/ioport.h>
27
28 #include <mach/dc.h>
29
30 #include "board.h"
31 #include "board-panel.h"
32 #include "devices.h"
33 #include "gpio-names.h"
34 #include "tegra11_host1x_devices.h"
35
36
37 #define DSI_PANEL_RESET         0
38 #define DC_CTRL_MODE    TEGRA_DC_OUT_CONTINUOUS_MODE
39
40 static bool reg_requested;
41 static bool gpio_requested;
42 static struct platform_device *disp_device;
43 static struct regulator *avdd_lcd_3v3;
44 static struct regulator *dvdd_lcd;
45 static struct regulator *vdd_lcd_bl_en;
46
47 static struct tegra_dc_sd_settings dsi_lgd_wxga_7_0_sd_settings = {
48         .enable = 1, /* enabled by default. */
49         .use_auto_pwm = false,
50         .hw_update_delay = 0,
51         .bin_width = -1,
52         .aggressiveness = 5,
53         .use_vid_luma = false,
54         .phase_in_adjustments = 0,
55         .k_limit_enable = true,
56         .k_limit = 200,
57         .sd_window_enable = false,
58         .soft_clipping_enable = true,
59         /* Low soft clipping threshold to compensate for aggressive k_limit */
60         .soft_clipping_threshold = 128,
61         .smooth_k_enable = false,
62         .smooth_k_incr = 64,
63         /* Default video coefficients */
64         .coeff = {5, 9, 2},
65         .fc = {0, 0},
66         /* Immediate backlight changes */
67         .blp = {1024, 255},
68         /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
69         /* Default BL TF */
70         .bltf = {
71                         {
72                                 {57, 65, 73, 82},
73                                 {92, 103, 114, 125},
74                                 {138, 150, 164, 178},
75                                 {193, 208, 224, 241},
76                         },
77                 },
78         /* Default LUT */
79         .lut = {
80                         {
81                                 {255, 255, 255},
82                                 {199, 199, 199},
83                                 {153, 153, 153},
84                                 {116, 116, 116},
85                                 {85, 85, 85},
86                                 {59, 59, 59},
87                                 {36, 36, 36},
88                                 {17, 17, 17},
89                                 {0, 0, 0},
90                         },
91                 },
92         .sd_brightness = &sd_brightness,
93         .use_vpulse2 = true,
94 };
95
96 static struct tegra_dsi_cmd dsi_lgd_wxga_7_0_init_cmd[] = {
97         DSI_CMD_SHORT(0x15, 0x01, 0x0),
98         DSI_DLY_MS(20),
99         DSI_CMD_SHORT(0x15, 0xAE, 0x0B),
100         DSI_CMD_SHORT(0x15, 0xEE, 0xEA),
101         DSI_CMD_SHORT(0x15, 0xEF, 0x5F),
102         DSI_CMD_SHORT(0x15, 0xF2, 0x68),
103         DSI_CMD_SHORT(0x15, 0xEE, 0x0),
104         DSI_CMD_SHORT(0x15, 0xEF, 0x0),
105 };
106
107 static struct tegra_dsi_cmd dsi_lgd_wxga_7_0_late_resume_cmd[] = {
108         DSI_CMD_SHORT(0x15, 0x10, 0x0),
109         DSI_DLY_MS(120),
110 };
111
112 static struct tegra_dsi_cmd dsi_lgd_wxga_7_0_early_suspend_cmd[] = {
113         DSI_CMD_SHORT(0x15, 0x11, 0x0),
114         DSI_DLY_MS(160),
115 };
116
117 static struct tegra_dsi_cmd dsi_lgd_wxga_7_0_suspend_cmd[] = {
118         DSI_CMD_SHORT(0x15, 0x11, 0x0),
119         DSI_DLY_MS(160),
120 };
121
122 static struct tegra_dsi_out dsi_lgd_wxga_7_0_pdata = {
123 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
124         .n_data_lanes = 2,
125         .controller_vs = DSI_VS_0,
126 #else
127         .controller_vs = DSI_VS_1,
128 #endif
129
130         .n_data_lanes = 4,
131         .video_burst_mode = TEGRA_DSI_VIDEO_NONE_BURST_MODE,
132
133         .pixel_format = TEGRA_DSI_PIXEL_FORMAT_24BIT_P,
134         .refresh_rate = 60,
135         .virtual_channel = TEGRA_DSI_VIRTUAL_CHANNEL_0,
136
137         .dsi_instance = DSI_INSTANCE_0,
138
139         .panel_reset = DSI_PANEL_RESET,
140         .power_saving_suspend = true,
141         .video_data_type = TEGRA_DSI_VIDEO_TYPE_VIDEO_MODE,
142
143         .video_clock_mode = TEGRA_DSI_VIDEO_CLOCK_TX_ONLY,
144
145         .dsi_init_cmd = dsi_lgd_wxga_7_0_init_cmd,
146         .n_init_cmd = ARRAY_SIZE(dsi_lgd_wxga_7_0_init_cmd),
147
148         .dsi_early_suspend_cmd = dsi_lgd_wxga_7_0_early_suspend_cmd,
149         .n_early_suspend_cmd = ARRAY_SIZE(dsi_lgd_wxga_7_0_early_suspend_cmd),
150
151         .dsi_late_resume_cmd = dsi_lgd_wxga_7_0_late_resume_cmd,
152         .n_late_resume_cmd = ARRAY_SIZE(dsi_lgd_wxga_7_0_late_resume_cmd),
153
154         .dsi_suspend_cmd = dsi_lgd_wxga_7_0_suspend_cmd,
155         .n_suspend_cmd = ARRAY_SIZE(dsi_lgd_wxga_7_0_suspend_cmd),
156
157         .phy_timing = {
158                 .t_clkprepare_ns = 27,
159                 .t_clkzero_ns = 330,
160                 .t_hsprepare_ns = 30,
161                 .t_datzero_ns = 270,
162         },
163 };
164
165 static int tegratab_dsi_regulator_get(struct device *dev)
166 {
167         int err = 0;
168
169         if (reg_requested)
170                 return 0;
171         avdd_lcd_3v3 = regulator_get(dev, "avdd_lcd");
172         if (IS_ERR(avdd_lcd_3v3)) {
173                 pr_err("avdd_lcd regulator get failed\n");
174                 err = PTR_ERR(avdd_lcd_3v3);
175                 avdd_lcd_3v3 = NULL;
176                 goto fail;
177         }
178
179         vdd_lcd_bl_en = regulator_get(dev, "vdd_lcd_bl_en");
180         if (IS_ERR(vdd_lcd_bl_en)) {
181                 pr_err("vdd_lcd_bl_en regulator get failed\n");
182                 err = PTR_ERR(vdd_lcd_bl_en);
183                 vdd_lcd_bl_en = NULL;
184                 goto fail;
185         }
186
187         dvdd_lcd = regulator_get(dev, "dvdd_lcd");
188         if (IS_ERR(dvdd_lcd)) {
189                 pr_err("dvdd_lcd regulator get failed\n");
190                 err = PTR_ERR(dvdd_lcd);
191                 dvdd_lcd = NULL;
192                 goto fail;
193         }
194         reg_requested = true;
195         return 0;
196 fail:
197         return err;
198 }
199
200 static int tegratab_dsi_gpio_get(void)
201 {
202         int err = 0;
203
204         if (gpio_requested)
205                 return 0;
206
207         /* free pwm GPIO */
208         err = gpio_request(dsi_lgd_wxga_7_0_pdata.dsi_panel_bl_pwm_gpio,
209                 "panel pwm");
210         if (err < 0) {
211                 pr_err("panel pwm gpio request failed\n");
212                 goto fail;
213         }
214         gpio_free(dsi_lgd_wxga_7_0_pdata.dsi_panel_bl_pwm_gpio);
215         gpio_requested = true;
216         return 0;
217 fail:
218         return err;
219 }
220
221 static int dsi_lgd_wxga_7_0_enable(struct device *dev)
222 {
223         int err = 0;
224
225         err = tegratab_dsi_regulator_get(dev);
226
227         if (err < 0) {
228                 pr_err("dsi regulator get failed\n");
229                 goto fail;
230         }
231
232         err = tegra_panel_gpio_get_dt("lg,wxga-7", &panel_of);
233         if (err < 0) {
234                 /* try to request gpios from board file */
235                 err = tegratab_dsi_gpio_get();
236                 if (err < 0) {
237                         pr_err("dsi gpio request failed\n");
238                         goto fail;
239                 }
240         }
241
242         /*
243          * Turning on 1.8V then AVDD after 5ms is required per spec.
244          */
245         msleep(20);
246
247         if (avdd_lcd_3v3) {
248                 err = regulator_enable(avdd_lcd_3v3);
249                 if (err < 0) {
250                         pr_err("avdd_lcd regulator enable failed\n");
251                         goto fail;
252                 }
253                 regulator_set_voltage(avdd_lcd_3v3, 3300000, 3300000);
254         }
255
256         msleep(150);
257         if (dvdd_lcd) {
258                 err = regulator_enable(dvdd_lcd);
259                 if (err < 0) {
260                         pr_err("dvdd_lcd regulator enable failed\n");
261                         goto fail;
262                 }
263         }
264
265         msleep(100);
266         if (vdd_lcd_bl_en) {
267                 err = regulator_enable(vdd_lcd_bl_en);
268                 if (err < 0) {
269                         pr_err("vdd_lcd_bl_en regulator enable failed\n");
270                         goto fail;
271                 }
272         }
273
274         msleep(100);
275 #if DSI_PANEL_RESET
276 /*
277  * Nothing is requested.
278  */
279 #endif
280
281         return 0;
282 fail:
283         return err;
284 }
285
286 static int dsi_lgd_wxga_7_0_disable(void)
287 {
288         if (vdd_lcd_bl_en)
289                 regulator_disable(vdd_lcd_bl_en);
290
291         if (dvdd_lcd)
292                 regulator_disable(dvdd_lcd);
293
294         if (avdd_lcd_3v3)
295                 regulator_disable(avdd_lcd_3v3);
296
297         return 0;
298 }
299
300 static int dsi_lgd_wxga_7_0_postsuspend(void)
301 {
302         return 0;
303 }
304
305 /*
306  * See display standard timings and a few constraints underneath
307  * \vendor\nvidia\tegra\core\drivers\hwinc
308  *
309  * Class: Display Standard Timings
310  *
311  * Programming of display timing registers must meet these restrictions:
312  * Constraint 1: H_REF_TO_SYNC + H_SYNC_WIDTH + H_BACK_PORCH > 11.
313  * Constraint 2: V_REF_TO_SYNC + V_SYNC_WIDTH + V_BACK_PORCH > 1.
314  * Constraint 3: V_FRONT_PORCH + V_SYNC_WIDTH +
315                                 V_BACK_PORCH > 1 (vertical blank).
316  * Constraint 4: V_SYNC_WIDTH >= 1, H_SYNC_WIDTH >= 1
317  * Constraint 5: V_REF_TO_SYNC >= 1, H_REF_TO_SYNC >= 0
318  * Constraint 6: V_FRONT_PORT >= (V_REF_TO_SYNC + 1),
319                                 H_FRONT_PORT >= (H_REF_TO_SYNC + 1)
320  * Constraint 7: H_DISP_ACTIVE >= 16, V_DISP_ACTIVE >= 16
321  */
322
323 /*
324  * how to determine pclk
325  * h_total =
326  * Horiz_BackPorch + Horiz_SyncWidth + Horiz_DispActive + Horiz_FrontPorch;
327  *
328  * v_total =
329  * Vert_BackPorch + Vert_SyncWidth + Vert_DispActive + Vert_FrontPorch;
330  * panel_freq = ( h_total * v_total * refresh_freq );
331  */
332
333 static struct tegra_dc_mode dsi_lgd_wxga_7_0_modes[] = {
334         {
335                 .pclk = 71000000, /* 890 *1323 *60 = 70648200 */
336                 .h_ref_to_sync = 10,
337                 .v_ref_to_sync = 1,
338                 .h_sync_width = 1,
339                 .v_sync_width = 1,
340                 .h_back_porch = 57,
341                 .v_back_porch = 14,
342                 .h_active = 800,
343                 .v_active = 1280,
344                 .h_front_porch = 32,
345                 .v_front_porch = 28,
346         },
347 };
348
349 static int dsi_lgd_wxga_7_0_bl_notify(struct device *unused, int brightness)
350 {
351         /*
352          * In early panel bring-up, we will
353          * not enable PRISM.
354          * Just use same brightness that is delivered from user side.
355          * TODO...
356          * use PRSIM brightness later.
357          */
358         if (brightness > 255) {
359                 pr_info("Error: Brightness > 255!\n");
360                 brightness = 255;
361         }
362         return brightness;
363 }
364
365 static int dsi_lgd_wxga_7_0_check_fb(struct device *dev, struct fb_info *info)
366 {
367         return info->device == &disp_device->dev;
368 }
369
370 static struct platform_pwm_backlight_data dsi_lgd_wxga_7_0_bl_data = {
371         .pwm_id         = 1,
372         .max_brightness = 255,
373         .dft_brightness = 224,
374         .pwm_period_ns  = 1000000,
375         .notify         = dsi_lgd_wxga_7_0_bl_notify,
376         /* Only toggle backlight on fb blank notifications for disp1 */
377         .check_fb       = dsi_lgd_wxga_7_0_check_fb,
378 };
379
380 static struct platform_device __maybe_unused
381                 dsi_lgd_wxga_7_0_bl_device = {
382         .name   = "pwm-backlight",
383         .id     = -1,
384         .dev    = {
385                 .platform_data = &dsi_lgd_wxga_7_0_bl_data,
386         },
387 };
388
389 static struct platform_device __maybe_unused
390                         *dsi_lgd_wxga_7_0_bl_devices[] __initdata = {
391         &tegra_pwfm_device,
392         &dsi_lgd_wxga_7_0_bl_device,
393 };
394
395 static int  __init dsi_lgd_wxga_7_0_register_bl_dev(void)
396 {
397         int err = 0;
398
399         err = platform_add_devices(dsi_lgd_wxga_7_0_bl_devices,
400                                 ARRAY_SIZE(dsi_lgd_wxga_7_0_bl_devices));
401         if (err) {
402                 pr_err("disp1 bl device registration failed");
403                 return err;
404         }
405         return err;
406 }
407
408 static void dsi_lgd_wxga_7_0_set_disp_device(
409         struct platform_device *display_device)
410 {
411         disp_device = display_device;
412 }
413
414 static void dsi_lgd_wxga_7_0_dc_out_init(struct tegra_dc_out *dc)
415 {
416         dc->dsi = &dsi_lgd_wxga_7_0_pdata;
417         dc->parent_clk = "pll_d_out0";
418         dc->modes = dsi_lgd_wxga_7_0_modes;
419         dc->n_modes = ARRAY_SIZE(dsi_lgd_wxga_7_0_modes);
420         dc->enable = dsi_lgd_wxga_7_0_enable;
421         dc->disable = dsi_lgd_wxga_7_0_disable;
422         dc->postsuspend = dsi_lgd_wxga_7_0_postsuspend,
423         dc->width = 94;
424         dc->height = 150;
425         dc->flags = DC_CTRL_MODE;
426 }
427
428 static void dsi_lgd_wxga_7_0_fb_data_init(struct tegra_fb_data *fb)
429 {
430         fb->xres = dsi_lgd_wxga_7_0_modes[0].h_active;
431         fb->yres = dsi_lgd_wxga_7_0_modes[0].v_active;
432 }
433
434 static void
435 dsi_lgd_wxga_7_0_sd_settings_init(struct tegra_dc_sd_settings *settings)
436 {
437         *settings = dsi_lgd_wxga_7_0_sd_settings;
438         settings->bl_device_name = "pwm-backlight";
439 }
440
441 static void dsi_lgd_wxga_7_0_cmu_init(struct tegra_dc_platform_data *pdata)
442 {
443         pdata->cmu = NULL; /* will write CMU stuff after calibration */
444 }
445
446 struct tegra_panel_ops dsi_lgd_wxga_7_0_ops = {
447         .enable = dsi_lgd_wxga_7_0_enable,
448         .disable = dsi_lgd_wxga_7_0_disable,
449         .postsuspend = dsi_lgd_wxga_7_0_postsuspend,
450 };
451
452 struct tegra_panel __initdata dsi_lgd_wxga_7_0 = {
453         .init_sd_settings = dsi_lgd_wxga_7_0_sd_settings_init,
454         .init_dc_out = dsi_lgd_wxga_7_0_dc_out_init,
455         .init_fb_data = dsi_lgd_wxga_7_0_fb_data_init,
456         .register_bl_dev = dsi_lgd_wxga_7_0_register_bl_dev,
457         .init_cmu_data = dsi_lgd_wxga_7_0_cmu_init,
458         .set_disp_device = dsi_lgd_wxga_7_0_set_disp_device,
459 };
460 EXPORT_SYMBOL(dsi_lgd_wxga_7_0);