ARM: tegra: fix regulator_get() return value check
[linux-3.10.git] / arch / arm / mach-tegra / board-pluto-panel.c
1 /*
2  * arch/arm/mach-tegra/board-pluto-panel.c
3  *
4  * Copyright (c) 2012-2013, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that 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 along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19 #include <linux/ioport.h>
20 #include <linux/fb.h>
21 #include <linux/nvmap.h>
22 #include <linux/nvhost.h>
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/gpio.h>
26 #include <linux/tegra_pwm_bl.h>
27 #include <linux/regulator/consumer.h>
28 #include <linux/pwm_backlight.h>
29 #include <linux/i2c/pca953x.h>
30 #include <linux/of.h>
31 #include <mach/irqs.h>
32 #include <mach/dc.h>
33
34 #include "board.h"
35 #include "devices.h"
36 #include "gpio-names.h"
37 #include "board-pluto.h"
38 #include "board-panel.h"
39 #include "common.h"
40 #include "iomap.h"
41
42 #include "tegra11_host1x_devices.h"
43
44 #define DSI_PANEL_RST_GPIO      TEGRA_GPIO_PH5
45 #define DSI_PANEL_BL_EN_GPIO    TEGRA_GPIO_PH2
46 #define DSI_PANEL_BL_PWM_GPIO   TEGRA_GPIO_PH1
47
48 struct platform_device * __init pluto_host1x_init(void)
49 {
50         struct platform_device *pdev = NULL;
51
52 #ifdef CONFIG_TEGRA_GRHOST
53         if (!of_have_populated_dt())
54                 pdev = tegra11_register_host1x_devices();
55         else
56                 pdev = to_platform_device(bus_find_device_by_name(
57                         &platform_bus_type, NULL, "host1x"));
58 #endif
59         return pdev;
60 }
61
62
63 /* hdmi pins for hotplug */
64 #define pluto_hdmi_hpd          TEGRA_GPIO_PN7
65
66 /* hdmi related regulators */
67 static struct regulator *pluto_hdmi_vddio;
68 static struct regulator *pluto_hdmi_reg;
69 static struct regulator *pluto_hdmi_pll;
70
71 static struct resource pluto_disp1_resources[] = {
72         {
73                 .name   = "irq",
74                 .start  = INT_DISPLAY_GENERAL,
75                 .end    = INT_DISPLAY_GENERAL,
76                 .flags  = IORESOURCE_IRQ,
77         },
78         {
79                 .name   = "regs",
80                 .start  = TEGRA_DISPLAY_BASE,
81                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
82                 .flags  = IORESOURCE_MEM,
83         },
84         {
85                 .name   = "fbmem",
86                 .start  = 0, /* Filled in by pluto_panel_init() */
87                 .end    = 0, /* Filled in by pluto_panel_init() */
88                 .flags  = IORESOURCE_MEM,
89         },
90         {
91                 .name   = "dsi_regs",
92                 .start  = 0, /* Filled in the panel file by init_resources() */
93                 .end    = 0, /* Filled in the panel file by init_resources() */
94                 .flags  = IORESOURCE_MEM,
95         },
96         {
97                 .name   = "mipi_cal",
98                 .start  = TEGRA_MIPI_CAL_BASE,
99                 .end    = TEGRA_MIPI_CAL_BASE + TEGRA_MIPI_CAL_SIZE - 1,
100                 .flags  = IORESOURCE_MEM,
101         },
102 };
103
104 static struct resource pluto_disp2_resources[] = {
105         {
106                 .name   = "irq",
107                 .start  = INT_DISPLAY_B_GENERAL,
108                 .end    = INT_DISPLAY_B_GENERAL,
109                 .flags  = IORESOURCE_IRQ,
110         },
111         {
112                 .name   = "regs",
113                 .start  = TEGRA_DISPLAY2_BASE,
114                 .end    = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
115                 .flags  = IORESOURCE_MEM,
116         },
117         {
118                 .name   = "fbmem",
119                 .start  = 0, /* Filled in by pluto_panel_init() */
120                 .end    = 0, /* Filled in by pluto_panel_init() */
121                 .flags  = IORESOURCE_MEM,
122         },
123         {
124                 .name   = "hdmi_regs",
125                 .start  = TEGRA_HDMI_BASE,
126                 .end    = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
127                 .flags  = IORESOURCE_MEM,
128         },
129 };
130
131 static struct tegra_dc_sd_settings sd_settings;
132
133 static struct tegra_dc_out pluto_disp1_out = {
134         .type           = TEGRA_DC_OUT_DSI,
135         .sd_settings    = &sd_settings,
136 };
137
138 static int pluto_hdmi_enable(struct device *dev)
139 {
140         int ret;
141         if (!pluto_hdmi_reg) {
142                 pluto_hdmi_reg = regulator_get(dev, "avdd_hdmi");
143                 if (IS_ERR(pluto_hdmi_reg)) {
144                         pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
145                         pluto_hdmi_reg = NULL;
146                         return PTR_ERR(pluto_hdmi_reg);
147                 }
148         }
149         ret = regulator_enable(pluto_hdmi_reg);
150         if (ret < 0) {
151                 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
152                 return ret;
153         }
154         if (!pluto_hdmi_pll) {
155                 pluto_hdmi_pll = regulator_get(dev, "avdd_hdmi_pll");
156                 if (IS_ERR(pluto_hdmi_pll)) {
157                         pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
158                         pluto_hdmi_pll = NULL;
159                         regulator_put(pluto_hdmi_reg);
160                         pluto_hdmi_reg = NULL;
161                         return PTR_ERR(pluto_hdmi_pll);
162                 }
163         }
164         ret = regulator_enable(pluto_hdmi_pll);
165         if (ret < 0) {
166                 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
167                 return ret;
168         }
169         return 0;
170 }
171
172 static int pluto_hdmi_disable(void)
173 {
174         if (pluto_hdmi_reg) {
175                 regulator_disable(pluto_hdmi_reg);
176                 regulator_put(pluto_hdmi_reg);
177                 pluto_hdmi_reg = NULL;
178         }
179
180         if (pluto_hdmi_pll) {
181                 regulator_disable(pluto_hdmi_pll);
182                 regulator_put(pluto_hdmi_pll);
183                 pluto_hdmi_pll = NULL;
184         }
185
186         return 0;
187 }
188
189 static int pluto_hdmi_postsuspend(void)
190 {
191         if (pluto_hdmi_vddio) {
192                 regulator_disable(pluto_hdmi_vddio);
193                 regulator_put(pluto_hdmi_vddio);
194                 pluto_hdmi_vddio = NULL;
195         }
196         return 0;
197 }
198
199 static int pluto_hdmi_hotplug_init(struct device *dev)
200 {
201         int ret = 0;
202         if (!pluto_hdmi_vddio) {
203                 pluto_hdmi_vddio = regulator_get(dev, "vdd_hdmi_5v0");
204                 if (IS_ERR(pluto_hdmi_vddio)) {
205                         ret = PTR_ERR(pluto_hdmi_vddio);
206                         pr_err("hdmi: couldn't get regulator vdd_hdmi_5v0\n");
207                         pluto_hdmi_vddio = NULL;
208                         return ret;
209                 }
210         }
211         ret = regulator_enable(pluto_hdmi_vddio);
212         if (ret < 0) {
213                 pr_err("hdmi: couldn't enable regulator vdd_hdmi_5v0\n");
214                 regulator_put(pluto_hdmi_vddio);
215                 pluto_hdmi_vddio = NULL;
216                 return ret;
217         }
218         return ret;
219 }
220
221 static struct tegra_dc_out pluto_disp2_out = {
222         .type           = TEGRA_DC_OUT_HDMI,
223         .flags          = TEGRA_DC_OUT_HOTPLUG_HIGH,
224         .parent_clk     = "pll_d2_out0",
225
226         .dcc_bus        = 3,
227         .hotplug_gpio   = pluto_hdmi_hpd,
228
229         .max_pixclock   = KHZ2PICOS(297000),
230
231         .enable         = pluto_hdmi_enable,
232         .disable        = pluto_hdmi_disable,
233         .postsuspend    = pluto_hdmi_postsuspend,
234         .hotplug_init   = pluto_hdmi_hotplug_init,
235 };
236
237 static struct tegra_fb_data pluto_disp1_fb_data = {
238         .win            = 0,
239         .bits_per_pixel = 32,
240         .flags          = TEGRA_FB_FLIP_ON_PROBE,
241 };
242
243 static struct tegra_dc_platform_data pluto_disp1_pdata = {
244         .flags          = TEGRA_DC_FLAG_ENABLED,
245         .default_out    = &pluto_disp1_out,
246         .fb             = &pluto_disp1_fb_data,
247         .emc_clk_rate   = 204000000,
248 #ifdef CONFIG_TEGRA_DC_CMU
249         .cmu_enable     = 1,
250 #endif
251 };
252
253 static struct tegra_fb_data pluto_disp2_fb_data = {
254         .win            = 0,
255         .xres           = 1024,
256         .yres           = 600,
257         .bits_per_pixel = 32,
258         .flags          = TEGRA_FB_FLIP_ON_PROBE,
259 };
260
261 static struct tegra_dc_platform_data pluto_disp2_pdata = {
262         .flags          = TEGRA_DC_FLAG_ENABLED,
263         .default_out    = &pluto_disp2_out,
264         .fb             = &pluto_disp2_fb_data,
265         .emc_clk_rate   = 300000000,
266 #ifdef CONFIG_TEGRA_DC_CMU
267         .cmu_enable     = 1,
268 #endif
269 };
270
271 static struct platform_device pluto_disp2_device = {
272         .name           = "tegradc",
273         .id             = 1,
274         .resource       = pluto_disp2_resources,
275         .num_resources  = ARRAY_SIZE(pluto_disp2_resources),
276         .dev = {
277                 .platform_data = &pluto_disp2_pdata,
278         },
279 };
280
281 static struct platform_device pluto_disp1_device = {
282         .name           = "tegradc",
283         .id             = 0,
284         .resource       = pluto_disp1_resources,
285         .num_resources  = ARRAY_SIZE(pluto_disp1_resources),
286         .dev = {
287                 .platform_data = &pluto_disp1_pdata,
288         },
289 };
290
291 static struct nvmap_platform_carveout pluto_carveouts[] = {
292         [0] = {
293                 .name           = "iram",
294                 .usage_mask     = NVMAP_HEAP_CARVEOUT_IRAM,
295                 .base           = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
296                 .size           = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
297         },
298         [1] = {
299                 .name           = "generic-0",
300                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
301                 .base           = 0, /* Filled in by pluto_panel_init() */
302                 .size           = 0, /* Filled in by pluto_panel_init() */
303         },
304         [2] = {
305                 .name           = "vpr",
306                 .usage_mask     = NVMAP_HEAP_CARVEOUT_VPR,
307                 .base           = 0, /* Filled in by pluto_panel_init() */
308                 .size           = 0, /* Filled in by pluto_panel_init() */
309         },
310 };
311
312 static struct nvmap_platform_data pluto_nvmap_data = {
313         .carveouts      = pluto_carveouts,
314         .nr_carveouts   = ARRAY_SIZE(pluto_carveouts),
315 };
316
317 static struct platform_device pluto_nvmap_device = {
318         .name   = "tegra-nvmap",
319         .id     = -1,
320         .dev    = {
321                 .platform_data = &pluto_nvmap_data,
322         },
323 };
324
325 static struct tegra_dc_sd_settings pluto_sd_settings = {
326         .enable = 1, /* enabled by default */
327         .use_auto_pwm = false,
328         .hw_update_delay = 0,
329         .bin_width = -1,
330         .aggressiveness = 5,
331         .use_vid_luma = false,
332         .phase_in_adjustments = 0,
333         .k_limit_enable = true,
334         .k_limit = 180,
335         .sd_window_enable = false,
336         .soft_clipping_enable = true,
337         /* Low soft clipping threshold to compensate for aggressive k_limit */
338         .soft_clipping_threshold = 128,
339         .smooth_k_enable = true,
340         .smooth_k_incr = 4,
341         /* Default video coefficients */
342         .coeff = {5, 9, 2},
343         .fc = {0, 0},
344         /* Immediate backlight changes */
345         .blp = {1024, 255},
346         /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
347         /* Default BL TF */
348         .bltf = {
349                         {
350                                 {57, 65, 73, 82},
351                                 {92, 103, 114, 125},
352                                 {138, 150, 164, 178},
353                                 {193, 208, 224, 241},
354                         },
355                 },
356         /* Default LUT */
357         .lut = {
358                         {
359                                 {255, 255, 255},
360                                 {199, 199, 199},
361                                 {153, 153, 153},
362                                 {116, 116, 116},
363                                 {85, 85, 85},
364                                 {59, 59, 59},
365                                 {36, 36, 36},
366                                 {17, 17, 17},
367                                 {0, 0, 0},
368                         },
369                 },
370         .sd_brightness = &sd_brightness,
371         .use_vpulse2 = true,
372 };
373
374 static void pluto_panel_select(void)
375 {
376         struct tegra_panel *panel;
377         struct board_info board;
378         u8 dsi_instance = 0;
379
380         tegra_get_display_board_info(&board);
381
382         switch (board.board_id) {
383         case BOARD_E1605:
384                 panel = &dsi_j_720p_4_7;
385                 dsi_instance = DSI_INSTANCE_1;
386                 break;
387         case BOARD_E1577:
388                 panel = &dsi_s_1080p_5;
389                 break;
390         case BOARD_E1582:
391         default:
392                 if (tegra_get_board_panel_id()) {
393                         panel = &dsi_s_1080p_5;
394                         dsi_instance = DSI_INSTANCE_1;
395                 } else {
396                         panel = &dsi_l_720p_5;
397                         dsi_instance = DSI_INSTANCE_0;
398                 }
399                 break;
400         }
401
402         if (panel->init_sd_settings)
403                 panel->init_sd_settings(&sd_settings);
404
405         if (panel->init_dc_out) {
406                 panel->init_dc_out(&pluto_disp1_out);
407                 pluto_disp1_out.dsi->dsi_instance = dsi_instance;
408                 pluto_disp1_out.dsi->dsi_panel_rst_gpio = DSI_PANEL_RST_GPIO;
409                 pluto_disp1_out.dsi->dsi_panel_bl_en_gpio =
410                         DSI_PANEL_BL_EN_GPIO;
411                 pluto_disp1_out.dsi->dsi_panel_bl_pwm_gpio =
412                         DSI_PANEL_BL_PWM_GPIO;
413                 /* update the init cmd if dependent on reset GPIO */
414                 tegra_dsi_update_init_cmd_gpio_rst(&pluto_disp1_out);
415         }
416
417         if (panel->init_fb_data)
418                 panel->init_fb_data(&pluto_disp1_fb_data);
419
420         if (panel->init_cmu_data)
421                 panel->init_cmu_data(&pluto_disp1_pdata);
422
423         if (panel->set_disp_device)
424                 panel->set_disp_device(&pluto_disp1_device);
425
426         tegra_dsi_resources_init(dsi_instance, pluto_disp1_resources,
427                 ARRAY_SIZE(pluto_disp1_resources));
428
429         if (panel->register_bl_dev)
430                 panel->register_bl_dev();
431
432 }
433 int __init pluto_panel_init(void)
434 {
435         int err = 0;
436         struct resource __maybe_unused *res;
437         struct platform_device *phost1x = NULL;
438
439         sd_settings = pluto_sd_settings;
440
441         pluto_panel_select();
442
443 #ifdef CONFIG_TEGRA_NVMAP
444         pluto_carveouts[1].base = tegra_carveout_start;
445         pluto_carveouts[1].size = tegra_carveout_size;
446         pluto_carveouts[2].base = tegra_vpr_start;
447         pluto_carveouts[2].size = tegra_vpr_size;
448 #ifdef CONFIG_NVMAP_USE_CMA_FOR_CARVEOUT
449         pluto_carveouts[1].cma_dev = &tegra_generic_cma_dev;
450         pluto_carveouts[1].resize = false;
451         pluto_carveouts[2].cma_dev = &tegra_vpr_cma_dev;
452         pluto_carveouts[2].resize = true;
453         pluto_carveouts[2].cma_chunk_size = SZ_32M;
454 #endif
455
456         err = platform_device_register(&pluto_nvmap_device);
457         if (err) {
458                 pr_err("nvmap device registration failed\n");
459                 return err;
460         }
461 #endif
462         phost1x = pluto_host1x_init();
463         if (!phost1x) {
464                 pr_err("host1x devices registration failed\n");
465                 return -EINVAL;
466         }
467
468         res = platform_get_resource_byname(&pluto_disp1_device,
469                                          IORESOURCE_MEM, "fbmem");
470         res->start = tegra_fb_start;
471         res->end = tegra_fb_start + tegra_fb_size - 1;
472
473         /* Copy the bootloader fb to the fb. */
474         __tegra_move_framebuffer(&pluto_nvmap_device,
475                 tegra_fb_start, tegra_bootloader_fb_start,
476                         min(tegra_fb_size, tegra_bootloader_fb_size));
477
478         pluto_disp1_device.dev.parent = &phost1x->dev;
479         err = platform_device_register(&pluto_disp1_device);
480         if (err) {
481                 pr_err("disp1 device registration failed\n");
482                 return err;
483         }
484
485         err = tegra_init_hdmi(&pluto_disp2_device, phost1x);
486         if (err)
487                 return err;
488
489 #ifdef CONFIG_TEGRA_NVAVP
490         nvavp_device.dev.parent = &phost1x->dev;
491         err = platform_device_register(&nvavp_device);
492         if (err) {
493                 pr_err("nvavp device registration failed\n");
494                 return err;
495         }
496 #endif
497         return err;
498 }