blob: a87aaf3e6cd61048ed609a455b0cbed3e4d386b9 [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * (C) Copyright 1997-2002 ELTEC Elektronik AG
3 * Frank Gottschling <fgottschling@eltec.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
wdenkaea86e42004-03-23 22:53:55 +000015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wdenkc6097192002-11-03 00:24:07 +000016 * 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 * smiLynxEM.c
26 *
27 * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
28 *
29 * modification history
30 * --------------------
31 * 04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
32 *
wdenkaea86e42004-03-23 22:53:55 +000033 * 18-03-2004 - Unify videomodes handling with the ct69000
34 * - The video output can be set via the variable "videoout"
35 * in the environment.
36 * videoout=1 output on LCD
37 * videoout=2 output on CRT (default value)
38 * <p.aubert@staubli.com>
wdenkc6097192002-11-03 00:24:07 +000039 */
40
41#include <common.h>
42
43#if defined(CONFIG_VIDEO_SMI_LYNXEM)
44
45#include <pci.h>
46#include <video_fb.h>
wdenkaea86e42004-03-23 22:53:55 +000047#include "videomodes.h"
wdenkc6097192002-11-03 00:24:07 +000048/*
49 * Export Graphic Device
50 */
51GraphicDevice smi;
52
53/*
54 * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external
55 */
wdenkaea86e42004-03-23 22:53:55 +000056#define VIDEO_MEM_SIZE 0x400000
wdenkc6097192002-11-03 00:24:07 +000057
wdenkc6097192002-11-03 00:24:07 +000058
59/*
60 * ISA mapped regs
61 */
wdenkaea86e42004-03-23 22:53:55 +000062#define SMI_INDX_C4 (pGD->isaBase + 0x03c4) /* index reg */
63#define SMI_DATA_C5 (pGD->isaBase + 0x03c5) /* data reg */
64#define SMI_INDX_D4 (pGD->isaBase + 0x03d4) /* index reg */
65#define SMI_DATA_D5 (pGD->isaBase + 0x03d5) /* data reg */
66#define SMI_ISR1 (pGD->isaBase + 0x03ca)
67#define SMI_INDX_CE (pGD->isaBase + 0x03ce) /* index reg */
68#define SMI_DATA_CF (pGD->isaBase + 0x03cf) /* data reg */
69#define SMI_LOCK_REG (pGD->isaBase + 0x03c3) /* unlock/lock ext crt reg */
70#define SMI_MISC_REG (pGD->isaBase + 0x03c2) /* misc reg */
71#define SMI_LUT_MASK (pGD->isaBase + 0x03c6) /* lut mask reg */
72#define SMI_LUT_START (pGD->isaBase + 0x03c8) /* lut start index */
73#define SMI_LUT_RGB (pGD->isaBase + 0x03c9) /* lut colors auto incr.*/
74#define SMI_INDX_ATTR (pGD->isaBase + 0x03c0) /* attributes index reg */
wdenkc6097192002-11-03 00:24:07 +000075
76/*
77 * Video processor control
wdenkaea86e42004-03-23 22:53:55 +000078 */
wdenkc6097192002-11-03 00:24:07 +000079typedef struct {
wdenkaea86e42004-03-23 22:53:55 +000080 unsigned int control;
81 unsigned int colorKey;
82 unsigned int colorKeyMask;
83 unsigned int start;
84 unsigned short offset;
85 unsigned short width;
86 unsigned int fifoPrio;
87 unsigned int fifoERL;
88 unsigned int YUVtoRGB;
wdenkc6097192002-11-03 00:24:07 +000089} SmiVideoProc;
90
91/*
92 * Video window control
93 */
94typedef struct {
wdenkaea86e42004-03-23 22:53:55 +000095 unsigned short top;
96 unsigned short left;
97 unsigned short bottom;
98 unsigned short right;
99 unsigned int srcStart;
100 unsigned short width;
101 unsigned short offset;
102 unsigned char hStretch;
103 unsigned char vStretch;
wdenkc6097192002-11-03 00:24:07 +0000104} SmiVideoWin;
105
106/*
107 * Capture port control
108 */
109typedef struct {
wdenkaea86e42004-03-23 22:53:55 +0000110 unsigned int control;
111 unsigned short topClip;
112 unsigned short leftClip;
113 unsigned short srcHeight;
114 unsigned short srcWidth;
115 unsigned int srcBufStart1;
116 unsigned int srcBufStart2;
117 unsigned short srcOffset;
118 unsigned short fifoControl;
wdenkc6097192002-11-03 00:24:07 +0000119} SmiCapturePort;
120
121
wdenkc6097192002-11-03 00:24:07 +0000122/*
123 * Register values for common video modes
124 */
wdenkaea86e42004-03-23 22:53:55 +0000125static char SMI_SCR[] = {
126 /* all modes */
127 0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x15, 0x90,
128 0x17, 0x20, 0x18, 0xb1, 0x19, 0x00,
wdenkc6097192002-11-03 00:24:07 +0000129};
wdenkaea86e42004-03-23 22:53:55 +0000130static char SMI_EXT_CRT[] = {
131 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
Wolfgang Denkc6b0fb82005-09-03 01:21:50 +0200132 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00,
wdenkc6097192002-11-03 00:24:07 +0000133};
wdenkaea86e42004-03-23 22:53:55 +0000134static char SMI_ATTR [] = {
135 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05,
136 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b,
137 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x41, 0x11, 0x00,
138 0x12, 0x0f, 0x13, 0x00, 0x14, 0x00,
wdenkc6097192002-11-03 00:24:07 +0000139};
wdenkaea86e42004-03-23 22:53:55 +0000140static char SMI_GCR[18] = {
141 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x40,
Wolfgang Denkc6b0fb82005-09-03 01:21:50 +0200142 0x06, 0x05, 0x07, 0x0f, 0x08, 0xff,
wdenkc6097192002-11-03 00:24:07 +0000143};
wdenkaea86e42004-03-23 22:53:55 +0000144static char SMI_SEQR[] = {
Wolfgang Denkc6b0fb82005-09-03 01:21:50 +0200145 0x00, 0x00, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e, 0x00, 0x03,
wdenkc6097192002-11-03 00:24:07 +0000146};
wdenkaea86e42004-03-23 22:53:55 +0000147static char SMI_PCR [] = {
Wolfgang Denkc6b0fb82005-09-03 01:21:50 +0200148 0x20, 0x04, 0x21, 0x30, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00,
wdenkc6097192002-11-03 00:24:07 +0000149};
wdenkaea86e42004-03-23 22:53:55 +0000150static char SMI_MCR[] = {
wdenkd3602132004-03-25 15:14:43 +0000151 0x60, 0x01, 0x61, 0x00,
Wolfgang Denkc6b0fb82005-09-03 01:21:50 +0200152#ifdef CONFIG_HMI1001
153 0x62, 0x74, /* Memory type is not configured by pins on HMI1001 */
154#endif
wdenkc6097192002-11-03 00:24:07 +0000155};
156
wdenkaea86e42004-03-23 22:53:55 +0000157static char SMI_HCR[] = {
158 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
Wolfgang Denkc6b0fb82005-09-03 01:21:50 +0200159 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00,
wdenkc6097192002-11-03 00:24:07 +0000160};
161
wdenkc6097192002-11-03 00:24:07 +0000162
163/*******************************************************************************
wdenkaea86e42004-03-23 22:53:55 +0000164 *
165 * Write SMI ISA register
166 */
wdenkc6097192002-11-03 00:24:07 +0000167static void smiWrite (unsigned short index, char reg, char val)
168{
wdenkaea86e42004-03-23 22:53:55 +0000169 register GraphicDevice *pGD = (GraphicDevice *)&smi;
wdenkc6097192002-11-03 00:24:07 +0000170
wdenkaea86e42004-03-23 22:53:55 +0000171 out8 ((pGD->isaBase + index), reg);
172 out8 ((pGD->isaBase + index + 1), val);
wdenkc6097192002-11-03 00:24:07 +0000173}
174
175/*******************************************************************************
wdenkaea86e42004-03-23 22:53:55 +0000176 *
177 * Write a table of SMI ISA register
178 */
wdenkc6097192002-11-03 00:24:07 +0000179static void smiLoadRegs (
wdenkaea86e42004-03-23 22:53:55 +0000180 unsigned int iReg,
181 unsigned int dReg,
182 char *regTab,
183 unsigned int tabSize
184 )
wdenkc6097192002-11-03 00:24:07 +0000185{
wdenkaea86e42004-03-23 22:53:55 +0000186 register GraphicDevice *pGD = (GraphicDevice *)&smi;
187 register int i;
wdenkc6097192002-11-03 00:24:07 +0000188
wdenkaea86e42004-03-23 22:53:55 +0000189 for (i=0; i<tabSize; i+=2) {
190 if (iReg == SMI_INDX_ATTR) {
191 /* Reset the Flip Flop */
192 in8 (SMI_ISR1);
193 out8 (iReg, regTab[i]);
194 out8 (iReg, regTab[i+1]);
195 } else {
196 out8 (iReg, regTab[i]);
197 out8 (dReg, regTab[i+1]);
198 }
199 }
wdenkc6097192002-11-03 00:24:07 +0000200}
201
202/*******************************************************************************
wdenkaea86e42004-03-23 22:53:55 +0000203 *
204 * Init capture port registers
205 */
wdenkc6097192002-11-03 00:24:07 +0000206static void smiInitCapturePort (void)
207{
wdenkaea86e42004-03-23 22:53:55 +0000208 SmiCapturePort smiCP = { 0x01400600, 0x30, 0x40, 480, 640, 0, 0, 2560, 6 };
209 register GraphicDevice *pGD = (GraphicDevice *)&smi;
210 register SmiCapturePort *pCP = (SmiCapturePort *)&smiCP;
wdenkc6097192002-11-03 00:24:07 +0000211
wdenkaea86e42004-03-23 22:53:55 +0000212 out32r ((pGD->cprBase + 0x0004), ((pCP->topClip<<16) | pCP->leftClip));
213 out32r ((pGD->cprBase + 0x0008), ((pCP->srcHeight<<16) | pCP->srcWidth));
214 out32r ((pGD->cprBase + 0x000c), pCP->srcBufStart1/8);
215 out32r ((pGD->cprBase + 0x0010), pCP->srcBufStart2/8);
216 out32r ((pGD->cprBase + 0x0014), pCP->srcOffset/8);
217 out32r ((pGD->cprBase + 0x0018), pCP->fifoControl);
218 out32r ((pGD->cprBase + 0x0000), pCP->control);
wdenkc6097192002-11-03 00:24:07 +0000219}
220
221
222/*******************************************************************************
wdenkaea86e42004-03-23 22:53:55 +0000223 *
224 * Init video processor registers
225 */
wdenkc6097192002-11-03 00:24:07 +0000226static void smiInitVideoProcessor (void)
227{
wdenkaea86e42004-03-23 22:53:55 +0000228 SmiVideoProc smiVP = { 0x100000, 0, 0, 0, 0, 1600, 0x1200543, 4, 0xededed };
229 SmiVideoWin smiVW = { 0, 0, 599, 799, 0, 1600, 0, 0, 0 };
230 register GraphicDevice *pGD = (GraphicDevice *)&smi;
231 register SmiVideoProc *pVP = (SmiVideoProc *)&smiVP;
232 register SmiVideoWin *pVWin = (SmiVideoWin *)&smiVW;
wdenkc6097192002-11-03 00:24:07 +0000233
wdenkaea86e42004-03-23 22:53:55 +0000234 pVP->width = pGD->plnSizeX * pGD->gdfBytesPP;
235 pVP->control |= pGD->gdfIndex << 16;
236 pVWin->bottom = pGD->winSizeY - 1;
237 pVWin->right = pGD->winSizeX - 1;
238 pVWin->width = pVP->width;
wdenkc6097192002-11-03 00:24:07 +0000239
wdenkaea86e42004-03-23 22:53:55 +0000240 /* color key */
241 out32r ((pGD->vprBase + 0x0004), pVP->colorKey);
wdenkc6097192002-11-03 00:24:07 +0000242
wdenkaea86e42004-03-23 22:53:55 +0000243 /* color key mask */
244 out32r ((pGD->vprBase + 0x0008), pVP->colorKeyMask);
wdenkc6097192002-11-03 00:24:07 +0000245
wdenkaea86e42004-03-23 22:53:55 +0000246 /* data src start adrs */
247 out32r ((pGD->vprBase + 0x000c), pVP->start / 8);
wdenkc6097192002-11-03 00:24:07 +0000248
wdenkaea86e42004-03-23 22:53:55 +0000249 /* data width and offset */
250 out32r ((pGD->vprBase + 0x0010),
251 ((pVP->offset / 8 * pGD->gdfBytesPP) << 16) |
252 (pGD->plnSizeX / 8 * pGD->gdfBytesPP));
wdenkc6097192002-11-03 00:24:07 +0000253
wdenkaea86e42004-03-23 22:53:55 +0000254 /* video window 1 */
255 out32r ((pGD->vprBase + 0x0014),
256 ((pVWin->top << 16) | pVWin->left));
wdenkc6097192002-11-03 00:24:07 +0000257
wdenkaea86e42004-03-23 22:53:55 +0000258 out32r ((pGD->vprBase + 0x0018),
259 ((pVWin->bottom << 16) | pVWin->right));
wdenkc6097192002-11-03 00:24:07 +0000260
wdenkaea86e42004-03-23 22:53:55 +0000261 out32r ((pGD->vprBase + 0x001c), pVWin->srcStart / 8);
wdenkc6097192002-11-03 00:24:07 +0000262
wdenkaea86e42004-03-23 22:53:55 +0000263 out32r ((pGD->vprBase + 0x0020),
264 (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
wdenkc6097192002-11-03 00:24:07 +0000265
wdenkaea86e42004-03-23 22:53:55 +0000266 out32r ((pGD->vprBase + 0x0024),
267 (((pVWin->hStretch) << 8) | pVWin->vStretch));
wdenkc6097192002-11-03 00:24:07 +0000268
wdenkaea86e42004-03-23 22:53:55 +0000269 /* video window 2 */
270 out32r ((pGD->vprBase + 0x0028),
271 ((pVWin->top << 16) | pVWin->left));
wdenkc6097192002-11-03 00:24:07 +0000272
wdenkaea86e42004-03-23 22:53:55 +0000273 out32r ((pGD->vprBase + 0x002c),
274 ((pVWin->bottom << 16) | pVWin->right));
wdenkc6097192002-11-03 00:24:07 +0000275
wdenkaea86e42004-03-23 22:53:55 +0000276 out32r ((pGD->vprBase + 0x0030),
277 pVWin->srcStart / 8);
wdenkc6097192002-11-03 00:24:07 +0000278
wdenkaea86e42004-03-23 22:53:55 +0000279 out32r ((pGD->vprBase + 0x0034),
280 (((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
wdenkc6097192002-11-03 00:24:07 +0000281
wdenkaea86e42004-03-23 22:53:55 +0000282 out32r ((pGD->vprBase + 0x0038),
283 (((pVWin->hStretch) << 8) | pVWin->vStretch));
wdenkc6097192002-11-03 00:24:07 +0000284
wdenkaea86e42004-03-23 22:53:55 +0000285 /* fifo prio control */
286 out32r ((pGD->vprBase + 0x0054), pVP->fifoPrio);
wdenkc6097192002-11-03 00:24:07 +0000287
wdenkaea86e42004-03-23 22:53:55 +0000288 /* fifo empty request levell */
289 out32r ((pGD->vprBase + 0x0058), pVP->fifoERL);
wdenkc6097192002-11-03 00:24:07 +0000290
wdenkaea86e42004-03-23 22:53:55 +0000291 /* conversion constant */
292 out32r ((pGD->vprBase + 0x005c), pVP->YUVtoRGB);
wdenkc6097192002-11-03 00:24:07 +0000293
wdenkaea86e42004-03-23 22:53:55 +0000294 /* vpr control word */
295 out32r ((pGD->vprBase + 0x0000), pVP->control);
wdenkc6097192002-11-03 00:24:07 +0000296}
297
298/******************************************************************************
299 *
300 * Init drawing engine registers
301 */
302static void smiInitDrawingEngine (void)
303{
wdenkaea86e42004-03-23 22:53:55 +0000304 GraphicDevice *pGD = (GraphicDevice *)&smi;
305 unsigned int val;
wdenkc6097192002-11-03 00:24:07 +0000306
wdenkaea86e42004-03-23 22:53:55 +0000307 /* don't start now */
308 out32r ((pGD->dprBase + 0x000c), 0x000f0000);
wdenkc6097192002-11-03 00:24:07 +0000309
wdenkaea86e42004-03-23 22:53:55 +0000310 /* set rop2 to copypen */
311 val = 0xffff3ff0 & in32r ((pGD->dprBase + 0x000c));
312 out32r ((pGD->dprBase + 0x000c), (val | 0x8000 | 0x0c));
wdenkc6097192002-11-03 00:24:07 +0000313
wdenkaea86e42004-03-23 22:53:55 +0000314 /* set clip rect */
315 out32r ((pGD->dprBase + 0x002c), 0);
316 out32r ((pGD->dprBase + 0x0030),
317 ((pGD->winSizeY<<16) | pGD->winSizeX * pGD->gdfBytesPP ));
wdenkc6097192002-11-03 00:24:07 +0000318
wdenkaea86e42004-03-23 22:53:55 +0000319 /* src row pitch */
320 val = 0xffff0000 & (in32r ((pGD->dprBase + 0x0010)));
321 out32r ((pGD->dprBase + 0x0010),
322 (val | pGD->plnSizeX * pGD->gdfBytesPP));
wdenkc6097192002-11-03 00:24:07 +0000323
wdenkaea86e42004-03-23 22:53:55 +0000324 /* dst row pitch */
325 val = 0x0000ffff & (in32r ((pGD->dprBase + 0x0010)));
326 out32r ((pGD->dprBase + 0x0010),
327 (((pGD->plnSizeX * pGD->gdfBytesPP)<<16) | val));
wdenkc6097192002-11-03 00:24:07 +0000328
wdenkaea86e42004-03-23 22:53:55 +0000329 /* window width src/dst */
330 out32r ((pGD->dprBase + 0x003c),
331 (((pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)<<16) |
332 (pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)));
333 out16r ((pGD->dprBase + 0x001e), 0x0000);
wdenkc6097192002-11-03 00:24:07 +0000334
wdenkaea86e42004-03-23 22:53:55 +0000335 /* src base adrs */
336 out32r ((pGD->dprBase + 0x0040),
337 (((pGD->frameAdrs/8) & 0x000fffff)));
wdenkc6097192002-11-03 00:24:07 +0000338
wdenkaea86e42004-03-23 22:53:55 +0000339 /* dst base adrs */
340 out32r ((pGD->dprBase + 0x0044),
341 (((pGD->frameAdrs/8) & 0x000fffff)));
wdenkc6097192002-11-03 00:24:07 +0000342
wdenkaea86e42004-03-23 22:53:55 +0000343 /* foreground color */
344 out32r ((pGD->dprBase + 0x0014), pGD->fg);
wdenkc6097192002-11-03 00:24:07 +0000345
wdenkaea86e42004-03-23 22:53:55 +0000346 /* background color */
347 out32r ((pGD->dprBase + 0x0018), pGD->bg);
wdenkc6097192002-11-03 00:24:07 +0000348
wdenkaea86e42004-03-23 22:53:55 +0000349 /* xcolor */
350 out32r ((pGD->dprBase + 0x0020), 0x00ffffff);
wdenkc6097192002-11-03 00:24:07 +0000351
wdenkaea86e42004-03-23 22:53:55 +0000352 /* xcolor mask */
353 out32r ((pGD->dprBase + 0x0024), 0x00ffffff);
wdenkc6097192002-11-03 00:24:07 +0000354
wdenkaea86e42004-03-23 22:53:55 +0000355 /* bit mask */
356 out32r ((pGD->dprBase + 0x0028), 0x00ffffff);
wdenkc6097192002-11-03 00:24:07 +0000357
wdenkaea86e42004-03-23 22:53:55 +0000358 /* load mono pattern */
359 out32r ((pGD->dprBase + 0x0034), 0);
360 out32r ((pGD->dprBase + 0x0038), 0);
wdenkc6097192002-11-03 00:24:07 +0000361}
362
363static struct pci_device_id supported[] = {
wdenkaea86e42004-03-23 22:53:55 +0000364 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_710 },
365 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712 },
366 { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_810 },
367 { }
wdenkc6097192002-11-03 00:24:07 +0000368};
369
wdenkaea86e42004-03-23 22:53:55 +0000370/*****************************************************************************/
371static void smiLoadMsr (struct ctfb_res_modes *mode)
372{
373 unsigned char h_synch_high, v_synch_high;
374 register GraphicDevice *pGD = (GraphicDevice *)&smi;
wdenkc6097192002-11-03 00:24:07 +0000375
wdenkaea86e42004-03-23 22:53:55 +0000376 h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40; /* horizontal Synch High active */
377 v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80; /* vertical Synch High active */
378 out8 (SMI_MISC_REG, (h_synch_high | v_synch_high | 0x29));
379 /* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01
380 * Selects the upper 64KB page.Bit5=1
381 * CLK2 (left reserved in standard VGA) Bit3|2=1|0
382 * Disables CPU access to frame buffer. Bit1=0
383 * Sets the I/O address decode for ST01, FCR, and all CR registers
384 * to the 3Dx I/O address range (CGA emulation). Bit0=1
385 */
386}
387/*****************************************************************************/
388static void smiLoadCrt (struct ctfb_res_modes *var, int bits_per_pixel)
wdenkc6097192002-11-03 00:24:07 +0000389{
wdenkaea86e42004-03-23 22:53:55 +0000390 unsigned char cr[0x7a];
391 int i;
392 unsigned int hd, hs, he, ht, hbs, hbe; /* Horizontal. */
393 unsigned int vd, vs, ve, vt, vbs, vbe; /* vertical */
394 unsigned int bpp, wd, dblscan, interlaced;
wdenkc6097192002-11-03 00:24:07 +0000395
wdenkaea86e42004-03-23 22:53:55 +0000396 const int LineCompare = 0x3ff;
397 unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor */
398 register GraphicDevice *pGD = (GraphicDevice *)&smi;
wdenkc6097192002-11-03 00:24:07 +0000399
wdenkaea86e42004-03-23 22:53:55 +0000400 /* Horizontal */
401 hd = (var->xres) / 8; /* HDisp. */
402 hs = (var->xres + var->right_margin) / 8; /* HsStrt */
403 he = (var->xres + var->right_margin + var->hsync_len) / 8; /* HsEnd */
404 ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8; /* HTotal */
405 /* Blank */
wdenkd3602132004-03-25 15:14:43 +0000406 hbs = hd;
wdenkaea86e42004-03-23 22:53:55 +0000407 hbe = 0; /* Blank end at 0 */
wdenkc6097192002-11-03 00:24:07 +0000408
wdenkaea86e42004-03-23 22:53:55 +0000409 /* Vertical */
410 vd = var->yres; /* VDisplay */
411 vs = var->yres + var->lower_margin; /* VSyncStart */
412 ve = var->yres + var->lower_margin + var->vsync_len; /* VSyncEnd */
413 vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; /* VTotal */
414 vbs = vd;
415 vbe = 0;
wdenkd3602132004-03-25 15:14:43 +0000416
wdenkaea86e42004-03-23 22:53:55 +0000417 bpp = bits_per_pixel;
418 dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
419 interlaced = var->vmode & FB_VMODE_INTERLACED;
wdenkc6097192002-11-03 00:24:07 +0000420
wdenkc6097192002-11-03 00:24:07 +0000421
wdenkaea86e42004-03-23 22:53:55 +0000422 if (bpp == 15)
423 bpp = 16;
424 wd = var->xres * bpp / 64; /* double words per line */
425 if (interlaced) { /* we divide all vertical timings, exept vd */
426 vs >>= 1;
427 vbs >>= 1;
428 ve >>= 1;
429 vt >>= 1;
wdenk57b2d802003-06-27 21:31:46 +0000430 }
wdenkc6097192002-11-03 00:24:07 +0000431
wdenkaea86e42004-03-23 22:53:55 +0000432 memset (cr, 0, sizeof (cr));
433 cr[0x00] = ht - 5;
434 cr[0x01] = hd - 1;
435 cr[0x02] = hbs - 1;
436 cr[0x03] = (hbe & 0x1F);
437 cr[0x04] = hs;
438 cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
wdenkd3602132004-03-25 15:14:43 +0000439
wdenkaea86e42004-03-23 22:53:55 +0000440 cr[0x06] = (vt - 2) & 0xFF;
441 cr[0x07] = (((vt - 2) & 0x100) >> 8)
442 | (((vd - 1) & 0x100) >> 7)
443 | ((vs & 0x100) >> 6)
444 | (((vbs - 1) & 0x100) >> 5)
445 | ((LineCompare & 0x100) >> 4)
446 | (((vt - 2) & 0x200) >> 4)
447 | (((vd - 1) & 0x200) >> 3)
448 | ((vs & 0x200) >> 2);
wdenkc6097192002-11-03 00:24:07 +0000449
wdenkaea86e42004-03-23 22:53:55 +0000450 cr[0x30] = ((vt - 2) & 0x400) >> 7
451 | (((vd - 1) & 0x400) >> 8)
452 | (((vbs - 1) & 0x400) >> 9)
453 | ((vs & 0x400) >> 10)
454 | (interlaced) ? 0x80 : 0;
wdenkd3602132004-03-25 15:14:43 +0000455
wdenkc6097192002-11-03 00:24:07 +0000456
wdenkaea86e42004-03-23 22:53:55 +0000457 cr[0x08] = 0x00;
458 cr[0x09] = (dblscan << 7)
459 | ((LineCompare & 0x200) >> 3)
460 | (((vbs - 1) & 0x200) >> 4)
461 | (TextScanLines - 1);
wdenkc6097192002-11-03 00:24:07 +0000462
wdenkaea86e42004-03-23 22:53:55 +0000463 cr[0x10] = vs & 0xff; /* VSyncPulseStart */
wdenkd3602132004-03-25 15:14:43 +0000464 cr[0x11] = (ve & 0x0f);
wdenkaea86e42004-03-23 22:53:55 +0000465 cr[0x12] = (vd - 1) & 0xff; /* LineCount */
466 cr[0x13] = wd & 0xff;
467 cr[0x14] = 0x40;
468 cr[0x15] = (vbs - 1) & 0xff;
469 cr[0x16] = vbe & 0xff;
470 cr[0x17] = 0xe3; /* but it does not work */
471 cr[0x18] = 0xff & LineCompare;
472 cr[0x22] = 0x00; /* todo? */
wdenkc6097192002-11-03 00:24:07 +0000473
wdenkc6097192002-11-03 00:24:07 +0000474
wdenkaea86e42004-03-23 22:53:55 +0000475 /* now set the registers */
476 for (i = 0; i <= 0x18; i++) { /*CR00 .. CR18 */
477 smiWrite (SMI_INDX_D4, i, cr[i]);
478 }
479 i = 0x22; /*CR22 */
480 smiWrite (SMI_INDX_D4, i, cr[i]);
481 i = 0x30; /*CR30 */
482 smiWrite (SMI_INDX_D4, i, cr[i]);
483}
wdenkc6097192002-11-03 00:24:07 +0000484
wdenkaea86e42004-03-23 22:53:55 +0000485/*****************************************************************************/
486#define REF_FREQ 14318180
487#define PMIN 1
488#define PMAX 255
489#define QMIN 1
490#define QMAX 63
wdenkc6097192002-11-03 00:24:07 +0000491
wdenkaea86e42004-03-23 22:53:55 +0000492static unsigned int FindPQ (unsigned int freq, unsigned int *pp, unsigned int *pq)
493{
494 unsigned int n = QMIN, m = 0;
495 long long int L = 0, P = freq, Q = REF_FREQ, H = P >> 1;
496 long long int D = 0x7ffffffffffffffLL;
wdenkc6097192002-11-03 00:24:07 +0000497
wdenkaea86e42004-03-23 22:53:55 +0000498 for (n = QMIN; n <= QMAX; n++) {
499 m = PMIN; /* p/q ~ freq/ref -> p*ref-freq*q ~ 0 */
wdenkd3602132004-03-25 15:14:43 +0000500 L = P * n - m * Q;
wdenkaea86e42004-03-23 22:53:55 +0000501 while (L > 0 && m < PMAX) {
502 L -= REF_FREQ; /* difference is greater as 0 subtract fref */
503 m++; /* and increment m */
504 }
505 /* difference is less or equal than 0 or m > maximum */
506 if (m > PMAX)
507 break; /* no solution: if we increase n we get the same situation */
508 /* L is <= 0 now */
509 if (-L > H && m > PMIN) { /* if difference > the half fref */
510 L += REF_FREQ; /* we take the situation before */
511 m--; /* because its closer to 0 */
512 }
513 L = (L < 0) ? -L : +L; /* absolute value */
514 if (D < L) /* if last difference was better take next n */
515 continue;
516 D = L;
517 *pp = m;
518 *pq = n; /* keep improved data */
519 if (D == 0)
520 break; /* best result we can get */
521 }
522 return (unsigned int) (0xffffffff & D);
523}
wdenkc6097192002-11-03 00:24:07 +0000524
wdenkaea86e42004-03-23 22:53:55 +0000525/*****************************************************************************/
526static void smiLoadCcr (struct ctfb_res_modes *var, unsigned short device_id)
527{
528 unsigned int p, q;
529 long long freq;
530 register GraphicDevice *pGD = (GraphicDevice *)&smi;
wdenkc6097192002-11-03 00:24:07 +0000531
wdenkaea86e42004-03-23 22:53:55 +0000532 smiWrite (SMI_INDX_C4, 0x65, 0);
533 smiWrite (SMI_INDX_C4, 0x66, 0);
534 smiWrite (SMI_INDX_C4, 0x68, 0x50);
535 if (device_id == PCI_DEVICE_ID_SMI_810) {
536 smiWrite (SMI_INDX_C4, 0x69, 0x3);
537 } else {
538 smiWrite (SMI_INDX_C4, 0x69, 0x0);
539 }
wdenkc6097192002-11-03 00:24:07 +0000540
wdenkaea86e42004-03-23 22:53:55 +0000541 /* Memory clock */
542 switch (device_id) {
543 case PCI_DEVICE_ID_SMI_710 :
544 smiWrite (SMI_INDX_C4, 0x6a, 0x75);
545 break;
546 case PCI_DEVICE_ID_SMI_712 :
547 smiWrite (SMI_INDX_C4, 0x6a, 0x80);
548 break;
549 default :
550 smiWrite (SMI_INDX_C4, 0x6a, 0x53);
551 break;
552 }
553 smiWrite (SMI_INDX_C4, 0x6b, 0x15);
wdenkd3602132004-03-25 15:14:43 +0000554
wdenkaea86e42004-03-23 22:53:55 +0000555 /* VCLK */
wdenka0ebde52004-09-08 22:03:11 +0000556 freq = 1000000000000LL / var -> pixclock;
wdenkd3602132004-03-25 15:14:43 +0000557
wdenkaea86e42004-03-23 22:53:55 +0000558 FindPQ ((unsigned int)freq, &p, &q);
wdenkd3602132004-03-25 15:14:43 +0000559
wdenkaea86e42004-03-23 22:53:55 +0000560 smiWrite (SMI_INDX_C4, 0x6c, p);
561 smiWrite (SMI_INDX_C4, 0x6d, q);
wdenkc6097192002-11-03 00:24:07 +0000562
wdenkaea86e42004-03-23 22:53:55 +0000563}
wdenkc6097192002-11-03 00:24:07 +0000564
wdenkaea86e42004-03-23 22:53:55 +0000565/*******************************************************************************
566 *
567 * Init video chip with common Linux graphic modes (lilo)
568 */
569void *video_hw_init (void)
570{
571 GraphicDevice *pGD = (GraphicDevice *)&smi;
572 unsigned short device_id;
573 pci_dev_t devbusfn;
574 int videomode;
575 unsigned long t1, hsynch, vsynch;
576 unsigned int pci_mem_base, *vm;
577 char *penv;
578 int tmp, i, bits_per_pixel;
579 struct ctfb_res_modes *res_mode;
580 struct ctfb_res_modes var_mode;
581 unsigned char videoout;
wdenkd3602132004-03-25 15:14:43 +0000582
wdenkaea86e42004-03-23 22:53:55 +0000583 /* Search for video chip */
584 printf("Video: ");
wdenkc6097192002-11-03 00:24:07 +0000585
wdenkaea86e42004-03-23 22:53:55 +0000586 if ((devbusfn = pci_find_devices(supported, 0)) < 0)
587 {
588 printf ("Controller not found !\n");
589 return (NULL);
590 }
wdenkc6097192002-11-03 00:24:07 +0000591
wdenkaea86e42004-03-23 22:53:55 +0000592 /* PCI setup */
593 pci_write_config_dword (devbusfn, PCI_COMMAND, (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
594 pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
595 pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
596 pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
wdenkc6097192002-11-03 00:24:07 +0000597
wdenkaea86e42004-03-23 22:53:55 +0000598 tmp = 0;
wdenkd3602132004-03-25 15:14:43 +0000599
wdenkaea86e42004-03-23 22:53:55 +0000600 videomode = CFG_DEFAULT_VIDEO_MODE;
601 /* get video mode via environment */
602 if ((penv = getenv ("videomode")) != NULL) {
603 /* deceide if it is a string */
604 if (penv[0] <= '9') {
605 videomode = (int) simple_strtoul (penv, NULL, 16);
606 tmp = 1;
607 }
608 } else {
609 tmp = 1;
610 }
611 if (tmp) {
612 /* parameter are vesa modes */
613 /* search params */
614 for (i = 0; i < VESA_MODES_COUNT; i++) {
615 if (vesa_modes[i].vesanr == videomode)
616 break;
617 }
618 if (i == VESA_MODES_COUNT) {
619 printf ("no VESA Mode found, switching to mode 0x%x ", CFG_DEFAULT_VIDEO_MODE);
620 i = 0;
621 }
622 res_mode =
623 (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
624 resindex];
625 bits_per_pixel = vesa_modes[i].bits_per_pixel;
626 } else {
wdenkd3602132004-03-25 15:14:43 +0000627
wdenkaea86e42004-03-23 22:53:55 +0000628 res_mode = (struct ctfb_res_modes *) &var_mode;
629 bits_per_pixel = video_get_params (res_mode, penv);
630 }
wdenkc6097192002-11-03 00:24:07 +0000631
wdenkaea86e42004-03-23 22:53:55 +0000632 /* calculate hsynch and vsynch freq (info only) */
633 t1 = (res_mode->left_margin + res_mode->xres +
634 res_mode->right_margin + res_mode->hsync_len) / 8;
635 t1 *= 8;
636 t1 *= res_mode->pixclock;
637 t1 /= 1000;
638 hsynch = 1000000000L / t1;
639 t1 *=
640 (res_mode->upper_margin + res_mode->yres +
641 res_mode->lower_margin + res_mode->vsync_len);
642 t1 /= 1000;
643 vsynch = 1000000000L / t1;
wdenkd3602132004-03-25 15:14:43 +0000644
wdenkaea86e42004-03-23 22:53:55 +0000645 /* fill in Graphic device struct */
646 sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
647 res_mode->yres, bits_per_pixel, (hsynch / 1000),
648 (vsynch / 1000));
649 printf ("%s\n", pGD->modeIdent);
650 pGD->winSizeX = res_mode->xres;
651 pGD->winSizeY = res_mode->yres;
652 pGD->plnSizeX = res_mode->xres;
653 pGD->plnSizeY = res_mode->yres;
654 switch (bits_per_pixel) {
655 case 8:
656 pGD->gdfBytesPP = 1;
657 pGD->gdfIndex = GDF__8BIT_INDEX;
658 break;
659 case 15:
660 pGD->gdfBytesPP = 2;
661 pGD->gdfIndex = GDF_15BIT_555RGB;
662 break;
663 case 16:
664 pGD->gdfBytesPP = 2;
665 pGD->gdfIndex = GDF_16BIT_565RGB;
666 break;
667 case 24:
668 pGD->gdfBytesPP = 3;
669 pGD->gdfIndex = GDF_24BIT_888RGB;
670 break;
671 }
wdenkc6097192002-11-03 00:24:07 +0000672
wdenkaea86e42004-03-23 22:53:55 +0000673 pGD->isaBase = CFG_ISA_IO;
674 pGD->pciBase = pci_mem_base;
675 pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000);
676 pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000);
677 pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000);
678 pGD->frameAdrs = pci_mem_base;
679 pGD->memSize = VIDEO_MEM_SIZE;
wdenkc6097192002-11-03 00:24:07 +0000680
wdenkaea86e42004-03-23 22:53:55 +0000681 /* Set up hardware : select color mode,
682 set Register base to isa 3dx for 3?x regs*/
683 out8 (SMI_MISC_REG, 0x01);
wdenkc6097192002-11-03 00:24:07 +0000684
wdenkaea86e42004-03-23 22:53:55 +0000685 /* Turn off display */
686 smiWrite (SMI_INDX_C4, 0x01, 0x20);
wdenkc6097192002-11-03 00:24:07 +0000687
wdenkaea86e42004-03-23 22:53:55 +0000688 /* Unlock ext. crt regs */
689 out8 (SMI_LOCK_REG, 0x40);
wdenkc6097192002-11-03 00:24:07 +0000690
wdenkaea86e42004-03-23 22:53:55 +0000691 /* Unlock crt regs 0-7 */
692 smiWrite (SMI_INDX_D4, 0x11, 0x0e);
wdenkc6097192002-11-03 00:24:07 +0000693
wdenkaea86e42004-03-23 22:53:55 +0000694 /* Sytem Control Register */
695 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SCR, sizeof(SMI_SCR));
wdenkc6097192002-11-03 00:24:07 +0000696
wdenkaea86e42004-03-23 22:53:55 +0000697 /* extented CRT Register */
698 smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5, SMI_EXT_CRT, sizeof(SMI_EXT_CRT));
wdenkc6097192002-11-03 00:24:07 +0000699
wdenkaea86e42004-03-23 22:53:55 +0000700 /* Attributes controller registers */
701 smiLoadRegs (SMI_INDX_ATTR, SMI_INDX_ATTR, SMI_ATTR, sizeof(SMI_ATTR));
wdenkd3602132004-03-25 15:14:43 +0000702
wdenkaea86e42004-03-23 22:53:55 +0000703 /* Graphics Controller Register */
704 smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF, SMI_GCR, sizeof(SMI_GCR));
wdenkc6097192002-11-03 00:24:07 +0000705
wdenkaea86e42004-03-23 22:53:55 +0000706 /* Sequencer Register */
707 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SEQR, sizeof(SMI_SEQR));
wdenkc6097192002-11-03 00:24:07 +0000708
wdenkaea86e42004-03-23 22:53:55 +0000709 /* Power Control Register */
710 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_PCR, sizeof(SMI_PCR));
wdenkc6097192002-11-03 00:24:07 +0000711
wdenkaea86e42004-03-23 22:53:55 +0000712 /* Memory Control Register */
713 /* Register MSR62 is a power on configurable register. We don't */
714 /* modify it */
715 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_MCR, sizeof(SMI_MCR));
wdenkc6097192002-11-03 00:24:07 +0000716
wdenkaea86e42004-03-23 22:53:55 +0000717 /* Set misc output register */
718 smiLoadMsr (res_mode);
wdenkd3602132004-03-25 15:14:43 +0000719
wdenkaea86e42004-03-23 22:53:55 +0000720 /* Set CRT and Clock control registers */
721 smiLoadCrt (res_mode, bits_per_pixel);
wdenkd3602132004-03-25 15:14:43 +0000722
wdenkaea86e42004-03-23 22:53:55 +0000723 smiLoadCcr (res_mode, device_id);
wdenkc6097192002-11-03 00:24:07 +0000724
wdenkaea86e42004-03-23 22:53:55 +0000725 /* Hardware Cusor Register */
726 smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_HCR, sizeof(SMI_HCR));
wdenkc6097192002-11-03 00:24:07 +0000727
wdenkaea86e42004-03-23 22:53:55 +0000728 /* Enable Display */
729 videoout = 2; /* Default output is CRT */
730 if ((penv = getenv ("videoout")) != NULL) {
731 /* deceide if it is a string */
732 videoout = (int) simple_strtoul (penv, NULL, 16);
733 }
734 smiWrite (SMI_INDX_C4, 0x31, videoout);
wdenkc6097192002-11-03 00:24:07 +0000735
wdenkaea86e42004-03-23 22:53:55 +0000736 /* Video processor default setup */
737 smiInitVideoProcessor ();
wdenkc6097192002-11-03 00:24:07 +0000738
wdenkaea86e42004-03-23 22:53:55 +0000739 /* Capture port default setup */
740 smiInitCapturePort ();
741
742 /* Drawing engine default setup */
743 smiInitDrawingEngine ();
744
745 /* Turn on display */
746 smiWrite (0x3c4, 0x01, 0x01);
747
748 /* Clear video memory */
749 i = pGD->memSize/4;
750 vm = (unsigned int *)pGD->pciBase;
751 while(i--)
752 *vm++ = 0;
753 return ((void*)&smi);
wdenkc6097192002-11-03 00:24:07 +0000754}
755
756/*******************************************************************************
wdenkaea86e42004-03-23 22:53:55 +0000757 *
758 * Drawing engine fill on screen region
759 */
wdenkc6097192002-11-03 00:24:07 +0000760void video_hw_rectfill (
wdenkaea86e42004-03-23 22:53:55 +0000761 unsigned int bpp, /* bytes per pixel */
762 unsigned int dst_x, /* dest pos x */
763 unsigned int dst_y, /* dest pos y */
764 unsigned int dim_x, /* frame width */
765 unsigned int dim_y, /* frame height */
766 unsigned int color /* fill color */
767 )
wdenkc6097192002-11-03 00:24:07 +0000768{
wdenkaea86e42004-03-23 22:53:55 +0000769 register GraphicDevice *pGD = (GraphicDevice *)&smi;
770 register unsigned int control;
wdenkc6097192002-11-03 00:24:07 +0000771
wdenkaea86e42004-03-23 22:53:55 +0000772 dim_x *= bpp;
wdenkc6097192002-11-03 00:24:07 +0000773
wdenkaea86e42004-03-23 22:53:55 +0000774 out32r ((pGD->dprBase + 0x0014), color);
775 out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
776 out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
wdenkc6097192002-11-03 00:24:07 +0000777
wdenkaea86e42004-03-23 22:53:55 +0000778 control = 0x0000ffff & in32r ((pGD->dprBase + 0x000c));
wdenkc6097192002-11-03 00:24:07 +0000779
wdenkaea86e42004-03-23 22:53:55 +0000780 control |= 0x80010000;
wdenkc6097192002-11-03 00:24:07 +0000781
wdenkaea86e42004-03-23 22:53:55 +0000782 out32r ((pGD->dprBase + 0x000c), control);
wdenkc6097192002-11-03 00:24:07 +0000783
wdenkaea86e42004-03-23 22:53:55 +0000784 /* Wait for drawing processor */
785 do
786 {
787 out8 ((pGD->isaBase + 0x3c4), 0x16);
788 } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
wdenkc6097192002-11-03 00:24:07 +0000789}
790
791/*******************************************************************************
wdenkaea86e42004-03-23 22:53:55 +0000792 *
793 * Drawing engine bitblt with screen region
794 */
wdenkc6097192002-11-03 00:24:07 +0000795void video_hw_bitblt (
wdenkaea86e42004-03-23 22:53:55 +0000796 unsigned int bpp, /* bytes per pixel */
797 unsigned int src_x, /* source pos x */
798 unsigned int src_y, /* source pos y */
799 unsigned int dst_x, /* dest pos x */
800 unsigned int dst_y, /* dest pos y */
801 unsigned int dim_x, /* frame width */
802 unsigned int dim_y /* frame height */
803 )
wdenkc6097192002-11-03 00:24:07 +0000804{
wdenkaea86e42004-03-23 22:53:55 +0000805 register GraphicDevice *pGD = (GraphicDevice *)&smi;
806 register unsigned int control;
wdenkc6097192002-11-03 00:24:07 +0000807
wdenkaea86e42004-03-23 22:53:55 +0000808 dim_x *= bpp;
wdenkc6097192002-11-03 00:24:07 +0000809
wdenkaea86e42004-03-23 22:53:55 +0000810 if ((src_y<dst_y) || ((src_y==dst_y) && (src_x<dst_x)))
811 {
812 out32r ((pGD->dprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1)));
813 out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1)));
814 control = 0x88000000;
815 } else {
816 out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y));
817 out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
818 control = 0x80000000;
819 }
wdenkc6097192002-11-03 00:24:07 +0000820
wdenkaea86e42004-03-23 22:53:55 +0000821 out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
822 control |= (0x0000ffff & in32r ((pGD->dprBase + 0x000c)));
823 out32r ((pGD->dprBase + 0x000c), control);
wdenkc6097192002-11-03 00:24:07 +0000824
wdenkaea86e42004-03-23 22:53:55 +0000825 /* Wait for drawing processor */
826 do
827 {
828 out8 ((pGD->isaBase + 0x3c4), 0x16);
829 } while (in8 (pGD->isaBase + 0x3c5) & 0x08);
wdenkc6097192002-11-03 00:24:07 +0000830}
831
832/*******************************************************************************
wdenkaea86e42004-03-23 22:53:55 +0000833 *
834 * Set a RGB color in the LUT (8 bit index)
835 */
wdenkc6097192002-11-03 00:24:07 +0000836void video_set_lut (
wdenkaea86e42004-03-23 22:53:55 +0000837 unsigned int index, /* color number */
838 unsigned char r, /* red */
839 unsigned char g, /* green */
840 unsigned char b /* blue */
841 )
wdenkc6097192002-11-03 00:24:07 +0000842{
wdenkaea86e42004-03-23 22:53:55 +0000843 register GraphicDevice *pGD = (GraphicDevice *)&smi;
wdenkc6097192002-11-03 00:24:07 +0000844
wdenkaea86e42004-03-23 22:53:55 +0000845 out8 (SMI_LUT_MASK, 0xff);
wdenkc6097192002-11-03 00:24:07 +0000846
wdenkaea86e42004-03-23 22:53:55 +0000847 out8 (SMI_LUT_START, (char)index);
wdenkc6097192002-11-03 00:24:07 +0000848
wdenkaea86e42004-03-23 22:53:55 +0000849 out8 (SMI_LUT_RGB, r>>2); /* red */
850 udelay (10);
851 out8 (SMI_LUT_RGB, g>>2); /* green */
852 udelay (10);
853 out8 (SMI_LUT_RGB, b>>2); /* blue */
854 udelay (10);
wdenkc6097192002-11-03 00:24:07 +0000855}
856
857#endif /* CONFIG_VIDEO_SMI_LYNXEM */