blob: 3c1ff7bb240a8f52748647bd149584be67a3eaac [file] [log] [blame]
Kuogee Hsieh5accef12013-12-18 14:12:09 -08001/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
Arpita Banerjee841fa062013-05-24 14:59:51 -07002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in
10 * the documentation and/or other materials provided with the
11 * distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <debug.h>
31#include <err.h>
32#include <smem.h>
33#include <msm_panel.h>
Dhaval Patel9f61f132013-07-18 14:45:11 -070034#include <string.h>
35#include <stdlib.h>
Arpita Banerjee841fa062013-05-24 14:59:51 -070036#include <board.h>
37#include <mdp5.h>
38#include <platform/gpio.h>
39#include <mipi_dsi.h>
40
41#include "include/display_resource.h"
42#include "include/panel.h"
43#include "panel_display.h"
44#include "gcdb_display.h"
45#include "target/display.h"
Arpita Banerjeeda0c39a2013-05-24 16:12:45 -070046#include "gcdb_autopll.h"
Arpita Banerjee841fa062013-05-24 14:59:51 -070047
48/*---------------------------------------------------------------------------*/
49/* static */
50/*---------------------------------------------------------------------------*/
51static struct msm_fb_panel_data panel;
52struct panel_struct panelstruct;
53static uint8_t display_enable;
54static struct mdss_dsi_phy_ctrl dsi_video_mode_phy_db;
55
Arpita Banerjee841fa062013-05-24 14:59:51 -070056/*---------------------------------------------------------------------------*/
57/* Extern */
58/*---------------------------------------------------------------------------*/
59extern int msm_display_init(struct msm_fb_panel_data *pdata);
60extern int msm_display_off();
61
62static uint32_t panel_backlight_ctrl(uint8_t enable)
63{
Kuogee Hsieh5accef12013-12-18 14:12:09 -080064 return target_backlight_ctrl(panelstruct.backlightinfo, enable);
Arpita Banerjee841fa062013-05-24 14:59:51 -070065}
66
67static uint32_t mdss_dsi_panel_reset(uint8_t enable)
68{
69 uint32_t ret = NO_ERROR;
70
Dhaval Patel29f24492013-08-08 20:45:42 -070071 ret = target_panel_reset(enable, panelstruct.panelresetseq,
72 &panel.panel_info);
Arpita Banerjee841fa062013-05-24 14:59:51 -070073
74 return ret;
75}
76
Arpita Banerjeeda0c39a2013-05-24 16:12:45 -070077static uint32_t mdss_dsi_panel_clock(uint8_t enable,
78 struct msm_panel_info *pinfo)
Arpita Banerjee841fa062013-05-24 14:59:51 -070079{
80 uint32_t ret = NO_ERROR;
81
Arpita Banerjeeda0c39a2013-05-24 16:12:45 -070082 ret = calculate_clock_config(pinfo);
83 if (ret) {
84 dprintf(CRITICAL, "Clock calculation failed \n");
85 /* should it stop here ? check with display team */
86 }
87
Arpita Banerjee0906ffd2013-05-24 16:25:38 -070088 ret = target_panel_clock(enable, pinfo);
Arpita Banerjee841fa062013-05-24 14:59:51 -070089
90 return ret;
91}
92
93static int mdss_dsi_panel_power(uint8_t enable)
94{
95 int ret = NO_ERROR;
96
97 if (enable) {
Dhaval Patel29f24492013-08-08 20:45:42 -070098 ret = target_ldo_ctrl(enable);
Arpita Banerjee841fa062013-05-24 14:59:51 -070099 if (ret) {
Jayant Shekharc9611a92013-11-20 16:59:27 +0530100 dprintf(CRITICAL, "LDO control enable failed\n");
Arpita Banerjee841fa062013-05-24 14:59:51 -0700101 return ret;
102 }
103
104 /* Panel Reset */
Jayant Shekharc9611a92013-11-20 16:59:27 +0530105 if (!panelstruct.paneldata->panel_lp11_init) {
106 ret = mdss_dsi_panel_reset(enable);
107 if (ret) {
108 dprintf(CRITICAL, "panel reset failed\n");
109 return ret;
110 }
Arpita Banerjee841fa062013-05-24 14:59:51 -0700111 }
112 dprintf(SPEW, "Panel power on done\n");
113 } else {
Casey Piper1bbd1572013-09-11 16:23:18 -0700114 /* Disable panel and ldo */
Arpita Banerjee841fa062013-05-24 14:59:51 -0700115 ret = mdss_dsi_panel_reset(enable);
116 if (ret) {
Jayant Shekharc9611a92013-11-20 16:59:27 +0530117 dprintf(CRITICAL, "panel reset disable failed\n");
Arpita Banerjee841fa062013-05-24 14:59:51 -0700118 return ret;
119 }
120
Dhaval Patel29f24492013-08-08 20:45:42 -0700121 ret = target_ldo_ctrl(enable);
Arpita Banerjee841fa062013-05-24 14:59:51 -0700122 if (ret) {
Jayant Shekharc9611a92013-11-20 16:59:27 +0530123 dprintf(CRITICAL, "ldo control disable failed\n");
Arpita Banerjee841fa062013-05-24 14:59:51 -0700124 return ret;
125 }
126 dprintf(SPEW, "Panel power off done\n");
127 }
128
129 return ret;
130}
131
Ray Zhangeb462f62013-12-03 17:16:08 +0800132static int mdss_dsi_panel_pre_init(void)
Jayant Shekharc9611a92013-11-20 16:59:27 +0530133{
134 int ret = NO_ERROR;
135
Ray Zhangeb462f62013-12-03 17:16:08 +0800136 if (panelstruct.paneldata->panel_lp11_init) {
137 ret = mdss_dsi_panel_reset(1);
138 if (ret) {
139 dprintf(CRITICAL, "panel reset failed\n");
140 return ret;
Jayant Shekharc9611a92013-11-20 16:59:27 +0530141 }
Jayant Shekharc9611a92013-11-20 16:59:27 +0530142 }
143
Ray Zhangeb462f62013-12-03 17:16:08 +0800144 if(panelstruct.paneldata->panel_init_delay)
145 udelay(panelstruct.paneldata->panel_init_delay);
146
147 dprintf(SPEW, "Panel pre init done\n");
Jayant Shekharc9611a92013-11-20 16:59:27 +0530148 return ret;
149}
150
Casey Piper1bbd1572013-09-11 16:23:18 -0700151static int mdss_dsi_bl_enable(uint8_t enable)
152{
153 int ret = NO_ERROR;
154
155 ret = panel_backlight_ctrl(enable);
156 if (ret)
157 dprintf(CRITICAL, "Backlight %s failed\n", enable ? "enable" :
158 "disable");
159 return ret;
160}
161
Dhaval Patel9f61f132013-07-18 14:45:11 -0700162bool target_display_panel_node(char *pbuf, uint16_t buf_size)
163{
Channagoud Kadabi4767b472013-09-26 20:45:34 -0700164 char *dsi_id = NULL;
165 char *panel_node = NULL;
Dhaval Patel7b9d6782014-01-03 13:31:09 -0800166 char *slave_panel_node = NULL;
167 uint16_t dsi_id_len = 0, panel_node_len = 0, slave_panel_node_len = 0;
168 uint32_t arg_size = 0;
Dhaval Patel9f61f132013-07-18 14:45:11 -0700169 bool ret = true;
Casey Pipera078d492013-11-15 12:26:17 -0800170 char *default_str;
Dhaval Patel7b9d6782014-01-03 13:31:09 -0800171 int panel_mode = SPLIT_DISPLAY_FLAG | DUAL_PIPE_FLAG;
Dhaval Patel9f61f132013-07-18 14:45:11 -0700172
Channagoud Kadabi4767b472013-09-26 20:45:34 -0700173 if (panelstruct.paneldata)
174 {
175 dsi_id = panelstruct.paneldata->panel_controller;
176 panel_node = panelstruct.paneldata->panel_node_id;
Dhaval Patel7b9d6782014-01-03 13:31:09 -0800177 panel_mode = panelstruct.paneldata->panel_operating_mode &
178 panel_mode;
179 slave_panel_node = panelstruct.paneldata->slave_panel_node_id;
Channagoud Kadabi4767b472013-09-26 20:45:34 -0700180 }
Casey Pipera078d492013-11-15 12:26:17 -0800181 else
182 {
183 if (target_is_edp())
184 {
185 default_str = "0:edp:";
186 }
187 else
188 {
189 default_str = "0:dsi:0:";
190 }
191 strlcpy(pbuf, default_str, buf_size);
192 return true;
193 }
Channagoud Kadabi4767b472013-09-26 20:45:34 -0700194
Dhaval Patel7b9d6782014-01-03 13:31:09 -0800195 if (dsi_id == NULL || panel_node == NULL) {
196 dprintf(CRITICAL, "panel node or dsi ctrl not present\n");
Dhaval Patelbc7fa212013-08-28 10:46:42 -0700197 return false;
Dhaval Patel7b9d6782014-01-03 13:31:09 -0800198 }
199
200 if (panel_mode && slave_panel_node == NULL) {
201 dprintf(CRITICAL, "slave node not present in dual dsi case\n");
202 return false;
203 }
Dhaval Patelbc7fa212013-08-28 10:46:42 -0700204
205 dsi_id_len = strlen(dsi_id);
Dhaval Patel7b9d6782014-01-03 13:31:09 -0800206 panel_node_len = strlen(panel_node);
207 slave_panel_node_len = strlen(slave_panel_node);
Dhaval Patelbc7fa212013-08-28 10:46:42 -0700208
Dhaval Patel7b9d6782014-01-03 13:31:09 -0800209 arg_size = dsi_id_len + panel_node_len + LK_OVERRIDE_PANEL_LEN + 1;
210
211 /* For dual pipe or split display */
212 if (panel_mode)
213 arg_size += DSI_1_STRING_LEN + slave_panel_node_len;
214
215 if (buf_size < arg_size)
Dhaval Patel9f61f132013-07-18 14:45:11 -0700216 {
Dhaval Patel7b9d6782014-01-03 13:31:09 -0800217 dprintf(CRITICAL, "display command line buffer is small\n");
Dhaval Patel9f61f132013-07-18 14:45:11 -0700218 ret = false;
219 }
220 else
221 {
Dhaval Patel7b9d6782014-01-03 13:31:09 -0800222 strlcpy(pbuf, LK_OVERRIDE_PANEL, buf_size);
223 pbuf += LK_OVERRIDE_PANEL_LEN;
224 buf_size -= LK_OVERRIDE_PANEL_LEN;
Dhaval Patel9f61f132013-07-18 14:45:11 -0700225
226 strlcpy(pbuf, dsi_id, buf_size);
Dhaval Patelbc7fa212013-08-28 10:46:42 -0700227 pbuf += dsi_id_len;
228 buf_size -= dsi_id_len;
Dhaval Patel9f61f132013-07-18 14:45:11 -0700229
230 strlcpy(pbuf, panel_node, buf_size);
Dhaval Patel7b9d6782014-01-03 13:31:09 -0800231
232 /* Return string for single dsi */
233 if (!panel_mode)
234 goto end;
235
236 pbuf += panel_node_len;
237 buf_size -= panel_node_len;
238
239 strlcpy(pbuf, DSI_1_STRING, buf_size);
240 pbuf += DSI_1_STRING_LEN;
241 buf_size -= DSI_1_STRING_LEN;
242
243 strlcpy(pbuf, slave_panel_node, buf_size);
Dhaval Patel9f61f132013-07-18 14:45:11 -0700244 }
Dhaval Patel7b9d6782014-01-03 13:31:09 -0800245end:
Dhaval Patel9f61f132013-07-18 14:45:11 -0700246 return ret;
247}
248
249
Arpita Banerjee841fa062013-05-24 14:59:51 -0700250static void init_platform_data()
251{
252 memcpy(dsi_video_mode_phy_db.regulator, panel_regulator_settings,
253 REGULATOR_SIZE);
254 memcpy(dsi_video_mode_phy_db.ctrl, panel_physical_ctrl,
255 PHYSICAL_SIZE);
256 memcpy(dsi_video_mode_phy_db.strength, panel_strength_ctrl,
257 STRENGTH_SIZE);
258 memcpy(dsi_video_mode_phy_db.bistCtrl, panel_bist_ctrl, BIST_SIZE);
259 memcpy(dsi_video_mode_phy_db.laneCfg, panel_lane_config, LANE_SIZE);
260}
261
Casey Piperc574e082013-09-05 14:54:42 -0700262int gcdb_display_init(uint32_t rev, void *base)
Arpita Banerjee841fa062013-05-24 14:59:51 -0700263{
Casey Piperc574e082013-09-05 14:54:42 -0700264 int ret = NO_ERROR;
Arpita Banerjee841fa062013-05-24 14:59:51 -0700265
266 if (!oem_panel_select(&panelstruct, &(panel.panel_info),
267 &dsi_video_mode_phy_db)) {
268 dprintf(CRITICAL, "Target panel init not found!\n");
Casey Piperc574e082013-09-05 14:54:42 -0700269 ret = ERR_NOT_SUPPORTED;
270 goto error_gcdb_display_init;
Arpita Banerjee841fa062013-05-24 14:59:51 -0700271 }
Arpita Banerjee841fa062013-05-24 14:59:51 -0700272 init_platform_data();
273
274 if (dsi_panel_init(&(panel.panel_info), &panelstruct)) {
275 dprintf(CRITICAL, "DSI panel init failed!\n");
Casey Piperc574e082013-09-05 14:54:42 -0700276 ret = ERROR;
277 goto error_gcdb_display_init;
Arpita Banerjee841fa062013-05-24 14:59:51 -0700278 }
279
280 panel.panel_info.mipi.mdss_dsi_phy_db = &dsi_video_mode_phy_db;
281
Arpita Banerjeeda0c39a2013-05-24 16:12:45 -0700282 panel.pll_clk_func = mdss_dsi_panel_clock;
Arpita Banerjee841fa062013-05-24 14:59:51 -0700283 panel.power_func = mdss_dsi_panel_power;
Ray Zhangeb462f62013-12-03 17:16:08 +0800284 panel.pre_init_func = mdss_dsi_panel_pre_init;
Casey Piper1bbd1572013-09-11 16:23:18 -0700285 panel.bl_func = mdss_dsi_bl_enable;
Arpita Banerjee841fa062013-05-24 14:59:51 -0700286 panel.fb.base = base;
287 panel.fb.width = panel.panel_info.xres;
288 panel.fb.height = panel.panel_info.yres;
289 panel.fb.stride = panel.panel_info.xres;
290 panel.fb.bpp = panel.panel_info.bpp;
291 panel.fb.format = panel.panel_info.mipi.dst_format;
292 panel.mdp_rev = rev;
293
Casey Piperc574e082013-09-05 14:54:42 -0700294 ret = msm_display_init(&panel);
Arpita Banerjee841fa062013-05-24 14:59:51 -0700295
Casey Piperc574e082013-09-05 14:54:42 -0700296error_gcdb_display_init:
297 display_enable = ret ? 0 : 1;
298 return ret;
Arpita Banerjee841fa062013-05-24 14:59:51 -0700299}
300
301void gcdb_display_shutdown(void)
302{
303 if (display_enable)
304 msm_display_off();
305}