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