]>
Commit | Line | Data |
---|---|---|
b2621bcb MW |
1 | /* |
2 | * (C) Copyright 2010 | |
3 | * Matthias Weisser <weisserm@arcor.de> | |
4 | * | |
1a459660 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
b2621bcb MW |
6 | */ |
7 | ||
8 | /* | |
9 | * mb86r0xgdc.c - Graphic interface for Fujitsu MB86R0x integrated graphic | |
10 | * controller. | |
11 | */ | |
12 | ||
13 | #include <common.h> | |
14 | ||
15 | #include <malloc.h> | |
16 | #include <asm/io.h> | |
17 | #include <asm/arch/hardware.h> | |
18 | #include <video_fb.h> | |
19 | #include "videomodes.h" | |
20 | ||
21 | /* | |
22 | * 4MB (at the end of system RAM) | |
23 | */ | |
24 | #define VIDEO_MEM_SIZE 0x400000 | |
25 | ||
26 | #define FB_SYNC_CLK_INV (1<<16) /* pixel clock inverted */ | |
27 | ||
28 | /* | |
29 | * Graphic Device | |
30 | */ | |
31 | static GraphicDevice mb86r0x; | |
32 | ||
33 | static void dsp_init(struct mb86r0x_gdc_dsp *dsp, char *modestr, | |
34 | u32 *videomem) | |
35 | { | |
36 | struct ctfb_res_modes var_mode; | |
37 | u32 dcm1, dcm2, dcm3; | |
38 | u16 htp, hdp, hdb, hsp, vtr, vsp, vdp; | |
39 | u8 hsw, vsw; | |
40 | u32 l2m, l2em, l2oa0, l2da0, l2oa1, l2da1; | |
41 | u16 l2dx, l2dy, l2wx, l2wy, l2ww, l2wh; | |
42 | unsigned long div; | |
43 | int bpp; | |
b2621bcb MW |
44 | |
45 | bpp = video_get_params(&var_mode, modestr); | |
46 | ||
47 | if (bpp == 0) { | |
48 | var_mode.xres = 640; | |
49 | var_mode.yres = 480; | |
50 | var_mode.pixclock = 39721; /* 25MHz */ | |
51 | var_mode.left_margin = 48; | |
52 | var_mode.right_margin = 16; | |
53 | var_mode.upper_margin = 33; | |
54 | var_mode.lower_margin = 10; | |
55 | var_mode.hsync_len = 96; | |
56 | var_mode.vsync_len = 2; | |
57 | var_mode.sync = 0; | |
58 | var_mode.vmode = 0; | |
59 | bpp = 15; | |
60 | } | |
61 | ||
62 | /* Fill memory with white */ | |
8370befc | 63 | memset(videomem, 0xFF, var_mode.xres * var_mode.yres * 2); |
b2621bcb MW |
64 | |
65 | mb86r0x.winSizeX = var_mode.xres; | |
66 | mb86r0x.winSizeY = var_mode.yres; | |
67 | ||
68 | /* LCD base clock is ~ 660MHZ. We do calculations in kHz */ | |
69 | div = 660000 / (1000000000L / var_mode.pixclock); | |
70 | if (div > 64) | |
71 | div = 64; | |
72 | if (0 == div) | |
73 | div = 1; | |
74 | ||
75 | dcm1 = (div - 1) << 8; | |
76 | dcm2 = 0x00000000; | |
77 | if (var_mode.sync & FB_SYNC_CLK_INV) | |
78 | dcm3 = 0x00000100; | |
79 | else | |
80 | dcm3 = 0x00000000; | |
81 | ||
82 | htp = var_mode.left_margin + var_mode.xres + | |
83 | var_mode.hsync_len + var_mode.right_margin; | |
84 | hdp = var_mode.xres; | |
85 | hdb = var_mode.xres; | |
86 | hsp = var_mode.xres + var_mode.right_margin; | |
87 | hsw = var_mode.hsync_len; | |
88 | ||
89 | vsw = var_mode.vsync_len; | |
90 | vtr = var_mode.upper_margin + var_mode.yres + | |
91 | var_mode.vsync_len + var_mode.lower_margin; | |
92 | vsp = var_mode.yres + var_mode.lower_margin; | |
93 | vdp = var_mode.yres; | |
94 | ||
95 | l2m = ((var_mode.yres - 1) << (0)) | | |
96 | (((var_mode.xres * 2) / 64) << (16)) | | |
97 | ((1) << (31)); | |
98 | ||
99 | l2em = (1 << 0) | (1 << 1); | |
100 | ||
101 | l2oa0 = mb86r0x.frameAdrs; | |
102 | l2da0 = mb86r0x.frameAdrs; | |
103 | l2oa1 = mb86r0x.frameAdrs; | |
104 | l2da1 = mb86r0x.frameAdrs; | |
105 | l2dx = 0; | |
106 | l2dy = 0; | |
107 | l2wx = 0; | |
108 | l2wy = 0; | |
109 | l2ww = var_mode.xres; | |
110 | l2wh = var_mode.yres - 1; | |
111 | ||
112 | writel(dcm1, &dsp->dcm1); | |
113 | writel(dcm2, &dsp->dcm2); | |
114 | writel(dcm3, &dsp->dcm3); | |
115 | ||
116 | writew(htp, &dsp->htp); | |
117 | writew(hdp, &dsp->hdp); | |
118 | writew(hdb, &dsp->hdb); | |
119 | writew(hsp, &dsp->hsp); | |
120 | writeb(hsw, &dsp->hsw); | |
121 | ||
122 | writeb(vsw, &dsp->vsw); | |
123 | writew(vtr, &dsp->vtr); | |
124 | writew(vsp, &dsp->vsp); | |
125 | writew(vdp, &dsp->vdp); | |
126 | ||
127 | writel(l2m, &dsp->l2m); | |
128 | writel(l2em, &dsp->l2em); | |
129 | writel(l2oa0, &dsp->l2oa0); | |
130 | writel(l2da0, &dsp->l2da0); | |
131 | writel(l2oa1, &dsp->l2oa1); | |
132 | writel(l2da1, &dsp->l2da1); | |
133 | writew(l2dx, &dsp->l2dx); | |
134 | writew(l2dy, &dsp->l2dy); | |
135 | writew(l2wx, &dsp->l2wx); | |
136 | writew(l2wy, &dsp->l2wy); | |
137 | writew(l2ww, &dsp->l2ww); | |
138 | writew(l2wh, &dsp->l2wh); | |
139 | ||
140 | writel(dcm1 | (1 << 18) | (1 << 31), &dsp->dcm1); | |
141 | } | |
142 | ||
143 | void *video_hw_init(void) | |
144 | { | |
145 | struct mb86r0x_gdc *gdc = (struct mb86r0x_gdc *) MB86R0x_GDC_BASE; | |
146 | GraphicDevice *pGD = &mb86r0x; | |
147 | char *s; | |
148 | u32 *vid; | |
149 | ||
150 | memset(pGD, 0, sizeof(GraphicDevice)); | |
151 | ||
152 | pGD->gdfIndex = GDF_15BIT_555RGB; | |
153 | pGD->gdfBytesPP = 2; | |
154 | pGD->memSize = VIDEO_MEM_SIZE; | |
155 | pGD->frameAdrs = PHYS_SDRAM + PHYS_SDRAM_SIZE - VIDEO_MEM_SIZE; | |
156 | ||
157 | vid = (u32 *)pGD->frameAdrs; | |
158 | ||
159 | s = getenv("videomode"); | |
160 | if (s != NULL) | |
161 | dsp_init(&gdc->dsp0, s, vid); | |
162 | ||
163 | s = getenv("videomode1"); | |
164 | if (s != NULL) | |
165 | dsp_init(&gdc->dsp1, s, vid); | |
166 | ||
167 | return pGD; | |
168 | } |