1/*
2 * Copyright 1998 by Alan Hourihane, Wigan, England.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
23 *
24 * Permedia2OutIndReg() and Permedia2InIndReg() are used to access
25 * the indirect Permedia2 RAMDAC registers only.
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "xf86.h"
33#include "xf86_OSproc.h"
34
35#include "xf86Pci.h"
36
37#include "glint_regs.h"
38#include "glint.h"
39
40void
41Permedia2OutIndReg(ScrnInfoPtr pScrn,
42		     CARD32 reg, unsigned char mask, unsigned char data)
43{
44  GLINTPtr pGlint = GLINTPTR(pScrn);
45  unsigned char tmp = 0x00;
46
47  GLINT_SLOW_WRITE_REG (reg, PM2DACIndexReg);
48
49  if (mask != 0x00)
50    tmp = GLINT_READ_REG (PM2DACIndexData) & mask;
51
52  GLINT_SLOW_WRITE_REG (tmp | data, PM2DACIndexData);
53}
54
55unsigned char
56Permedia2InIndReg (ScrnInfoPtr pScrn, CARD32 reg)
57{
58  GLINTPtr pGlint = GLINTPTR(pScrn);
59  unsigned char ret;
60
61  GLINT_SLOW_WRITE_REG (reg, PM2DACIndexReg);
62  GLINTDACDelay(5);
63  ret = GLINT_READ_REG (PM2DACIndexData);
64
65  return (ret);
66}
67
68void
69Permedia2WriteAddress (ScrnInfoPtr pScrn, CARD32 index)
70{
71    GLINTPtr pGlint = GLINTPTR(pScrn);
72
73    GLINT_SLOW_WRITE_REG(index, PM2DACWriteAddress);
74}
75
76void
77Permedia2WriteData (ScrnInfoPtr pScrn, unsigned char data)
78{
79    GLINTPtr pGlint = GLINTPTR(pScrn);
80
81    GLINT_SLOW_WRITE_REG(data, PM2DACData);
82}
83
84void
85Permedia2ReadAddress (ScrnInfoPtr pScrn, CARD32 index)
86{
87    GLINTPtr pGlint = GLINTPTR(pScrn);
88
89    GLINT_SLOW_WRITE_REG(0xFF, PM2DACReadMask);
90    GLINT_SLOW_WRITE_REG(index, PM2DACReadAddress);
91}
92
93unsigned char
94Permedia2ReadData (ScrnInfoPtr pScrn)
95{
96    GLINTPtr pGlint = GLINTPTR(pScrn);
97    GLINTDACDelay(5);
98    return(GLINT_READ_REG(PM2DACData));
99}
100
101void Permedia2LoadPalette(
102    ScrnInfoPtr pScrn,
103    int numColors,
104    int *indices,
105    LOCO *colors,
106    VisualPtr pVisual
107){
108    GLINTPtr pGlint = GLINTPTR(pScrn);
109    int i, index, shift = 0, j, repeat = 1;
110
111    if (pScrn->depth == 15) {
112	repeat = 8;
113	shift = 3;
114    }
115
116    for(i = 0; i < numColors; i++) {
117	index = indices[i];
118	for (j = 0; j < repeat; j++) {
119	    Permedia2WriteAddress(pScrn, (index << shift)+j);
120	    Permedia2WriteData(pScrn, colors[index].red);
121	    Permedia2WriteData(pScrn, colors[index].green);
122	    Permedia2WriteData(pScrn, colors[index].blue);
123	}
124	/* for video i/o */
125        GLINT_SLOW_WRITE_REG(index, TexelLUTIndex);
126	GLINT_SLOW_WRITE_REG((colors[index].red & 0xFF) |
127			     ((colors[index].green & 0xFF) << 8) |
128			     ((colors[index].blue & 0xFF) << 16),
129			     TexelLUTData);
130    }
131}
132
133/* special one for 565 mode */
134void Permedia2LoadPalette16(
135    ScrnInfoPtr pScrn,
136    int numColors,
137    int *indices,
138    LOCO *colors,
139    VisualPtr pVisual
140){
141    GLINTPtr pGlint = GLINTPTR(pScrn);
142    int i, index, j;
143
144    for(i = 0; i < numColors; i++) {
145	index = indices[i];
146	for (j = 0; j < 4; j++) {
147	    Permedia2WriteAddress(pScrn, (index << 2)+j);
148	    Permedia2WriteData(pScrn, colors[index >> 1].red);
149	    Permedia2WriteData(pScrn, colors[index].green);
150	    Permedia2WriteData(pScrn, colors[index >> 1].blue);
151	}
152        GLINT_SLOW_WRITE_REG(index, TexelLUTIndex);
153	GLINT_SLOW_WRITE_REG((colors[index].red & 0xFF) |
154			     ((colors[index].green & 0xFF) << 8) |
155			     ((colors[index].blue & 0xFF) << 16),
156			     TexelLUTData);
157
158	if(index <= 31) {
159	    for (j = 0; j < 4; j++) {
160	    	Permedia2WriteAddress(pScrn, (index << 3)+j);
161	    	Permedia2WriteData(pScrn, colors[index].red);
162	    	Permedia2WriteData(pScrn, colors[(index << 1) + 1].green);
163	    	Permedia2WriteData(pScrn, colors[index].blue);
164	    }
165	}
166    }
167}
168