coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
rl5c476.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <device/device.h>
4 #include <device/pci.h>
5 #include <device/pci_ops.h>
6 #include <device/pci_ids.h>
7 #include <console/console.h>
8 #include <device/cardbus.h>
9 #include <delay.h>
10 #include "rl5c476.h"
11 #include "chip.h"
12 
13 static int enable_cf_boot = 0;
14 static unsigned int cf_base;
15 
16 static void rl5c476_init(struct device *dev)
17 {
18  pc16reg_t *pc16;
19  unsigned char *base;
20 
21  /* cardbus controller function 1 for CF Socket */
22  printk(BIOS_DEBUG, "Ricoh RL5c476: Initializing.\n");
23 
24  printk(BIOS_DEBUG, "CF Base = %0x\n",cf_base);
25 
26  /* misc control register */
27  pci_write_config16(dev,0x82,0x00a0);
28 
29  /* set up second slot as compact flash port if asked to do so */
30 
31  if (!enable_cf_boot) {
32  printk(BIOS_DEBUG, "CF boot not enabled.\n");
33  return;
34  }
35 
36  if (PCI_FUNC(dev->path.pci.devfn) != 1) {
37  // Only configure if second CF slot.
38  return;
39  }
40 
41  /* make sure isa interrupts are enabled */
42  pci_write_config16(dev,0x3e,0x0780);
43 
44  /* pick up where 16 bit card control structure is
45  * (0x800 bytes into config structure)
46  */
47  base = (unsigned char *)pci_read_config32(dev,0x10);
48  pc16 = (pc16reg_t *)(base + 0x800);
49 
50  /* disable memory and io windows and turn off socket power */
51  pc16->pwctrl = 0;
52 
53  /* disable irq lines */
54  pc16->igctrl = 0;
55 
56  /* disable memory and I/O windows */
57  pc16->awinen = 0;
58 
59  /* reset card, configure for I/O and set IRQ line */
60  pc16->igctrl = 0x69;
61 
62  /* set io window 0 for 1e0 - 1ef */
63  /* NOTE: This now sets CF up on a contiguous I/O window of
64  * 16 bytes, 0x1e0 to 0x1ef.
65  * Be warned that this is not a standard IDE address as
66  * automatically detected by the likes of FILO, and would need
67  * patching to recognize these addresses as an IDE drive.
68  *
69  * An earlier version of this driver set up 2 I/O windows to
70  * emulate the expected addresses for IDE2, however the PCMCIA
71  * package within Linux then could not re-initialize the
72  * device as it tried to take control of it. So I believe it is
73  * easier to patch Filo or the like to pick up this drive
74  * rather than playing silly games as the kernel tries to
75  * boot.
76  *
77  * Nonetheless, FILO needs a special option enabled to boot
78  * from this configuration, and it needs to clean up
79  * afterwards. Please refer to FILO documentation and source
80  * code for more details.
81  */
82  pc16->iostl0 = 0xe0;
83  pc16->iosth0 = 1;
84 
85  pc16->iospl0 = 0xef;
86  pc16->iosph0 = 1;
87 
88  pc16->ioffl0 = 0;
89  pc16->ioffh0 = 0;
90 
91  /* clear window 1 */
92  pc16->iostl1 = 0;
93  pc16->iosth1 = 0;
94 
95  pc16->iospl1 = 0;
96  pc16->iosph1 = 0;
97 
98  pc16->ioffl1 = 0x0;
99  pc16->ioffh1 = 0;
100 
101  /* set up CF config window */
102  pc16->smpga0 = cf_base>>24;
103  pc16->smsth0 = (cf_base>>20)&0x0f;
104  pc16->smstl0 = (cf_base>>12)&0xff;
105  pc16->smsph0 = ((cf_base>>20)&0x0f) | 0x80;
106  pc16->smspl0 = (cf_base>>12)&0xff;
107  pc16->moffl0 = 0;
108  pc16->moffh0 = 0x40;
109 
110  /* set I/O width for Auto Data width */
111  pc16->ioctrl = 0x22;
112 
113  /* enable I/O window 0 and 1 */
114  pc16->awinen = 0xc1;
115 
116  pc16->miscc1 = 1;
117 
118  /* apply power and enable outputs */
119  pc16->pwctrl = 0xb0;
120 
121  // delay could be optimised, but this works
122  udelay(100000);
123 
124  pc16->igctrl = 0x69;
125 
126  /* 16 bit CF always have first config byte at 0x200 into
127  * Config structure, but CF+ may not according to spec -
128  * should locate through reading tuple data, but this should
129  * do for now.
130  */
131  unsigned char *cptr;
132  cptr = (unsigned char *)(cf_base + 0x200);
133  printk(BIOS_DEBUG, "CF Config = %x\n",*cptr);
134 
135  /* Set CF to decode 16 IO bytes on any 16 byte boundary -
136  * rely on the io windows of the bridge set up above to
137  * map those bytes into the addresses for IDE controller 3
138  * (0x1e8 - 0x1ef and 0x3ed - 0x3ee)
139  */
140  *cptr = 0x41;
141 }
142 
143 static void rl5c476_read_resources(struct device *dev)
144 {
145 
146  struct resource *resource;
147 
148  /* For CF socket we need an extra memory window for
149  * the control structure of the CF itself
150  */
151  if (enable_cf_boot && (PCI_FUNC(dev->path.pci.devfn) == 1)) {
152  /* fake index as it isn't in PCI config space */
153  resource = new_resource(dev, 1);
155  resource->size = 0x1000;
156  resource->align = resource->gran = 12;
157  resource->limit= 0xffff0000;
158  }
160 }
161 
162 static void rl5c476_set_resources(struct device *dev)
163 {
164  struct resource *resource;
165  printk(BIOS_DEBUG, "%s In set resources\n",dev_path(dev));
166  if (enable_cf_boot && (PCI_FUNC(dev->path.pci.devfn) == 1)) {
167  resource = find_resource(dev,1);
168  if (!(resource->flags & IORESOURCE_STORED)) {
170  printk(BIOS_DEBUG, "%s 1 ==> %llx\n", dev_path(dev), resource->base);
171  cf_base = resource->base;
172  }
173  }
174 
176 
177 }
178 
179 static void rl5c476_set_subsystem(struct device *dev, unsigned int vendor,
180  unsigned int device)
181 {
182  u16 miscreg = pci_read_config16(dev, 0x82);
183  /* Enable subsystem id register writes */
184  pci_write_config16(dev, 0x82, miscreg | 0x40);
185 
187 
188  /* restore original contents */
189  pci_write_config16(dev, 0x82, miscreg);
190 }
191 
192 static struct pci_operations rl5c476_pci_ops = {
193  .set_subsystem = rl5c476_set_subsystem,
194 };
195 
196 static struct device_operations ricoh_rl5c476_ops = {
198  .set_resources = rl5c476_set_resources,
199  .enable_resources = cardbus_enable_resources,
200  .init = rl5c476_init,
201  .scan_bus = pci_scan_bridge,
202  .ops_pci = &rl5c476_pci_ops,
203 };
204 
205 static const struct pci_driver ricoh_rl5c476_driver __pci_driver = {
206  .ops = &ricoh_rl5c476_ops,
207  .vendor = PCI_VID_RICOH,
208  .device = PCI_DID_RICOH_RL5C476,
209 };
210 
211 static void southbridge_init(struct device *dev)
212 {
213  struct southbridge_ricoh_rl5c476_config *conf = dev->chip_info;
214  enable_cf_boot = conf->enable_cf;
215 }
216 
218  CHIP_NAME("Ricoh RL5C476 CardBus Controller")
219  .enable_dev = southbridge_init,
220 };
int vendor
Definition: cpu.c:91
void cardbus_enable_resources(struct device *dev)
void cardbus_read_resources(struct device *dev)
#define printk(level,...)
Definition: stdlib.h:16
struct resource * new_resource(struct device *dev, unsigned int index)
See if a resource structure already exists for a given index and if not allocate one.
Definition: device_util.c:346
struct resource * find_resource(const struct device *dev, unsigned int index)
Return an existing resource structure for a given index.
Definition: device_util.c:394
const char * dev_path(const struct device *dev)
Definition: device_util.c:149
#define CHIP_NAME(X)
Definition: device.h:32
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Definition: pci_ops.h:70
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define PCI_FUNC(devfn)
Definition: pci_def.h:550
void pci_dev_set_subsystem(struct device *dev, unsigned int vendor, unsigned int device)
Definition: pci_device.c:791
void pci_scan_bridge(struct device *dev)
Scan a PCI bridge and the buses behind the bridge.
Definition: pci_device.c:1598
void pci_dev_set_resources(struct device *dev)
Definition: pci_device.c:691
#define PCI_VID_RICOH
Definition: pci_ids.h:1656
#define PCI_DID_RICOH_RL5C476
Definition: pci_ids.h:1660
#define IORESOURCE_MEM
Definition: resource.h:10
#define IORESOURCE_STORED
Definition: resource.h:32
static void rl5c476_set_subsystem(struct device *dev, unsigned int vendor, unsigned int device)
Definition: rl5c476.c:179
static int enable_cf_boot
Definition: rl5c476.c:13
static unsigned int cf_base
Definition: rl5c476.c:14
static void rl5c476_init(struct device *dev)
Definition: rl5c476.c:16
static void rl5c476_read_resources(struct device *dev)
Definition: rl5c476.c:143
static const struct pci_driver ricoh_rl5c476_driver __pci_driver
Definition: rl5c476.c:205
static struct device_operations ricoh_rl5c476_ops
Definition: rl5c476.c:196
struct chip_operations southbridge_ricoh_rl5c476_ops
Definition: rl5c476.c:217
static struct pci_operations rl5c476_pci_ops
Definition: rl5c476.c:192
static void rl5c476_set_resources(struct device *dev)
Definition: rl5c476.c:162
static void southbridge_init(struct device *dev)
Definition: rl5c476.c:211
uintptr_t base
Definition: uart.c:17
uint16_t u16
Definition: stdint.h:48
void(* read_resources)(struct device *dev)
Definition: device.h:39
struct pci_path pci
Definition: path.h:116
Definition: device.h:107
struct device_path path
Definition: device.h:115
DEVTREE_CONST void * chip_info
Definition: device.h:164
Definition: rl5c476.h:8
u8 iospl1
Definition: rl5c476.h:23
u8 iosth0
Definition: rl5c476.h:18
u8 pwctrl
Definition: rl5c476.h:11
u8 iospl0
Definition: rl5c476.h:19
u8 ioffh1
Definition: rl5c476.h:66
u8 iosph0
Definition: rl5c476.h:20
u8 miscc1
Definition: rl5c476.h:56
u8 smstl0
Definition: rl5c476.h:25
u8 smsph0
Definition: rl5c476.h:28
u8 moffl0
Definition: rl5c476.h:29
u8 moffh0
Definition: rl5c476.h:30
u8 igctrl
Definition: rl5c476.h:12
u8 smsth0
Definition: rl5c476.h:26
u8 iostl0
Definition: rl5c476.h:17
u8 awinen
Definition: rl5c476.h:15
u8 iosph1
Definition: rl5c476.h:24
u8 ioffl0
Definition: rl5c476.h:63
u8 ioffh0
Definition: rl5c476.h:64
u8 ioffl1
Definition: rl5c476.h:65
u8 iosth1
Definition: rl5c476.h:22
u8 ioctrl
Definition: rl5c476.h:16
u8 smpga0
Definition: rl5c476.h:73
u8 iostl1
Definition: rl5c476.h:21
u8 smspl0
Definition: rl5c476.h:27
unsigned int devfn
Definition: path.h:54
unsigned long flags
Definition: resource.h:49
unsigned char align
Definition: resource.h:51
resource_t limit
Definition: resource.h:47
unsigned char gran
Definition: resource.h:52
resource_t base
Definition: resource.h:45
resource_t size
Definition: resource.h:46
void udelay(uint32_t us)
Definition: udelay.c:15