Commit 390a15a523c5aefb99008a5f67d6c8f9ec7ef63c
1 parent
42f1298bde
Exists in
smarc-imx_v2017.03_o8.1.0_1.3.0_8m
and in
1 other branch
MLK-17404-3 arch: arm: Adding support for i.MX8 HDMI
Adding basic HDMI support for i.MX8 for splash screen. Signed-off-by: Oliver Brown <oliver.brown@nxp.com>
Showing 3 changed files with 778 additions and 0 deletions Side-by-side Diff
arch/arm/cpu/armv8/imx8m/Makefile
arch/arm/cpu/armv8/imx8m/video_common.c
1 | +/* | |
2 | + * Copyright 2018 NXP | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#include <common.h> | |
8 | +#include <dm.h> | |
9 | +#include <asm/io.h> | |
10 | +#include <linux/errno.h> | |
11 | +#include <asm/arch/clock.h> | |
12 | +#include <asm/arch/imx-regs.h> | |
13 | +#include <i2c.h> | |
14 | +#include <asm/arch/sys_proto.h> | |
15 | + | |
16 | +#include <video_fb.h> | |
17 | +#include <asm/arch/video_common.h> | |
18 | +#include <power-domain.h> | |
19 | +#include <imx8_hdmi.h> | |
20 | + | |
21 | +DECLARE_GLOBAL_DATA_PTR; | |
22 | + | |
23 | +/* test congiurations */ | |
24 | +#undef IMXDCSS_LOAD_HDMI_FIRMWARE | |
25 | +#undef IMXDCSS_SET_PIXEL_CLOCK | |
26 | + | |
27 | +static struct video_mode_settings gmode; | |
28 | +static uint32_t gpixfmt; | |
29 | +GraphicDevice panel; | |
30 | +struct video_mode_settings *imx8m_get_gmode(void) | |
31 | +{ | |
32 | + return &gmode; | |
33 | +} | |
34 | + | |
35 | +void imx8m_show_gmode(void) | |
36 | +{ | |
37 | + printf("gmode =\n" | |
38 | + "pixelclock = %u\n" | |
39 | + "xres = %u\n" | |
40 | + "yres = %u\n" | |
41 | + "hfp = %u\n" | |
42 | + "hbp = %u\n" | |
43 | + "vfp = %u\n" | |
44 | + "vbp = %u\n" | |
45 | + "hsync = %u\n" | |
46 | + "vsync = %u\n" | |
47 | + "hpol = %u\n" | |
48 | + "vpol = %u\n", | |
49 | + gmode.pixelclock, | |
50 | + gmode.xres, | |
51 | + gmode.yres, | |
52 | + gmode.hfp, | |
53 | + gmode.hbp, | |
54 | + gmode.vfp, | |
55 | + gmode.vbp, gmode.hsync, gmode.vsync, gmode.hpol, gmode.vpol); | |
56 | +} | |
57 | + | |
58 | +GraphicDevice *imx8m_get_gd(void) | |
59 | +{ | |
60 | + return &panel; | |
61 | +} | |
62 | + | |
63 | +#define REG_BASE_ADDR 0x32e00000UL | |
64 | + | |
65 | +/*#define DEBUGREG*/ | |
66 | +#ifdef DEBUGREG | |
67 | +#define reg32_write(addr, val) \ | |
68 | +do { \ | |
69 | + debug("%s():%d 0x%08x -> 0x%08x\n", __func__, __LINE__, \ | |
70 | + (unsigned int)addr, (unsigned int)val); \ | |
71 | + __raw_writel(val, addr); \ | |
72 | +} while (0) | |
73 | +#else | |
74 | +#define reg32_write(addr, val) __raw_writel(val, addr) | |
75 | +#endif | |
76 | + | |
77 | +#define reg32_read(addr) __raw_readl(addr) | |
78 | + | |
79 | +#define reg32setbit(addr, bitpos) \ | |
80 | + reg32_write((addr), (reg32_read((addr)) | (1<<(bitpos)))) | |
81 | +#define reg32clearbit(addr, bitpos) \ | |
82 | + reg32_write((addr), (reg32_read((addr)) & ~(1<<(bitpos)))) | |
83 | + | |
84 | +#define reg32_read_tst(addr, val, mask) \ | |
85 | +do { \ | |
86 | + u32 temp = reg32_read((addr)); \ | |
87 | + if ((temp & (mask)) == ((val) & (mask))) \ | |
88 | + debug("%s():%d 0x%08x -> 0x%08x\n", \ | |
89 | + __func__, __LINE__, addr, val); \ | |
90 | + else \ | |
91 | + debug("%s():%d 0x%08x -> 0x%08x instead of 0x%08x\n", \ | |
92 | + __func__, __LINE__, addr, temp, val); \ | |
93 | +} while (0) | |
94 | + | |
95 | +#define COLOR_LIST_SIZE 8 | |
96 | +static u32 color_list_argb32[COLOR_LIST_SIZE] = { | |
97 | + 0xFFFFFFFF, /* white */ | |
98 | + 0xFFFF0000, /* red */ | |
99 | + 0xFF00FF00, /* green */ | |
100 | + 0xFF0000FF, /* blue */ | |
101 | + 0xFFFFFF00, /* yellow */ | |
102 | + 0xFF00FFFF, /* cyan */ | |
103 | + 0xFFFF00FF, /* magenta */ | |
104 | + 0xFFC1C2C3, /* silver */ | |
105 | +}; /*AARRGGBB */ | |
106 | + | |
107 | +static unsigned int get_color_index(unsigned short px, unsigned short py, | |
108 | + unsigned short width, unsigned short height, | |
109 | + unsigned short bar_size) | |
110 | +{ | |
111 | + const int mw = 5; /* margin width */ | |
112 | + if ((py >= 0 && py < mw) || (py >= height - mw && py < height) || | |
113 | + (px >= 0 && px < mw) || (px >= width - mw && px < width)) { | |
114 | + return 1; | |
115 | + } | |
116 | + | |
117 | + return py / bar_size; | |
118 | +} | |
119 | + | |
120 | +void imx8m_create_color_bar(void *start_address, | |
121 | + struct video_mode_settings *vms) | |
122 | +{ | |
123 | + /*struct video_mode_settings *vms = &vm_settings[g_vm]; */ | |
124 | + uint32_t color_bar_size = vms->yres / COLOR_LIST_SIZE; | |
125 | + int i, j; | |
126 | + u32 *pointer; | |
127 | + int color_index = 0; | |
128 | + pointer = (u32 *)start_address; | |
129 | + uint32_t *color_map = &color_list_argb32[0]; | |
130 | + debug("%s(), %d: start_address %p\n", | |
131 | + __func__, __LINE__, start_address); | |
132 | + debug("%s(), %d: pointer %p\n", __func__, __LINE__, pointer); | |
133 | + debug("%s(), %d x %d\n", __func__, vms->xres, vms->yres); | |
134 | + for (i = 0; i < vms->yres; i++) { | |
135 | + for (j = 0; j < vms->xres; j++) { | |
136 | + color_index = get_color_index(j, i, vms->xres, | |
137 | + vms->yres, | |
138 | + color_bar_size); | |
139 | + *pointer = color_map[color_index]; | |
140 | + pointer++; | |
141 | + } | |
142 | + } | |
143 | + invalidate_dcache_all(); | |
144 | +} | |
145 | + | |
146 | +static void imx8m_set_clocks(int apb_clk, int b_clk, int hdmi_core_clk, | |
147 | + int p_clk, int rtr_clk) | |
148 | +{ | |
149 | + if (b_clk == 800) { | |
150 | + /* b_clk: bus_clk_root(4) sel 2nd input source and | |
151 | + pre_div to 0; output should be 800M */ | |
152 | + reg32_write(CCM_BUS_CLK_ROOT_GEN_TAGET_CLR(4), | |
153 | + (0x7 << 24) | (0x7 << 16)); | |
154 | + reg32_write(CCM_BUS_CLK_ROOT_GEN_TAGET_SET(4), (0x2 << 24)); | |
155 | + } else { | |
156 | + printf("b_clk does not match a supported frequency"); | |
157 | + } | |
158 | + if (rtr_clk == 400) { | |
159 | + /* rtr_clk: bus_clk_root(6) sel 1st input source | |
160 | + and pre_div to 1; output should be 400M */ | |
161 | + reg32_write(CCM_BUS_CLK_ROOT_GEN_TAGET_CLR(6), | |
162 | + (0x7 << 24) | (0x7 << 16)); | |
163 | + reg32_write(CCM_BUS_CLK_ROOT_GEN_TAGET_SET(6), | |
164 | + (0x1 << 24) | (0x1 << 16)); | |
165 | + } else { | |
166 | + debug("rtr_clk does not match a supported frequency"); | |
167 | + } | |
168 | + | |
169 | +#ifdef IMXDCSS_LOAD_HDMI_FIRMWARE | |
170 | + /* If ROM is loading HDMI firmware then this clock should not be set */ | |
171 | + if (hdmi_core_clk == 200) { | |
172 | + /* hdmi_core_clk: ip_clk_root(69) sel 1st input source and | |
173 | + pre_div to 0 */ | |
174 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(69), | |
175 | + (0x7 << 24) | (0x7 << 16)); | |
176 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_SET(69), (0x1 << 24)); | |
177 | + g_hdmi_core_clock = 200000000; | |
178 | + } else { | |
179 | + debug("hdmi_core_clk does not match a supported frequency"); | |
180 | + } | |
181 | +#endif | |
182 | + | |
183 | +#ifdef IMXDCSS_SET_PIXEL_CLOCK | |
184 | + /* This would be needed for MIPI-DSI DCSS display */ | |
185 | + if (p_clk == 27) { | |
186 | + /* p_clk: ip_clk_root(9) sel 1st input source and | |
187 | + pre_div to 1; post_div to 5, output 100M */ | |
188 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(9), | |
189 | + (0x7 << 24) | (0x7 << 16)); | |
190 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_SET(9), | |
191 | + (0x1 << 24) | (29 << 16)); | |
192 | + } else if (p_clk == 100) { | |
193 | + /* p_clk: ip_clk_root(9) sel 1st input source and | |
194 | + pre_div to 1; post_div to 5, output 100M */ | |
195 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(9), | |
196 | + (0x7 << 24) | (0x7 << 16)); | |
197 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_SET(9), | |
198 | + (0x1 << 24) | (0x5 << 16)); | |
199 | + } else if (p_clk == 120) { | |
200 | + /* p_clk: ip_clk_root(9) sel 1st input source and | |
201 | + pre_div to 1; post_div to 4, output 120M */ | |
202 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(9), | |
203 | + (0x7 << 24) | (0x7 << 16)); | |
204 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_SET(9), | |
205 | + (0x1 << 24) | (0x4 << 16)); | |
206 | + } else if (p_clk == 200) { | |
207 | + /* I added this to speed up the pixel clock and | |
208 | + get frames out faster. may need to adjust this. | |
209 | + */ | |
210 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(9), | |
211 | + (0x7 << 24) | (0x7 << 16)); | |
212 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_SET(9), | |
213 | + (0x4 << 24) | (0x3 << 16)); /*for emu use 800 / 4 */ | |
214 | + } else if (p_clk == 400) { | |
215 | + /* I added this to speed up the pixel clock and | |
216 | + get frames out faster. may need to adjust this. | |
217 | + */ | |
218 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(9), | |
219 | + (0x7 << 24) | (0x7 << 16)); | |
220 | + reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_SET(9), | |
221 | + (0x4 << 24) | (0x1 << 16)); /*for emu use 800 / 2 */ | |
222 | + } else if (p_clk == 40) { /* Do not reprogram, will get 40MHz */ | |
223 | + } else { | |
224 | + debug("p_clk does not match a supported frequency"); | |
225 | + } | |
226 | +#endif | |
227 | +} | |
228 | + | |
229 | +static int imx8m_power_init(uint32_t clock_control) | |
230 | +{ | |
231 | + u32 temp; | |
232 | + /*struct video_mode_settings *vms = &vm_settings[g_vm]; */ | |
233 | + | |
234 | + debug("\nenabling display clock...\n"); | |
235 | + clock_enable(CCGR_DISPLAY, 1); | |
236 | + | |
237 | + reg32_write(0x303A00EC, 0x0000ffff); /*PGC_CPU_MAPPING */ | |
238 | + reg32setbit(0x303A00F8, 10); /*PU_PGC_SW_PUP_REQ : disp was 10 */ | |
239 | +#ifdef LOAD_HDMI_FIRMWARE | |
240 | + reg32setbit(0x303A00F8, 9); /*PU_PGC_SW_PUP_REQ : hdmi was 9 */ | |
241 | +#endif | |
242 | + imx8m_set_clocks(133, 800, 200, 27, 400); | |
243 | + | |
244 | + /* DCSS reset */ | |
245 | + reg32_write(0x32e2f000, 0xffffffff); | |
246 | + | |
247 | + /* DCSS clock selection */ | |
248 | + reg32_write(0x32e2f010, clock_control); | |
249 | + temp = reg32_read(0x32e2f010); | |
250 | + debug("%s(): DCSS clock control 0x%08x\n", __func__, temp); | |
251 | + | |
252 | + /* take DCSS out of reset - not needed OFB */ | |
253 | + /*__raw_writel(0xffffffff, 0x32e2f004); */ | |
254 | + | |
255 | + return 0; | |
256 | +} | |
257 | + | |
258 | +static void imx8m_display_init(u64 buffer, int encoding, | |
259 | + struct video_mode_settings *vms) | |
260 | +{ | |
261 | + /*struct video_mode_settings *vms = &vm_settings[g_vm]; */ | |
262 | + | |
263 | + debug("entering %s() ...\n", __func__); | |
264 | + debug("%s() buffer ...\n", __func__); | |
265 | + | |
266 | + /* DTRC-CHAN2/3 */ | |
267 | + reg32_write(REG_BASE_ADDR + 0x160c8, 0x00000002); | |
268 | + reg32_write(REG_BASE_ADDR + 0x170c8, 0x00000002); | |
269 | + | |
270 | + /* CHAN1_DPR */ | |
271 | + reg32_write(REG_BASE_ADDR + 0x180c0, (unsigned int)buffer); | |
272 | + reg32_write(REG_BASE_ADDR + 0x18090, 0x00000002); | |
273 | + reg32_write(REG_BASE_ADDR + 0x180a0, vms->xres); | |
274 | + reg32_write(REG_BASE_ADDR + 0x180b0, vms->yres); | |
275 | + reg32_write(REG_BASE_ADDR + 0x18110, | |
276 | + (unsigned int)buffer + vms->xres * vms->yres); | |
277 | + reg32_write(REG_BASE_ADDR + 0x180f0, 0x00000280); | |
278 | + reg32_write(REG_BASE_ADDR + 0x18100, 0x000000f0); | |
279 | + reg32_write(REG_BASE_ADDR + 0x18070, ((vms->xres * 4) << 16)); | |
280 | + reg32_write(REG_BASE_ADDR + 0x18050, 0x000e4203); | |
281 | + reg32_write(REG_BASE_ADDR + 0x18050, 0x000e4203); | |
282 | + reg32_write(REG_BASE_ADDR + 0x18200, 0x00000038); | |
283 | + reg32_write(REG_BASE_ADDR + 0x18000, 0x00000004); | |
284 | + reg32_write(REG_BASE_ADDR + 0x18000, 0x00000005); | |
285 | + | |
286 | + /* SCALER */ | |
287 | + reg32_write(REG_BASE_ADDR + 0x1c008, 0x00000000); | |
288 | + reg32_write(REG_BASE_ADDR + 0x1c00c, 0x00000000); | |
289 | + reg32_write(REG_BASE_ADDR + 0x1c010, 0x00000002); | |
290 | + reg32_write(REG_BASE_ADDR + 0x1c014, 0x00000002); | |
291 | + reg32_write(REG_BASE_ADDR + 0x1c018, | |
292 | + ((vms->yres - 1) << 16 | (vms->xres - 1))); | |
293 | + reg32_write(REG_BASE_ADDR + 0x1c01c, | |
294 | + ((vms->yres - 1) << 16 | (vms->xres - 1))); | |
295 | + reg32_write(REG_BASE_ADDR + 0x1c020, | |
296 | + ((vms->yres - 1) << 16 | (vms->xres - 1))); | |
297 | + reg32_write(REG_BASE_ADDR + 0x1c024, | |
298 | + ((vms->yres - 1) << 16 | (vms->xres - 1))); | |
299 | + reg32_write(REG_BASE_ADDR + 0x1c028, 0x00000000); | |
300 | + reg32_write(REG_BASE_ADDR + 0x1c02c, 0x00000000); | |
301 | + reg32_write(REG_BASE_ADDR + 0x1c030, 0x00000000); | |
302 | + reg32_write(REG_BASE_ADDR + 0x1c034, 0x00000000); | |
303 | + reg32_write(REG_BASE_ADDR + 0x1c038, 0x00000000); | |
304 | + reg32_write(REG_BASE_ADDR + 0x1c03c, 0x00000000); | |
305 | + reg32_write(REG_BASE_ADDR + 0x1c040, 0x00000000); | |
306 | + reg32_write(REG_BASE_ADDR + 0x1c044, 0x00000000); | |
307 | + reg32_write(REG_BASE_ADDR + 0x1c048, 0x00000000); | |
308 | + reg32_write(REG_BASE_ADDR + 0x1c04c, 0x00002000); | |
309 | + reg32_write(REG_BASE_ADDR + 0x1c050, 0x00000000); | |
310 | + reg32_write(REG_BASE_ADDR + 0x1c054, 0x00002000); | |
311 | + reg32_write(REG_BASE_ADDR + 0x1c058, 0x00000000); | |
312 | + reg32_write(REG_BASE_ADDR + 0x1c05c, 0x00002000); | |
313 | + reg32_write(REG_BASE_ADDR + 0x1c060, 0x00000000); | |
314 | + reg32_write(REG_BASE_ADDR + 0x1c064, 0x00002000); | |
315 | + reg32_write(REG_BASE_ADDR + 0x1c080, 0x00000000); | |
316 | + reg32_write(REG_BASE_ADDR + 0x1c0c0, 0x00040000); | |
317 | + reg32_write(REG_BASE_ADDR + 0x1c100, 0x00000000); | |
318 | + reg32_write(REG_BASE_ADDR + 0x1c084, 0x00000000); | |
319 | + reg32_write(REG_BASE_ADDR + 0x1c0c4, 0x00000000); | |
320 | + reg32_write(REG_BASE_ADDR + 0x1c104, 0x00000000); | |
321 | + reg32_write(REG_BASE_ADDR + 0x1c088, 0x00000000); | |
322 | + reg32_write(REG_BASE_ADDR + 0x1c0c8, 0x00000000); | |
323 | + reg32_write(REG_BASE_ADDR + 0x1c108, 0x00000000); | |
324 | + reg32_write(REG_BASE_ADDR + 0x1c08c, 0x00000000); | |
325 | + reg32_write(REG_BASE_ADDR + 0x1c0cc, 0x00000000); | |
326 | + reg32_write(REG_BASE_ADDR + 0x1c10c, 0x00000000); | |
327 | + reg32_write(REG_BASE_ADDR + 0x1c090, 0x00000000); | |
328 | + reg32_write(REG_BASE_ADDR + 0x1c0d0, 0x00000000); | |
329 | + reg32_write(REG_BASE_ADDR + 0x1c110, 0x00000000); | |
330 | + reg32_write(REG_BASE_ADDR + 0x1c094, 0x00000000); | |
331 | + reg32_write(REG_BASE_ADDR + 0x1c0d4, 0x00000000); | |
332 | + reg32_write(REG_BASE_ADDR + 0x1c114, 0x00000000); | |
333 | + reg32_write(REG_BASE_ADDR + 0x1c098, 0x00000000); | |
334 | + reg32_write(REG_BASE_ADDR + 0x1c0d8, 0x00000000); | |
335 | + reg32_write(REG_BASE_ADDR + 0x1c118, 0x00000000); | |
336 | + reg32_write(REG_BASE_ADDR + 0x1c09c, 0x00000000); | |
337 | + reg32_write(REG_BASE_ADDR + 0x1c0dc, 0x00000000); | |
338 | + reg32_write(REG_BASE_ADDR + 0x1c11c, 0x00000000); | |
339 | + reg32_write(REG_BASE_ADDR + 0x1c0a0, 0x00000000); | |
340 | + reg32_write(REG_BASE_ADDR + 0x1c0e0, 0x00000000); | |
341 | + reg32_write(REG_BASE_ADDR + 0x1c120, 0x00000000); | |
342 | + reg32_write(REG_BASE_ADDR + 0x1c0a4, 0x00000000); | |
343 | + reg32_write(REG_BASE_ADDR + 0x1c0e4, 0x00000000); | |
344 | + reg32_write(REG_BASE_ADDR + 0x1c124, 0x00000000); | |
345 | + reg32_write(REG_BASE_ADDR + 0x1c0a8, 0x00000000); | |
346 | + reg32_write(REG_BASE_ADDR + 0x1c0e8, 0x00000000); | |
347 | + reg32_write(REG_BASE_ADDR + 0x1c128, 0x00000000); | |
348 | + reg32_write(REG_BASE_ADDR + 0x1c0ac, 0x00000000); | |
349 | + reg32_write(REG_BASE_ADDR + 0x1c0ec, 0x00000000); | |
350 | + reg32_write(REG_BASE_ADDR + 0x1c12c, 0x00000000); | |
351 | + reg32_write(REG_BASE_ADDR + 0x1c0b0, 0x00000000); | |
352 | + reg32_write(REG_BASE_ADDR + 0x1c0f0, 0x00000000); | |
353 | + reg32_write(REG_BASE_ADDR + 0x1c130, 0x00000000); | |
354 | + reg32_write(REG_BASE_ADDR + 0x1c0b4, 0x00000000); | |
355 | + reg32_write(REG_BASE_ADDR + 0x1c0f4, 0x00000000); | |
356 | + reg32_write(REG_BASE_ADDR + 0x1c134, 0x00000000); | |
357 | + reg32_write(REG_BASE_ADDR + 0x1c0b8, 0x00000000); | |
358 | + reg32_write(REG_BASE_ADDR + 0x1c0f8, 0x00000000); | |
359 | + reg32_write(REG_BASE_ADDR + 0x1c138, 0x00000000); | |
360 | + reg32_write(REG_BASE_ADDR + 0x1c0bc, 0x00000000); | |
361 | + reg32_write(REG_BASE_ADDR + 0x1c0fc, 0x00000000); | |
362 | + reg32_write(REG_BASE_ADDR + 0x1c13c, 0x00000000); | |
363 | + reg32_write(REG_BASE_ADDR + 0x1c140, 0x00000000); | |
364 | + reg32_write(REG_BASE_ADDR + 0x1c180, 0x00040000); | |
365 | + reg32_write(REG_BASE_ADDR + 0x1c1c0, 0x00000000); | |
366 | + reg32_write(REG_BASE_ADDR + 0x1c144, 0x00000000); | |
367 | + reg32_write(REG_BASE_ADDR + 0x1c184, 0x00000000); | |
368 | + reg32_write(REG_BASE_ADDR + 0x1c1c4, 0x00000000); | |
369 | + reg32_write(REG_BASE_ADDR + 0x1c148, 0x00000000); | |
370 | + reg32_write(REG_BASE_ADDR + 0x1c188, 0x00000000); | |
371 | + reg32_write(REG_BASE_ADDR + 0x1c1c8, 0x00000000); | |
372 | + reg32_write(REG_BASE_ADDR + 0x1c14c, 0x00000000); | |
373 | + reg32_write(REG_BASE_ADDR + 0x1c18c, 0x00000000); | |
374 | + reg32_write(REG_BASE_ADDR + 0x1c1cc, 0x00000000); | |
375 | + reg32_write(REG_BASE_ADDR + 0x1c150, 0x00000000); | |
376 | + reg32_write(REG_BASE_ADDR + 0x1c190, 0x00000000); | |
377 | + reg32_write(REG_BASE_ADDR + 0x1c1d0, 0x00000000); | |
378 | + reg32_write(REG_BASE_ADDR + 0x1c154, 0x00000000); | |
379 | + reg32_write(REG_BASE_ADDR + 0x1c194, 0x00000000); | |
380 | + reg32_write(REG_BASE_ADDR + 0x1c1d4, 0x00000000); | |
381 | + reg32_write(REG_BASE_ADDR + 0x1c158, 0x00000000); | |
382 | + reg32_write(REG_BASE_ADDR + 0x1c198, 0x00000000); | |
383 | + reg32_write(REG_BASE_ADDR + 0x1c1d8, 0x00000000); | |
384 | + reg32_write(REG_BASE_ADDR + 0x1c15c, 0x00000000); | |
385 | + reg32_write(REG_BASE_ADDR + 0x1c19c, 0x00000000); | |
386 | + reg32_write(REG_BASE_ADDR + 0x1c1dc, 0x00000000); | |
387 | + reg32_write(REG_BASE_ADDR + 0x1c160, 0x00000000); | |
388 | + reg32_write(REG_BASE_ADDR + 0x1c1a0, 0x00000000); | |
389 | + reg32_write(REG_BASE_ADDR + 0x1c1e0, 0x00000000); | |
390 | + reg32_write(REG_BASE_ADDR + 0x1c164, 0x00000000); | |
391 | + reg32_write(REG_BASE_ADDR + 0x1c1a4, 0x00000000); | |
392 | + reg32_write(REG_BASE_ADDR + 0x1c1e4, 0x00000000); | |
393 | + reg32_write(REG_BASE_ADDR + 0x1c168, 0x00000000); | |
394 | + reg32_write(REG_BASE_ADDR + 0x1c1a8, 0x00000000); | |
395 | + reg32_write(REG_BASE_ADDR + 0x1c1e8, 0x00000000); | |
396 | + reg32_write(REG_BASE_ADDR + 0x1c16c, 0x00000000); | |
397 | + reg32_write(REG_BASE_ADDR + 0x1c1ac, 0x00000000); | |
398 | + reg32_write(REG_BASE_ADDR + 0x1c1ec, 0x00000000); | |
399 | + reg32_write(REG_BASE_ADDR + 0x1c170, 0x00000000); | |
400 | + reg32_write(REG_BASE_ADDR + 0x1c1b0, 0x00000000); | |
401 | + reg32_write(REG_BASE_ADDR + 0x1c1f0, 0x00000000); | |
402 | + reg32_write(REG_BASE_ADDR + 0x1c174, 0x00000000); | |
403 | + reg32_write(REG_BASE_ADDR + 0x1c1b4, 0x00000000); | |
404 | + reg32_write(REG_BASE_ADDR + 0x1c1f4, 0x00000000); | |
405 | + reg32_write(REG_BASE_ADDR + 0x1c178, 0x00000000); | |
406 | + reg32_write(REG_BASE_ADDR + 0x1c1b8, 0x00000000); | |
407 | + reg32_write(REG_BASE_ADDR + 0x1c1f8, 0x00000000); | |
408 | + reg32_write(REG_BASE_ADDR + 0x1c17c, 0x00000000); | |
409 | + reg32_write(REG_BASE_ADDR + 0x1c1bc, 0x00000000); | |
410 | + reg32_write(REG_BASE_ADDR + 0x1c1fc, 0x00000000); | |
411 | + reg32_write(REG_BASE_ADDR + 0x1c300, 0x00000000); | |
412 | + reg32_write(REG_BASE_ADDR + 0x1c340, 0x00000000); | |
413 | + reg32_write(REG_BASE_ADDR + 0x1c380, 0x00000000); | |
414 | + reg32_write(REG_BASE_ADDR + 0x1c304, 0x00000000); | |
415 | + reg32_write(REG_BASE_ADDR + 0x1c344, 0x00000000); | |
416 | + reg32_write(REG_BASE_ADDR + 0x1c384, 0x00000000); | |
417 | + reg32_write(REG_BASE_ADDR + 0x1c308, 0x00000000); | |
418 | + reg32_write(REG_BASE_ADDR + 0x1c348, 0x00000000); | |
419 | + reg32_write(REG_BASE_ADDR + 0x1c388, 0x00000000); | |
420 | + reg32_write(REG_BASE_ADDR + 0x1c30c, 0x00000000); | |
421 | + reg32_write(REG_BASE_ADDR + 0x1c34c, 0x00000000); | |
422 | + reg32_write(REG_BASE_ADDR + 0x1c38c, 0x00000000); | |
423 | + reg32_write(REG_BASE_ADDR + 0x1c310, 0x00000000); | |
424 | + reg32_write(REG_BASE_ADDR + 0x1c350, 0x00000000); | |
425 | + reg32_write(REG_BASE_ADDR + 0x1c390, 0x00000000); | |
426 | + reg32_write(REG_BASE_ADDR + 0x1c314, 0x00000000); | |
427 | + reg32_write(REG_BASE_ADDR + 0x1c354, 0x00000000); | |
428 | + reg32_write(REG_BASE_ADDR + 0x1c394, 0x00000000); | |
429 | + reg32_write(REG_BASE_ADDR + 0x1c318, 0x00000000); | |
430 | + reg32_write(REG_BASE_ADDR + 0x1c358, 0x00000000); | |
431 | + reg32_write(REG_BASE_ADDR + 0x1c398, 0x00000000); | |
432 | + reg32_write(REG_BASE_ADDR + 0x1c31c, 0x00000000); | |
433 | + reg32_write(REG_BASE_ADDR + 0x1c35c, 0x00000000); | |
434 | + reg32_write(REG_BASE_ADDR + 0x1c39c, 0x00000000); | |
435 | + reg32_write(REG_BASE_ADDR + 0x1c320, 0x00000000); | |
436 | + reg32_write(REG_BASE_ADDR + 0x1c360, 0x00000000); | |
437 | + reg32_write(REG_BASE_ADDR + 0x1c3a0, 0x00000000); | |
438 | + reg32_write(REG_BASE_ADDR + 0x1c324, 0x00000000); | |
439 | + reg32_write(REG_BASE_ADDR + 0x1c364, 0x00000000); | |
440 | + reg32_write(REG_BASE_ADDR + 0x1c3a4, 0x00000000); | |
441 | + reg32_write(REG_BASE_ADDR + 0x1c328, 0x00000000); | |
442 | + reg32_write(REG_BASE_ADDR + 0x1c368, 0x00000000); | |
443 | + reg32_write(REG_BASE_ADDR + 0x1c3a8, 0x00000000); | |
444 | + reg32_write(REG_BASE_ADDR + 0x1c32c, 0x00000000); | |
445 | + reg32_write(REG_BASE_ADDR + 0x1c36c, 0x00000000); | |
446 | + reg32_write(REG_BASE_ADDR + 0x1c3ac, 0x00000000); | |
447 | + reg32_write(REG_BASE_ADDR + 0x1c330, 0x00000000); | |
448 | + reg32_write(REG_BASE_ADDR + 0x1c370, 0x00000000); | |
449 | + reg32_write(REG_BASE_ADDR + 0x1c3b0, 0x00000000); | |
450 | + reg32_write(REG_BASE_ADDR + 0x1c334, 0x00000000); | |
451 | + reg32_write(REG_BASE_ADDR + 0x1c374, 0x00000000); | |
452 | + reg32_write(REG_BASE_ADDR + 0x1c3b4, 0x00000000); | |
453 | + reg32_write(REG_BASE_ADDR + 0x1c338, 0x00000000); | |
454 | + reg32_write(REG_BASE_ADDR + 0x1c378, 0x00000000); | |
455 | + reg32_write(REG_BASE_ADDR + 0x1c3b8, 0x00000000); | |
456 | + reg32_write(REG_BASE_ADDR + 0x1c33c, 0x00000000); | |
457 | + reg32_write(REG_BASE_ADDR + 0x1c37c, 0x00000000); | |
458 | + reg32_write(REG_BASE_ADDR + 0x1c3bc, 0x00000000); | |
459 | + reg32_write(REG_BASE_ADDR + 0x1c200, 0x00000000); | |
460 | + reg32_write(REG_BASE_ADDR + 0x1c240, 0x00000000); | |
461 | + reg32_write(REG_BASE_ADDR + 0x1c280, 0x00000000); | |
462 | + reg32_write(REG_BASE_ADDR + 0x1c204, 0x00000000); | |
463 | + reg32_write(REG_BASE_ADDR + 0x1c244, 0x00000000); | |
464 | + reg32_write(REG_BASE_ADDR + 0x1c284, 0x00000000); | |
465 | + reg32_write(REG_BASE_ADDR + 0x1c208, 0x00000000); | |
466 | + reg32_write(REG_BASE_ADDR + 0x1c248, 0x00000000); | |
467 | + reg32_write(REG_BASE_ADDR + 0x1c288, 0x00000000); | |
468 | + reg32_write(REG_BASE_ADDR + 0x1c20c, 0x00000000); | |
469 | + reg32_write(REG_BASE_ADDR + 0x1c24c, 0x00000000); | |
470 | + reg32_write(REG_BASE_ADDR + 0x1c28c, 0x00000000); | |
471 | + reg32_write(REG_BASE_ADDR + 0x1c210, 0x00000000); | |
472 | + reg32_write(REG_BASE_ADDR + 0x1c250, 0x00000000); | |
473 | + reg32_write(REG_BASE_ADDR + 0x1c290, 0x00000000); | |
474 | + reg32_write(REG_BASE_ADDR + 0x1c214, 0x00000000); | |
475 | + reg32_write(REG_BASE_ADDR + 0x1c254, 0x00000000); | |
476 | + reg32_write(REG_BASE_ADDR + 0x1c294, 0x00000000); | |
477 | + reg32_write(REG_BASE_ADDR + 0x1c218, 0x00000000); | |
478 | + reg32_write(REG_BASE_ADDR + 0x1c258, 0x00000000); | |
479 | + reg32_write(REG_BASE_ADDR + 0x1c298, 0x00000000); | |
480 | + reg32_write(REG_BASE_ADDR + 0x1c21c, 0x00000000); | |
481 | + reg32_write(REG_BASE_ADDR + 0x1c25c, 0x00000000); | |
482 | + reg32_write(REG_BASE_ADDR + 0x1c29c, 0x00000000); | |
483 | + reg32_write(REG_BASE_ADDR + 0x1c220, 0x00000000); | |
484 | + reg32_write(REG_BASE_ADDR + 0x1c260, 0x00000000); | |
485 | + reg32_write(REG_BASE_ADDR + 0x1c2a0, 0x00000000); | |
486 | + reg32_write(REG_BASE_ADDR + 0x1c224, 0x00000000); | |
487 | + reg32_write(REG_BASE_ADDR + 0x1c264, 0x00000000); | |
488 | + reg32_write(REG_BASE_ADDR + 0x1c2a4, 0x00000000); | |
489 | + reg32_write(REG_BASE_ADDR + 0x1c228, 0x00000000); | |
490 | + reg32_write(REG_BASE_ADDR + 0x1c268, 0x00000000); | |
491 | + reg32_write(REG_BASE_ADDR + 0x1c2a8, 0x00000000); | |
492 | + reg32_write(REG_BASE_ADDR + 0x1c22c, 0x00000000); | |
493 | + reg32_write(REG_BASE_ADDR + 0x1c26c, 0x00000000); | |
494 | + reg32_write(REG_BASE_ADDR + 0x1c2ac, 0x00000000); | |
495 | + reg32_write(REG_BASE_ADDR + 0x1c230, 0x00000000); | |
496 | + reg32_write(REG_BASE_ADDR + 0x1c270, 0x00000000); | |
497 | + reg32_write(REG_BASE_ADDR + 0x1c2b0, 0x00000000); | |
498 | + reg32_write(REG_BASE_ADDR + 0x1c234, 0x00000000); | |
499 | + reg32_write(REG_BASE_ADDR + 0x1c274, 0x00000000); | |
500 | + reg32_write(REG_BASE_ADDR + 0x1c2b4, 0x00000000); | |
501 | + reg32_write(REG_BASE_ADDR + 0x1c238, 0x00000000); | |
502 | + reg32_write(REG_BASE_ADDR + 0x1c278, 0x00000000); | |
503 | + reg32_write(REG_BASE_ADDR + 0x1c2b8, 0x00000000); | |
504 | + reg32_write(REG_BASE_ADDR + 0x1c23c, 0x00000000); | |
505 | + reg32_write(REG_BASE_ADDR + 0x1c27c, 0x00000000); | |
506 | + reg32_write(REG_BASE_ADDR + 0x1c2bc, 0x00000000); | |
507 | + reg32_write(REG_BASE_ADDR + 0x1c2bc, 0x00000000); | |
508 | + reg32_write(REG_BASE_ADDR + 0x1c000, 0x00000011); | |
509 | + | |
510 | + /* SUBSAM */ | |
511 | + reg32_write(REG_BASE_ADDR + 0x1b070, 0x21612161); | |
512 | + reg32_write(REG_BASE_ADDR + 0x1b080, 0x03ff0000); | |
513 | + reg32_write(REG_BASE_ADDR + 0x1b090, 0x03ff0000); | |
514 | + | |
515 | + reg32_write(REG_BASE_ADDR + 0x1b010, | |
516 | + (((vms->vfp + vms->vbp + vms->vsync + vms->yres - | |
517 | + 1) << 16) | (vms->hfp + vms->hbp + vms->hsync + | |
518 | + vms->xres - 1))); | |
519 | + reg32_write(REG_BASE_ADDR + 0x1b020, | |
520 | + (((vms->hsync - 1) << 16) | vms->hpol << 31 | (vms->hfp + | |
521 | + vms->hbp + | |
522 | + vms->hsync + | |
523 | + vms->xres - | |
524 | + 1))); | |
525 | + reg32_write(REG_BASE_ADDR + 0x1b030, | |
526 | + (((vms->vfp + vms->vsync - | |
527 | + 1) << 16) | vms->vpol << 31 | (vms->vfp - 1))); | |
528 | + | |
529 | + reg32_write(REG_BASE_ADDR + 0x1b040, | |
530 | + ((1 << 31) | ((vms->vsync + vms->vfp + vms->vbp) << 16) | | |
531 | + (vms->hsync + vms->hbp - 1))); | |
532 | + reg32_write(REG_BASE_ADDR + 0x1b050, | |
533 | + (((vms->vsync + vms->vfp + vms->vbp + vms->yres - | |
534 | + 1) << 16) | (vms->hsync + vms->hbp + vms->xres - 1))); | |
535 | + | |
536 | + /* subsample mode 0 none, 1 422, 2 420 */ | |
537 | + switch (encoding) { | |
538 | + case 4: | |
539 | + reg32_write(REG_BASE_ADDR + 0x1b060, 0x00000001); | |
540 | + break; | |
541 | + | |
542 | + case 8: | |
543 | + reg32_write(REG_BASE_ADDR + 0x1b060, 0x00000002); | |
544 | + break; | |
545 | + | |
546 | + case 2: | |
547 | + case 1: | |
548 | + default: | |
549 | + reg32_write(REG_BASE_ADDR + 0x1b060, 0x0000000); | |
550 | + } | |
551 | + | |
552 | + reg32_write(REG_BASE_ADDR + 0x1b000, 0x00000001); | |
553 | +#if 0 | |
554 | + /* not needed for splash setup */ | |
555 | + /* HDR10 Chan3 LUT */ | |
556 | + reg32_write(REG_BASE_ADDR + 0x03874, 0x00000000); | |
557 | + reg32_write(REG_BASE_ADDR + 0x03080, 0x00000000); | |
558 | + reg32_write(REG_BASE_ADDR + 0x03000, 0x00000000); | |
559 | + reg32_write(REG_BASE_ADDR + 0x03800, 0x00000000); | |
560 | + reg32_write(REG_BASE_ADDR + 0x07874, 0x00000000); | |
561 | + reg32_write(REG_BASE_ADDR + 0x07080, 0x00000000); | |
562 | + reg32_write(REG_BASE_ADDR + 0x07000, 0x00000000); | |
563 | + reg32_write(REG_BASE_ADDR + 0x07800, 0x00000000); | |
564 | + reg32_write(REG_BASE_ADDR + 0x0b874, 0x00000000); | |
565 | + reg32_write(REG_BASE_ADDR + 0x0b080, 0x00000000); | |
566 | + reg32_write(REG_BASE_ADDR + 0x0b000, 0x00000000); | |
567 | + reg32_write(REG_BASE_ADDR + 0x0b800, 0x00000000); | |
568 | + | |
569 | + /* HDR10 Tables and Registers */ | |
570 | + /*reg32_write(REG_BASE_ADDR+0x0f074, 0x00000003); */ | |
571 | + /*reg32_write(REG_BASE_ADDR+0x0f000, 0x00000004); */ | |
572 | + | |
573 | + reg32_write(REG_BASE_ADDR + 0x0f004, 0x00000000); | |
574 | + reg32_write(REG_BASE_ADDR + 0x0f008, 0x00000001); | |
575 | + reg32_write(REG_BASE_ADDR + 0x0f00c, 0x00000000); | |
576 | + reg32_write(REG_BASE_ADDR + 0x0f010, 0x00000000); | |
577 | + reg32_write(REG_BASE_ADDR + 0x0f014, 0x00000000); | |
578 | + reg32_write(REG_BASE_ADDR + 0x0f018, 0x00000001); | |
579 | + reg32_write(REG_BASE_ADDR + 0x0f01c, 0x00000001); | |
580 | + reg32_write(REG_BASE_ADDR + 0x0f020, 0x00000000); | |
581 | + reg32_write(REG_BASE_ADDR + 0x0f024, 0x00000000); | |
582 | + reg32_write(REG_BASE_ADDR + 0x0f028, 0x00000000); | |
583 | + reg32_write(REG_BASE_ADDR + 0x0f02c, 0x00000000); | |
584 | + reg32_write(REG_BASE_ADDR + 0x0f030, 0x00000000); | |
585 | + reg32_write(REG_BASE_ADDR + 0x0f034, 0x00000000); | |
586 | + reg32_write(REG_BASE_ADDR + 0x0f038, 0x00000000); | |
587 | + reg32_write(REG_BASE_ADDR + 0x0f03c, 0x00000000); | |
588 | + reg32_write(REG_BASE_ADDR + 0x0f040, 0xffffffff); | |
589 | + reg32_write(REG_BASE_ADDR + 0x0f044, 0xffffffff); | |
590 | + reg32_write(REG_BASE_ADDR + 0x0f048, 0xffffffff); | |
591 | + reg32_write(REG_BASE_ADDR + 0x0f04c, 0x00000000); | |
592 | + reg32_write(REG_BASE_ADDR + 0x0f050, 0x00000000); | |
593 | + reg32_write(REG_BASE_ADDR + 0x0f054, 0x00000000); | |
594 | + reg32_write(REG_BASE_ADDR + 0x0f058, 0x00000000); | |
595 | + reg32_write(REG_BASE_ADDR + 0x0f05c, 0x00000000); | |
596 | + reg32_write(REG_BASE_ADDR + 0x0f060, 0x00000000); | |
597 | + reg32_write(REG_BASE_ADDR + 0x0f064, 0x00000000); | |
598 | + reg32_write(REG_BASE_ADDR + 0x0f068, 0xffffffff); | |
599 | + reg32_write(REG_BASE_ADDR + 0x0f06c, 0xffffffff); | |
600 | + reg32_write(REG_BASE_ADDR + 0x0f070, 0xffffffff); | |
601 | + reg32_write(REG_BASE_ADDR + 0x0f074, 0x00000000); | |
602 | + reg32_write(REG_BASE_ADDR + 0x0f000, 0x00000003); | |
603 | +#endif | |
604 | + /* DTG */ | |
605 | + /*reg32_write(REG_BASE_ADDR + 0x20000, 0xff000484); */ | |
606 | + /* disable local alpha */ | |
607 | + reg32_write(REG_BASE_ADDR + 0x20000, 0xff005084); | |
608 | + reg32_write(REG_BASE_ADDR + 0x20004, | |
609 | + (((vms->vfp + vms->vbp + vms->vsync + vms->yres - | |
610 | + 1) << 16) | (vms->hfp + vms->hbp + vms->hsync + | |
611 | + vms->xres - 1))); | |
612 | + reg32_write(REG_BASE_ADDR + 0x20008, | |
613 | + (((vms->vsync + vms->vfp + vms->vbp - | |
614 | + 1) << 16) | (vms->hsync + vms->hbp - 1))); | |
615 | + reg32_write(REG_BASE_ADDR + 0x2000c, | |
616 | + (((vms->vsync + vms->vfp + vms->vbp + vms->yres - | |
617 | + 1) << 16) | (vms->hsync + vms->hbp + vms->xres - 1))); | |
618 | + reg32_write(REG_BASE_ADDR + 0x20010, | |
619 | + (((vms->vsync + vms->vfp + vms->vbp - | |
620 | + 1) << 16) | (vms->hsync + vms->hbp - 1))); | |
621 | + reg32_write(REG_BASE_ADDR + 0x20014, | |
622 | + (((vms->vsync + vms->vfp + vms->vbp + vms->yres - | |
623 | + 1) << 16) | (vms->hsync + vms->hbp + vms->xres - 1))); | |
624 | + reg32_write(REG_BASE_ADDR + 0x20028, 0x000b000a); | |
625 | + | |
626 | + /* disable local alpha */ | |
627 | + reg32_write(REG_BASE_ADDR + 0x20000, 0xff005184); | |
628 | + | |
629 | + debug("leaving %s() ...\n", __func__); | |
630 | +} | |
631 | + | |
632 | +void imx8m_display_shutdown(void) | |
633 | +{ | |
634 | + /* stop the DCSS modules in use */ | |
635 | + /* dtg */ | |
636 | + reg32_write(REG_BASE_ADDR + 0x20000, 0); | |
637 | + /* scaler */ | |
638 | + reg32_write(REG_BASE_ADDR + 0x1c000, 0); | |
639 | + reg32_write(REG_BASE_ADDR + 0x1c400, 0); | |
640 | + reg32_write(REG_BASE_ADDR + 0x1c800, 0); | |
641 | + /* dpr */ | |
642 | + reg32_write(REG_BASE_ADDR + 0x18000, 0); | |
643 | + reg32_write(REG_BASE_ADDR + 0x19000, 0); | |
644 | + reg32_write(REG_BASE_ADDR + 0x1a000, 0); | |
645 | + /* sub-sampler*/ | |
646 | + reg32_write(REG_BASE_ADDR + 0x1b000, 0); | |
647 | +#if 0 | |
648 | + /* reset the DCSS */ | |
649 | + reg32_write(0x32e2f000, 0xffffe8); | |
650 | + udelay(100); | |
651 | + reg32_write(0x32e2f000, 0xffffff); | |
652 | +#endif | |
653 | + | |
654 | +} | |
655 | +void *video_hw_init(void) | |
656 | +{ | |
657 | + void *fb; | |
658 | + int encoding = 1; | |
659 | + | |
660 | + debug("%s()\n", __func__); | |
661 | + | |
662 | + imx8m_power_init(0x1); | |
663 | + | |
664 | + panel.winSizeX = gmode.xres; | |
665 | + panel.winSizeY = gmode.yres; | |
666 | + panel.plnSizeX = gmode.xres; | |
667 | + panel.plnSizeY = gmode.yres; | |
668 | + panel.gdfBytesPP = 4; | |
669 | + panel.gdfIndex = GDF_32BIT_X888RGB; | |
670 | + panel.memSize = gmode.xres * gmode.yres * panel.gdfBytesPP; | |
671 | + | |
672 | + /* Allocate framebuffer */ | |
673 | + fb = memalign(0x1000, roundup(panel.memSize, 0x1000)); | |
674 | + debug("%s(): fb %p\n", __func__, fb); | |
675 | + if (!fb) { | |
676 | + printf("%s, %s(): Error allocating framebuffer!\n", | |
677 | + __FILE__, __func__); | |
678 | + return NULL; | |
679 | + } | |
680 | + | |
681 | + imx8m_create_color_bar((void *)((uint64_t) fb), &gmode); | |
682 | + | |
683 | + imx8_hdmi_enable(encoding, &gmode); /* may change gmode */ | |
684 | + | |
685 | + /* start dccs */ | |
686 | + imx8m_display_init((uint64_t) fb, encoding, &gmode); | |
687 | + | |
688 | + panel.frameAdrs = (ulong) fb; | |
689 | + debug("IMXDCSS display started ...\n"); | |
690 | + | |
691 | + return &panel; | |
692 | +} | |
693 | + | |
694 | +void imx8m_fb_disable(void) | |
695 | +{ | |
696 | + debug("%s()\n", __func__); | |
697 | + if (panel.frameAdrs) { | |
698 | +#ifdef CONFIG_VIDEO_IMX8_HDMI | |
699 | + imx8_hdmi_disable(); | |
700 | +#endif | |
701 | + imx8m_display_shutdown(); | |
702 | + } | |
703 | + | |
704 | +} | |
705 | + | |
706 | +int imx8m_fb_init(struct fb_videomode const *mode, | |
707 | + uint8_t disp, uint32_t pixfmt) | |
708 | +{ | |
709 | + debug("entering %s()\n", __func__); | |
710 | + | |
711 | + if (disp > 1) { | |
712 | + debug("Invalid disp parameter %d for imxdcss_fb_init()\n", | |
713 | + disp); | |
714 | + return -EINVAL; | |
715 | + } | |
716 | + | |
717 | + memset(&gmode, 0, sizeof(struct video_mode_settings)); | |
718 | + gmode.pixelclock = PS2KHZ(mode->pixclock) * 1000; | |
719 | + gmode.xres = mode->xres; | |
720 | + gmode.hbp = mode->left_margin; | |
721 | + gmode.hfp = mode->right_margin; | |
722 | + | |
723 | + gmode.yres = mode->yres; | |
724 | + gmode.vbp = mode->upper_margin; | |
725 | + gmode.vfp = mode->lower_margin; | |
726 | + | |
727 | + gmode.hsync = mode->hsync_len; | |
728 | + gmode.vsync = mode->vsync_len; | |
729 | + gmode.hpol = (mode->flag & FB_SYNC_HOR_HIGH_ACT) ? 1 : 0; | |
730 | + gmode.vpol = (mode->flag & FB_SYNC_VERT_HIGH_ACT) ? 1 : 0; | |
731 | + gpixfmt = pixfmt; | |
732 | + | |
733 | + debug("leaving %s()\n", __func__); | |
734 | + | |
735 | + return 0; | |
736 | +} |
arch/arm/include/asm/arch-imx8m/video_common.h
1 | +/* | |
2 | + * Copyright 2018 NXP | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + * | |
6 | + */ | |
7 | + | |
8 | +#ifndef __ASM_ARCH_VIDEO_COMMON_H__ | |
9 | +#define __ASM_ARCH_VIDEO_COMMON_H__ | |
10 | +#include <linux/fb.h> | |
11 | +#include <video_fb.h> | |
12 | + | |
13 | +struct video_mode_settings { | |
14 | + uint32_t pixelclock; /* horizontal resolution */ | |
15 | + uint16_t xres; /* horizontal resolution */ | |
16 | + uint16_t yres; /* vertical resolution */ | |
17 | + uint16_t hfp; /* horizontal front porch */ | |
18 | + uint16_t hbp; /* horizontal back porch */ | |
19 | + uint16_t vfp; /* vertical front porch */ | |
20 | + uint16_t vbp; /* vertical back porch */ | |
21 | + uint16_t hsync; /* horizontal sync pulse width */ | |
22 | + uint16_t vsync; /* vertical sync pulse width */ | |
23 | + bool hpol; /* horizontal pulse polarity */ | |
24 | + bool vpol; /* vertical pulse polarity */ | |
25 | +}; | |
26 | + | |
27 | +#define PS2KHZ(ps) (1000000000UL / (ps)) | |
28 | +struct video_mode_settings *imx8m_get_gmode(void); | |
29 | +GraphicDevice *imx8m_get_gd(void); | |
30 | +void imx8m_show_gmode(void); | |
31 | +void imx8m_create_color_bar( | |
32 | + void *start_address, | |
33 | + struct video_mode_settings *vms); | |
34 | +int imx8m_fb_init( | |
35 | + struct fb_videomode const *mode, | |
36 | + uint8_t disp, | |
37 | + uint32_t pixfmt); | |
38 | +void imx8m_fb_disable(void); | |
39 | + | |
40 | +#endif /* __ASM_ARCH_VIDEO_COMMON_H__ */ |