blob: f3f4f1c9471e55df9597eb45e11f14c096b2cbb6 [file] [log] [blame]
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +00001/*
2 * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Ronald G. Minnich94425912005-11-22 16:47:40 +000017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
18 * MA 02110-1301 USA
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000019 */
Ronald G. Minnich43225bc2005-11-22 00:07:02 +000020/* (C) Copyright 2005 Nick Barker <nick.barker@btinternet.com
21 brought into line with the current architecture of LinuxBios */
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000022
23
24#include <arch/io.h>
25#include <device/device.h>
26#include <device/pci.h>
27#include <device/pci_ops.h>
28#include <device/pci_ids.h>
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000029#include <console/console.h>
Ronald G. Minnich43225bc2005-11-22 00:07:02 +000030#include <device/cardbus.h>
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000031#include "rl5c476.h"
32#include "chip.h"
33
Ronald G. Minnich43225bc2005-11-22 00:07:02 +000034static int enable_cf_boot = 0;
35static unsigned int cf_base;
36
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000037static void udelay(int i){
38 for(; i > 0 ; i--)
39 inb(0x80);
40
41}
42
Eric Biedermandbec2d42004-10-21 10:44:08 +000043static void rl5c476_init(device_t dev)
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000044{
45 //unsigned char enables;
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000046 pc16reg_t *pc16;
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000047
Ronald G. Minnich43225bc2005-11-22 00:07:02 +000048 unsigned char *base;
49
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000050 /* cardbus controller function 1 for CF Socket */
Eric Biedermandbec2d42004-10-21 10:44:08 +000051 printk_debug("rl5c476 init\n");
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000052
Ronald G. Minnich43225bc2005-11-22 00:07:02 +000053 printk_debug("CF Base = %0x\n",cf_base);
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000054
Ronald G. Minnich43225bc2005-11-22 00:07:02 +000055 /* misc control register */
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +000056 pci_write_config16(dev,0x82,0x00a0);
57
Ronald G. Minnich43225bc2005-11-22 00:07:02 +000058 /* set up second slot as compact flash port if asked to do so */
59 if( enable_cf_boot && (PCI_FUNC(dev->path.u.pci.devfn) == 1)){
60
61 /* make sure isa interrupts are enabled */
62 pci_write_config16(dev,0x3e,0x0780);
63
64 /* pick up where 16 bit card control structure is (0x800 bytes into config structure) */
65 base = (unsigned char *)pci_read_config32(dev,0x10);
66 pc16 = (pc16reg_t *)(base + 0x800);
67
68 /* disable memory and io windows and turn off socket power */
69 pc16->pwctrl = 0;
70
71 /* disable irq lines */
72 pc16->igctrl = 0;
73
74 /* disable memory and I/O windows */
75 pc16->awinen = 0;
76
77 /* reset card, configure for I/O and set IRQ line */
78 pc16->igctrl = 0x69;
79
80 // set io window 0 for 1e0 - 1ef
81 /* note this now sets CF up on a contiguous I/O window of 16 bytes, 0x1e0 to 0x1ef
82 Be warned that this is not a standard IDE address as automatically detected by the likes
83 of Filo, and would need patching to recognise these addresses as an IDE drive */
84 /* an earlier version of this driver set up 2 io windows to emulate the expected addresses
85 for IDE2, however the pcmcia package within Linux then could not re-initiailse the
86 device as it tried to take control of it. So I belive it is easier to patch Filo or the like
87 to pick up this drive rather than playing silly games as the kernel tries to boot.
88 */
89 pc16->iostl0 = 0xe0;
90 pc16->iosth0 = 1;
91
92 pc16->iospl0 = 0xef;
93 pc16->iosph0 = 1;
94
95 pc16->ioffl0 = 0;
96 pc16->ioffh0 = 0;
97
98 // clear window 1
99 pc16->iostl1 = 0;
100 pc16->iosth1 = 0;
101
102 pc16->iospl1 = 0;
103 pc16->iosph1 = 0;
104
105 pc16->ioffl1 = 0x0;
106 pc16->ioffh1 = 0;
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000107
108
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000109
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000110 // set up CF config window
111 pc16->smpga0 = cf_base>>24;
112 pc16->smsth0 = (cf_base>>20)&0x0f;
113 pc16->smstl0 = (cf_base>>12)&0xff;
114 pc16->smsph0 = ((cf_base>>20)&0x0f) | 0x80;
115 pc16->smspl0 = (cf_base>>12)&0xff;
116 pc16->moffl0 = 0;
117 pc16->moffh0 = 0x40;
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000118
119
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000120 // set I/O width for Auto Data width
121 pc16->ioctrl = 0x22;
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000122
123
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000124 // enable I/O window 0 and 1
125 pc16->awinen = 0xc1;
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000126
127
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000128 pc16->miscc1 = 1;
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000129
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000130 // apply power and enable outputs
131 pc16->pwctrl = 0xb0;
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000132
133
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000134 // delay could be optimised, but this works
135 udelay(100000);
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000136
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000137 pc16->igctrl = 0x69;
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000138
139
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000140 // 16 bit CF always have first config byte at 0x200 into Config structure,
141 // but CF+ May Not according to spec - should locate through reading tuple data,
142 // but this will do for now !!!
143 unsigned char *cptr;
144 cptr = (unsigned char *)(cf_base + 0x200);
145 printk_debug("CF Config = %x\n",*cptr);
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000146
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000147 // set CF to decode 16 IO bytes on any 16 byte boundary - rely on the io
148 // windows of the bridge set up above to map those bytes into the
149 // addresses for ide controller 3 (0x1e8 - 0x1ef and 0x3ed - 0x3ee)
150 *cptr = 0x41;
151 }
152
153}
154
155void rl5c476_read_resources(device_t dev)
156{
157
158 struct resource *resource;
159
160 /* for cf socket we need an extra memory window for the control structure of the cf itself */
161 if( enable_cf_boot && (PCI_FUNC(dev->path.u.pci.devfn) == 1)){
162 resource = new_resource(dev,1); /* fake index as it isn't in pci config space */
163 resource->flags |= IORESOURCE_MEM ;
164 resource->size = 0x1000;
165 resource->align = resource->gran = 12;
166 resource->limit= 0xffff0000;
167 //compute_allocate_resource(&dev->link[0],resource,resource->flags,resource->flags);
168 }
169 cardbus_read_resources(dev);
170
171}
172
173void rl5c476_set_resources(device_t dev)
174{
175
176 struct resource *resource;
177 printk_debug("%s In set resources \n",dev_path(dev));
178 if( enable_cf_boot && (PCI_FUNC(dev->path.u.pci.devfn) == 1)){
179 resource = find_resource(dev,1);
180 if( !(resource->flags & IORESOURCE_STORED) ){
181 resource->flags |= IORESOURCE_STORED ;
182 compute_allocate_resource(&dev->link[0],resource,resource->flags,resource->flags);
183 printk_debug("%s 1 ==> %x\n",dev_path(dev),resource->base);
184 cf_base = resource->base;
185 }
186 }
187
188 pci_dev_set_resources(dev);
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000189
190}
191
Eric Biedermandbec2d42004-10-21 10:44:08 +0000192static struct device_operations ricoh_rl5c476_ops = {
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000193 .read_resources = rl5c476_read_resources,
194 .set_resources = rl5c476_set_resources,
195 .enable_resources = cardbus_enable_resources,
196 .init = rl5c476_init,
197 .scan_bus = cardbus_scan_bridge,
Eric Biedermandbec2d42004-10-21 10:44:08 +0000198};
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000199
Stefan Reinauerf1cf1f72007-10-24 09:08:58 +0000200static const struct pci_driver ricoh_rl5c476_driver __pci_driver = {
Eric Biedermandbec2d42004-10-21 10:44:08 +0000201 .ops = &ricoh_rl5c476_ops,
202 .vendor = PCI_VENDOR_ID_RICOH,
203 .device = PCI_DEVICE_ID_RICOH_RL5C476,
204};
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000205
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000206void southbridge_init(device_t dev)
207{
208
209 struct southbridge_ricoh_rl5c476_config *conf = dev->chip_info;
210 enable_cf_boot = conf->enable_cf;
211
212}
213
214struct chip_operations southbridge_ricoh_rl5c476_ops = {
Uwe Hermanna7aa29b2006-11-05 18:50:49 +0000215 CHIP_NAME("Ricoh RL5C476 CardBus Controller")
Ronald G. Minnich43225bc2005-11-22 00:07:02 +0000216 .enable_dev = southbridge_init,
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +0000217};