]>
Commit | Line | Data |
---|---|---|
e34fae78 AR |
1 | /* |
2 | * Copyright (C) 2012 CERN (www.cern.ch) | |
3 | * Author: Alessandro Rubini <rubini@gnudd.com> | |
4 | * | |
5 | * Released according to the GNU GPL, version 2 or any later version. | |
6 | * | |
7 | * This work is part of the White Rabbit project, a research effort led | |
8 | * by CERN, the European Institute for Nuclear Research. | |
9 | */ | |
10 | #ifndef __LINUX_FMC_H__ | |
11 | #define __LINUX_FMC_H__ | |
12 | #include <linux/types.h> | |
13 | #include <linux/moduleparam.h> | |
14 | #include <linux/device.h> | |
15 | #include <linux/list.h> | |
16 | #include <linux/interrupt.h> | |
17 | #include <linux/io.h> | |
18 | ||
19 | struct fmc_device; | |
20 | struct fmc_driver; | |
21 | ||
22 | /* | |
23 | * This bus abstraction is developed separately from drivers, so we need | |
24 | * to check the version of the data structures we receive. | |
25 | */ | |
26 | ||
27 | #define FMC_MAJOR 3 | |
28 | #define FMC_MINOR 0 | |
29 | #define FMC_VERSION ((FMC_MAJOR << 16) | FMC_MINOR) | |
30 | #define __FMC_MAJOR(x) ((x) >> 16) | |
31 | #define __FMC_MINOR(x) ((x) & 0xffff) | |
32 | ||
33 | /* | |
34 | * The device identification, as defined by the IPMI FRU (Field Replaceable | |
35 | * Unit) includes four different strings to describe the device. Here we | |
36 | * only match the "Board Manufacturer" and the "Board Product Name", | |
37 | * ignoring the "Board Serial Number" and "Board Part Number". All 4 are | |
38 | * expected to be strings, so they are treated as zero-terminated C strings. | |
39 | * Unspecified string (NULL) means "any", so if both are unspecified this | |
40 | * is a catch-all driver. So null entries are allowed and we use array | |
41 | * and length. This is unlike pci and usb that use null-terminated arrays | |
42 | */ | |
43 | struct fmc_fru_id { | |
44 | char *manufacturer; | |
45 | char *product_name; | |
46 | }; | |
47 | ||
48 | /* | |
49 | * If the FPGA is already programmed (think Etherbone or the second | |
50 | * SVEC slot), we can match on SDB devices in the memory image. This | |
51 | * match uses an array of devices that must all be present, and the | |
52 | * match is based on vendor and device only. Further checks are expected | |
53 | * to happen in the probe function. Zero means "any" and catch-all is allowed. | |
54 | */ | |
55 | struct fmc_sdb_one_id { | |
56 | uint64_t vendor; | |
57 | uint32_t device; | |
58 | }; | |
59 | struct fmc_sdb_id { | |
60 | struct fmc_sdb_one_id *cores; | |
61 | int cores_nr; | |
62 | }; | |
63 | ||
64 | struct fmc_device_id { | |
65 | struct fmc_fru_id *fru_id; | |
66 | int fru_id_nr; | |
67 | struct fmc_sdb_id *sdb_id; | |
68 | int sdb_id_nr; | |
69 | }; | |
70 | ||
71 | /* This sizes the module_param_array used by generic module parameters */ | |
72 | #define FMC_MAX_CARDS 32 | |
73 | ||
74 | /* The driver is a pretty simple thing */ | |
75 | struct fmc_driver { | |
76 | unsigned long version; | |
77 | struct device_driver driver; | |
78 | int (*probe)(struct fmc_device *); | |
79 | int (*remove)(struct fmc_device *); | |
80 | const struct fmc_device_id id_table; | |
81 | /* What follows is for generic module parameters */ | |
82 | int busid_n; | |
83 | int busid_val[FMC_MAX_CARDS]; | |
84 | int gw_n; | |
85 | char *gw_val[FMC_MAX_CARDS]; | |
86 | }; | |
87 | #define to_fmc_driver(x) container_of((x), struct fmc_driver, driver) | |
88 | ||
89 | /* These are the generic parameters, that drivers may instantiate */ | |
90 | #define FMC_PARAM_BUSID(_d) \ | |
91 | module_param_array_named(busid, _d.busid_val, int, &_d.busid_n, 0444) | |
92 | #define FMC_PARAM_GATEWARE(_d) \ | |
93 | module_param_array_named(gateware, _d.gw_val, charp, &_d.gw_n, 0444) | |
94 | ||
95 | /* | |
96 | * Drivers may need to configure gpio pins in the carrier. To read input | |
97 | * (a very uncommon operation, and definitely not in the hot paths), just | |
98 | * configure one gpio only and get 0 or 1 as retval of the config method | |
99 | */ | |
100 | struct fmc_gpio { | |
101 | char *carrier_name; /* name or NULL for virtual pins */ | |
102 | int gpio; | |
103 | int _gpio; /* internal use by the carrier */ | |
104 | int mode; /* GPIOF_DIR_OUT etc, from <linux/gpio.h> */ | |
105 | int irqmode; /* IRQF_TRIGGER_LOW and so on */ | |
106 | }; | |
107 | ||
108 | /* The numbering of gpio pins allows access to raw pins or virtual roles */ | |
109 | #define FMC_GPIO_RAW(x) (x) /* 4096 of them */ | |
110 | #define __FMC_GPIO_IS_RAW(x) ((x) < 0x1000) | |
111 | #define FMC_GPIO_IRQ(x) ((x) + 0x1000) /* 256 of them */ | |
112 | #define FMC_GPIO_LED(x) ((x) + 0x1100) /* 256 of them */ | |
113 | #define FMC_GPIO_KEY(x) ((x) + 0x1200) /* 256 of them */ | |
114 | #define FMC_GPIO_TP(x) ((x) + 0x1300) /* 256 of them */ | |
115 | #define FMC_GPIO_USER(x) ((x) + 0x1400) /* 256 of them */ | |
116 | /* We may add SCL and SDA, or other roles if the need arises */ | |
117 | ||
118 | /* GPIOF_DIR_IN etc are missing before 3.0. copy from <linux/gpio.h> */ | |
119 | #ifndef GPIOF_DIR_IN | |
120 | # define GPIOF_DIR_OUT (0 << 0) | |
121 | # define GPIOF_DIR_IN (1 << 0) | |
122 | # define GPIOF_INIT_LOW (0 << 1) | |
123 | # define GPIOF_INIT_HIGH (1 << 1) | |
124 | #endif | |
125 | ||
126 | /* | |
127 | * The operations are offered by each carrier and should make driver | |
128 | * design completely independent of the carrier. Named GPIO pins may be | |
129 | * the exception. | |
130 | */ | |
131 | struct fmc_operations { | |
c2955da0 AB |
132 | uint32_t (*read32)(struct fmc_device *fmc, int offset); |
133 | void (*write32)(struct fmc_device *fmc, uint32_t value, int offset); | |
e34fae78 AR |
134 | int (*validate)(struct fmc_device *fmc, struct fmc_driver *drv); |
135 | int (*reprogram)(struct fmc_device *f, struct fmc_driver *d, char *gw); | |
136 | int (*irq_request)(struct fmc_device *fmc, irq_handler_t h, | |
137 | char *name, int flags); | |
138 | void (*irq_ack)(struct fmc_device *fmc); | |
139 | int (*irq_free)(struct fmc_device *fmc); | |
140 | int (*gpio_config)(struct fmc_device *fmc, struct fmc_gpio *gpio, | |
141 | int ngpio); | |
142 | int (*read_ee)(struct fmc_device *fmc, int pos, void *d, int l); | |
143 | int (*write_ee)(struct fmc_device *fmc, int pos, const void *d, int l); | |
144 | }; | |
145 | ||
146 | /* Prefer this helper rather than calling of fmc->reprogram directly */ | |
147 | extern int fmc_reprogram(struct fmc_device *f, struct fmc_driver *d, char *gw, | |
148 | int sdb_entry); | |
149 | ||
150 | /* | |
151 | * The device reports all information needed to access hw. | |
152 | * | |
153 | * If we have eeprom_len and not contents, the core reads it. | |
154 | * Then, parsing of identifiers is done by the core which fills fmc_fru_id.. | |
155 | * Similarly a device that must be matched based on SDB cores must | |
156 | * fill the entry point and the core will scan the bus (FIXME: sdb match) | |
157 | */ | |
158 | struct fmc_device { | |
159 | unsigned long version; | |
160 | unsigned long flags; | |
161 | struct module *owner; /* char device must pin it */ | |
162 | struct fmc_fru_id id; /* for EEPROM-based match */ | |
163 | struct fmc_operations *op; /* carrier-provided */ | |
164 | int irq; /* according to host bus. 0 == none */ | |
165 | int eeprom_len; /* Usually 8kB, may be less */ | |
166 | int eeprom_addr; /* 0x50, 0x52 etc */ | |
167 | uint8_t *eeprom; /* Full contents or leading part */ | |
168 | char *carrier_name; /* "SPEC" or similar, for special use */ | |
169 | void *carrier_data; /* "struct spec *" or equivalent */ | |
170 | __iomem void *fpga_base; /* May be NULL (Etherbone) */ | |
171 | __iomem void *slot_base; /* Set by the driver */ | |
172 | struct fmc_device **devarray; /* Allocated by the bus */ | |
173 | int slot_id; /* Index in the slot array */ | |
174 | int nr_slots; /* Number of slots in this carrier */ | |
175 | unsigned long memlen; /* Used for the char device */ | |
176 | struct device dev; /* For Linux use */ | |
177 | struct device *hwdev; /* The underlying hardware device */ | |
178 | unsigned long sdbfs_entry; | |
179 | struct sdb_array *sdb; | |
180 | uint32_t device_id; /* Filled by the device */ | |
181 | char *mezzanine_name; /* Defaults to ``fmc'' */ | |
182 | void *mezzanine_data; | |
183 | }; | |
184 | #define to_fmc_device(x) container_of((x), struct fmc_device, dev) | |
185 | ||
186 | #define FMC_DEVICE_HAS_GOLDEN 1 | |
187 | #define FMC_DEVICE_HAS_CUSTOM 2 | |
188 | #define FMC_DEVICE_NO_MEZZANINE 4 | |
189 | #define FMC_DEVICE_MATCH_SDB 8 /* fmc-core must scan sdb in fpga */ | |
190 | ||
191 | /* | |
192 | * If fpga_base can be used, the carrier offers no readl/writel methods, and | |
193 | * this expands to a single, fast, I/O access. | |
194 | */ | |
195 | static inline uint32_t fmc_readl(struct fmc_device *fmc, int offset) | |
196 | { | |
c2955da0 AB |
197 | if (unlikely(fmc->op->read32)) |
198 | return fmc->op->read32(fmc, offset); | |
e34fae78 AR |
199 | return readl(fmc->fpga_base + offset); |
200 | } | |
201 | static inline void fmc_writel(struct fmc_device *fmc, uint32_t val, int off) | |
202 | { | |
c2955da0 AB |
203 | if (unlikely(fmc->op->write32)) |
204 | fmc->op->write32(fmc, val, off); | |
e34fae78 AR |
205 | else |
206 | writel(val, fmc->fpga_base + off); | |
207 | } | |
208 | ||
209 | /* pci-like naming */ | |
210 | static inline void *fmc_get_drvdata(const struct fmc_device *fmc) | |
211 | { | |
212 | return dev_get_drvdata(&fmc->dev); | |
213 | } | |
214 | ||
215 | static inline void fmc_set_drvdata(struct fmc_device *fmc, void *data) | |
216 | { | |
217 | dev_set_drvdata(&fmc->dev, data); | |
218 | } | |
219 | ||
220 | /* The 4 access points */ | |
221 | extern int fmc_driver_register(struct fmc_driver *drv); | |
222 | extern void fmc_driver_unregister(struct fmc_driver *drv); | |
223 | extern int fmc_device_register(struct fmc_device *tdev); | |
224 | extern void fmc_device_unregister(struct fmc_device *tdev); | |
225 | ||
226 | /* Two more for device sets, all driven by the same FPGA */ | |
227 | extern int fmc_device_register_n(struct fmc_device **devs, int n); | |
228 | extern void fmc_device_unregister_n(struct fmc_device **devs, int n); | |
229 | ||
230 | /* Internal cross-calls between files; not exported to other modules */ | |
231 | extern int fmc_match(struct device *dev, struct device_driver *drv); | |
232 | extern int fmc_fill_id_info(struct fmc_device *fmc); | |
233 | extern void fmc_free_id_info(struct fmc_device *fmc); | |
234 | extern void fmc_dump_eeprom(const struct fmc_device *fmc); | |
235 | extern void fmc_dump_sdb(const struct fmc_device *fmc); | |
236 | ||
237 | #endif /* __LINUX_FMC_H__ */ |