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