blob: 7bc3c9be9013668f0635e1a6f9461fd2b406bda4 [file] [log] [blame]
Anatolij Gustschinbed53752008-01-11 14:30:01 +01001/*
2 * (C) Copyright 2007
3 * DENX Software Engineering, Anatolij Gustschin, agust@denx.de
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Jerry Van Barenae0b05d2009-02-05 22:18:02 -050015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Anatolij Gustschinbed53752008-01-11 14:30:01 +010016 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/*
25 * mb862xx.c - Graphic interface for Fujitsu CoralP/Lime
26 * PCI and video mode code was derived from smiLynxEM driver.
27 */
28
29#include <common.h>
30
Anatolij Gustschinbed53752008-01-11 14:30:01 +010031#include <asm/io.h>
32#include <pci.h>
33#include <video_fb.h>
34#include "videomodes.h"
35#include <mb862xx.h>
36
Yuri Tikhonov0d489262008-03-24 11:30:54 +010037#if defined(CONFIG_POST)
38#include <post.h>
39#endif
Anatolij Gustschine8652862009-07-07 13:24:08 +020040
Anatolij Gustschinbed53752008-01-11 14:30:01 +010041/*
42 * Graphic Device
43 */
44GraphicDevice mb862xx;
45
46/*
47 * 32MB external RAM - 256K Chip MMIO = 0x1FC0000 ;
48 */
49#define VIDEO_MEM_SIZE 0x01FC0000
50
51#if defined(CONFIG_PCI)
52#if defined(CONFIG_VIDEO_CORALP)
53
54static struct pci_device_id supported[] = {
55 { PCI_VENDOR_ID_FUJITSU, PCI_DEVICE_ID_CORAL_P },
56 { PCI_VENDOR_ID_FUJITSU, PCI_DEVICE_ID_CORAL_PA },
57 { }
58};
59
60/* Internal clock frequency divider table, index is mode number */
61unsigned int fr_div[] = { 0x00000f00, 0x00000900, 0x00000500 };
62#endif
63#endif
64
65#if defined(CONFIG_VIDEO_CORALP)
66#define rd_io in32r
67#define wr_io out32r
68#else
Anatolij Gustschine8652862009-07-07 13:24:08 +020069#define rd_io(addr) in_be32((volatile unsigned *)(addr))
70#define wr_io(addr, val) out_be32((volatile unsigned *)(addr), (val))
Anatolij Gustschinbed53752008-01-11 14:30:01 +010071#endif
72
Anatolij Gustschine8652862009-07-07 13:24:08 +020073#define HOST_RD_REG(off) rd_io((dev->frameAdrs + 0x01fc0000 + (off)))
74#define HOST_WR_REG(off, val) wr_io((dev->frameAdrs + 0x01fc0000 + (off)), \
75 (val))
76#define DISP_RD_REG(off) rd_io((dev->frameAdrs + 0x01fd0000 + (off)))
77#define DISP_WR_REG(off, val) wr_io((dev->frameAdrs + 0x01fd0000 + (off)), \
78 (val))
79#define DE_RD_REG(off) rd_io((dev->dprBase + (off)))
80#define DE_WR_REG(off, val) wr_io((dev->dprBase + (off)), (val))
Anatolij Gustschinbed53752008-01-11 14:30:01 +010081
82#if defined(CONFIG_VIDEO_CORALP)
Anatolij Gustschine8652862009-07-07 13:24:08 +020083#define DE_WR_FIFO(val) wr_io((dev->dprBase + (0x8400)), (val))
Anatolij Gustschinbed53752008-01-11 14:30:01 +010084#else
Anatolij Gustschine8652862009-07-07 13:24:08 +020085#define DE_WR_FIFO(val) wr_io((dev->dprBase + (0x04a0)), (val))
Anatolij Gustschinbed53752008-01-11 14:30:01 +010086#endif
87
Anatolij Gustschine8652862009-07-07 13:24:08 +020088#define L0PAL_WR_REG(idx, val) wr_io((dev->frameAdrs + 0x01fd0400 + \
89 ((idx) << 2)), (val))
Anatolij Gustschinbed53752008-01-11 14:30:01 +010090
Anatolij Gustschine8652862009-07-07 13:24:08 +020091static void gdc_sw_reset (void)
Anatolij Gustschinbed53752008-01-11 14:30:01 +010092{
Anatolij Gustschine8652862009-07-07 13:24:08 +020093 GraphicDevice *dev = &mb862xx;
94
Anatolij Gustschinbed53752008-01-11 14:30:01 +010095 HOST_WR_REG (0x002c, 0x00000001);
96 udelay (500);
97 video_hw_init ();
98}
99
100
Anatolij Gustschine8652862009-07-07 13:24:08 +0200101static void de_wait (void)
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100102{
Anatolij Gustschine8652862009-07-07 13:24:08 +0200103 GraphicDevice *dev = &mb862xx;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100104 int lc = 0x10000;
105
Anatolij Gustschine8652862009-07-07 13:24:08 +0200106 /*
107 * Sync with software writes to framebuffer,
108 * try to reset if engine locked
109 */
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100110 while (DE_RD_REG (0x0400) & 0x00000131)
111 if (lc-- < 0) {
112 gdc_sw_reset ();
Anatolij Gustschine8652862009-07-07 13:24:08 +0200113 printf ("gdc reset done after drawing engine lock.\n");
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100114 break;
115 }
116}
117
Anatolij Gustschine8652862009-07-07 13:24:08 +0200118static void de_wait_slots (int slots)
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100119{
Anatolij Gustschine8652862009-07-07 13:24:08 +0200120 GraphicDevice *dev = &mb862xx;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100121 int lc = 0x10000;
122
123 /* Wait for free fifo slots */
124 while (DE_RD_REG (0x0408) < slots)
125 if (lc-- < 0) {
126 gdc_sw_reset ();
Anatolij Gustschine8652862009-07-07 13:24:08 +0200127 printf ("gdc reset done after drawing engine lock.\n");
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100128 break;
129 }
130}
131
132#if !defined(CONFIG_VIDEO_CORALP)
Anatolij Gustschine8652862009-07-07 13:24:08 +0200133static void board_disp_init (void)
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100134{
Anatolij Gustschine8652862009-07-07 13:24:08 +0200135 GraphicDevice *dev = &mb862xx;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100136 const gdc_regs *regs = board_get_regs ();
137
138 while (regs->index) {
139 DISP_WR_REG (regs->index, regs->value);
140 regs++;
141 }
142}
143#endif
144
145/*
146 * Init drawing engine
147 */
148static void de_init (void)
149{
Anatolij Gustschine8652862009-07-07 13:24:08 +0200150 GraphicDevice *dev = &mb862xx;
151 int cf = (dev->gdfBytesPP == 1) ? 0x0000 : 0x8000;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100152
Anatolij Gustschine8652862009-07-07 13:24:08 +0200153 dev->dprBase = dev->frameAdrs + 0x01ff0000;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100154
155 /* Setup mode and fbbase, xres, fg, bg */
156 de_wait_slots (2);
157 DE_WR_FIFO (0xf1010108);
158 DE_WR_FIFO (cf | 0x0300);
159 DE_WR_REG (0x0440, 0x0000);
Anatolij Gustschine8652862009-07-07 13:24:08 +0200160 DE_WR_REG (0x0444, dev->winSizeX);
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100161 DE_WR_REG (0x0480, 0x0000);
162 DE_WR_REG (0x0484, 0x0000);
163 /* Reset clipping */
164 DE_WR_REG (0x0454, 0x0000);
Anatolij Gustschine8652862009-07-07 13:24:08 +0200165 DE_WR_REG (0x0458, dev->winSizeX);
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100166 DE_WR_REG (0x045c, 0x0000);
Anatolij Gustschine8652862009-07-07 13:24:08 +0200167 DE_WR_REG (0x0460, dev->winSizeY);
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100168
169 /* Clear framebuffer using drawing engine */
170 de_wait_slots (3);
171 DE_WR_FIFO (0x09410000);
172 DE_WR_FIFO (0x00000000);
Anatolij Gustschine8652862009-07-07 13:24:08 +0200173 DE_WR_FIFO (dev->winSizeY << 16 | dev->winSizeX);
Anatolij Gustschin322716a2008-07-12 17:31:36 +0200174 /* sync with SW access to framebuffer */
175 de_wait ();
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100176}
177
178#if defined(CONFIG_VIDEO_CORALP)
Anatolij Gustschine8652862009-07-07 13:24:08 +0200179unsigned int pci_video_init (void)
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100180{
Anatolij Gustschine8652862009-07-07 13:24:08 +0200181 GraphicDevice *dev = &mb862xx;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100182 pci_dev_t devbusfn;
183
Anatolij Gustschine8652862009-07-07 13:24:08 +0200184 if ((devbusfn = pci_find_devices (supported, 0)) < 0) {
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100185 printf ("PCI video controller not found!\n");
186 return 0;
187 }
188
189 /* PCI setup */
Anatolij Gustschine8652862009-07-07 13:24:08 +0200190 pci_write_config_dword (devbusfn, PCI_COMMAND,
191 (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
192 pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &dev->frameAdrs);
193 dev->frameAdrs = pci_mem_to_phys (devbusfn, dev->frameAdrs);
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100194
Anatolij Gustschine8652862009-07-07 13:24:08 +0200195 if (dev->frameAdrs == 0) {
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100196 printf ("PCI config: failed to get base address\n");
197 return 0;
198 }
199
Anatolij Gustschine8652862009-07-07 13:24:08 +0200200 dev->pciBase = dev->frameAdrs;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100201
202 /* Setup clocks and memory mode for Coral-P Eval. Board */
203 HOST_WR_REG (0x0038, 0x00090000);
204 udelay (200);
205 HOST_WR_REG (0xfffc, 0x11d7fa13);
206 udelay (100);
Anatolij Gustschine8652862009-07-07 13:24:08 +0200207 return dev->frameAdrs;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100208}
209
210unsigned int card_init (void)
211{
Anatolij Gustschine8652862009-07-07 13:24:08 +0200212 GraphicDevice *dev = &mb862xx;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100213 unsigned int cf, videomode, div = 0;
214 unsigned long t1, hsync, vsync;
215 char *penv;
216 int tmp, i, bpp;
217 struct ctfb_res_modes *res_mode;
218 struct ctfb_res_modes var_mode;
219
Anatolij Gustschine8652862009-07-07 13:24:08 +0200220 memset (dev, 0, sizeof (GraphicDevice));
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100221
Anatolij Gustschine8652862009-07-07 13:24:08 +0200222 if (!pci_video_init ())
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100223 return 0;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100224
225 printf ("CoralP\n");
226
227 tmp = 0;
228 videomode = 0x310;
229 /* get video mode via environment */
230 if ((penv = getenv ("videomode")) != NULL) {
Anatolij Gustschine8652862009-07-07 13:24:08 +0200231 /* decide if it is a string */
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100232 if (penv[0] <= '9') {
233 videomode = (int) simple_strtoul (penv, NULL, 16);
234 tmp = 1;
235 }
236 } else {
237 tmp = 1;
238 }
Anatolij Gustschine8652862009-07-07 13:24:08 +0200239
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100240 if (tmp) {
Anatolij Gustschine8652862009-07-07 13:24:08 +0200241 /* parameter are vesa modes, search params */
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100242 for (i = 0; i < VESA_MODES_COUNT; i++) {
243 if (vesa_modes[i].vesanr == videomode)
244 break;
245 }
246 if (i == VESA_MODES_COUNT) {
Anatolij Gustschine8652862009-07-07 13:24:08 +0200247 printf ("\tno VESA Mode found, fallback to mode 0x%x\n",
248 videomode);
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100249 i = 0;
250 }
Anatolij Gustschine8652862009-07-07 13:24:08 +0200251 res_mode = (struct ctfb_res_modes *)
252 &res_mode_init[vesa_modes[i].resindex];
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100253 if (vesa_modes[i].resindex > 2) {
Anatolij Gustschine8652862009-07-07 13:24:08 +0200254 printf ("\tUnsupported resolution, using default\n");
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100255 bpp = vesa_modes[1].bits_per_pixel;
256 div = fr_div[1];
257 }
258 bpp = vesa_modes[i].bits_per_pixel;
259 div = fr_div[vesa_modes[i].resindex];
260 } else {
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100261 res_mode = (struct ctfb_res_modes *) &var_mode;
262 bpp = video_get_params (res_mode, penv);
263 }
264
265 /* calculate hsync and vsync freq (info only) */
266 t1 = (res_mode->left_margin + res_mode->xres +
267 res_mode->right_margin + res_mode->hsync_len) / 8;
268 t1 *= 8;
269 t1 *= res_mode->pixclock;
270 t1 /= 1000;
271 hsync = 1000000000L / t1;
272 t1 *= (res_mode->upper_margin + res_mode->yres +
273 res_mode->lower_margin + res_mode->vsync_len);
274 t1 /= 1000;
275 vsync = 1000000000L / t1;
276
277 /* fill in Graphic device struct */
Anatolij Gustschine8652862009-07-07 13:24:08 +0200278 sprintf (dev->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100279 res_mode->yres, bpp, (hsync / 1000), (vsync / 1000));
Anatolij Gustschine8652862009-07-07 13:24:08 +0200280 printf ("\t%s\n", dev->modeIdent);
281 dev->winSizeX = res_mode->xres;
282 dev->winSizeY = res_mode->yres;
283 dev->memSize = VIDEO_MEM_SIZE;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100284
285 switch (bpp) {
286 case 8:
Anatolij Gustschine8652862009-07-07 13:24:08 +0200287 dev->gdfIndex = GDF__8BIT_INDEX;
288 dev->gdfBytesPP = 1;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100289 break;
290 case 15:
291 case 16:
Anatolij Gustschine8652862009-07-07 13:24:08 +0200292 dev->gdfIndex = GDF_15BIT_555RGB;
293 dev->gdfBytesPP = 2;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100294 break;
295 default:
Anatolij Gustschine8652862009-07-07 13:24:08 +0200296 printf ("\t%d bpp configured, but only 8,15 and 16 supported\n",
297 bpp);
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100298 printf ("\tSwitching back to 15bpp\n");
Anatolij Gustschine8652862009-07-07 13:24:08 +0200299 dev->gdfIndex = GDF_15BIT_555RGB;
300 dev->gdfBytesPP = 2;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100301 }
302
303 /* Setup dot clock (internal pll, division rate) */
304 DISP_WR_REG (0x0100, div);
305 /* L0 init */
Anatolij Gustschine8652862009-07-07 13:24:08 +0200306 cf = (dev->gdfBytesPP == 1) ? 0x00000000 : 0x80000000;
307 DISP_WR_REG (0x0020, ((dev->winSizeX * dev->gdfBytesPP) / 64) << 16 |
308 (dev->winSizeY - 1) | cf);
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100309 DISP_WR_REG (0x0024, 0x00000000);
310 DISP_WR_REG (0x0028, 0x00000000);
311 DISP_WR_REG (0x002c, 0x00000000);
312 DISP_WR_REG (0x0110, 0x00000000);
313 DISP_WR_REG (0x0114, 0x00000000);
Anatolij Gustschine8652862009-07-07 13:24:08 +0200314 DISP_WR_REG (0x0118, (dev->winSizeY - 1) << 16 | dev->winSizeX);
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100315
316 /* Display timing init */
Anatolij Gustschine8652862009-07-07 13:24:08 +0200317 DISP_WR_REG (0x0004, (dev->winSizeX +
318 res_mode->left_margin +
319 res_mode->right_margin +
320 res_mode->hsync_len - 1) << 16);
321 DISP_WR_REG (0x0008, (dev->winSizeX - 1) << 16 | (dev->winSizeX - 1));
322 DISP_WR_REG (0x000c, (res_mode->vsync_len - 1) << 24 |
323 (res_mode->hsync_len - 1) << 16 |
324 (dev->winSizeX + res_mode->right_margin - 1));
325 DISP_WR_REG (0x0010, (dev->winSizeY + res_mode->lower_margin +
326 res_mode->upper_margin +
327 res_mode->vsync_len - 1) << 16);
328 DISP_WR_REG (0x0014, (dev->winSizeY-1) << 16 |
329 (dev->winSizeY + res_mode->lower_margin - 1));
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100330 DISP_WR_REG (0x0018, 0x00000000);
Anatolij Gustschine8652862009-07-07 13:24:08 +0200331 DISP_WR_REG (0x001c, dev->winSizeY << 16 | dev->winSizeX);
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100332 /* Display enable, L0 layer */
333 DISP_WR_REG (0x0100, 0x80010000 | div);
334
Anatolij Gustschine8652862009-07-07 13:24:08 +0200335 return dev->frameAdrs;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100336}
337#endif
338
339void *video_hw_init (void)
340{
Anatolij Gustschine8652862009-07-07 13:24:08 +0200341 GraphicDevice *dev = &mb862xx;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100342
343 printf ("Video: Fujitsu ");
344
Anatolij Gustschine8652862009-07-07 13:24:08 +0200345 memset (dev, 0, sizeof (GraphicDevice));
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100346
347#if defined(CONFIG_VIDEO_CORALP)
Anatolij Gustschine8652862009-07-07 13:24:08 +0200348 if (card_init () == 0)
349 return NULL;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100350#else
Anatolij Gustschine8652862009-07-07 13:24:08 +0200351 /*
352 * Preliminary init of the onboard graphic controller,
353 * retrieve base address
354 */
355 if ((dev->frameAdrs = board_video_init ()) == 0) {
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100356 printf ("Controller not found!\n");
Anatolij Gustschine8652862009-07-07 13:24:08 +0200357 return NULL;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100358 } else
Anatolij Gustschine8652862009-07-07 13:24:08 +0200359 printf ("Lime\n");
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100360#endif
361
362 de_init ();
363
364#if !defined(CONFIG_VIDEO_CORALP)
Anatolij Gustschine8652862009-07-07 13:24:08 +0200365 board_disp_init ();
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100366#endif
367
Anatolij Gustschine64987a2008-08-15 15:42:13 +0200368#if (defined(CONFIG_LWMON5) || \
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200369 defined(CONFIG_SOCRATES)) && !(CONFIG_POST & CONFIG_SYS_POST_SYSMON)
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100370 /* Lamp on */
371 board_backlight_switch (1);
372#endif
373
Anatolij Gustschine8652862009-07-07 13:24:08 +0200374 return dev;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100375}
376
377/*
378 * Set a RGB color in the LUT
379 */
Anatolij Gustschine8652862009-07-07 13:24:08 +0200380void video_set_lut (unsigned int index, unsigned char r,
381 unsigned char g, unsigned char b)
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100382{
Anatolij Gustschine8652862009-07-07 13:24:08 +0200383 GraphicDevice *dev = &mb862xx;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100384
385 L0PAL_WR_REG (index, (r << 16) | (g << 8) | (b));
386}
387
388/*
389 * Drawing engine Fill and BitBlt screen region
390 */
Anatolij Gustschine8652862009-07-07 13:24:08 +0200391void video_hw_rectfill (unsigned int bpp, unsigned int dst_x,
392 unsigned int dst_y, unsigned int dim_x,
393 unsigned int dim_y, unsigned int color)
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100394{
Anatolij Gustschine8652862009-07-07 13:24:08 +0200395 GraphicDevice *dev = &mb862xx;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100396
397 de_wait_slots (3);
398 DE_WR_REG (0x0480, color);
399 DE_WR_FIFO (0x09410000);
400 DE_WR_FIFO ((dst_y << 16) | dst_x);
401 DE_WR_FIFO ((dim_y << 16) | dim_x);
402 de_wait ();
403}
404
Anatolij Gustschine8652862009-07-07 13:24:08 +0200405void video_hw_bitblt (unsigned int bpp, unsigned int src_x,
406 unsigned int src_y, unsigned int dst_x,
407 unsigned int dst_y, unsigned int width,
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100408 unsigned int height)
409{
Anatolij Gustschine8652862009-07-07 13:24:08 +0200410 GraphicDevice *dev = &mb862xx;
Anatolij Gustschinbed53752008-01-11 14:30:01 +0100411 unsigned int ctrl = 0x0d000000L;
412
413 if (src_x >= dst_x && src_y >= dst_y)
414 ctrl |= 0x00440000L;
415 else if (src_x >= dst_x && src_y <= dst_y)
416 ctrl |= 0x00460000L;
417 else if (src_x <= dst_x && src_y >= dst_y)
418 ctrl |= 0x00450000L;
419 else
420 ctrl |= 0x00470000L;
421
422 de_wait_slots (4);
423 DE_WR_FIFO (ctrl);
424 DE_WR_FIFO ((src_y << 16) | src_x);
425 DE_WR_FIFO ((dst_y << 16) | dst_x);
426 DE_WR_FIFO ((height << 16) | width);
427 de_wait (); /* sync */
428}