aboutsummaryrefslogtreecommitdiff
path: root/board/tb0229/vr4131-pci.c
blob: 4c9192341e0f51205607d2af7374219883f5ce66 (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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/*
 * VR4131 PCIU support code for TANBAC Evaluation board TB0229.
 *
 * (C) Masami Komiya <mkomiya@sonare.it> 2004
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2, or (at
 * your option) any later version.
 */

#include <common.h>
#include <pci.h>
#include <asm/addrspace.h>

#define VR4131_PCIMMAW1REG	(volatile unsigned int *)(CKSEG1 + 0x0f000c00)
#define VR4131_PCIMMAW2REG	(volatile unsigned int *)(CKSEG1 + 0x0f000c04)
#define VR4131_PCITAW1REG	(volatile unsigned int *)(CKSEG1 + 0x0f000c08)
#define VR4131_PCITAW2REG	(volatile unsigned int *)(CKSEG1 + 0x0f000c0c)
#define VR4131_PCIMIOAWREG	(volatile unsigned int *)(CKSEG1 + 0x0f000c10)
#define VR4131_PCICONFDREG	(volatile unsigned int *)(CKSEG1 + 0x0f000c14)
#define VR4131_PCICONFAREG	(volatile unsigned int *)(CKSEG1 + 0x0f000c18)
#define VR4131_PCIMAILREG	(volatile unsigned int *)(CKSEG1 + 0x0f000c1c)
#define VR4131_BUSERRADREG	(volatile unsigned int *)(CKSEG1 + 0x0f000c24)
#define VR4131_INTCNTSTAREG	(volatile unsigned int *)(CKSEG1 + 0x0f000c28)
#define VR4131_PCIEXACCREG	(volatile unsigned int *)(CKSEG1 + 0x0f000c2c)
#define VR4131_PCIRECONTREG	(volatile unsigned int *)(CKSEG1 + 0x0f000c30)
#define VR4131_PCIENREG		(volatile unsigned int *)(CKSEG1 + 0x0f000c34)
#define VR4131_PCICLKSELREG	(volatile unsigned int *)(CKSEG1 + 0x0f000c38)
#define VR4131_PCITRDYREG	(volatile unsigned int *)(CKSEG1 + 0x0f000c3c)
#define VR4131_PCICLKRUNREG	(volatile unsigned int *)(CKSEG1 + 0x0f000c60)
#define VR4131_PCIHOSTCONFIG	(volatile unsigned int *)(CKSEG1 + 0x0f000d00)
#define VR4131_VENDORIDREG	(volatile unsigned int *)(CKSEG1 + 0x0f000d00)
#define VR4131_DEVICEIDREG	(volatile unsigned int *)(CKSEG1 + 0x0f000d00)
#define VR4131_COMMANDREG	(volatile unsigned int *)(CKSEG1 + 0x0f000d04)
#define VR4131_STATUSREG	(volatile unsigned int *)(CKSEG1 + 0x0f000d04)
#define VR4131_REVREG		(volatile unsigned int *)(CKSEG1 + 0x0f000d08)
#define VR4131_CLASSREG		(volatile unsigned int *)(CKSEG1 + 0x0f000d08)
#define VR4131_CACHELSREG	(volatile unsigned int *)(CKSEG1 + 0x0f000d0c)
#define VR4131_LATTIMERRG	(volatile unsigned int *)(CKSEG1 + 0x0f000d0c)
#define VR4131_MAILBAREG	(volatile unsigned int *)(CKSEG1 + 0x0f000d10)
#define VR4131_PCIMBA1REG	(volatile unsigned int *)(CKSEG1 + 0x0f000d14)
#define VR4131_PCIMBA2REG	(volatile unsigned int *)(CKSEG1 + 0x0f000d18)

/*#define VR41XX_PCIIRQ_OFFSET    (VR41XX_IRQ_MAX + 1)	*/
/*#define VR41XX_PCIIRQ_MAX       (VR41XX_IRQ_MAX + 12)	*/
/*#define VR4122_PCI_HOST_BASE    0xa0000000		*/

volatile unsigned int *pciconfigaddr;
volatile unsigned int *pciconfigdata;

#define PCI_ACCESS_READ  0
#define PCI_ACCESS_WRITE 1

/*
 *	Access PCI Configuration Register for VR4131
 */

static int vr4131_pci_config_access (u8 access_type, u32 dev, u32 reg,
				     u32 * data)
{
	u32 bus;
	u32 device;

	bus = ((dev & 0xff0000) >> 16);
	device = ((dev & 0xf800) >> 11);

	if (bus == 0) {
		/* Type 0 Configuration */
		*VR4131_PCICONFAREG = (u32) (1UL << device | (reg & 0xfc));
	} else {
		/* Type 1 Configuration */
		*VR4131_PCICONFAREG = (u32) (dev | ((reg / 4) << 2) | 1);
	}

	if (access_type == PCI_ACCESS_WRITE) {
		*VR4131_PCICONFDREG = *data;
	} else {
		*data = *VR4131_PCICONFDREG;
	}

	return (0);
}

static int vr4131_pci_read_config_byte (u32 hose, u32 dev, u32 reg, u8 * val)
{
	u32 data;

	if (vr4131_pci_config_access (PCI_ACCESS_READ, dev, reg, &data))
		return -1;

	*val = (data >> ((reg & 3) << 3)) & 0xff;

	return 0;
}


static int vr4131_pci_read_config_word (u32 hose, u32 dev, u32 reg, u16 * val)
{
	u32 data;

	if (reg & 1)
		return -1;

	if (vr4131_pci_config_access (PCI_ACCESS_READ, dev, reg, &data))
		return -1;

	*val = (data >> ((reg & 3) << 3)) & 0xffff;

	return 0;
}


static int vr4131_pci_read_config_dword (u32 hose, u32 dev, u32 reg,
					 u32 * val)
{
	u32 data = 0;

	if (reg & 3)
		return -1;

	if (vr4131_pci_config_access (PCI_ACCESS_READ, dev, reg, &data))
		return -1;

	*val = data;

	return (0);
}

static int vr4131_pci_write_config_byte (u32 hose, u32 dev, u32 reg, u8 val)
{
	u32 data = 0;

	if (vr4131_pci_config_access (PCI_ACCESS_READ, dev, reg, &data))
		return -1;

	data = (data & ~(0xff << ((reg & 3) << 3))) | (val <<
						       ((reg & 3) << 3));

	if (vr4131_pci_config_access (PCI_ACCESS_WRITE, dev, reg, &data))
		return -1;

	return 0;
}


static int vr4131_pci_write_config_word (u32 hose, u32 dev, u32 reg, u16 val)
{
	u32 data = 0;

	if (reg & 1)
		return -1;

	if (vr4131_pci_config_access (PCI_ACCESS_READ, dev, reg, &data))
		return -1;

	data = (data & ~(0xffff << ((reg & 3) << 3))) | (val <<
							 ((reg & 3) << 3));

	if (vr4131_pci_config_access (PCI_ACCESS_WRITE, dev, reg, &data))
		return -1;

	return 0;
}

static int vr4131_pci_write_config_dword (u32 hose, u32 dev, u32 reg, u32 val)
{
	u32 data;

	if (reg & 3) {
		return -1;
	}

	data = val;

	if (vr4131_pci_config_access (PCI_ACCESS_WRITE, dev, reg, &data))
		return -1;

	return (0);
}


/*
 *	Initialize VR4131 PCIU
 */

vr4131_pciu_init ()
{
	/* PCI clock */
	*VR4131_PCICLKSELREG = 0x00000002;

	/* PCI memory and I/O space */
	*VR4131_PCIMMAW1REG = 0x100F9010;
	*VR4131_PCIMMAW2REG = 0x140FD014;
	*VR4131_PCIMIOAWREG = 0x160FD000;

	/* Target memory window */
	*VR4131_PCITAW1REG = 0x00081000;	/* 64MB */
	*VR4131_PCITAW2REG = 0x00000000;

	*VR4131_MAILBAREG = 0UL;
	*VR4131_PCIMBA1REG = 0UL;

	*VR4131_PCITRDYREG = 0x00008004;

	*VR4131_PCIENREG = 0x00000004;	/* PCI enable */
	*VR4131_COMMANDREG = 0x02000007;
}

/*
 *	Initialize Module
 */

void init_vr4131_pci (struct pci_controller *hose)
{
	hose->first_busno = 0;
	hose->last_busno = 0xff;

	vr4131_pciu_init ();	/* Initialize VR4131 PCIU */

	/* PCI memory space #1 */
	pci_set_region (hose->regions + 0,
			0x10000000, 0xb0000000, 0x04000000, PCI_REGION_MEM);

	/* PCI memory space #2 */
	pci_set_region (hose->regions + 1,
			0x14000000, 0xb4000000, 0x02000000, PCI_REGION_MEM);


	/* PCI I/O space */
	pci_set_region (hose->regions + 2,
			0x16000000, 0xb6000000, 0x02000000, PCI_REGION_IO);

	/* System memory space */
	pci_set_region (hose->regions + 3,
			0x00000000,
			0x80000000,
			0x04000000, PCI_REGION_MEM | PCI_REGION_MEMORY);

	hose->region_count = 4;

	hose->read_byte = vr4131_pci_read_config_byte;
	hose->read_word = vr4131_pci_read_config_word;
	hose->read_dword = vr4131_pci_read_config_dword;
	hose->write_byte = vr4131_pci_write_config_byte;
	hose->write_word = vr4131_pci_write_config_word;
	hose->write_dword = vr4131_pci_write_config_dword;

	pci_register_hose (hose);

	hose->last_busno = pci_hose_scan (hose);

	return;
}