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