blob: 017326291b27f8b063af48b3bcad9b35a9769aec [file] [log] [blame]
Asaf Pensob8f524c2013-05-20 12:32:31 +03001/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
2 *
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 "edp.h"
31#include "mdp5.h"
32
33#define RGB_COMPONENTS 3
34#define MAX_NUMBER_EDP_LANES 4
35
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -070036struct edp_aux_ctrl edpctrl;
37
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -070038static struct msm_panel_info *edp_pinfo;
39
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -070040static void edp_config_ctrl(void)
Asaf Pensob8f524c2013-05-20 12:32:31 +030041{
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -070042 struct edp_aux_ctrl *ep;
43 struct dpcd_cap *cap;
44 struct display_timing_desc *dp;
45 unsigned long data = 0;
Asaf Pensob8f524c2013-05-20 12:32:31 +030046
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -070047 ep = &edpctrl;
48
49 dp = &ep->edid.timing[0];
50
51 cap = &ep->dpcd;
52
53 data = cap->max_lane_count - 1;
54 data <<= 4;
55
56 if (cap->enhanced_frame)
57 data |= 0x40;
58
59 if (ep->edid.color_depth == 8) {
60 /* 0 == 6 bits, 1 == 8 bits */
61 data |= 0x100; /* bit 8 */
62 }
63
64 if (!dp->interlaced) /* progressive */
65 data |= 0x04;
66
67 data |= 0x03; /* sycn clock & static Mvid */
68
69 dprintf(SPEW, "%s: data=%x\n", __func__, data);
70
71 edp_write(EDP_BASE + 0xc, data); /* EDP_CONFIGURATION_CTRL */
Asaf Pensob8f524c2013-05-20 12:32:31 +030072}
73
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -070074static void edp_config_sw_mvid_nvid(void)
Asaf Pensob8f524c2013-05-20 12:32:31 +030075{
76 edp_write(EDP_BASE + 0x14, 0x13b); /* EDP_SOFTWARE_MVID */
77 edp_write(EDP_BASE + 0x18, 0x266); /* EDP_SOFTWARE_NVID */
78}
79
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -070080void edp_clock_synchrous(void)
Asaf Pensob8f524c2013-05-20 12:32:31 +030081{
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -070082 struct edp_aux_ctrl *ep;
83 unsigned long data;
84 unsigned long color;
Asaf Pensob8f524c2013-05-20 12:32:31 +030085
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -070086 ep = &edpctrl;
87
88 data = 1; /* sync */
89
90 /* only legacy rgb mode supported */
91 color = 0; /* 6 bits */
92 if (ep->edid.color_depth == 8)
93 color = 0x01;
94 else if (ep->edid.color_depth == 10)
95 color = 0x02;
96 else if (ep->edid.color_depth == 12)
97 color = 0x03;
98 else if (ep->edid.color_depth == 16)
99 color = 0x04;
100
101 color <<= 5; /* bit 5 to bit 7 */
102
103 data |= color;
104
105 dprintf(SPEW, "%s: data=%x\n", __func__, data);
106
107 /* EDP_MISC1_MISC0 */
108 edp_write(EDP_BASE + 0x2c, data);
Asaf Pensob8f524c2013-05-20 12:32:31 +0300109}
110
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700111static void edp_config_tu(void)
Asaf Pensob8f524c2013-05-20 12:32:31 +0300112{
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700113 /* temporary */
114 edp_write(EDP_BASE + 0x160, 0x2b);
115 edp_write(EDP_BASE + 0x15c, 0x00320033);
116 edp_write(EDP_BASE + 0x34, 0x0023001a);
117
118}
119
120static void edp_config_timing(struct msm_panel_info *pinfo)
121{
122 unsigned long total_ver, total_hor;
123 unsigned long data;
124
125 dprintf(INFO, "%s: width=%d hporch= %d %d %d\n", __func__,
126 pinfo->xres, pinfo->lcdc.h_back_porch,
127 pinfo->lcdc.h_front_porch, pinfo->lcdc.h_pulse_width);
128
129 dprintf(INFO, "%s: height=%d vporch= %d %d %d\n", __func__,
130 pinfo->yres, pinfo->lcdc.v_back_porch,
131 pinfo->lcdc.v_front_porch, pinfo->lcdc.v_pulse_width);
132
133 total_hor = pinfo->xres + pinfo->lcdc.h_back_porch +
134 pinfo->lcdc.h_front_porch + pinfo->lcdc.h_pulse_width;
135
136 total_ver = pinfo->yres + pinfo->lcdc.v_back_porch +
137 pinfo->lcdc.v_front_porch + pinfo->lcdc.v_pulse_width;
138
139 data = total_ver;
140 data <<= 16;
141 data |= total_hor;
142 edp_write(EDP_BASE + 0x1c, data); /* EDP_TOTAL_HOR_VER */
143
144 data = (pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width);
145 data <<= 16;
146 data |= (pinfo->lcdc.h_back_porch + pinfo->lcdc.h_pulse_width);
147 edp_write(EDP_BASE + 0x20, data); /* EDP_START_HOR_VER_FROM_SYNC */
148
149 data = pinfo->lcdc.v_pulse_width;
150 data <<= 16;
151 data |= pinfo->lcdc.h_pulse_width;
152 edp_write(EDP_BASE + 0x24, data); /* EDP_HSYNC_VSYNC_WIDTH_POLARITY */
153
154 data = pinfo->yres;
155 data <<= 16;
156 data |= pinfo->xres;
157 edp_write(EDP_BASE + 0x28, data); /* EDP_ACTIVE_HOR_VER */
Asaf Pensob8f524c2013-05-20 12:32:31 +0300158}
159
160static void edp_enable(int enable)
161{
162 edp_write(EDP_BASE + 0x8, 0x0); /* EDP_STATE_CTRL */
163 edp_write(EDP_BASE + 0x8, 0x40); /* EDP_STATE_CTRL */
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700164 edp_write(EDP_BASE + 0x4, 0x01); /* EDP_MAINLINK_CTRL */
Asaf Pensob8f524c2013-05-20 12:32:31 +0300165}
166
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700167static void edp_disable(int enable)
Asaf Pensob8f524c2013-05-20 12:32:31 +0300168{
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700169 edp_write(EDP_BASE + 0x8, 0x0); /* EDP_STATE_CTRL */
170 edp_write(EDP_BASE + 0x4, 0x00); /* EDP_MAINLINK_CTRL */
Asaf Pensob8f524c2013-05-20 12:32:31 +0300171}
172
173int edp_on(void)
174{
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700175 mdss_edp_pll_configure();
176 mdss_edp_phy_pll_ready();
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -0700177 edp_phy_vm_pe_init();
178 edp_config_ctrl();
179 edp_config_sw_mvid_nvid();
180 edp_clock_synchrous();
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700181 edp_config_timing(edp_pinfo);
182 edp_config_tu();
Asaf Pensob8f524c2013-05-20 12:32:31 +0300183
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700184 edp_config_clk();
185 mdss_edp_lane_power_ctrl(1);
Asaf Pensob8f524c2013-05-20 12:32:31 +0300186
187 edp_enable_mainlink(1);
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700188
189 mdss_edp_link_train();
190
Asaf Pensob8f524c2013-05-20 12:32:31 +0300191 edp_enable(1);
192
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700193 mdss_edp_wait_for_video_ready();
194
195 mdss_edp_irq_disable();
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -0700196 dprintf(SPEW, "%s:\n", __func__);
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700197
Asaf Pensob8f524c2013-05-20 12:32:31 +0300198 return 0;
199}
200
201int edp_off(void)
202{
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700203 mdss_edp_irq_disable();
Asaf Pensob8f524c2013-05-20 12:32:31 +0300204 edp_enable_mainlink(0);
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700205 edp_phy_pll_reset();
206 edp_mainlink_reset();
207 edp_aux_reset();
Asaf Pensob8f524c2013-05-20 12:32:31 +0300208
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700209 edp_disable(1);
210 edp_unconfig_clk();
Asaf Pensob8f524c2013-05-20 12:32:31 +0300211
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700212 mdss_edp_lane_power_ctrl(0);
213 edp_phy_powerup(0);
214
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -0700215 dprintf(SPEW, "%s:\n", __func__);
Asaf Pensob8f524c2013-05-20 12:32:31 +0300216
217 return 0;
218}
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700219
220int edp_prepare(void)
221{
222
223 mdss_edp_aux_init();
224 edp_phy_pll_reset();
225 edp_mainlink_reset();
226 edp_aux_reset();
227 edp_phy_powerup(1);
228 edp_aux_enable();
229 mdss_edp_irq_enable();
230
231 mdss_edp_wait_for_hpd();
232
233 mdss_edp_edid_read();
234 mdss_edp_dpcd_cap_read();
235
236 edp_edid2pinfo(edp_pinfo);
237 edp_cap2pinfo(edp_pinfo);
238
Kuogee Hsiehe3b50dd2013-09-25 14:40:25 -0700239 dprintf(SPEW, "%s:\n", __func__);
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700240
241 return 0;
242}
243
244void edp_panel_init(struct msm_panel_info *pinfo)
245{
246 if (!pinfo)
247 return;
248
Siddhartha Agrawal967c9622013-10-23 18:08:04 -0700249 pinfo->lcdc.dual_pipe = 0;
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -0700250 pinfo->lcdc.split_display = 0;
251
252 edp_pinfo = pinfo;
253 edp_pinfo->on = edp_on;
254 edp_pinfo->off = edp_off;
255 edp_pinfo->prepare = edp_prepare;
256}