ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / board-panel.c
1 /*
2  * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16
17 #include <linux/ioport.h>
18 #include <linux/kernel.h>
19 #include <linux/of.h>
20 #include <linux/delay.h>
21 #include <linux/gpio.h>
22 #include <linux/of_gpio.h>
23 #include <linux/export.h>
24 #include <linux/platform_device.h>
25 #include <linux/of.h>
26 #include <linux/of_address.h>
27
28 #include <mach/dc.h>
29
30 #include "board-panel.h"
31 #include "board.h"
32 #include "iomap.h"
33
34 atomic_t sd_brightness = ATOMIC_INIT(255);
35 EXPORT_SYMBOL(sd_brightness);
36
37 void tegra_dsi_resources_init(u8 dsi_instance,
38                         struct resource *resources, int n_resources)
39 {
40         int i;
41         for (i = 0; i < n_resources; i++) {
42                 struct resource *r = &resources[i];
43                 if (resource_type(r) == IORESOURCE_MEM &&
44                         !strcmp(r->name, "dsi_regs")) {
45                         switch (dsi_instance) {
46                         case DSI_INSTANCE_0:
47                                 r->start = TEGRA_DSI_BASE;
48                                 r->end = TEGRA_DSI_BASE + TEGRA_DSI_SIZE - 1;
49                                 break;
50                         case DSI_INSTANCE_1:
51                         default:
52                                 r->start = TEGRA_DSIB_BASE;
53                                 r->end = TEGRA_DSIB_BASE + TEGRA_DSIB_SIZE - 1;
54                                 break;
55                         }
56                 }
57                 if (resource_type(r) == IORESOURCE_MEM &&
58                         !strcmp(r->name, "ganged_dsia_regs")) {
59                         r->start = TEGRA_DSI_BASE;
60                         r->end = TEGRA_DSI_BASE + TEGRA_DSI_SIZE - 1;
61                 }
62                 if (resource_type(r) == IORESOURCE_MEM &&
63                         !strcmp(r->name, "ganged_dsib_regs")) {
64                         r->start = TEGRA_DSIB_BASE;
65                         r->end = TEGRA_DSIB_BASE + TEGRA_DSIB_SIZE - 1;
66                 }
67         }
68 }
69
70 void tegra_dsi_update_init_cmd_gpio_rst(
71         struct tegra_dc_out *dsi_disp1_out)
72 {
73         int i;
74         for (i = 0; i < dsi_disp1_out->dsi->n_init_cmd; i++) {
75                 if (dsi_disp1_out->dsi->dsi_init_cmd[i].cmd_type ==
76                                         TEGRA_DSI_GPIO_SET)
77                         dsi_disp1_out->dsi->dsi_init_cmd[i].sp_len_dly.gpio
78                                 = dsi_disp1_out->dsi->dsi_panel_rst_gpio;
79         }
80 }
81
82 int tegra_panel_reset(struct tegra_panel_of *panel, unsigned int delay_ms)
83 {
84         int gpio = panel->panel_gpio[TEGRA_GPIO_RESET];
85
86         if (!gpio_is_valid(gpio))
87                 return -ENOENT;
88
89         gpio_direction_output(gpio, 1);
90         usleep_range(1000, 5000);
91         gpio_set_value(gpio, 0);
92         usleep_range(1000, 5000);
93         gpio_set_value(gpio, 1);
94         msleep(delay_ms);
95
96         return 0;
97 }
98
99 int tegra_panel_gpio_get_dt(const char *comp_str,
100                                 struct tegra_panel_of *panel)
101 {
102         int cnt = 0;
103         char *label;
104         const char *node_status;
105         int err = 0;
106         struct device_node *node =
107                 of_find_compatible_node(NULL, NULL, comp_str);
108
109         /*
110          * If gpios are already populated, just return.
111          */
112         if (panel->panel_gpio_populated)
113                 return 0;
114
115         if (!node) {
116                 pr_info("%s panel dt support not available\n", comp_str);
117                 err = -ENOENT;
118                 goto fail;
119         }
120
121         of_property_read_string(node, "status", &node_status);
122         if (strcmp(node_status, "okay")) {
123                 pr_info("%s panel dt support disabled\n", comp_str);
124                 err = -ENOENT;
125                 goto fail;
126         }
127
128         panel->panel_gpio[TEGRA_GPIO_RESET] =
129                 of_get_named_gpio(node, "nvidia,dsi-panel-rst-gpio", 0);
130
131         panel->panel_gpio[TEGRA_GPIO_BL_ENABLE] =
132                 of_get_named_gpio(node, "nvidia,dsi-panel-bl-en-gpio", 0);
133
134         panel->panel_gpio[TEGRA_GPIO_PWM] =
135                 of_get_named_gpio(node, "nvidia,dsi-panel-bl-pwm-gpio", 0);
136
137         panel->panel_gpio[TEGRA_GPIO_TE] =
138                 of_get_named_gpio(node, "nvidia,te-gpio", 0);
139
140         for (cnt = 0; cnt < TEGRA_N_GPIO_PANEL; cnt++) {
141                 if (gpio_is_valid(panel->panel_gpio[cnt])) {
142                         switch (cnt) {
143                         case TEGRA_GPIO_RESET:
144                                 label = "tegra-panel-reset";
145                                 break;
146                         case TEGRA_GPIO_BL_ENABLE:
147                                 label = "tegra-panel-bl-enable";
148                                 break;
149                         case TEGRA_GPIO_PWM:
150                                 label = "tegra-panel-pwm";
151                                 break;
152                         case TEGRA_GPIO_TE:
153                                 label = "tegra-panel-te";
154                                 break;
155                         default:
156                                 pr_err("tegra panel no gpio entry\n");
157                         }
158                         gpio_request(panel->panel_gpio[cnt], label);
159                 }
160         }
161         panel->panel_gpio_populated = true;
162 fail:
163         of_node_put(node);
164         return err;
165 }
166
167 static void tegra_panel_register_ops(struct tegra_dc_out *dc_out,
168                                 struct tegra_panel_ops *p_ops)
169 {
170         BUG_ON(!dc_out);
171
172         if (!p_ops) {
173                 /* TODO: register default ops */
174         }
175
176         dc_out->enable = p_ops->enable;
177         dc_out->postpoweron = p_ops->postpoweron;
178         dc_out->prepoweroff = p_ops->prepoweroff;
179         dc_out->disable = p_ops->disable;
180         dc_out->hotplug_init = p_ops->hotplug_init;
181         dc_out->postsuspend = p_ops->postsuspend;
182         dc_out->hotplug_report = p_ops->hotplug_report;
183 }
184
185 struct device_node *tegra_panel_get_dt_node(
186                         struct tegra_dc_platform_data *pdata)
187 {
188         struct tegra_dc_out *dc_out = pdata->default_out;
189         struct device_node *np_panel = NULL;
190         struct board_info display_board;
191
192         tegra_get_display_board_info(&display_board);
193
194         switch (display_board.board_id) {
195         case BOARD_E1627:
196                 tegra_panel_register_ops(dc_out, &dsi_p_wuxga_10_1_ops);
197                 np_panel = of_find_compatible_node(NULL, NULL, "p,wuxga-10-1");
198                 break;
199         case BOARD_E1549:
200                 tegra_panel_register_ops(dc_out, &dsi_lgd_wxga_7_0_ops);
201                 np_panel = of_find_compatible_node(NULL, NULL, "lg,wxga-7");
202                 break;
203         default:
204                 WARN(1, "Display panel not supported\n");
205         };
206
207         return of_device_is_available(np_panel) ? np_panel : NULL;
208 }
209
210 #ifdef CONFIG_TEGRA_DC
211 /**
212  * tegra_init_hdmi - initialize and add HDMI device if not disabled by DT
213  */
214 int tegra_init_hdmi(struct platform_device *pdev,
215                      struct platform_device *phost1x)
216 {
217         struct resource __maybe_unused *res;
218         bool enabled = true;
219         int err;
220 #ifdef CONFIG_OF
221         struct device_node *hdmi_node = NULL;
222
223         hdmi_node = of_find_node_by_path("/host1x/hdmi");
224         /* disable HDMI if explicitly set that way in the device tree */
225         enabled = !hdmi_node || of_device_is_available(hdmi_node);
226 #endif
227
228         if (enabled) {
229 #ifndef CONFIG_TEGRA_HDMI_PRIMARY
230                 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
231                                                    "fbmem");
232                 res->start = tegra_fb2_start;
233                 res->end = tegra_fb2_start + tegra_fb2_size - 1;
234 #endif
235                 pdev->dev.parent = &phost1x->dev;
236                 err = platform_device_register(pdev);
237                 if (err) {
238                         dev_err(&pdev->dev, "device registration failed\n");
239                         return err;
240                 }
241         }
242
243         return 0;
244 }
245 #else
246 int tegra_init_hdmi(struct platform_device *pdev,
247                      struct platform_device *phost1x)
248 {
249         return 0;
250 }
251 #endif