1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2016 Nexell Co., Ltd.
4 *
5 * Author: junghyun, kim <jhkim@nexell.co.kr>
6 */
7
8 #include <config.h>
9 #include <common.h>
10 #include <errno.h>
11 #include <log.h>
12
13 #include <asm/arch/nexell.h>
14 #include <asm/arch/tieoff.h>
15 #include <asm/arch/reset.h>
16 #include <asm/arch/display.h>
17
18 #include <linux/delay.h>
19
20 #include "soc/s5pxx18_soc_dpc.h"
21 #include "soc/s5pxx18_soc_hdmi.h"
22 #include "soc/s5pxx18_soc_disptop.h"
23 #include "soc/s5pxx18_soc_disptop_clk.h"
24
25 #define __io_address(a) (void *)(uintptr_t)(a)
26
27 static const u8 hdmiphy_preset74_25[32] = {
28 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0xc8, 0x81,
29 0xe8, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0a,
30 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x86, 0x54,
31 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x10, 0x80,
32 };
33
34 static const u8 hdmiphy_preset148_5[32] = {
35 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0xc8, 0x81,
36 0xe8, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0a,
37 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x86, 0x54,
38 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
39 };
40
41 #define HDMIPHY_PRESET_TABLE_SIZE (32)
42
43 enum NXP_HDMI_PRESET {
44 NXP_HDMI_PRESET_720P = 0, /* 1280 x 720 */
45 NXP_HDMI_PRESET_1080P, /* 1920 x 1080 */
46 NXP_HDMI_PRESET_MAX
47 };
48
hdmi_reset(void)49 static void hdmi_reset(void)
50 {
51 nx_rstcon_setrst(RESET_ID_HDMI_VIDEO, RSTCON_ASSERT);
52 nx_rstcon_setrst(RESET_ID_HDMI_SPDIF, RSTCON_ASSERT);
53 nx_rstcon_setrst(RESET_ID_HDMI_TMDS, RSTCON_ASSERT);
54 nx_rstcon_setrst(RESET_ID_HDMI_VIDEO, RSTCON_NEGATE);
55 nx_rstcon_setrst(RESET_ID_HDMI_SPDIF, RSTCON_NEGATE);
56 nx_rstcon_setrst(RESET_ID_HDMI_TMDS, RSTCON_NEGATE);
57 }
58
hdmi_phy_enable(int preset,int enable)59 static int hdmi_phy_enable(int preset, int enable)
60 {
61 const u8 *table = NULL;
62 int size = 0;
63 u32 addr, i = 0;
64
65 if (!enable)
66 return 0;
67
68 switch (preset) {
69 case NXP_HDMI_PRESET_720P:
70 table = hdmiphy_preset74_25;
71 size = 32;
72 break;
73 case NXP_HDMI_PRESET_1080P:
74 table = hdmiphy_preset148_5;
75 size = 31;
76 break;
77 default:
78 printf("hdmi: phy not support preset %d\n", preset);
79 return -EINVAL;
80 }
81
82 nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (0 << 7));
83 nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (0 << 7));
84 nx_hdmi_set_reg(0, HDMI_PHY_REG04, (0 << 4));
85 nx_hdmi_set_reg(0, HDMI_PHY_REG04, (0 << 4));
86 nx_hdmi_set_reg(0, HDMI_PHY_REG24, (1 << 7));
87 nx_hdmi_set_reg(0, HDMI_PHY_REG24, (1 << 7));
88
89 for (i = 0, addr = HDMI_PHY_REG04; size > i; i++, addr += 4) {
90 nx_hdmi_set_reg(0, addr, table[i]);
91 nx_hdmi_set_reg(0, addr, table[i]);
92 }
93
94 nx_hdmi_set_reg(0, HDMI_PHY_REG7C, 0x80);
95 nx_hdmi_set_reg(0, HDMI_PHY_REG7C, 0x80);
96 nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (1 << 7));
97 nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (1 << 7));
98 debug("%s: preset = %d\n", __func__, preset);
99
100 return 0;
101 }
102
hdmi_wait_phy_ready(void)103 static inline int hdmi_wait_phy_ready(void)
104 {
105 int count = 500;
106
107 do {
108 u32 val = nx_hdmi_get_reg(0, HDMI_LINK_PHY_STATUS_0);
109
110 if (val & 0x01) {
111 printf("HDMI: phy ready...\n");
112 return 1;
113 }
114 mdelay(10);
115 } while (count--);
116
117 return 0;
118 }
119
hdmi_get_vsync(int preset,struct dp_sync_info * sync,struct dp_ctrl_info * ctrl)120 static inline int hdmi_get_vsync(int preset,
121 struct dp_sync_info *sync,
122 struct dp_ctrl_info *ctrl)
123 {
124 switch (preset) {
125 case NXP_HDMI_PRESET_720P: /* 720p: 1280x720 */
126 sync->h_active_len = 1280;
127 sync->h_sync_width = 40;
128 sync->h_back_porch = 220;
129 sync->h_front_porch = 110;
130 sync->h_sync_invert = 0;
131 sync->v_active_len = 720;
132 sync->v_sync_width = 5;
133 sync->v_back_porch = 20;
134 sync->v_front_porch = 5;
135 sync->v_sync_invert = 0;
136 break;
137
138 case NXP_HDMI_PRESET_1080P: /* 1080p: 1920x1080 */
139 sync->h_active_len = 1920;
140 sync->h_sync_width = 44;
141 sync->h_back_porch = 148;
142 sync->h_front_porch = 88;
143 sync->h_sync_invert = 0;
144 sync->v_active_len = 1080;
145 sync->v_sync_width = 5;
146 sync->v_back_porch = 36;
147 sync->v_front_porch = 4;
148 sync->v_sync_invert = 0;
149 break;
150 default:
151 printf("HDMI: not support preset sync %d\n", preset);
152 return -EINVAL;
153 }
154
155 ctrl->clk_src_lv0 = 4;
156 ctrl->clk_div_lv0 = 1;
157 ctrl->clk_src_lv1 = 7;
158 ctrl->clk_div_lv1 = 1;
159
160 ctrl->out_format = outputformat_rgb888;
161 ctrl->delay_mask = (DP_SYNC_DELAY_RGB_PVD | DP_SYNC_DELAY_HSYNC_CP1 |
162 DP_SYNC_DELAY_VSYNC_FRAM | DP_SYNC_DELAY_DE_CP);
163 ctrl->d_rgb_pvd = 0;
164 ctrl->d_hsync_cp1 = 0;
165 ctrl->d_vsync_fram = 0;
166 ctrl->d_de_cp2 = 7;
167
168 /* HFP + HSW + HBP + AVWidth-VSCLRPIXEL- 1; */
169 ctrl->vs_start_offset = (sync->h_front_porch + sync->h_sync_width +
170 sync->h_back_porch + sync->h_active_len - 1);
171 ctrl->vs_end_offset = 0;
172
173 /* HFP + HSW + HBP + AVWidth-EVENVSCLRPIXEL- 1 */
174 ctrl->ev_start_offset = (sync->h_front_porch + sync->h_sync_width +
175 sync->h_back_porch + sync->h_active_len - 1);
176 ctrl->ev_end_offset = 0;
177 debug("%s: preset: %d\n", __func__, preset);
178
179 return 0;
180 }
181
hdmi_clock(void)182 static void hdmi_clock(void)
183 {
184 void *base =
185 __io_address(nx_disp_top_clkgen_get_physical_address
186 (to_mipi_clkgen));
187
188 nx_disp_top_clkgen_set_base_address(to_mipi_clkgen, base);
189 nx_disp_top_clkgen_set_clock_divisor_enable(to_mipi_clkgen, 0);
190 nx_disp_top_clkgen_set_clock_pclk_mode(to_mipi_clkgen,
191 nx_pclkmode_always);
192 nx_disp_top_clkgen_set_clock_source(to_mipi_clkgen, HDMI_SPDIF_CLKOUT,
193 2);
194 nx_disp_top_clkgen_set_clock_divisor(to_mipi_clkgen, HDMI_SPDIF_CLKOUT,
195 2);
196 nx_disp_top_clkgen_set_clock_source(to_mipi_clkgen, 1, 7);
197 nx_disp_top_clkgen_set_clock_divisor_enable(to_mipi_clkgen, 1);
198
199 /* must initialize this !!! */
200 nx_disp_top_hdmi_set_vsync_hsstart_end(0, 0);
201 nx_disp_top_hdmi_set_vsync_start(0);
202 nx_disp_top_hdmi_set_hactive_start(0);
203 nx_disp_top_hdmi_set_hactive_end(0);
204 }
205
hdmi_vsync(struct dp_sync_info * sync)206 static void hdmi_vsync(struct dp_sync_info *sync)
207 {
208 int width = sync->h_active_len;
209 int hsw = sync->h_sync_width;
210 int hbp = sync->h_back_porch;
211 int height = sync->v_active_len;
212 int vsw = sync->v_sync_width;
213 int vbp = sync->v_back_porch;
214
215 int v_sync_s = vsw + vbp + height - 1;
216 int h_active_s = hsw + hbp;
217 int h_active_e = width + hsw + hbp;
218 int v_sync_hs_se0 = hsw + hbp + 1;
219 int v_sync_hs_se1 = hsw + hbp + 2;
220
221 nx_disp_top_hdmi_set_vsync_start(v_sync_s);
222 nx_disp_top_hdmi_set_hactive_start(h_active_s);
223 nx_disp_top_hdmi_set_hactive_end(h_active_e);
224 nx_disp_top_hdmi_set_vsync_hsstart_end(v_sync_hs_se0, v_sync_hs_se1);
225 }
226
hdmi_prepare(struct dp_sync_info * sync)227 static int hdmi_prepare(struct dp_sync_info *sync)
228 {
229 int width = sync->h_active_len;
230 int hsw = sync->h_sync_width;
231 int hfp = sync->h_front_porch;
232 int hbp = sync->h_back_porch;
233 int height = sync->v_active_len;
234 int vsw = sync->v_sync_width;
235 int vfp = sync->v_front_porch;
236 int vbp = sync->v_back_porch;
237
238 u32 h_blank, h_line, h_sync_start, h_sync_end;
239 u32 v_blank, v2_blank, v_line;
240 u32 v_sync_line_bef_1, v_sync_line_bef_2;
241
242 u32 fixed_ffff = 0xffff;
243
244 /* calculate sync variables */
245 h_blank = hfp + hsw + hbp;
246 v_blank = vfp + vsw + vbp;
247 v2_blank = height + vfp + vsw + vbp;
248 v_line = height + vfp + vsw + vbp; /* total v */
249 h_line = width + hfp + hsw + hbp; /* total h */
250 h_sync_start = hfp;
251 h_sync_end = hfp + hsw;
252 v_sync_line_bef_1 = vfp;
253 v_sync_line_bef_2 = vfp + vsw;
254
255 /* no blue screen mode, encoding order as it is */
256 nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_0, (0 << 5) | (1 << 4));
257
258 /* set HDMI_LINK_BLUE_SCREEN_* to 0x0 */
259 nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_R_0, 0x5555);
260 nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_R_1, 0x5555);
261 nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_G_0, 0x5555);
262 nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_G_1, 0x5555);
263 nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_B_0, 0x5555);
264 nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_B_1, 0x5555);
265
266 /* set HDMI_CON_1 to 0x0 */
267 nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_1, 0x0);
268 nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_2, 0x0);
269
270 /* set interrupt : enable hpd_plug, hpd_unplug */
271 nx_hdmi_set_reg(0, HDMI_LINK_INTC_CON_0,
272 (1 << 6) | (1 << 3) | (1 << 2));
273
274 /* set STATUS_EN to 0x17 */
275 nx_hdmi_set_reg(0, HDMI_LINK_STATUS_EN, 0x17);
276
277 /* TODO set HDP to 0x0 : later check hpd */
278 nx_hdmi_set_reg(0, HDMI_LINK_HPD, 0x0);
279
280 /* set MODE_SEL to 0x02 */
281 nx_hdmi_set_reg(0, HDMI_LINK_MODE_SEL, 0x2);
282
283 /* set H_BLANK_*, V1_BLANK_*, V2_BLANK_*, V_LINE_*,
284 * H_LINE_*, H_SYNC_START_*, H_SYNC_END_ *
285 * V_SYNC_LINE_BEF_1_*, V_SYNC_LINE_BEF_2_*
286 */
287 nx_hdmi_set_reg(0, HDMI_LINK_H_BLANK_0, h_blank % 256);
288 nx_hdmi_set_reg(0, HDMI_LINK_H_BLANK_1, h_blank >> 8);
289 nx_hdmi_set_reg(0, HDMI_LINK_V1_BLANK_0, v_blank % 256);
290 nx_hdmi_set_reg(0, HDMI_LINK_V1_BLANK_1, v_blank >> 8);
291 nx_hdmi_set_reg(0, HDMI_LINK_V2_BLANK_0, v2_blank % 256);
292 nx_hdmi_set_reg(0, HDMI_LINK_V2_BLANK_1, v2_blank >> 8);
293 nx_hdmi_set_reg(0, HDMI_LINK_V_LINE_0, v_line % 256);
294 nx_hdmi_set_reg(0, HDMI_LINK_V_LINE_1, v_line >> 8);
295 nx_hdmi_set_reg(0, HDMI_LINK_H_LINE_0, h_line % 256);
296 nx_hdmi_set_reg(0, HDMI_LINK_H_LINE_1, h_line >> 8);
297
298 if (width == 1280) {
299 nx_hdmi_set_reg(0, HDMI_LINK_HSYNC_POL, 0x1);
300 nx_hdmi_set_reg(0, HDMI_LINK_VSYNC_POL, 0x1);
301 } else {
302 nx_hdmi_set_reg(0, HDMI_LINK_HSYNC_POL, 0x0);
303 nx_hdmi_set_reg(0, HDMI_LINK_VSYNC_POL, 0x0);
304 }
305
306 nx_hdmi_set_reg(0, HDMI_LINK_INT_PRO_MODE, 0x0);
307
308 nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_START_0, (h_sync_start % 256) - 2);
309 nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_START_1, h_sync_start >> 8);
310 nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_END_0, (h_sync_end % 256) - 2);
311 nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_END_1, h_sync_end >> 8);
312 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_1_0,
313 v_sync_line_bef_1 % 256);
314 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_1_1,
315 v_sync_line_bef_1 >> 8);
316 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_2_0,
317 v_sync_line_bef_2 % 256);
318 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_2_1,
319 v_sync_line_bef_2 >> 8);
320
321 /* Set V_SYNC_LINE_AFT*, V_SYNC_LINE_AFT_PXL*, VACT_SPACE* */
322 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_1_0, fixed_ffff % 256);
323 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_1_1, fixed_ffff >> 8);
324 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_2_0, fixed_ffff % 256);
325 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_2_1, fixed_ffff >> 8);
326 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_3_0, fixed_ffff % 256);
327 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_3_1, fixed_ffff >> 8);
328 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_4_0, fixed_ffff % 256);
329 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_4_1, fixed_ffff >> 8);
330 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_5_0, fixed_ffff % 256);
331 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_5_1, fixed_ffff >> 8);
332 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_6_0, fixed_ffff % 256);
333 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_6_1, fixed_ffff >> 8);
334
335 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_1_0, fixed_ffff % 256);
336 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_1_1, fixed_ffff >> 8);
337 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_2_0, fixed_ffff % 256);
338 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_2_1, fixed_ffff >> 8);
339 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_3_0, fixed_ffff % 256);
340 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_3_1, fixed_ffff >> 8);
341 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_4_0, fixed_ffff % 256);
342 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_4_1, fixed_ffff >> 8);
343 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_5_0, fixed_ffff % 256);
344 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_5_1, fixed_ffff >> 8);
345 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_6_0, fixed_ffff % 256);
346 nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_6_1, fixed_ffff >> 8);
347
348 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE1_0, fixed_ffff % 256);
349 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE1_1, fixed_ffff >> 8);
350 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE2_0, fixed_ffff % 256);
351 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE2_1, fixed_ffff >> 8);
352 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE3_0, fixed_ffff % 256);
353 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE3_1, fixed_ffff >> 8);
354 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE4_0, fixed_ffff % 256);
355 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE4_1, fixed_ffff >> 8);
356 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE5_0, fixed_ffff % 256);
357 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE5_1, fixed_ffff >> 8);
358 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE6_0, fixed_ffff % 256);
359 nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE6_1, fixed_ffff >> 8);
360
361 nx_hdmi_set_reg(0, HDMI_LINK_CSC_MUX, 0x0);
362 nx_hdmi_set_reg(0, HDMI_LINK_SYNC_GEN_MUX, 0x0);
363
364 nx_hdmi_set_reg(0, HDMI_LINK_SEND_START_0, 0xfd);
365 nx_hdmi_set_reg(0, HDMI_LINK_SEND_START_1, 0x01);
366 nx_hdmi_set_reg(0, HDMI_LINK_SEND_END_0, 0x0d);
367 nx_hdmi_set_reg(0, HDMI_LINK_SEND_END_1, 0x3a);
368 nx_hdmi_set_reg(0, HDMI_LINK_SEND_END_2, 0x08);
369
370 /* Set DC_CONTROL to 0x00 */
371 nx_hdmi_set_reg(0, HDMI_LINK_DC_CONTROL, 0x0);
372
373 if (IS_ENABLED(CONFIG_HDMI_PATTERN))
374 nx_hdmi_set_reg(0, HDMI_LINK_VIDEO_PATTERN_GEN, 0x1);
375 else
376 nx_hdmi_set_reg(0, HDMI_LINK_VIDEO_PATTERN_GEN, 0x0);
377
378 nx_hdmi_set_reg(0, HDMI_LINK_GCP_CON, 0x0a);
379 return 0;
380 }
381
hdmi_init(void)382 static void hdmi_init(void)
383 {
384 void *base;
385 /**
386 * [SEQ 2] set the HDMI CLKGEN's PCLKMODE to always enabled
387 */
388 base =
389 __io_address(nx_disp_top_clkgen_get_physical_address(hdmi_clkgen));
390 nx_disp_top_clkgen_set_base_address(hdmi_clkgen, base);
391 nx_disp_top_clkgen_set_clock_pclk_mode(hdmi_clkgen, nx_pclkmode_always);
392
393 base = __io_address(nx_hdmi_get_physical_address(0));
394 nx_hdmi_set_base_address(0, base);
395
396 /**
397 * [SEQ 3] set the 0xC001100C[0] to 1
398 */
399 nx_tieoff_set(NX_TIEOFF_DISPLAYTOP0_i_HDMI_PHY_REFCLK_SEL, 1);
400
401 /**
402 * [SEQ 4] release the resets of HDMI.i_PHY_nRST and HDMI.i_nRST
403 */
404 nx_rstcon_setrst(RESET_ID_HDMI_PHY, RSTCON_ASSERT);
405 nx_rstcon_setrst(RESET_ID_HDMI, RSTCON_ASSERT);
406 nx_rstcon_setrst(RESET_ID_HDMI_PHY, RSTCON_NEGATE);
407 nx_rstcon_setrst(RESET_ID_HDMI, RSTCON_NEGATE);
408 }
409
hdmi_enable(int input,int preset,struct dp_sync_info * sync,int enable)410 void hdmi_enable(int input, int preset, struct dp_sync_info *sync, int enable)
411 {
412 if (enable) {
413 nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_0,
414 (nx_hdmi_get_reg(0, HDMI_LINK_HDMI_CON_0) |
415 0x1));
416 hdmi_vsync(sync);
417 } else {
418 hdmi_phy_enable(preset, 0);
419 }
420 }
421
hdmi_setup(int input,int preset,struct dp_sync_info * sync,struct dp_ctrl_info * ctrl)422 static int hdmi_setup(int input, int preset,
423 struct dp_sync_info *sync, struct dp_ctrl_info *ctrl)
424 {
425 u32 HDMI_SEL = 0;
426 int ret;
427
428 switch (input) {
429 case DP_DEVICE_DP0:
430 HDMI_SEL = primary_mlc;
431 break;
432 case DP_DEVICE_DP1:
433 HDMI_SEL = secondary_mlc;
434 break;
435 case DP_DEVICE_RESCONV:
436 HDMI_SEL = resolution_conv;
437 break;
438 default:
439 printf("HDMI: not support source device %d\n", input);
440 return -EINVAL;
441 }
442
443 /**
444 * [SEQ 5] set up the HDMI PHY to specific video clock.
445 */
446 ret = hdmi_phy_enable(preset, 1);
447 if (ret < 0)
448 return ret;
449
450 /**
451 * [SEQ 6] I2S (or SPDIFTX) configuration for the source audio data
452 * this is done in another user app - ex> Android Audio HAL
453 */
454
455 /**
456 * [SEQ 7] Wait for ECID ready
457 */
458
459 /**
460 * [SEQ 8] release the resets of HDMI.i_VIDEO_nRST and HDMI.i_SPDIF_nRST
461 * and HDMI.i_TMDS_nRST
462 */
463 hdmi_reset();
464
465 /**
466 * [SEQ 9] Wait for HDMI PHY ready (wait until 0xC0200020.[0], 1)
467 */
468 if (hdmi_wait_phy_ready() == 0) {
469 printf("%s: failed to wait for hdmiphy ready\n", __func__);
470 hdmi_phy_enable(preset, 0);
471 return -EIO;
472 }
473 /* set mux */
474 nx_disp_top_set_hdmimux(1, HDMI_SEL);
475
476 /**
477 * [SEC 10] Set the DPC CLKGEN's Source Clock to HDMI_CLK &
478 * Set Sync Parameter
479 */
480 hdmi_clock();
481 /* set hdmi link clk to clkgen vs default is hdmi phy clk */
482
483 /**
484 * [SEQ 11] Set up the HDMI Converter parameters
485 */
486 hdmi_get_vsync(preset, sync, ctrl);
487 hdmi_prepare(sync);
488
489 return 0;
490 }
491
nx_hdmi_display(int module,struct dp_sync_info * sync,struct dp_ctrl_info * ctrl,struct dp_plane_top * top,struct dp_plane_info * planes,struct dp_hdmi_dev * dev)492 void nx_hdmi_display(int module,
493 struct dp_sync_info *sync, struct dp_ctrl_info *ctrl,
494 struct dp_plane_top *top, struct dp_plane_info *planes,
495 struct dp_hdmi_dev *dev)
496 {
497 struct dp_plane_info *plane = planes;
498 int input = module == 0 ? DP_DEVICE_DP0 : DP_DEVICE_DP1;
499 int count = top->plane_num;
500 int preset = dev->preset;
501 int i = 0;
502
503 debug("HDMI: display.%d\n", module);
504
505 switch (preset) {
506 case 0:
507 top->screen_width = 1280;
508 top->screen_height = 720;
509 sync->h_active_len = 1280;
510 sync->v_active_len = 720;
511 break;
512 case 1:
513 top->screen_width = 1920;
514 top->screen_height = 1080;
515 sync->h_active_len = 1920;
516 sync->v_active_len = 1080;
517 break;
518 default:
519 printf("hdmi not support preset %d\n", preset);
520 return;
521 }
522
523 printf("HDMI: display.%d, preset %d (%4d * %4d)\n",
524 module, preset, top->screen_width, top->screen_height);
525
526 dp_control_init(module);
527 dp_plane_init(module);
528
529 hdmi_init();
530 hdmi_setup(input, preset, sync, ctrl);
531
532 dp_plane_screen_setup(module, top);
533 for (i = 0; count > i; i++, plane++) {
534 if (!plane->enable)
535 continue;
536 dp_plane_layer_setup(module, plane);
537 dp_plane_layer_enable(module, plane, 1);
538 }
539 dp_plane_screen_enable(module, 1);
540
541 dp_control_setup(module, sync, ctrl);
542 dp_control_enable(module, 1);
543
544 hdmi_enable(input, preset, sync, 1);
545 }
546