summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/o2micro.h
blob: 5096e92c7a4cfb39e1e300f5d8ac8016b5fe54d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
 * o2micro.h 1.13 1999/10/25 20:03:34
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License
 * at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and
 * limitations under the License. 
 *
 * The initial developer of the original code is David A. Hinds
 * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
 * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 *
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License version 2 (the "GPL"), in which
 * case the provisions of the GPL are applicable instead of the
 * above.  If you wish to allow the use of your version of this file
 * only under the terms of the GPL and not to allow others to use
 * your version of this file under the MPL, indicate your decision by
 * deleting the provisions above and replace them with the notice and
 * other provisions required by the GPL.  If you do not delete the
 * provisions above, a recipient may use your version of this file
 * under either the MPL or the GPL.
 */

#ifndef _LINUX_O2MICRO_H
#define _LINUX_O2MICRO_H

/* Additional PCI configuration registers */

#define O2_MUX_CONTROL		0x90	/* 32 bit */
#define  O2_MUX_RING_OUT	0x0000000f
#define  O2_MUX_SKTB_ACTV	0x000000f0
#define  O2_MUX_SCTA_ACTV_ENA	0x00000100
#define  O2_MUX_SCTB_ACTV_ENA	0x00000200
#define  O2_MUX_SER_IRQ_ROUTE	0x0000e000
#define  O2_MUX_SER_PCI		0x00010000

#define  O2_MUX_SKTA_TURBO	0x000c0000	/* for 6833, 6860 */
#define  O2_MUX_SKTB_TURBO	0x00300000
#define  O2_MUX_AUX_VCC_3V	0x00400000
#define  O2_MUX_PCI_VCC_5V	0x00800000
#define  O2_MUX_PME_MUX		0x0f000000

/* Additional ExCA registers */

#define O2_MODE_A		0x38
#define O2_MODE_A_2		0x26	/* for 6833B, 6860C */
#define  O2_MODE_A_CD_PULSE	0x04
#define  O2_MODE_A_SUSP_EDGE	0x08
#define  O2_MODE_A_HOST_SUSP	0x10
#define  O2_MODE_A_PWR_MASK	0x60
#define  O2_MODE_A_QUIET	0x80

#define O2_MODE_B		0x39
#define O2_MODE_B_2		0x2e	/* for 6833B, 6860C */
#define  O2_MODE_B_IDENT	0x03
#define  O2_MODE_B_ID_BSTEP	0x00
#define  O2_MODE_B_ID_CSTEP	0x01
#define  O2_MODE_B_ID_O2	0x02
#define  O2_MODE_B_VS1		0x04
#define  O2_MODE_B_VS2		0x08
#define  O2_MODE_B_IRQ15_RI	0x80

#define O2_MODE_C		0x3a
#define  O2_MODE_C_DREQ_MASK	0x03
#define  O2_MODE_C_DREQ_INPACK	0x01
#define  O2_MODE_C_DREQ_WP	0x02
#define  O2_MODE_C_DREQ_BVD2	0x03
#define  O2_MODE_C_ZVIDEO	0x08
#define  O2_MODE_C_IREQ_SEL	0x30
#define  O2_MODE_C_MGMT_SEL	0xc0

#define O2_MODE_D		0x3b
#define  O2_MODE_D_IRQ_MODE	0x03
#define  O2_MODE_D_PCI_CLKRUN	0x04
#define  O2_MODE_D_CB_CLKRUN	0x08
#define  O2_MODE_D_SKT_ACTV	0x20
#define  O2_MODE_D_PCI_FIFO	0x40	/* for OZ6729, OZ6730 */
#define  O2_MODE_D_W97_IRQ	0x40
#define  O2_MODE_D_ISA_IRQ	0x80

#define O2_MHPG_DMA		0x3c
#define  O2_MHPG_CHANNEL	0x07
#define  O2_MHPG_CINT_ENA	0x08
#define  O2_MHPG_CSC_ENA	0x10

#define O2_FIFO_ENA		0x3d
#define  O2_FIFO_ZVIDEO_3	0x08
#define  O2_FIFO_PCI_FIFO	0x10
#define  O2_FIFO_POSTWR		0x40
#define  O2_FIFO_BUFFER		0x80

#define O2_MODE_E		0x3e
#define  O2_MODE_E_MHPG_DMA	0x01
#define  O2_MODE_E_SPKR_OUT	0x02
#define  O2_MODE_E_LED_OUT	0x08
#define  O2_MODE_E_SKTA_ACTV	0x10

#define O2_RESERVED1		0x94
#define O2_RESERVED2		0xD4
#define O2_RES_READ_PREFETCH	0x02
#define O2_RES_WRITE_BURST	0x08

static int o2micro_override(struct yenta_socket *socket)
{
	/*
	 * 'reserved' register at 0x94/D4. allows setting read prefetch and write
	 * bursting. read prefetching for example makes the RME Hammerfall DSP
	 * working. for some bridges it is at 0x94, for others at 0xD4. it's
	 * ok to write to both registers on all O2 bridges.
	 * from Eric Still, 02Micro.
	 */
	u8 a, b;
	bool use_speedup;

	if (PCI_FUNC(socket->dev->devfn) == 0) {
		a = config_readb(socket, O2_RESERVED1);
		b = config_readb(socket, O2_RESERVED2);
		dev_dbg(&socket->dev->dev, "O2: 0x94/0xD4: %02x/%02x\n", a, b);

		switch (socket->dev->device) {
		/*
		 * older bridges have problems with both read prefetch and write
		 * bursting depending on the combination of the chipset, bridge
		 * and the cardbus card. so disable them to be on the safe side.
		 */
		case PCI_DEVICE_ID_O2_6729:
		case PCI_DEVICE_ID_O2_6730:
		case PCI_DEVICE_ID_O2_6812:
		case PCI_DEVICE_ID_O2_6832:
		case PCI_DEVICE_ID_O2_6836:
		case PCI_DEVICE_ID_O2_6933:
			use_speedup = false;
			break;
		default:
			use_speedup = true;
			break;
		}

		/* the user may override our decision */
		if (strcasecmp(o2_speedup, "on") == 0)
			use_speedup = true;
		else if (strcasecmp(o2_speedup, "off") == 0)
			use_speedup = false;
		else if (strcasecmp(o2_speedup, "default") != 0)
			dev_warn(&socket->dev->dev,
				"O2: Unknown parameter, using 'default'");

		if (use_speedup) {
			dev_info(&socket->dev->dev,
				"O2: enabling read prefetch/write burst. If you experience problems or performance issues, use the yenta_socket parameter 'o2_speedup=off'\n");
			config_writeb(socket, O2_RESERVED1,
				      a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
			config_writeb(socket, O2_RESERVED2,
				      b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
		} else {
			dev_info(&socket->dev->dev,
				"O2: disabling read prefetch/write burst. If you experience problems or performance issues, use the yenta_socket parameter 'o2_speedup=on'\n");
			config_writeb(socket, O2_RESERVED1,
				      a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
			config_writeb(socket, O2_RESERVED2,
				      b & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
		}
	}

	return 0;
}

static void o2micro_restore_state(struct yenta_socket *socket)
{
	/*
	 * as long as read prefetch is the only thing in
	 * o2micro_override, it's safe to call it from here
	 */
	o2micro_override(socket);
}

#endif /* _LINUX_O2MICRO_H */