blob: 3500bf1d01ac29e5565f136d49adcac874daefe4 [file] [log] [blame]
Jitao Shi4a04a7b2016-01-08 16:02:13 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2015 MediaTek Inc.
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 as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <arch/io.h>
17#include <console/console.h>
18#include <delay.h>
19#include <soc/addressmap.h>
20#include <soc/i2c.h>
21#include <soc/gpio.h>
22#include <soc/dsi.h>
Jitao Shi700b0392016-07-15 14:23:53 +080023#include <timer.h>
Jitao Shi4a04a7b2016-01-08 16:02:13 +080024
25static int mtk_dsi_phy_clk_setting(u32 format, u32 lanes,
26 const struct edid *edid)
27{
28 u32 txdiv0, txdiv1;
29 u64 pcw;
30 u32 reg;
31 u32 bit_per_pixel;
32 int i, data_rate;
33
34 reg = read32(&mipi_tx0->dsi_bg_con);
35
36 reg = (reg & (~RG_DSI_V02_SEL)) | (4 << 20);
37 reg = (reg & (~RG_DSI_V032_SEL)) | (4 << 17);
38 reg = (reg & (~RG_DSI_V04_SEL)) | (4 << 14);
39 reg = (reg & (~RG_DSI_V072_SEL)) | (4 << 11);
40 reg = (reg & (~RG_DSI_V10_SEL)) | (4 << 8);
41 reg = (reg & (~RG_DSI_V12_SEL)) | (4 << 5);
42 reg |= RG_DSI_BG_CKEN;
43 reg |= RG_DSI_BG_CORE_EN;
44 write32(&mipi_tx0->dsi_bg_con, reg);
45 udelay(30);
46
47 clrsetbits_le32(&mipi_tx0->dsi_top_con, RG_DSI_LNT_IMP_CAL_CODE,
48 8 << 4 | RG_DSI_LNT_HS_BIAS_EN);
49
50 setbits_le32(&mipi_tx0->dsi_con,
51 RG_DSI0_CKG_LDOOUT_EN | RG_DSI0_LDOCORE_EN);
52
53 clrsetbits_le32(&mipi_tx0->dsi_pll_pwr, RG_DSI_MPPLL_SDM_ISO_EN,
54 RG_DSI_MPPLL_SDM_PWR_ON);
55
56 clrbits_le32(&mipi_tx0->dsi_pll_con0, RG_DSI0_MPPLL_PLL_EN);
57
58 switch (format) {
59 case MIPI_DSI_FMT_RGB565:
60 bit_per_pixel = 16;
61 break;
62 case MIPI_DSI_FMT_RGB666:
63 case MIPI_DSI_FMT_RGB666_PACKED:
64 bit_per_pixel = 18;
65 break;
66 case MIPI_DSI_FMT_RGB888:
67 default:
68 bit_per_pixel = 24;
69 break;
70 }
71
72 /**
73 * data_rate = (pixel_clock / 1000) * bit_per_pixel * mipi_ratio / lane_num
74 * pixel_clock unit is Khz, data_rata unit is MHz, so need divide 1000.
75 * mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
76 * we set mipi_ratio is 1.02.
77 * lane_num
78 */
79 data_rate = edid->mode.pixel_clock * 102 * bit_per_pixel /
80 (lanes * 1000 * 100);
81 if (data_rate > 500) {
82 txdiv0 = 0;
83 txdiv1 = 0;
84 } else if (data_rate >= 250) {
85 txdiv0 = 1;
86 txdiv1 = 0;
87 } else if (data_rate >= 125) {
88 txdiv0 = 2;
89 txdiv1 = 0;
90 } else if (data_rate >= 62) {
91 txdiv0 = 2;
92 txdiv1 = 1;
93 } else if (data_rate >= 50) {
94 txdiv0 = 2;
95 txdiv1 = 2;
96 } else {
97 printk(BIOS_ERR, "data rate (%u) must be >=50. Please check "
98 "pixel clock (%u), bpp (%u), and number of lanes (%u)\n",
99 data_rate, edid->mode.pixel_clock, bit_per_pixel, lanes);
100 return -1;
101 }
102
103 clrsetbits_le32(&mipi_tx0->dsi_pll_con0,
104 RG_DSI0_MPPLL_TXDIV1 | RG_DSI0_MPPLL_TXDIV0 |
105 RG_DSI0_MPPLL_PREDIV, txdiv1 << 5 | txdiv0 << 3);
106
107 /**
108 * PLL PCW config
109 * PCW bit 24~30 = integer part of pcw
110 * PCW bit 0~23 = fractional part of pcw
111 * pcw = data_Rate*4*txdiv/(Ref_clk*2);
112 * Post DIV =4, so need data_Rate*4
113 * Ref_clk is 26MHz
114 */
115 pcw = (u64)(data_rate * (1 << txdiv0) * (1 << txdiv1)) << 24;
116 pcw /= 13;
117 write32(&mipi_tx0->dsi_pll_con2, pcw);
118
119 setbits_le32(&mipi_tx0->dsi_pll_con1, RG_DSI0_MPPLL_SDM_FRA_EN);
120
121 setbits_le32(&mipi_tx0->dsi_clock_lane, LDOOUT_EN);
122
123 for (i = 0; i < lanes; i++)
124 setbits_le32(&mipi_tx0->dsi_data_lane[i], LDOOUT_EN);
125
126 setbits_le32(&mipi_tx0->dsi_pll_con0, RG_DSI0_MPPLL_PLL_EN);
127
128 udelay(40);
129
130 clrbits_le32(&mipi_tx0->dsi_pll_con1, RG_DSI0_MPPLL_SDM_SSC_EN);
131 clrbits_le32(&mipi_tx0->dsi_top_con, RG_DSI_PAD_TIE_LOW_EN);
132
133 return data_rate;
134}
135
136static void mtk_dsi_phy_timconfig(u32 data_rate)
137{
138 u32 timcon0, timcon1, timcon2, timcon3;
139 u32 cycle_time, ui, lpx;
140
141 ui = 1000 / data_rate + 0x01;
142 cycle_time = 8000 / data_rate + 0x01;
143 lpx = 5;
144
145 timcon0 = (8 << 24) | (0xa << 16) | (0x6 << 8) | lpx;
146 timcon1 = (7 << 24) | (5 * lpx << 16) | ((3 * lpx) / 2) << 8 |
147 (4 * lpx);
148 timcon2 = ((div_round_up(0x64, cycle_time) + 0xa) << 24) |
149 (div_round_up(0x150, cycle_time) << 16);
150 timcon3 = (2 * lpx) << 16 |
151 div_round_up(80 + 52 * ui, cycle_time) << 8 |
152 div_round_up(0x40, cycle_time);
153
154 write32(&dsi0->dsi_phy_timecon0, timcon0);
155 write32(&dsi0->dsi_phy_timecon1, timcon1);
156 write32(&dsi0->dsi_phy_timecon2, timcon2);
157 write32(&dsi0->dsi_phy_timecon3, timcon3);
158}
159
160static void mtk_dsi_reset(void)
161{
162 setbits_le32(&dsi0->dsi_con_ctrl, 3);
163 clrbits_le32(&dsi0->dsi_con_ctrl, 1);
164}
165
166static void mtk_dsi_clk_hs_mode_enable(void)
167{
168 setbits_le32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN);
169}
170
171static void mtk_dsi_clk_hs_mode_disable(void)
172{
173 clrbits_le32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN);
174}
175
176static void mtk_dsi_set_mode(u32 mode_flags)
177{
178 u32 tmp_reg1 = 0;
179
180 if (mode_flags & MIPI_DSI_MODE_VIDEO) {
181 tmp_reg1 = SYNC_PULSE_MODE;
182
183 if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
184 tmp_reg1 = BURST_MODE;
185
186 if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
187 tmp_reg1 = SYNC_PULSE_MODE;
188 }
189
190 write32(&dsi0->dsi_mode_ctrl, tmp_reg1);
191}
192
193static void mtk_dsi_rxtx_control(u32 lanes)
194{
195 u32 tmp_reg = 0;
196
197 switch (lanes) {
198 case 1:
199 tmp_reg = 1 << 2;
200 break;
201 case 2:
202 tmp_reg = 3 << 2;
203 break;
204 case 3:
205 tmp_reg = 7 << 2;
206 break;
207 case 4:
208 default:
209 tmp_reg = 0xf << 2;
210 break;
211 }
212
213 write32(&dsi0->dsi_txrx_ctrl, tmp_reg);
214}
215
216static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format,
217 const struct edid *edid)
218{
219 u32 hsync_active_byte;
220 u32 hbp_byte;
221 u32 hfp_byte;
222 u32 vbp_byte;
223 u32 vfp_byte;
224 u32 bpp;
225 u32 packet_fmt;
226
227 if (format == MIPI_DSI_FMT_RGB565)
228 bpp = 2;
229 else
230 bpp = 3;
231
232 vbp_byte = edid->mode.vbl - edid->mode.vso - edid->mode.vspw -
233 edid->mode.vborder;
234 vfp_byte = edid->mode.vso - edid->mode.vborder;
235
236 write32(&dsi0->dsi_vsa_nl, edid->mode.vspw);
237 write32(&dsi0->dsi_vbp_nl, vbp_byte);
238 write32(&dsi0->dsi_vfp_nl, vfp_byte);
239 write32(&dsi0->dsi_vact_nl, edid->mode.va);
240
241 if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
242 hbp_byte = (edid->mode.hbl - edid->mode.hso - edid->mode.hspw -
243 edid->mode.hborder) * bpp - 10;
244 else
245 hbp_byte = (edid->mode.hbl - edid->mode.hso -
246 edid->mode.hborder) * bpp - 10;
247
248 hsync_active_byte = edid->mode.hspw * bpp - 10;
249 hfp_byte = (edid->mode.hso - edid->mode.hborder) * bpp - 12;
250
251 write32(&dsi0->dsi_hsa_wc, hsync_active_byte);
252 write32(&dsi0->dsi_hbp_wc, hbp_byte);
253 write32(&dsi0->dsi_hfp_wc, hfp_byte);
254
255 switch (format) {
256 case MIPI_DSI_FMT_RGB888:
257 packet_fmt = PACKED_PS_24BIT_RGB888;
258 break;
259 case MIPI_DSI_FMT_RGB666:
260 packet_fmt = LOOSELY_PS_18BIT_RGB666;
261 break;
262 case MIPI_DSI_FMT_RGB666_PACKED:
263 packet_fmt = PACKED_PS_18BIT_RGB666;
264 break;
265 case MIPI_DSI_FMT_RGB565:
266 packet_fmt = PACKED_PS_16BIT_RGB565;
267 break;
268 default:
269 packet_fmt = PACKED_PS_24BIT_RGB888;
270 break;
271 }
272
273 packet_fmt |= edid->mode.ha * bpp & DSI_PS_WC;
274 write32(&dsi0->dsi_psctrl, packet_fmt);
275}
276
277static void mtk_dsi_start(void)
278{
279 write32(&dsi0->dsi_start, 0);
280 write32(&dsi0->dsi_start, 1);
281}
282
283int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes,
284 const struct edid *edid)
285{
286 int data_rate = mtk_dsi_phy_clk_setting(format, lanes, edid);
287
288 if (data_rate < 0)
289 return -1;
290
291 mtk_dsi_reset();
292 mtk_dsi_phy_timconfig(data_rate);
293 mtk_dsi_rxtx_control(lanes);
294 mtk_dsi_clk_hs_mode_disable();
295 mtk_dsi_config_vdo_timing(mode_flags, format, edid);
296 mtk_dsi_set_mode(mode_flags);
297 mtk_dsi_clk_hs_mode_enable();
298 mtk_dsi_start();
299
300 return 0;
301}
Jitao Shi700b0392016-07-15 14:23:53 +0800302
303void mtk_dsi_pin_drv_ctrl(void)
304{
305 struct stopwatch sw;
306
307 setbits_le32(&lvds_tx1->vopll_ctl3, RG_DA_LVDSTX_PWR_ON);
308
309 stopwatch_init_usecs_expire(&sw, 1000);
310
311 do {
312 if (stopwatch_expired(&sw)) {
313 printk(BIOS_ERR, "enable lvdstx_power failed!!!\n");
314 return;
315 }
316 } while ((read32(&lvds_tx1->vopll_ctl3) & RG_AD_LVDSTX_PWR_ACK) == 0);
317
318 clrbits_le32(&lvds_tx1->vopll_ctl3, RG_DA_LVDS_ISO_EN);
319}