ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / panel-c-lvds-1366-14.c
1 /*
2  * arch/arm/mach-tegra/panel-c-lvds-1366-4.c
3  *
4  * Copyright (c) 2013, 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 <mach/dc.h>
20 #include <linux/delay.h>
21 #include <linux/gpio.h>
22 #include <linux/tegra_pwm_bl.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/pwm_backlight.h>
25 #include <linux/max8831_backlight.h>
26 #include <linux/leds.h>
27 #include <linux/ioport.h>
28 #include "board.h"
29 #include "board-panel.h"
30 #include "devices.h"
31 #include "gpio-names.h"
32 #include "tegra12_host1x_devices.h"
33
34 #define DC_CTRL_MODE    TEGRA_DC_OUT_CONTINUOUS_MODE
35
36 #define LVDS_PANEL_BL_PWM       TEGRA_GPIO_PH1
37
38 static bool reg_requested;
39 static bool gpio_requested;
40 static struct platform_device *disp_device;
41
42 static struct regulator *vdd_lcd_bl;
43 static struct regulator *vdd_lcd_bl_en;
44 static struct regulator *avdd_lcd;
45 static struct regulator *vdd_ds_1v8;
46 static struct regulator *dvdd_lcd_1v8;
47
48 static struct tegra_dc_sd_settings lvds_c_1366_14_sd_settings = {
49         .enable = 1, /* enabled by default. */
50         .use_auto_pwm = false,
51         .hw_update_delay = 0,
52         .bin_width = -1,
53         .aggressiveness = 5,
54         .use_vid_luma = false,
55         .phase_in_adjustments = 0,
56         .k_limit_enable = true,
57         .k_limit = 200,
58         .sd_window_enable = false,
59         .soft_clipping_enable = true,
60         /* Low soft clipping threshold to compensate for aggressive k_limit */
61         .soft_clipping_threshold = 128,
62         .smooth_k_enable = false,
63         .smooth_k_incr = 64,
64         /* Default video coefficients */
65         .coeff = {5, 9, 2},
66         .fc = {0, 0},
67         /* Immediate backlight changes */
68         .blp = {1024, 255},
69         /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
70         /* Default BL TF */
71         .bltf = {
72                         {
73                                 {57, 65, 73, 82},
74                                 {92, 103, 114, 125},
75                                 {138, 150, 164, 178},
76                                 {193, 208, 224, 241},
77                         },
78                 },
79         /* Default LUT */
80         .lut = {
81                         {
82                                 {255, 255, 255},
83                                 {199, 199, 199},
84                                 {153, 153, 153},
85                                 {116, 116, 116},
86                                 {85, 85, 85},
87                                 {59, 59, 59},
88                                 {36, 36, 36},
89                                 {17, 17, 17},
90                                 {0, 0, 0},
91                         },
92                 },
93         .sd_brightness = &sd_brightness,
94         .use_vpulse2 = true,
95 };
96
97 static tegra_dc_bl_output lvds_c_1366_14_bl_output_measured = {
98         /*  TODO: linear backlight calibration */
99         0,   1,   2,   3,   4,   5,   6,   7,
100         8,   9,  10,  11,  12,  13,  14,  15,
101         16,  17,  18,  19,  20,  21,  22,  23,
102         24,  25,  26,  27,  28,  29,  30,  31,
103         32,  33,  34,  35,  36,  37,  38,  39,
104         40,  41,  42,  43,  44,  45,  46,  47,
105         48,  49,  50,  51,  52,  53,  54,  55,
106         56,  57,  58,  59,  60,  61,  62,  63,
107         64,  65,  66,  67,  68,  69,  70,  71,
108         72,  73,  74,  75,  76,  77,  78,  79,
109         80,  81,  82,  83,  84,  85,  86,  87,
110         88,  89,  90,  91,  92,  93,  94,  95,
111         96,  97,  98,  99, 100, 101, 102, 103,
112         104, 105, 106, 107, 108, 109, 110, 111,
113         112, 113, 114, 115, 116, 117, 118, 119,
114         120, 121, 122, 123, 124, 125, 126, 127,
115         128, 129, 130, 131, 132, 133, 134, 135,
116         136, 137, 138, 139, 140, 141, 142, 143,
117         144, 145, 146, 147, 148, 149, 150, 151,
118         152, 153, 154, 155, 156, 157, 158, 159,
119         160, 161, 162, 163, 164, 165, 166, 167,
120         168, 169, 170, 171, 172, 173, 174, 175,
121         176, 177, 178, 179, 180, 181, 182, 183,
122         184, 185, 186, 187, 188, 189, 190, 191,
123         192, 193, 194, 195, 196, 197, 198, 199,
124         200, 201, 202, 203, 204, 205, 206, 207,
125         208, 209, 210, 211, 212, 213, 214, 215,
126         216, 217, 218, 219, 220, 221, 222, 223,
127         224, 225, 226, 227, 228, 229, 230, 231,
128         232, 233, 234, 235, 236, 237, 238, 239,
129         240, 241, 242, 243, 244, 245, 246, 247,
130         248, 249, 250, 251, 252, 253, 254, 255
131 };
132
133 static int laguna_lvds_regulator_get(struct device *dev)
134 {
135         int err = 0;
136
137         if (reg_requested)
138                 return 0;
139
140         vdd_ds_1v8 = regulator_get(dev, "vdd_ds_1v8");
141         if (IS_ERR(vdd_ds_1v8)) {
142                 pr_err("vdd_ds_1v8 regulator get failed\n");
143                 err = PTR_ERR(vdd_ds_1v8);
144                 vdd_ds_1v8 = NULL;
145                 goto fail;
146         }
147
148         vdd_lcd_bl = regulator_get(dev, "vdd_lcd_bl");
149         if (IS_ERR(vdd_lcd_bl)) {
150                 pr_err("vdd_lcd_bl regulator get failed\n");
151                 err = PTR_ERR(vdd_lcd_bl);
152                 vdd_lcd_bl = NULL;
153                 goto fail;
154         }
155
156         vdd_lcd_bl_en = regulator_get(dev, "vdd_lcd_bl_en");
157         if (IS_ERR(vdd_lcd_bl_en)) {
158                 pr_err("vdd_lcd_bl_en regulator get failed\n");
159                 err = PTR_ERR(vdd_lcd_bl_en);
160                 vdd_lcd_bl_en = NULL;
161                 goto fail;
162         }
163
164         avdd_lcd = regulator_get(dev, "avdd_lcd");
165         if (IS_ERR(avdd_lcd)) {
166                 pr_err("avdd_lcd regulator get failed\n");
167                 err = PTR_ERR(avdd_lcd);
168                 avdd_lcd = NULL;
169                 goto fail;
170         }
171
172         dvdd_lcd_1v8 = regulator_get(dev, "dvdd_lcd");
173         if (IS_ERR(dvdd_lcd_1v8)) {
174                 pr_err("dvdd_lcd regulator get failed\n");
175                 err = PTR_ERR(dvdd_lcd_1v8);
176                 dvdd_lcd_1v8 = NULL;
177                 goto fail;
178         }
179
180         reg_requested = true;
181         return 0;
182 fail:
183         return err;
184 }
185
186 static int laguna_lvds_gpio_get(void)
187 {
188         int err = 0;
189
190         if (gpio_requested)
191                 return 0;
192
193         err = gpio_request(LVDS_PANEL_BL_PWM, "panel pwm");
194         if (err < 0) {
195                 pr_err("panel pwm gpio request failed\n");
196                 goto fail;
197         }
198         gpio_free(LVDS_PANEL_BL_PWM);
199
200         gpio_requested = true;
201         return 0;
202 fail:
203         return err;
204 }
205
206 static int lvds_c_1366_14_enable(struct device *dev)
207 {
208         int err = 0;
209
210         err = laguna_lvds_regulator_get(dev);
211         if (err < 0) {
212                 pr_err("lvds regulator get failed\n");
213                 goto fail;
214         }
215
216         err = laguna_lvds_gpio_get();
217         if (err < 0) {
218                 pr_err("lvds gpio request failed\n");
219                 goto fail;
220         }
221
222         if (vdd_lcd_bl) {
223                 err = regulator_enable(vdd_lcd_bl);
224                 if (err < 0) {
225                         pr_err("vdd_lcd_bl regulator enable failed\n");
226                         goto fail;
227                 }
228         }
229
230         msleep(20);
231
232         if (vdd_ds_1v8) {
233                 err = regulator_enable(vdd_ds_1v8);
234                 if (err < 0) {
235                         pr_err("vdd_ds_1v8 regulator enable failed\n");
236                         goto fail;
237                 }
238         }
239
240         if (avdd_lcd) {
241                 err = regulator_enable(avdd_lcd);
242                 if (err < 0) {
243                         pr_err("avdd_lcd regulator enable failed\n");
244                         goto fail;
245                 }
246         }
247
248         msleep(10);
249
250         if (vdd_lcd_bl_en) {
251                 err = regulator_enable(vdd_lcd_bl_en);
252                 if (err < 0) {
253                         pr_err("vdd_lcd_bl_en regulator enable failed\n");
254                         goto fail;
255                 }
256         }
257
258         if (dvdd_lcd_1v8) {
259                 err = regulator_enable(dvdd_lcd_1v8);
260                 if (err < 0) {
261                         pr_err("dvdd_lcd_1v8 regulator enable failed\n");
262                         goto fail;
263                 }
264         }
265
266         return 0;
267 fail:
268         return err;
269 }
270
271 static int lvds_c_1366_14_disable(void)
272 {
273         if (vdd_lcd_bl_en)
274                 regulator_disable(vdd_lcd_bl_en);
275
276         msleep(10);
277
278         if (avdd_lcd)
279                 regulator_disable(avdd_lcd);
280
281         if (vdd_ds_1v8)
282                 regulator_disable(vdd_ds_1v8);
283
284         msleep(10);
285
286         if (vdd_lcd_bl)
287                 regulator_disable(vdd_lcd_bl);
288
289         msleep(500);
290
291         return 0;
292 }
293
294 static int lvds_c_1366_14_postsuspend(void)
295 {
296         return 0;
297 }
298
299 static struct tegra_dc_out_pin lvds_out_pins[] = {
300         {
301                 .name   = TEGRA_DC_OUT_PIN_H_SYNC,
302                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
303         },
304         {
305                 .name   = TEGRA_DC_OUT_PIN_V_SYNC,
306                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
307         },
308         {
309                 .name   = TEGRA_DC_OUT_PIN_PIXEL_CLOCK,
310                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
311         },
312         {
313                 .name   = TEGRA_DC_OUT_PIN_DATA_ENABLE,
314                 .pol    = TEGRA_DC_OUT_PIN_POL_HIGH,
315         },
316 };
317
318 static struct tegra_dc_mode lvds_c_1366_14_modes[] = {
319         {
320                 .pclk = 74720100, /* 1366 x 768 @ 60hz */
321                 .h_ref_to_sync = 1,
322                 .v_ref_to_sync = 1,
323                 .h_sync_width = 45,
324                 .v_sync_width = 7,
325                 .h_back_porch = 113,
326                 .v_back_porch = 21,
327                 .h_active = 1366,
328                 .v_active = 768,
329                 .h_front_porch = 68,
330                 .v_front_porch = 4,
331         },
332 };
333
334 static int lvds_c_1366_14_bl_notify(struct device *unused, int brightness)
335 {
336         int cur_sd_brightness = atomic_read(&sd_brightness);
337
338         /* SD brightness is a percentage */
339         brightness = (brightness * cur_sd_brightness) / 255;
340
341         /* Apply any backlight response curve */
342         if (brightness > 255)
343                 pr_info("Error: Brightness > 255!\n");
344         else
345                 brightness = lvds_c_1366_14_bl_output_measured[brightness];
346
347         return brightness;
348 }
349
350 static int lvds_c_1366_14_check_fb(struct device *dev, struct fb_info *info)
351 {
352         return info->device == &disp_device->dev;
353 }
354
355 static struct platform_pwm_backlight_data lvds_c_1366_14_bl_data = {
356         .pwm_id         = 1,
357         .max_brightness = 255,
358         .dft_brightness = 224,
359         .pwm_period_ns  = 1000000,
360         .pwm_gpio       = TEGRA_GPIO_INVALID,
361         .notify         = lvds_c_1366_14_bl_notify,
362         /* Only toggle backlight on fb blank notifications for disp1 */
363         .check_fb       = lvds_c_1366_14_check_fb,
364 };
365
366 static struct platform_device __maybe_unused
367                 lvds_c_1366_14_bl_device = {
368         .name   = "pwm-backlight",
369         .id     = -1,
370         .dev    = {
371                 .platform_data = &lvds_c_1366_14_bl_data,
372         },
373 };
374
375 static struct platform_device __maybe_unused
376                         *lvds_c_1366_14_bl_devices[] __initdata = {
377         &tegra_pwfm_device,
378         &lvds_c_1366_14_bl_device,
379 };
380
381 static int  __init lvds_c_1366_14_register_bl_dev(void)
382 {
383         int err = 0;
384         err = platform_add_devices(lvds_c_1366_14_bl_devices,
385                                 ARRAY_SIZE(lvds_c_1366_14_bl_devices));
386         if (err) {
387                 pr_err("disp1 bl device registration failed");
388                 return err;
389         }
390         return err;
391 }
392
393 static void lvds_c_1366_14_set_disp_device(
394         struct platform_device *laguna_display_device)
395 {
396         disp_device = laguna_display_device;
397 }
398
399 static void lvds_c_1366_14_dc_out_init(struct tegra_dc_out *dc)
400 {
401         dc->align = TEGRA_DC_ALIGN_MSB,
402         dc->order = TEGRA_DC_ORDER_RED_BLUE,
403         dc->flags = DC_CTRL_MODE;
404         dc->modes = lvds_c_1366_14_modes;
405         dc->n_modes = ARRAY_SIZE(lvds_c_1366_14_modes);
406         dc->out_pins = lvds_out_pins,
407         dc->n_out_pins = ARRAY_SIZE(lvds_out_pins),
408         dc->depth = 18,
409         dc->parent_clk = "pll_d_out0";
410         dc->enable = lvds_c_1366_14_enable;
411         dc->disable = lvds_c_1366_14_disable;
412         dc->postsuspend = lvds_c_1366_14_postsuspend,
413         dc->width = 309;
414         dc->height = 174;
415 }
416
417 static void lvds_c_1366_14_fb_data_init(struct tegra_fb_data *fb)
418 {
419         fb->xres = lvds_c_1366_14_modes[0].h_active;
420         fb->yres = lvds_c_1366_14_modes[0].v_active;
421 }
422
423 static void
424 lvds_c_1366_14_sd_settings_init(struct tegra_dc_sd_settings *settings)
425 {
426         *settings = lvds_c_1366_14_sd_settings;
427         settings->bl_device_name = "pwm-backlight";
428 }
429
430 struct tegra_panel __initdata lvds_c_1366_14 = {
431         .init_sd_settings = lvds_c_1366_14_sd_settings_init,
432         .init_dc_out = lvds_c_1366_14_dc_out_init,
433         .init_fb_data = lvds_c_1366_14_fb_data_init,
434         .register_bl_dev = lvds_c_1366_14_register_bl_dev,
435         .set_disp_device = lvds_c_1366_14_set_disp_device,
436 };
437 EXPORT_SYMBOL(lvds_c_1366_14);
438