blob: 93ad57a2697352508d21708a4e3e9dd740a320f4 [file] [log] [blame]
Wolfgang Denk53dd6ce2006-07-21 11:29:20 +02001/*
2 * multiverse.c
3 *
4 * VME driver for Multiverse
5 *
6 * Author : Sangmoon Kim
7 * dogoil@etinsys.com
8 *
9 * Copyright 2005 ETIN SYSTEMS Co.,Ltd.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <common.h>
18#include <asm/io.h>
19#include <pci.h>
Wolfgang Denk17f81f62011-11-05 05:12:59 +000020#include <linux/compiler.h>
Wolfgang Denk53dd6ce2006-07-21 11:29:20 +020021
22#include "multiverse.h"
23
24static unsigned long vme_asi_addr;
25static unsigned long vme_iack_addr;
26static unsigned long pci_reg_addr;
27static unsigned long vme_reg_addr;
28
29int multiv_reset(unsigned long base)
30{
31 writeb(0x09, base + VME_SLAVE32_AM);
32 writeb(0x39, base + VME_SLAVE24_AM);
33 writeb(0x29, base + VME_SLAVE16_AM);
34 writeb(0x2f, base + VME_SLAVE_REG_AM);
35 writeb((VME_A32_SLV_BUS >> 24) & 0xff, base + VME_SLAVE32_A);
36 writeb((VME_A24_SLV_BUS >> 16) & 0xff, base + VME_SLAVE24_A);
37 writeb((VME_A16_SLV_BUS >> 8 ) & 0xff, base + VME_SLAVE16_A);
38#ifdef A32_SLV_WINDOW
39 if (readb(base + VME_STATUS) & VME_STATUS_SYSCON) {
40 writeb(((~(VME_A32_SLV_SIZE-1)) >> 24) & 0xff,
41 base + VME_SLAVE32_MASK);
42 writeb(0x01, base + VME_SLAVE32_EN);
43 } else {
44 writeb(0xff, base + VME_SLAVE32_MASK);
45 writeb(0x00, base + VME_SLAVE32_EN);
46 }
47#else
48 writeb(0xff, base + VME_SLAVE32_MASK);
49 writeb(0x00, base + VME_SLAVE32_EN);
50#endif
51#ifdef A24_SLV_WINDOW
52 if (readb(base + VME_STATUS) & VME_STATUS_SYSCON) {
53 writeb(((~(VME_A24_SLV_SIZE-1)) >> 16) & 0xff,
54 base + VME_SLAVE24_MASK);
55 writeb(0x01, base + VME_SLAVE24_EN);
56 } else {
57 writeb(0xff, base + VME_SLAVE24_MASK);
58 writeb(0x00, base + VME_SLAVE24_EN);
59 }
60#else
61 writeb(0xff, base + VME_SLAVE24_MASK);
62 writeb(0x00, base + VME_SLAVE24_EN);
63#endif
64#ifdef A16_SLV_WINDOW
65 if (readb(base + VME_STATUS) & VME_STATUS_SYSCON) {
66 writeb(((~(VME_A16_SLV_SIZE-1)) >> 8) & 0xff,
67 base + VME_SLAVE16_MASK);
68 writeb(0x01, base + VME_SLAVE16_EN);
69 } else {
70 writeb(0xff, base + VME_SLAVE16_MASK);
71 writeb(0x00, base + VME_SLAVE16_EN);
72 }
73#else
74 writeb(0xff, base + VME_SLAVE16_MASK);
75 writeb(0x00, base + VME_SLAVE16_EN);
76#endif
77#ifdef REG_SLV_WINDOW
78 if (readb(base + VME_STATUS) & VME_STATUS_SYSCON) {
79 writeb(((~(VME_REG_SLV_SIZE-1)) >> 16) & 0xff,
80 base + VME_SLAVE_REG_MASK);
81 writeb(0x01, base + VME_SLAVE_REG_EN);
82 } else {
83 writeb(0xf8, base + VME_SLAVE_REG_MASK);
84 }
85#else
86 writeb(0xf8, base + VME_SLAVE_REG_MASK);
87#endif
88 writeb(0x09, base + VME_MASTER32_AM);
89 writeb(0x39, base + VME_MASTER24_AM);
90 writeb(0x29, base + VME_MASTER16_AM);
91 writeb(0x2f, base + VME_MASTER_REG_AM);
92 writel(0x00000000, base + VME_RMW_ADRS);
93 writeb(0x00, base + VME_IRQ);
94 writeb(0x00, base + VME_INT_EN);
95 writel(0x00000000, base + VME_IRQ1_REG);
96 writel(0x00000000, base + VME_IRQ2_REG);
97 writel(0x00000000, base + VME_IRQ3_REG);
98 writel(0x00000000, base + VME_IRQ4_REG);
99 writel(0x00000000, base + VME_IRQ5_REG);
100 writel(0x00000000, base + VME_IRQ6_REG);
101 writel(0x00000000, base + VME_IRQ7_REG);
102 return 0;
103}
104
105void multiv_auto_slot_id(unsigned long base)
106{
Wolfgang Denk17f81f62011-11-05 05:12:59 +0000107 __maybe_unused unsigned int vector;
Wolfgang Denk53dd6ce2006-07-21 11:29:20 +0200108 int slot_id = 1;
109 if (readb(base + VME_CTRL) & VME_CTRL_SYSFAIL) {
110 *(volatile unsigned int*)(base + VME_IRQ2_REG) = 0xfe;
111 writeb(readb(base + VME_IRQ) | 0x04, base + VME_IRQ);
112 writeb(readb(base + VME_CTRL) & ~VME_CTRL_SYSFAIL,
113 base + VME_CTRL);
114 while (readb(base + VME_STATUS) & VME_STATUS_SYSFAIL);
115 if (readb(base + VME_STATUS) & VME_STATUS_SYSCON) {
116 while (readb(base + VME_INT) & 0x04) {
117 vector = *(volatile unsigned int*)
118 (vme_iack_addr + VME_IACK2);
119 *(unsigned char*)(vme_asi_addr + 0x7ffff)
120 = (slot_id << 3) & 0xff;
121 slot_id ++;
122 if (slot_id > 31)
123 break;
124 }
125 }
126 }
127}
128
129int multiverse_init(void)
130{
131 int i;
132 pci_dev_t pdev;
133 unsigned int bar[6];
134
135 pdev = pci_find_device(0x1895, 0x0001, 0);
136
137 if (pdev == 0)
138 return -1;
139
140 for (i = 0; i < 6; i++)
141 pci_read_config_dword (pdev,
142 PCI_BASE_ADDRESS_0 + i * 4, &bar[i]);
143
144 pci_reg_addr = bar[0];
145 vme_reg_addr = bar[1] + 0x00F00000;
146 vme_iack_addr = bar[1] + 0x00200000;
147 vme_asi_addr = bar[3];
148
149 pci_write_config_dword (pdev, PCI_COMMAND,
150 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
151
152 writel(0xFF000000, pci_reg_addr + P_TA1);
153 writel(0x04, pci_reg_addr + P_IMG_CTRL1);
154 writel(0xf0000000, pci_reg_addr + P_TA2);
155 writel(0x04, pci_reg_addr + P_IMG_CTRL2);
156 writel(0xF1000000, pci_reg_addr + P_TA3);
157 writel(0x04, pci_reg_addr + P_IMG_CTRL3);
158 writel(VME_A32_MSTR_BUS, pci_reg_addr + P_TA5);
159 writel(~(VME_A32_MSTR_SIZE-1), pci_reg_addr + P_AM5);
160 writel(0x04, pci_reg_addr + P_IMG_CTRL5);
161
162 writel(VME_A32_SLV_BUS, pci_reg_addr + W_BA1);
163 writel(~(VME_A32_SLV_SIZE-1), pci_reg_addr + W_AM1);
164 writel(VME_A32_SLV_LOCAL, pci_reg_addr + W_TA1);
165 writel(0x04, pci_reg_addr + W_IMG_CTRL1);
166
167 writel(0xF0000000, pci_reg_addr + W_BA2);
168 writel(0xFF000000, pci_reg_addr + W_AM2);
169 writel(VME_A24_SLV_LOCAL, pci_reg_addr + W_TA2);
170 writel(0x04, pci_reg_addr + W_IMG_CTRL2);
171
172 writel(0xFF000000, pci_reg_addr + W_BA3);
173 writel(0xFF000000, pci_reg_addr + W_AM3);
174 writel(VME_A16_SLV_LOCAL, pci_reg_addr + W_TA3);
175 writel(0x04, pci_reg_addr + W_IMG_CTRL3);
176
177 writel(0x00000001, pci_reg_addr + W_ERR_CS);
178 writel(0x00000001, pci_reg_addr + P_ERR_CS);
179
180 multiv_reset(vme_reg_addr);
181 writeb(readb(vme_reg_addr + VME_CTRL) | VME_CTRL_SHORT_D,
182 vme_reg_addr + VME_CTRL);
183
184 multiv_auto_slot_id(vme_reg_addr);
185
186 return 0;
187}