diff options
| author | Christoph Hellwig <hch@lst.de> | 2019-08-13 03:24:48 -0400 |
|---|---|---|
| committer | Tony Luck <tony.luck@intel.com> | 2019-08-16 14:33:56 -0400 |
| commit | 8334d1d415737198f64b0d31edb5daa0f14bb1e5 (patch) | |
| tree | 1ec73307d3c124c90d25076e542d7f82257a315e | |
| parent | c116954b2c9707f540eca852b3b86a087dffa4b4 (diff) | |
char: remove the SGI tiocx/mbcs driver
The SGI SN2 support is about to be removed. Remove this driver that
depends on the SN2 support.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lkml.kernel.org/r/20190813072514.23299-3-hch@lst.de
Signed-off-by: Tony Luck <tony.luck@intel.com>
| -rw-r--r-- | arch/ia64/configs/generic_defconfig | 2 | ||||
| -rw-r--r-- | arch/ia64/configs/gensparse_defconfig | 2 | ||||
| -rw-r--r-- | arch/ia64/sn/kernel/Makefile | 1 | ||||
| -rw-r--r-- | arch/ia64/sn/kernel/tiocx.c | 569 | ||||
| -rw-r--r-- | drivers/char/Kconfig | 14 | ||||
| -rw-r--r-- | drivers/char/Makefile | 1 | ||||
| -rw-r--r-- | drivers/char/mbcs.c | 831 | ||||
| -rw-r--r-- | drivers/char/mbcs.h | 553 |
8 files changed, 0 insertions, 1973 deletions
diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig index 22b98ddc9913..1fc4d5a77e0d 100644 --- a/arch/ia64/configs/generic_defconfig +++ b/arch/ia64/configs/generic_defconfig | |||
| @@ -90,8 +90,6 @@ CONFIG_IGB=y | |||
| 90 | # CONFIG_SERIO_SERPORT is not set | 90 | # CONFIG_SERIO_SERPORT is not set |
| 91 | CONFIG_GAMEPORT=m | 91 | CONFIG_GAMEPORT=m |
| 92 | CONFIG_SERIAL_NONSTANDARD=y | 92 | CONFIG_SERIAL_NONSTANDARD=y |
| 93 | CONFIG_SGI_TIOCX=y | ||
| 94 | CONFIG_SGI_MBCS=m | ||
| 95 | CONFIG_SERIAL_8250=y | 93 | CONFIG_SERIAL_8250=y |
| 96 | CONFIG_SERIAL_8250_CONSOLE=y | 94 | CONFIG_SERIAL_8250_CONSOLE=y |
| 97 | CONFIG_SERIAL_8250_NR_UARTS=6 | 95 | CONFIG_SERIAL_8250_NR_UARTS=6 |
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig index 1d230c0a90bd..289ed714ad8b 100644 --- a/arch/ia64/configs/gensparse_defconfig +++ b/arch/ia64/configs/gensparse_defconfig | |||
| @@ -79,8 +79,6 @@ CONFIG_E1000=y | |||
| 79 | # CONFIG_SERIO_SERPORT is not set | 79 | # CONFIG_SERIO_SERPORT is not set |
| 80 | CONFIG_GAMEPORT=m | 80 | CONFIG_GAMEPORT=m |
| 81 | CONFIG_SERIAL_NONSTANDARD=y | 81 | CONFIG_SERIAL_NONSTANDARD=y |
| 82 | CONFIG_SGI_TIOCX=y | ||
| 83 | CONFIG_SGI_MBCS=m | ||
| 84 | CONFIG_SERIAL_8250=y | 82 | CONFIG_SERIAL_8250=y |
| 85 | CONFIG_SERIAL_8250_CONSOLE=y | 83 | CONFIG_SERIAL_8250_CONSOLE=y |
| 86 | CONFIG_SERIAL_8250_NR_UARTS=6 | 84 | CONFIG_SERIAL_8250_NR_UARTS=6 |
diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile index 9c349dd23265..2f580603370d 100644 --- a/arch/ia64/sn/kernel/Makefile +++ b/arch/ia64/sn/kernel/Makefile | |||
| @@ -14,5 +14,4 @@ obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \ | |||
| 14 | io_init.o iomv.o klconflib.o pio_phys.o \ | 14 | io_init.o iomv.o klconflib.o pio_phys.o \ |
| 15 | sn2/ | 15 | sn2/ |
| 16 | obj-$(CONFIG_IA64_GENERIC) += machvec.o | 16 | obj-$(CONFIG_IA64_GENERIC) += machvec.o |
| 17 | obj-$(CONFIG_SGI_TIOCX) += tiocx.o | ||
| 18 | obj-$(CONFIG_PCI_MSI) += msi_sn.o | 17 | obj-$(CONFIG_PCI_MSI) += msi_sn.o |
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c deleted file mode 100644 index 32d0380eb72e..000000000000 --- a/arch/ia64/sn/kernel/tiocx.c +++ /dev/null | |||
| @@ -1,569 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2005 Silicon Graphics, Inc. All rights reserved. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/slab.h> | ||
| 12 | #include <linux/spinlock.h> | ||
| 13 | #include <linux/proc_fs.h> | ||
| 14 | #include <linux/capability.h> | ||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/uaccess.h> | ||
| 18 | #include <asm/sn/sn_sal.h> | ||
| 19 | #include <asm/sn/addrs.h> | ||
| 20 | #include <asm/sn/io.h> | ||
| 21 | #include <asm/sn/types.h> | ||
| 22 | #include <asm/sn/shubio.h> | ||
| 23 | #include <asm/sn/tiocx.h> | ||
| 24 | #include <asm/sn/l1.h> | ||
| 25 | #include <asm/sn/module.h> | ||
| 26 | #include "tio.h" | ||
| 27 | #include "xtalk/xwidgetdev.h" | ||
| 28 | #include "xtalk/hubdev.h" | ||
| 29 | |||
| 30 | #define CX_DEV_NONE 0 | ||
| 31 | #define DEVICE_NAME "tiocx" | ||
| 32 | #define WIDGET_ID 0 | ||
| 33 | #define TIOCX_DEBUG 0 | ||
| 34 | |||
| 35 | #if TIOCX_DEBUG | ||
| 36 | #define DBG(fmt...) printk(KERN_ALERT fmt) | ||
| 37 | #else | ||
| 38 | #define DBG(fmt...) | ||
| 39 | #endif | ||
| 40 | |||
| 41 | struct device_attribute dev_attr_cxdev_control; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * tiocx_match - Try to match driver id list with device. | ||
| 45 | * @dev: device pointer | ||
| 46 | * @drv: driver pointer | ||
| 47 | * | ||
| 48 | * Returns 1 if match, 0 otherwise. | ||
| 49 | */ | ||
| 50 | static int tiocx_match(struct device *dev, struct device_driver *drv) | ||
| 51 | { | ||
| 52 | struct cx_dev *cx_dev = to_cx_dev(dev); | ||
| 53 | struct cx_drv *cx_drv = to_cx_driver(drv); | ||
| 54 | const struct cx_device_id *ids = cx_drv->id_table; | ||
| 55 | |||
| 56 | if (!ids) | ||
| 57 | return 0; | ||
| 58 | |||
| 59 | while (ids->part_num) { | ||
| 60 | if (ids->part_num == cx_dev->cx_id.part_num) | ||
| 61 | return 1; | ||
| 62 | ids++; | ||
| 63 | } | ||
| 64 | return 0; | ||
| 65 | |||
| 66 | } | ||
| 67 | |||
| 68 | static int tiocx_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
| 69 | { | ||
| 70 | return -ENODEV; | ||
| 71 | } | ||
| 72 | |||
| 73 | static void tiocx_bus_release(struct device *dev) | ||
| 74 | { | ||
| 75 | kfree(to_cx_dev(dev)); | ||
| 76 | } | ||
| 77 | |||
| 78 | /** | ||
| 79 | * cx_device_match - Find cx_device in the id table. | ||
| 80 | * @ids: id table from driver | ||
| 81 | * @cx_device: part/mfg id for the device | ||
| 82 | * | ||
| 83 | */ | ||
| 84 | static const struct cx_device_id *cx_device_match(const struct cx_device_id | ||
| 85 | *ids, | ||
| 86 | struct cx_dev *cx_device) | ||
| 87 | { | ||
| 88 | /* | ||
| 89 | * NOTES: We may want to check for CX_ANY_ID too. | ||
| 90 | * Do we want to match against nasid too? | ||
| 91 | * CX_DEV_NONE == 0, if the driver tries to register for | ||
| 92 | * part/mfg == 0 we should return no-match (NULL) here. | ||
| 93 | */ | ||
| 94 | while (ids->part_num && ids->mfg_num) { | ||
| 95 | if (ids->part_num == cx_device->cx_id.part_num && | ||
| 96 | ids->mfg_num == cx_device->cx_id.mfg_num) | ||
| 97 | return ids; | ||
| 98 | ids++; | ||
| 99 | } | ||
| 100 | |||
| 101 | return NULL; | ||
| 102 | } | ||
| 103 | |||
| 104 | /** | ||
| 105 | * cx_device_probe - Look for matching device. | ||
| 106 | * Call driver probe routine if found. | ||
| 107 | * @cx_driver: driver table (cx_drv struct) from driver | ||
| 108 | * @cx_device: part/mfg id for the device | ||
| 109 | */ | ||
| 110 | static int cx_device_probe(struct device *dev) | ||
| 111 | { | ||
| 112 | const struct cx_device_id *id; | ||
| 113 | struct cx_drv *cx_drv = to_cx_driver(dev->driver); | ||
| 114 | struct cx_dev *cx_dev = to_cx_dev(dev); | ||
| 115 | int error = 0; | ||
| 116 | |||
| 117 | if (!cx_dev->driver && cx_drv->probe) { | ||
| 118 | id = cx_device_match(cx_drv->id_table, cx_dev); | ||
| 119 | if (id) { | ||
| 120 | if ((error = cx_drv->probe(cx_dev, id)) < 0) | ||
| 121 | return error; | ||
| 122 | else | ||
| 123 | cx_dev->driver = cx_drv; | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | return error; | ||
| 128 | } | ||
| 129 | |||
| 130 | /** | ||
| 131 | * cx_driver_remove - Remove driver from device struct. | ||
| 132 | * @dev: device | ||
| 133 | */ | ||
| 134 | static int cx_driver_remove(struct device *dev) | ||
| 135 | { | ||
| 136 | struct cx_dev *cx_dev = to_cx_dev(dev); | ||
| 137 | struct cx_drv *cx_drv = cx_dev->driver; | ||
| 138 | if (cx_drv->remove) | ||
| 139 | cx_drv->remove(cx_dev); | ||
| 140 | cx_dev->driver = NULL; | ||
| 141 | return 0; | ||
| 142 | } | ||
| 143 | |||
| 144 | struct bus_type tiocx_bus_type = { | ||
| 145 | .name = "tiocx", | ||
| 146 | .match = tiocx_match, | ||
| 147 | .uevent = tiocx_uevent, | ||
| 148 | .probe = cx_device_probe, | ||
| 149 | .remove = cx_driver_remove, | ||
| 150 | }; | ||
| 151 | |||
| 152 | /** | ||
| 153 | * cx_driver_register - Register the driver. | ||
| 154 | * @cx_driver: driver table (cx_drv struct) from driver | ||
| 155 | * | ||
| 156 | * Called from the driver init routine to register a driver. | ||
| 157 | * The cx_drv struct contains the driver name, a pointer to | ||
| 158 | * a table of part/mfg numbers and a pointer to the driver's | ||
| 159 | * probe/attach routine. | ||
| 160 | */ | ||
| 161 | int cx_driver_register(struct cx_drv *cx_driver) | ||
| 162 | { | ||
| 163 | cx_driver->driver.name = cx_driver->name; | ||
| 164 | cx_driver->driver.bus = &tiocx_bus_type; | ||
| 165 | |||
| 166 | return driver_register(&cx_driver->driver); | ||
| 167 | } | ||
| 168 | |||
| 169 | /** | ||
| 170 | * cx_driver_unregister - Unregister the driver. | ||
| 171 | * @cx_driver: driver table (cx_drv struct) from driver | ||
| 172 | */ | ||
| 173 | int cx_driver_unregister(struct cx_drv *cx_driver) | ||
| 174 | { | ||
| 175 | driver_unregister(&cx_driver->driver); | ||
| 176 | return 0; | ||
| 177 | } | ||
| 178 | |||
| 179 | /** | ||
| 180 | * cx_device_register - Register a device. | ||
| 181 | * @nasid: device's nasid | ||
| 182 | * @part_num: device's part number | ||
| 183 | * @mfg_num: device's manufacturer number | ||
| 184 | * @hubdev: hub info associated with this device | ||
| 185 | * @bt: board type of the device | ||
| 186 | * | ||
| 187 | */ | ||
| 188 | int | ||
| 189 | cx_device_register(nasid_t nasid, int part_num, int mfg_num, | ||
| 190 | struct hubdev_info *hubdev, int bt) | ||
| 191 | { | ||
| 192 | struct cx_dev *cx_dev; | ||
| 193 | int r; | ||
| 194 | |||
| 195 | cx_dev = kzalloc(sizeof(struct cx_dev), GFP_KERNEL); | ||
| 196 | DBG("cx_dev= 0x%p\n", cx_dev); | ||
| 197 | if (cx_dev == NULL) | ||
| 198 | return -ENOMEM; | ||
| 199 | |||
| 200 | cx_dev->cx_id.part_num = part_num; | ||
| 201 | cx_dev->cx_id.mfg_num = mfg_num; | ||
| 202 | cx_dev->cx_id.nasid = nasid; | ||
| 203 | cx_dev->hubdev = hubdev; | ||
| 204 | cx_dev->bt = bt; | ||
| 205 | |||
| 206 | cx_dev->dev.parent = NULL; | ||
| 207 | cx_dev->dev.bus = &tiocx_bus_type; | ||
| 208 | cx_dev->dev.release = tiocx_bus_release; | ||
| 209 | dev_set_name(&cx_dev->dev, "%d", cx_dev->cx_id.nasid); | ||
| 210 | r = device_register(&cx_dev->dev); | ||
| 211 | if (r) { | ||
| 212 | kfree(cx_dev); | ||
| 213 | return r; | ||
| 214 | } | ||
| 215 | get_device(&cx_dev->dev); | ||
| 216 | |||
| 217 | device_create_file(&cx_dev->dev, &dev_attr_cxdev_control); | ||
| 218 | |||
| 219 | return 0; | ||
| 220 | } | ||
| 221 | |||
| 222 | /** | ||
| 223 | * cx_device_unregister - Unregister a device. | ||
| 224 | * @cx_dev: part/mfg id for the device | ||
| 225 | */ | ||
| 226 | int cx_device_unregister(struct cx_dev *cx_dev) | ||
| 227 | { | ||
| 228 | put_device(&cx_dev->dev); | ||
| 229 | device_unregister(&cx_dev->dev); | ||
| 230 | return 0; | ||
| 231 | } | ||
| 232 | |||
| 233 | /** | ||
| 234 | * cx_device_reload - Reload the device. | ||
| 235 | * @nasid: device's nasid | ||
| 236 | * @part_num: device's part number | ||
| 237 | * @mfg_num: device's manufacturer number | ||
| 238 | * | ||
| 239 | * Remove the device associated with 'nasid' from device list and then | ||
| 240 | * call device-register with the given part/mfg numbers. | ||
| 241 | */ | ||
| 242 | static int cx_device_reload(struct cx_dev *cx_dev) | ||
| 243 | { | ||
| 244 | cx_device_unregister(cx_dev); | ||
| 245 | return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num, | ||
| 246 | cx_dev->cx_id.mfg_num, cx_dev->hubdev, | ||
| 247 | cx_dev->bt); | ||
| 248 | } | ||
| 249 | |||
| 250 | static inline u64 tiocx_intr_alloc(nasid_t nasid, int widget, | ||
| 251 | u64 sn_irq_info, | ||
| 252 | int req_irq, nasid_t req_nasid, | ||
| 253 | int req_slice) | ||
| 254 | { | ||
| 255 | struct ia64_sal_retval rv; | ||
| 256 | rv.status = 0; | ||
| 257 | rv.v0 = 0; | ||
| 258 | |||
| 259 | ia64_sal_oemcall_nolock(&rv, SN_SAL_IOIF_INTERRUPT, | ||
| 260 | SAL_INTR_ALLOC, nasid, | ||
| 261 | widget, sn_irq_info, req_irq, | ||
| 262 | req_nasid, req_slice); | ||
| 263 | return rv.status; | ||
| 264 | } | ||
| 265 | |||
| 266 | static inline void tiocx_intr_free(nasid_t nasid, int widget, | ||
| 267 | struct sn_irq_info *sn_irq_info) | ||
| 268 | { | ||
| 269 | struct ia64_sal_retval rv; | ||
| 270 | rv.status = 0; | ||
| 271 | rv.v0 = 0; | ||
| 272 | |||
| 273 | ia64_sal_oemcall_nolock(&rv, SN_SAL_IOIF_INTERRUPT, | ||
| 274 | SAL_INTR_FREE, nasid, | ||
| 275 | widget, sn_irq_info->irq_irq, | ||
| 276 | sn_irq_info->irq_cookie, 0, 0); | ||
| 277 | } | ||
| 278 | |||
| 279 | struct sn_irq_info *tiocx_irq_alloc(nasid_t nasid, int widget, int irq, | ||
| 280 | nasid_t req_nasid, int slice) | ||
| 281 | { | ||
| 282 | struct sn_irq_info *sn_irq_info; | ||
| 283 | int status; | ||
| 284 | int sn_irq_size = sizeof(struct sn_irq_info); | ||
| 285 | |||
| 286 | if ((nasid & 1) == 0) | ||
| 287 | return NULL; | ||
| 288 | |||
| 289 | sn_irq_info = kzalloc(sn_irq_size, GFP_KERNEL); | ||
| 290 | if (sn_irq_info == NULL) | ||
| 291 | return NULL; | ||
| 292 | |||
| 293 | status = tiocx_intr_alloc(nasid, widget, __pa(sn_irq_info), irq, | ||
| 294 | req_nasid, slice); | ||
| 295 | if (status) { | ||
| 296 | kfree(sn_irq_info); | ||
| 297 | return NULL; | ||
| 298 | } else { | ||
| 299 | return sn_irq_info; | ||
| 300 | } | ||
| 301 | } | ||
| 302 | |||
| 303 | void tiocx_irq_free(struct sn_irq_info *sn_irq_info) | ||
| 304 | { | ||
| 305 | u64 bridge = (u64) sn_irq_info->irq_bridge; | ||
| 306 | nasid_t nasid = NASID_GET(bridge); | ||
| 307 | int widget; | ||
| 308 | |||
| 309 | if (nasid & 1) { | ||
| 310 | widget = TIO_SWIN_WIDGETNUM(bridge); | ||
| 311 | tiocx_intr_free(nasid, widget, sn_irq_info); | ||
| 312 | kfree(sn_irq_info); | ||
| 313 | } | ||
| 314 | } | ||
| 315 | |||
| 316 | u64 tiocx_dma_addr(u64 addr) | ||
| 317 | { | ||
| 318 | return PHYS_TO_TIODMA(addr); | ||
| 319 | } | ||
| 320 | |||
| 321 | u64 tiocx_swin_base(int nasid) | ||
| 322 | { | ||
| 323 | return TIO_SWIN_BASE(nasid, TIOCX_CORELET); | ||
| 324 | } | ||
| 325 | |||
| 326 | EXPORT_SYMBOL(cx_driver_register); | ||
| 327 | EXPORT_SYMBOL(cx_driver_unregister); | ||
| 328 | EXPORT_SYMBOL(cx_device_register); | ||
| 329 | EXPORT_SYMBOL(cx_device_unregister); | ||
| 330 | EXPORT_SYMBOL(tiocx_irq_alloc); | ||
| 331 | EXPORT_SYMBOL(tiocx_irq_free); | ||
| 332 | EXPORT_SYMBOL(tiocx_bus_type); | ||
| 333 | EXPORT_SYMBOL(tiocx_dma_addr); | ||
| 334 | EXPORT_SYMBOL(tiocx_swin_base); | ||
| 335 | |||
| 336 | static void tio_conveyor_set(nasid_t nasid, int enable_flag) | ||
| 337 | { | ||
| 338 | u64 ice_frz; | ||
| 339 | u64 disable_cb = (1ull << 61); | ||
| 340 | |||
| 341 | if (!(nasid & 1)) | ||
| 342 | return; | ||
| 343 | |||
| 344 | ice_frz = REMOTE_HUB_L(nasid, TIO_ICE_FRZ_CFG); | ||
| 345 | if (enable_flag) { | ||
| 346 | if (!(ice_frz & disable_cb)) /* already enabled */ | ||
| 347 | return; | ||
| 348 | ice_frz &= ~disable_cb; | ||
| 349 | } else { | ||
| 350 | if (ice_frz & disable_cb) /* already disabled */ | ||
| 351 | return; | ||
| 352 | ice_frz |= disable_cb; | ||
| 353 | } | ||
| 354 | DBG(KERN_ALERT "TIO_ICE_FRZ_CFG= 0x%lx\n", ice_frz); | ||
| 355 | REMOTE_HUB_S(nasid, TIO_ICE_FRZ_CFG, ice_frz); | ||
| 356 | } | ||
| 357 | |||
| 358 | #define tio_conveyor_enable(nasid) tio_conveyor_set(nasid, 1) | ||
| 359 | #define tio_conveyor_disable(nasid) tio_conveyor_set(nasid, 0) | ||
| 360 | |||
| 361 | static void tio_corelet_reset(nasid_t nasid, int corelet) | ||
| 362 | { | ||
| 363 | if (!(nasid & 1)) | ||
| 364 | return; | ||
| 365 | |||
| 366 | REMOTE_HUB_S(nasid, TIO_ICE_PMI_TX_CFG, 1 << corelet); | ||
| 367 | udelay(2000); | ||
| 368 | REMOTE_HUB_S(nasid, TIO_ICE_PMI_TX_CFG, 0); | ||
| 369 | udelay(2000); | ||
| 370 | } | ||
| 371 | |||
| 372 | static int is_fpga_tio(int nasid, int *bt) | ||
| 373 | { | ||
| 374 | u16 uninitialized_var(ioboard_type); /* GCC be quiet */ | ||
| 375 | long rc; | ||
| 376 | |||
| 377 | rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard_type); | ||
| 378 | if (rc) { | ||
| 379 | printk(KERN_WARNING "ia64_sn_sysctl_ioboard_get failed: %ld\n", | ||
| 380 | rc); | ||
| 381 | return 0; | ||
| 382 | } | ||
| 383 | |||
| 384 | switch (ioboard_type) { | ||
| 385 | case L1_BRICKTYPE_SA: | ||
| 386 | case L1_BRICKTYPE_ATHENA: | ||
| 387 | case L1_BOARDTYPE_DAYTONA: | ||
| 388 | *bt = ioboard_type; | ||
| 389 | return 1; | ||
| 390 | } | ||
| 391 | |||
| 392 | return 0; | ||
| 393 | } | ||
| 394 | |||
| 395 | static int bitstream_loaded(nasid_t nasid) | ||
| 396 | { | ||
| 397 | u64 cx_credits; | ||
| 398 | |||
| 399 | cx_credits = REMOTE_HUB_L(nasid, TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3); | ||
| 400 | cx_credits &= TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3_CREDIT_CNT_MASK; | ||
| 401 | DBG("cx_credits= 0x%lx\n", cx_credits); | ||
| 402 | |||
| 403 | return (cx_credits == 0xf) ? 1 : 0; | ||
| 404 | } | ||
| 405 | |||
| 406 | static int tiocx_reload(struct cx_dev *cx_dev) | ||
| 407 | { | ||
| 408 | int part_num = CX_DEV_NONE; | ||
| 409 | int mfg_num = CX_DEV_NONE; | ||
| 410 | nasid_t nasid = cx_dev->cx_id.nasid; | ||
| 411 | |||
| 412 | if (bitstream_loaded(nasid)) { | ||
| 413 | u64 cx_id; | ||
| 414 | int rv; | ||
| 415 | |||
| 416 | rv = ia64_sn_sysctl_tio_clock_reset(nasid); | ||
| 417 | if (rv) { | ||
| 418 | printk(KERN_ALERT "CX port JTAG reset failed.\n"); | ||
| 419 | } else { | ||
| 420 | cx_id = *(volatile u64 *) | ||
| 421 | (TIO_SWIN_BASE(nasid, TIOCX_CORELET) + | ||
| 422 | WIDGET_ID); | ||
| 423 | part_num = XWIDGET_PART_NUM(cx_id); | ||
| 424 | mfg_num = XWIDGET_MFG_NUM(cx_id); | ||
| 425 | DBG("part= 0x%x, mfg= 0x%x\n", part_num, mfg_num); | ||
| 426 | /* just ignore it if it's a CE */ | ||
| 427 | if (part_num == TIO_CE_ASIC_PARTNUM) | ||
| 428 | return 0; | ||
| 429 | } | ||
| 430 | } | ||
| 431 | |||
| 432 | cx_dev->cx_id.part_num = part_num; | ||
| 433 | cx_dev->cx_id.mfg_num = mfg_num; | ||
| 434 | |||
| 435 | /* | ||
| 436 | * Delete old device and register the new one. It's ok if | ||
| 437 | * part_num/mfg_num == CX_DEV_NONE. We want to register | ||
| 438 | * devices in the table even if a bitstream isn't loaded. | ||
| 439 | * That allows use to see that a bitstream isn't loaded via | ||
| 440 | * TIOCX_IOCTL_DEV_LIST. | ||
| 441 | */ | ||
| 442 | return cx_device_reload(cx_dev); | ||
| 443 | } | ||
| 444 | |||
| 445 | static ssize_t show_cxdev_control(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 446 | { | ||
| 447 | struct cx_dev *cx_dev = to_cx_dev(dev); | ||
| 448 | |||
| 449 | return sprintf(buf, "0x%x 0x%x 0x%x 0x%x\n", | ||
| 450 | cx_dev->cx_id.nasid, | ||
| 451 | cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num, | ||
| 452 | cx_dev->bt); | ||
| 453 | } | ||
| 454 | |||
| 455 | static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *attr, const char *buf, | ||
| 456 | size_t count) | ||
| 457 | { | ||
| 458 | int n; | ||
| 459 | struct cx_dev *cx_dev = to_cx_dev(dev); | ||
| 460 | |||
| 461 | if (!capable(CAP_SYS_ADMIN)) | ||
| 462 | return -EPERM; | ||
| 463 | |||
| 464 | if (count <= 0) | ||
| 465 | return 0; | ||
| 466 | |||
| 467 | n = simple_strtoul(buf, NULL, 0); | ||
| 468 | |||
| 469 | switch (n) { | ||
| 470 | case 1: | ||
| 471 | tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET); | ||
| 472 | tiocx_reload(cx_dev); | ||
| 473 | break; | ||
| 474 | case 2: | ||
| 475 | tiocx_reload(cx_dev); | ||
| 476 | break; | ||
| 477 | case 3: | ||
| 478 | tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET); | ||
| 479 | break; | ||
| 480 | default: | ||
| 481 | break; | ||
| 482 | } | ||
| 483 | |||
| 484 | return count; | ||
| 485 | } | ||
| 486 | |||
| 487 | DEVICE_ATTR(cxdev_control, 0644, show_cxdev_control, store_cxdev_control); | ||
| 488 | |||
| 489 | static int __init tiocx_init(void) | ||
| 490 | { | ||
| 491 | cnodeid_t cnodeid; | ||
| 492 | int found_tiocx_device = 0; | ||
| 493 | int err; | ||
| 494 | |||
| 495 | if (!ia64_platform_is("sn2")) | ||
| 496 | return 0; | ||
| 497 | |||
| 498 | err = bus_register(&tiocx_bus_type); | ||
| 499 | if (err) | ||
| 500 | return err; | ||
| 501 | |||
| 502 | for (cnodeid = 0; cnodeid < num_cnodes; cnodeid++) { | ||
| 503 | nasid_t nasid; | ||
| 504 | int bt; | ||
| 505 | |||
| 506 | nasid = cnodeid_to_nasid(cnodeid); | ||
| 507 | |||
| 508 | if ((nasid & 0x1) && is_fpga_tio(nasid, &bt)) { | ||
| 509 | struct hubdev_info *hubdev; | ||
| 510 | struct xwidget_info *widgetp; | ||
| 511 | |||
| 512 | DBG("Found TIO at nasid 0x%x\n", nasid); | ||
| 513 | |||
| 514 | hubdev = | ||
| 515 | (struct hubdev_info *)(NODEPDA(cnodeid)->pdinfo); | ||
| 516 | |||
| 517 | widgetp = &hubdev->hdi_xwidget_info[TIOCX_CORELET]; | ||
| 518 | |||
| 519 | /* The CE hangs off of the CX port but is not an FPGA */ | ||
| 520 | if (widgetp->xwi_hwid.part_num == TIO_CE_ASIC_PARTNUM) | ||
| 521 | continue; | ||
| 522 | |||
| 523 | tio_corelet_reset(nasid, TIOCX_CORELET); | ||
| 524 | tio_conveyor_enable(nasid); | ||
| 525 | |||
| 526 | if (cx_device_register | ||
| 527 | (nasid, widgetp->xwi_hwid.part_num, | ||
| 528 | widgetp->xwi_hwid.mfg_num, hubdev, bt) < 0) | ||
| 529 | return -ENXIO; | ||
| 530 | else | ||
| 531 | found_tiocx_device++; | ||
| 532 | } | ||
| 533 | } | ||
| 534 | |||
| 535 | /* It's ok if we find zero devices. */ | ||
| 536 | DBG("found_tiocx_device= %d\n", found_tiocx_device); | ||
| 537 | |||
| 538 | return 0; | ||
| 539 | } | ||
| 540 | |||
| 541 | static int cx_remove_device(struct device * dev, void * data) | ||
| 542 | { | ||
| 543 | struct cx_dev *cx_dev = to_cx_dev(dev); | ||
| 544 | device_remove_file(dev, &dev_attr_cxdev_control); | ||
| 545 | cx_device_unregister(cx_dev); | ||
| 546 | return 0; | ||
| 547 | } | ||
| 548 | |||
| 549 | static void __exit tiocx_exit(void) | ||
| 550 | { | ||
| 551 | DBG("tiocx_exit\n"); | ||
| 552 | |||
| 553 | /* | ||
| 554 | * Unregister devices. | ||
| 555 | */ | ||
| 556 | bus_for_each_dev(&tiocx_bus_type, NULL, NULL, cx_remove_device); | ||
| 557 | bus_unregister(&tiocx_bus_type); | ||
| 558 | } | ||
| 559 | |||
| 560 | fs_initcall(tiocx_init); | ||
| 561 | module_exit(tiocx_exit); | ||
| 562 | |||
| 563 | /************************************************************************ | ||
| 564 | * Module licensing and description | ||
| 565 | ************************************************************************/ | ||
| 566 | MODULE_LICENSE("GPL"); | ||
| 567 | MODULE_AUTHOR("Bruce Losure <blosure@sgi.com>"); | ||
| 568 | MODULE_DESCRIPTION("TIOCX module"); | ||
| 569 | MODULE_SUPPORTED_DEVICE(DEVICE_NAME); | ||
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index c9fbbc6a3967..96156c729a31 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
| @@ -26,20 +26,6 @@ config DEVKMEM | |||
| 26 | kind of kernel debugging operations. | 26 | kind of kernel debugging operations. |
| 27 | When in doubt, say "N". | 27 | When in doubt, say "N". |
| 28 | 28 | ||
| 29 | config SGI_TIOCX | ||
| 30 | bool "SGI TIO CX driver support" | ||
| 31 | depends on (IA64_SGI_SN2 || IA64_GENERIC) | ||
| 32 | help | ||
| 33 | If you have an SGI Altix and you have fpga devices attached | ||
| 34 | to your TIO, say Y here, otherwise say N. | ||
| 35 | |||
| 36 | config SGI_MBCS | ||
| 37 | tristate "SGI FPGA Core Services driver support" | ||
| 38 | depends on SGI_TIOCX | ||
| 39 | help | ||
| 40 | If you have an SGI Altix with an attached SABrick | ||
| 41 | say Y or M here, otherwise say N. | ||
| 42 | |||
| 43 | source "drivers/tty/serial/Kconfig" | 29 | source "drivers/tty/serial/Kconfig" |
| 44 | source "drivers/tty/serdev/Kconfig" | 30 | source "drivers/tty/serdev/Kconfig" |
| 45 | 31 | ||
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 50835d420471..7c5ea6f9df14 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
| @@ -12,7 +12,6 @@ obj-$(CONFIG_RAW_DRIVER) += raw.o | |||
| 12 | obj-$(CONFIG_MSPEC) += mspec.o | 12 | obj-$(CONFIG_MSPEC) += mspec.o |
| 13 | obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o | 13 | obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o |
| 14 | obj-$(CONFIG_IBM_BSR) += bsr.o | 14 | obj-$(CONFIG_IBM_BSR) += bsr.o |
| 15 | obj-$(CONFIG_SGI_MBCS) += mbcs.o | ||
| 16 | 15 | ||
| 17 | obj-$(CONFIG_PRINTER) += lp.o | 16 | obj-$(CONFIG_PRINTER) += lp.o |
| 18 | 17 | ||
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c deleted file mode 100644 index 0a31b60bee7b..000000000000 --- a/drivers/char/mbcs.c +++ /dev/null | |||
| @@ -1,831 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2005 Silicon Graphics, Inc. All rights reserved. | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | * MOATB Core Services driver. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/interrupt.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/moduleparam.h> | ||
| 16 | #include <linux/types.h> | ||
| 17 | #include <linux/ioport.h> | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/notifier.h> | ||
| 20 | #include <linux/reboot.h> | ||
| 21 | #include <linux/init.h> | ||
| 22 | #include <linux/fs.h> | ||
| 23 | #include <linux/delay.h> | ||
| 24 | #include <linux/device.h> | ||
| 25 | #include <linux/mm.h> | ||
| 26 | #include <linux/uio.h> | ||
| 27 | #include <linux/mutex.h> | ||
| 28 | #include <linux/slab.h> | ||
| 29 | #include <linux/pagemap.h> | ||
| 30 | #include <asm/io.h> | ||
| 31 | #include <linux/uaccess.h> | ||
| 32 | #include <asm/pgtable.h> | ||
| 33 | #include <asm/sn/addrs.h> | ||
| 34 | #include <asm/sn/intr.h> | ||
| 35 | #include <asm/sn/tiocx.h> | ||
| 36 | #include "mbcs.h" | ||
| 37 | |||
| 38 | #define MBCS_DEBUG 0 | ||
| 39 | #if MBCS_DEBUG | ||
| 40 | #define DBG(fmt...) printk(KERN_ALERT fmt) | ||
| 41 | #else | ||
| 42 | #define DBG(fmt...) | ||
| 43 | #endif | ||
| 44 | static DEFINE_MUTEX(mbcs_mutex); | ||
| 45 | static int mbcs_major; | ||
| 46 | |||
| 47 | static LIST_HEAD(soft_list); | ||
| 48 | |||
| 49 | /* | ||
| 50 | * file operations | ||
| 51 | */ | ||
| 52 | static const struct file_operations mbcs_ops = { | ||
| 53 | .owner = THIS_MODULE, | ||
| 54 | .open = mbcs_open, | ||
| 55 | .llseek = mbcs_sram_llseek, | ||
| 56 | .read = mbcs_sram_read, | ||
| 57 | .write = mbcs_sram_write, | ||
| 58 | .mmap = mbcs_gscr_mmap, | ||
| 59 | }; | ||
| 60 | |||
| 61 | struct mbcs_callback_arg { | ||
| 62 | int minor; | ||
| 63 | struct cx_dev *cx_dev; | ||
| 64 | }; | ||
| 65 | |||
| 66 | static inline void mbcs_getdma_init(struct getdma *gdma) | ||
| 67 | { | ||
| 68 | memset(gdma, 0, sizeof(struct getdma)); | ||
| 69 | gdma->DoneIntEnable = 1; | ||
| 70 | } | ||
| 71 | |||
| 72 | static inline void mbcs_putdma_init(struct putdma *pdma) | ||
| 73 | { | ||
| 74 | memset(pdma, 0, sizeof(struct putdma)); | ||
| 75 | pdma->DoneIntEnable = 1; | ||
| 76 | } | ||
| 77 | |||
| 78 | static inline void mbcs_algo_init(struct algoblock *algo_soft) | ||
| 79 | { | ||
| 80 | memset(algo_soft, 0, sizeof(struct algoblock)); | ||
| 81 | } | ||
| 82 | |||
| 83 | static inline void mbcs_getdma_set(void *mmr, | ||
| 84 | uint64_t hostAddr, | ||
| 85 | uint64_t localAddr, | ||
| 86 | uint64_t localRamSel, | ||
| 87 | uint64_t numPkts, | ||
| 88 | uint64_t amoEnable, | ||
| 89 | uint64_t intrEnable, | ||
| 90 | uint64_t peerIO, | ||
| 91 | uint64_t amoHostDest, | ||
| 92 | uint64_t amoModType, uint64_t intrHostDest, | ||
| 93 | uint64_t intrVector) | ||
| 94 | { | ||
| 95 | union dma_control rdma_control; | ||
| 96 | union dma_amo_dest amo_dest; | ||
| 97 | union intr_dest intr_dest; | ||
| 98 | union dma_localaddr local_addr; | ||
| 99 | union dma_hostaddr host_addr; | ||
| 100 | |||
| 101 | rdma_control.dma_control_reg = 0; | ||
| 102 | amo_dest.dma_amo_dest_reg = 0; | ||
| 103 | intr_dest.intr_dest_reg = 0; | ||
| 104 | local_addr.dma_localaddr_reg = 0; | ||
| 105 | host_addr.dma_hostaddr_reg = 0; | ||
| 106 | |||
| 107 | host_addr.dma_sys_addr = hostAddr; | ||
| 108 | MBCS_MMR_SET(mmr, MBCS_RD_DMA_SYS_ADDR, host_addr.dma_hostaddr_reg); | ||
| 109 | |||
| 110 | local_addr.dma_ram_addr = localAddr; | ||
| 111 | local_addr.dma_ram_sel = localRamSel; | ||
| 112 | MBCS_MMR_SET(mmr, MBCS_RD_DMA_LOC_ADDR, local_addr.dma_localaddr_reg); | ||
| 113 | |||
| 114 | rdma_control.dma_op_length = numPkts; | ||
| 115 | rdma_control.done_amo_en = amoEnable; | ||
| 116 | rdma_control.done_int_en = intrEnable; | ||
| 117 | rdma_control.pio_mem_n = peerIO; | ||
| 118 | MBCS_MMR_SET(mmr, MBCS_RD_DMA_CTRL, rdma_control.dma_control_reg); | ||
| 119 | |||
| 120 | amo_dest.dma_amo_sys_addr = amoHostDest; | ||
| 121 | amo_dest.dma_amo_mod_type = amoModType; | ||
| 122 | MBCS_MMR_SET(mmr, MBCS_RD_DMA_AMO_DEST, amo_dest.dma_amo_dest_reg); | ||
| 123 | |||
| 124 | intr_dest.address = intrHostDest; | ||
| 125 | intr_dest.int_vector = intrVector; | ||
| 126 | MBCS_MMR_SET(mmr, MBCS_RD_DMA_INT_DEST, intr_dest.intr_dest_reg); | ||
| 127 | |||
| 128 | } | ||
| 129 | |||
| 130 | static inline void mbcs_putdma_set(void *mmr, | ||
| 131 | uint64_t hostAddr, | ||
| 132 | uint64_t localAddr, | ||
| 133 | uint64_t localRamSel, | ||
| 134 | uint64_t numPkts, | ||
| 135 | uint64_t amoEnable, | ||
| 136 | uint64_t intrEnable, | ||
| 137 | uint64_t peerIO, | ||
| 138 | uint64_t amoHostDest, | ||
| 139 | uint64_t amoModType, | ||
| 140 | uint64_t intrHostDest, uint64_t intrVector) | ||
| 141 | { | ||
| 142 | union dma_control wdma_control; | ||
| 143 | union dma_amo_dest amo_dest; | ||
| 144 | union intr_dest intr_dest; | ||
| 145 | union dma_localaddr local_addr; | ||
| 146 | union dma_hostaddr host_addr; | ||
| 147 | |||
| 148 | wdma_control.dma_control_reg = 0; | ||
| 149 | amo_dest.dma_amo_dest_reg = 0; | ||
| 150 | intr_dest.intr_dest_reg = 0; | ||
| 151 | local_addr.dma_localaddr_reg = 0; | ||
| 152 | host_addr.dma_hostaddr_reg = 0; | ||
| 153 | |||
| 154 | host_addr.dma_sys_addr = hostAddr; | ||
| 155 | MBCS_MMR_SET(mmr, MBCS_WR_DMA_SYS_ADDR, host_addr.dma_hostaddr_reg); | ||
| 156 | |||
| 157 | local_addr.dma_ram_addr = localAddr; | ||
| 158 | local_addr.dma_ram_sel = localRamSel; | ||
| 159 | MBCS_MMR_SET(mmr, MBCS_WR_DMA_LOC_ADDR, local_addr.dma_localaddr_reg); | ||
| 160 | |||
| 161 | wdma_control.dma_op_length = numPkts; | ||
| 162 | wdma_control.done_amo_en = amoEnable; | ||
| 163 | wdma_control.done_int_en = intrEnable; | ||
| 164 | wdma_control.pio_mem_n = peerIO; | ||
| 165 | MBCS_MMR_SET(mmr, MBCS_WR_DMA_CTRL, wdma_control.dma_control_reg); | ||
| 166 | |||
| 167 | amo_dest.dma_amo_sys_addr = amoHostDest; | ||
| 168 | amo_dest.dma_amo_mod_type = amoModType; | ||
| 169 | MBCS_MMR_SET(mmr, MBCS_WR_DMA_AMO_DEST, amo_dest.dma_amo_dest_reg); | ||
| 170 | |||
| 171 | intr_dest.address = intrHostDest; | ||
| 172 | intr_dest.int_vector = intrVector; | ||
| 173 | MBCS_MMR_SET(mmr, MBCS_WR_DMA_INT_DEST, intr_dest.intr_dest_reg); | ||
| 174 | |||
| 175 | } | ||
| 176 | |||
| 177 | static inline void mbcs_algo_set(void *mmr, | ||
| 178 | uint64_t amoHostDest, | ||
| 179 | uint64_t amoModType, | ||
| 180 | uint64_t intrHostDest, | ||
| 181 | uint64_t intrVector, uint64_t algoStepCount) | ||
| 182 | { | ||
| 183 | union dma_amo_dest amo_dest; | ||
| 184 | union intr_dest intr_dest; | ||
| 185 | union algo_step step; | ||
| 186 | |||
| 187 | step.algo_step_reg = 0; | ||
| 188 | intr_dest.intr_dest_reg = 0; | ||
| 189 | amo_dest.dma_amo_dest_reg = 0; | ||
| 190 | |||
| 191 | amo_dest.dma_amo_sys_addr = amoHostDest; | ||
| 192 | amo_dest.dma_amo_mod_type = amoModType; | ||
| 193 | MBCS_MMR_SET(mmr, MBCS_ALG_AMO_DEST, amo_dest.dma_amo_dest_reg); | ||
| 194 | |||
| 195 | intr_dest.address = intrHostDest; | ||
| 196 | intr_dest.int_vector = intrVector; | ||
| 197 | MBCS_MMR_SET(mmr, MBCS_ALG_INT_DEST, intr_dest.intr_dest_reg); | ||
| 198 | |||
| 199 | step.alg_step_cnt = algoStepCount; | ||
| 200 | MBCS_MMR_SET(mmr, MBCS_ALG_STEP, step.algo_step_reg); | ||
| 201 | } | ||
| 202 | |||
| 203 | static inline int mbcs_getdma_start(struct mbcs_soft *soft) | ||
| 204 | { | ||
| 205 | void *mmr_base; | ||
| 206 | struct getdma *gdma; | ||
| 207 | uint64_t numPkts; | ||
| 208 | union cm_control cm_control; | ||
| 209 | |||
| 210 | mmr_base = soft->mmr_base; | ||
| 211 | gdma = &soft->getdma; | ||
| 212 | |||
| 213 | /* check that host address got setup */ | ||
| 214 | if (!gdma->hostAddr) | ||
| 215 | return -1; | ||
| 216 | |||
| 217 | numPkts = | ||
| 218 | (gdma->bytes + (MBCS_CACHELINE_SIZE - 1)) / MBCS_CACHELINE_SIZE; | ||
| 219 | |||
| 220 | /* program engine */ | ||
| 221 | mbcs_getdma_set(mmr_base, tiocx_dma_addr(gdma->hostAddr), | ||
| 222 | gdma->localAddr, | ||
| 223 | (gdma->localAddr < MB2) ? 0 : | ||
| 224 | (gdma->localAddr < MB4) ? 1 : | ||
| 225 | (gdma->localAddr < MB6) ? 2 : 3, | ||
| 226 | numPkts, | ||
| 227 | gdma->DoneAmoEnable, | ||
| 228 | gdma->DoneIntEnable, | ||
| 229 | gdma->peerIO, | ||
| 230 | gdma->amoHostDest, | ||
| 231 | gdma->amoModType, | ||
| 232 | gdma->intrHostDest, gdma->intrVector); | ||
| 233 | |||
| 234 | /* start engine */ | ||
| 235 | cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL); | ||
| 236 | cm_control.rd_dma_go = 1; | ||
| 237 | MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg); | ||
| 238 | |||
| 239 | return 0; | ||
| 240 | |||
| 241 | } | ||
| 242 | |||
| 243 | static inline int mbcs_putdma_start(struct mbcs_soft *soft) | ||
| 244 | { | ||
| 245 | void *mmr_base; | ||
| 246 | struct putdma *pdma; | ||
| 247 | uint64_t numPkts; | ||
| 248 | union cm_control cm_control; | ||
| 249 | |||
| 250 | mmr_base = soft->mmr_base; | ||
| 251 | pdma = &soft->putdma; | ||
| 252 | |||
| 253 | /* check that host address got setup */ | ||
| 254 | if (!pdma->hostAddr) | ||
| 255 | return -1; | ||
| 256 | |||
| 257 | numPkts = | ||
| 258 | (pdma->bytes + (MBCS_CACHELINE_SIZE - 1)) / MBCS_CACHELINE_SIZE; | ||
| 259 | |||
| 260 | /* program engine */ | ||
| 261 | mbcs_putdma_set(mmr_base, tiocx_dma_addr(pdma->hostAddr), | ||
| 262 | pdma->localAddr, | ||
| 263 | (pdma->localAddr < MB2) ? 0 : | ||
| 264 | (pdma->localAddr < MB4) ? 1 : | ||
| 265 | (pdma->localAddr < MB6) ? 2 : 3, | ||
| 266 | numPkts, | ||
| 267 | pdma->DoneAmoEnable, | ||
| 268 | pdma->DoneIntEnable, | ||
| 269 | pdma->peerIO, | ||
| 270 | pdma->amoHostDest, | ||
| 271 | pdma->amoModType, | ||
| 272 | pdma->intrHostDest, pdma->intrVector); | ||
| 273 | |||
| 274 | /* start engine */ | ||
| 275 | cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL); | ||
| 276 | cm_control.wr_dma_go = 1; | ||
| 277 | MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg); | ||
| 278 | |||
| 279 | return 0; | ||
| 280 | |||
| 281 | } | ||
| 282 | |||
| 283 | static inline int mbcs_algo_start(struct mbcs_soft *soft) | ||
| 284 | { | ||
| 285 | struct algoblock *algo_soft = &soft->algo; | ||
| 286 | void *mmr_base = soft->mmr_base; | ||
| 287 | union cm_control cm_control; | ||
| 288 | |||
| 289 | if (mutex_lock_interruptible(&soft->algolock)) | ||
| 290 | return -ERESTARTSYS; | ||
| 291 | |||
| 292 | atomic_set(&soft->algo_done, 0); | ||
| 293 | |||
| 294 | mbcs_algo_set(mmr_base, | ||
| 295 | algo_soft->amoHostDest, | ||
| 296 | algo_soft->amoModType, | ||
| 297 | algo_soft->intrHostDest, | ||
| 298 | algo_soft->intrVector, algo_soft->algoStepCount); | ||
| 299 | |||
| 300 | /* start algorithm */ | ||
| 301 | cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL); | ||
| 302 | cm_control.alg_done_int_en = 1; | ||
| 303 | cm_control.alg_go = 1; | ||
| 304 | MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg); | ||
| 305 | |||
| 306 | mutex_unlock(&soft->algolock); | ||
| 307 | |||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | |||
| 311 | static inline ssize_t | ||
| 312 | do_mbcs_sram_dmawrite(struct mbcs_soft *soft, uint64_t hostAddr, | ||
| 313 | size_t len, loff_t * off) | ||
| 314 | { | ||
| 315 | int rv = 0; | ||
| 316 | |||
| 317 | if (mutex_lock_interruptible(&soft->dmawritelock)) | ||
| 318 | return -ERESTARTSYS; | ||
| 319 | |||
| 320 | atomic_set(&soft->dmawrite_done, 0); | ||
| 321 | |||
| 322 | soft->putdma.hostAddr = hostAddr; | ||
| 323 | soft->putdma.localAddr = *off; | ||
| 324 | soft->putdma.bytes = len; | ||
| 325 | |||
| 326 | if (mbcs_putdma_start(soft) < 0) { | ||
| 327 | DBG(KERN_ALERT "do_mbcs_sram_dmawrite: " | ||
| 328 | "mbcs_putdma_start failed\n"); | ||
| 329 | rv = -EAGAIN; | ||
| 330 | goto dmawrite_exit; | ||
| 331 | } | ||
| 332 | |||
| 333 | if (wait_event_interruptible(soft->dmawrite_queue, | ||
| 334 | atomic_read(&soft->dmawrite_done))) { | ||
| 335 | rv = -ERESTARTSYS; | ||
| 336 | goto dmawrite_exit; | ||
| 337 | } | ||
| 338 | |||
| 339 | rv = len; | ||
| 340 | *off += len; | ||
| 341 | |||
| 342 | dmawrite_exit: | ||
| 343 | mutex_unlock(&soft->dmawritelock); | ||
| 344 | |||
| 345 | return rv; | ||
| 346 | } | ||
| 347 | |||
| 348 | static inline ssize_t | ||
| 349 | do_mbcs_sram_dmaread(struct mbcs_soft *soft, uint64_t hostAddr, | ||
| 350 | size_t len, loff_t * off) | ||
| 351 | { | ||
| 352 | int rv = 0; | ||
| 353 | |||
| 354 | if (mutex_lock_interruptible(&soft->dmareadlock)) | ||
| 355 | return -ERESTARTSYS; | ||
| 356 | |||
| 357 | atomic_set(&soft->dmawrite_done, 0); | ||
| 358 | |||
| 359 | soft->getdma.hostAddr = hostAddr; | ||
| 360 | soft->getdma.localAddr = *off; | ||
| 361 | soft->getdma.bytes = len; | ||
| 362 | |||
| 363 | if (mbcs_getdma_start(soft) < 0) { | ||
| 364 | DBG(KERN_ALERT "mbcs_strategy: mbcs_getdma_start failed\n"); | ||
| 365 | rv = -EAGAIN; | ||
| 366 | goto dmaread_exit; | ||
| 367 | } | ||
| 368 | |||
| 369 | if (wait_event_interruptible(soft->dmaread_queue, | ||
| 370 | atomic_read(&soft->dmaread_done))) { | ||
| 371 | rv = -ERESTARTSYS; | ||
| 372 | goto dmaread_exit; | ||
| 373 | } | ||
| 374 | |||
| 375 | rv = len; | ||
| 376 | *off += len; | ||
| 377 | |||
| 378 | dmaread_exit: | ||
| 379 | mutex_unlock(&soft->dmareadlock); | ||
| 380 | |||
| 381 | return rv; | ||
| 382 | } | ||
| 383 | |||
| 384 | static int mbcs_open(struct inode *ip, struct file *fp) | ||
| 385 | { | ||
| 386 | struct mbcs_soft *soft; | ||
| 387 | int minor; | ||
| 388 | |||
| 389 | mutex_lock(&mbcs_mutex); | ||
| 390 | minor = iminor(ip); | ||
| 391 | |||
| 392 | /* Nothing protects access to this list... */ | ||
| 393 | list_for_each_entry(soft, &soft_list, list) { | ||
| 394 | if (soft->nasid == minor) { | ||
| 395 | fp->private_data = soft->cxdev; | ||
| 396 | mutex_unlock(&mbcs_mutex); | ||
| 397 | return 0; | ||
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 401 | mutex_unlock(&mbcs_mutex); | ||
| 402 | return -ENODEV; | ||
| 403 | } | ||
| 404 | |||
| 405 | static ssize_t mbcs_sram_read(struct file * fp, char __user *buf, size_t len, loff_t * off) | ||
| 406 | { | ||
| 407 | struct cx_dev *cx_dev = fp->private_data; | ||
| 408 | struct mbcs_soft *soft = cx_dev->soft; | ||
| 409 | uint64_t hostAddr; | ||
| 410 | int rv = 0; | ||
| 411 | |||
| 412 | hostAddr = __get_dma_pages(GFP_KERNEL, get_order(len)); | ||
| 413 | if (hostAddr == 0) | ||
| 414 | return -ENOMEM; | ||
| 415 | |||
| 416 | rv = do_mbcs_sram_dmawrite(soft, hostAddr, len, off); | ||
| 417 | if (rv < 0) | ||
| 418 | goto exit; | ||
| 419 | |||
| 420 | if (copy_to_user(buf, (void *)hostAddr, len)) | ||
| 421 | rv = -EFAULT; | ||
| 422 | |||
| 423 | exit: | ||
| 424 | free_pages(hostAddr, get_order(len)); | ||
| 425 | |||
| 426 | return rv; | ||
| 427 | } | ||
| 428 | |||
| 429 | static ssize_t | ||
| 430 | mbcs_sram_write(struct file * fp, const char __user *buf, size_t len, loff_t * off) | ||
| 431 | { | ||
| 432 | struct cx_dev *cx_dev = fp->private_data; | ||
| 433 | struct mbcs_soft *soft = cx_dev->soft; | ||
| 434 | uint64_t hostAddr; | ||
| 435 | int rv = 0; | ||
| 436 | |||
| 437 | hostAddr = __get_dma_pages(GFP_KERNEL, get_order(len)); | ||
| 438 | if (hostAddr == 0) | ||
| 439 | return -ENOMEM; | ||
| 440 | |||
| 441 | if (copy_from_user((void *)hostAddr, buf, len)) { | ||
| 442 | rv = -EFAULT; | ||
| 443 | goto exit; | ||
| 444 | } | ||
| 445 | |||
| 446 | rv = do_mbcs_sram_dmaread(soft, hostAddr, len, off); | ||
| 447 | |||
| 448 | exit: | ||
| 449 | free_pages(hostAddr, get_order(len)); | ||
| 450 | |||
| 451 | return rv; | ||
| 452 | } | ||
| 453 | |||
| 454 | static loff_t mbcs_sram_llseek(struct file * filp, loff_t off, int whence) | ||
| 455 | { | ||
| 456 | return generic_file_llseek_size(filp, off, whence, MAX_LFS_FILESIZE, | ||
| 457 | MBCS_SRAM_SIZE); | ||
| 458 | } | ||
| 459 | |||
| 460 | static uint64_t mbcs_pioaddr(struct mbcs_soft *soft, uint64_t offset) | ||
| 461 | { | ||
| 462 | uint64_t mmr_base; | ||
| 463 | |||
| 464 | mmr_base = (uint64_t) (soft->mmr_base + offset); | ||
| 465 | |||
| 466 | return mmr_base; | ||
| 467 | } | ||
| 468 | |||
| 469 | static void mbcs_debug_pioaddr_set(struct mbcs_soft *soft) | ||
| 470 | { | ||
| 471 | soft->debug_addr = mbcs_pioaddr(soft, MBCS_DEBUG_START); | ||
| 472 | } | ||
| 473 | |||
| 474 | static void mbcs_gscr_pioaddr_set(struct mbcs_soft *soft) | ||
| 475 | { | ||
| 476 | soft->gscr_addr = mbcs_pioaddr(soft, MBCS_GSCR_START); | ||
| 477 | } | ||
| 478 | |||
| 479 | static int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma) | ||
| 480 | { | ||
| 481 | struct cx_dev *cx_dev = fp->private_data; | ||
| 482 | struct mbcs_soft *soft = cx_dev->soft; | ||
| 483 | |||
| 484 | if (vma->vm_pgoff != 0) | ||
| 485 | return -EINVAL; | ||
| 486 | |||
| 487 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
| 488 | |||
| 489 | /* Remap-pfn-range will mark the range VM_IO */ | ||
| 490 | if (remap_pfn_range(vma, | ||
| 491 | vma->vm_start, | ||
| 492 | __pa(soft->gscr_addr) >> PAGE_SHIFT, | ||
| 493 | PAGE_SIZE, | ||
| 494 | vma->vm_page_prot)) | ||
| 495 | return -EAGAIN; | ||
| 496 | |||
| 497 | return 0; | ||
| 498 | } | ||
| 499 | |||
| 500 | /** | ||
| 501 | * mbcs_completion_intr_handler - Primary completion handler. | ||
| 502 | * @irq: irq | ||
| 503 | * @arg: soft struct for device | ||
| 504 | * | ||
| 505 | */ | ||
| 506 | static irqreturn_t | ||
| 507 | mbcs_completion_intr_handler(int irq, void *arg) | ||
| 508 | { | ||
| 509 | struct mbcs_soft *soft = (struct mbcs_soft *)arg; | ||
| 510 | void *mmr_base; | ||
| 511 | union cm_status cm_status; | ||
| 512 | union cm_control cm_control; | ||
| 513 | |||
| 514 | mmr_base = soft->mmr_base; | ||
| 515 | cm_status.cm_status_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_STATUS); | ||
| 516 | |||
| 517 | if (cm_status.rd_dma_done) { | ||
| 518 | /* stop dma-read engine, clear status */ | ||
| 519 | cm_control.cm_control_reg = | ||
| 520 | MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL); | ||
| 521 | cm_control.rd_dma_clr = 1; | ||
| 522 | MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, | ||
| 523 | cm_control.cm_control_reg); | ||
| 524 | atomic_set(&soft->dmaread_done, 1); | ||
| 525 | wake_up(&soft->dmaread_queue); | ||
| 526 | } | ||
| 527 | if (cm_status.wr_dma_done) { | ||
| 528 | /* stop dma-write engine, clear status */ | ||
| 529 | cm_control.cm_control_reg = | ||
| 530 | MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL); | ||
| 531 | cm_control.wr_dma_clr = 1; | ||
| 532 | MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, | ||
| 533 | cm_control.cm_control_reg); | ||
| 534 | atomic_set(&soft->dmawrite_done, 1); | ||
| 535 | wake_up(&soft->dmawrite_queue); | ||
| 536 | } | ||
| 537 | if (cm_status.alg_done) { | ||
| 538 | /* clear status */ | ||
| 539 | cm_control.cm_control_reg = | ||
| 540 | MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL); | ||
| 541 | cm_control.alg_done_clr = 1; | ||
| 542 | MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, | ||
| 543 | cm_control.cm_control_reg); | ||
| 544 | atomic_set(&soft->algo_done, 1); | ||
| 545 | wake_up(&soft->algo_queue); | ||
| 546 | } | ||
| 547 | |||
| 548 | return IRQ_HANDLED; | ||
| 549 | } | ||
| 550 | |||
| 551 | /** | ||
| 552 | * mbcs_intr_alloc - Allocate interrupts. | ||
| 553 | * @dev: device pointer | ||
| 554 | * | ||
| 555 | */ | ||
| 556 | static int mbcs_intr_alloc(struct cx_dev *dev) | ||
| 557 | { | ||
| 558 | struct sn_irq_info *sn_irq; | ||
| 559 | struct mbcs_soft *soft; | ||
| 560 | struct getdma *getdma; | ||
| 561 | struct putdma *putdma; | ||
| 562 | struct algoblock *algo; | ||
| 563 | |||
| 564 | soft = dev->soft; | ||
| 565 | getdma = &soft->getdma; | ||
| 566 | putdma = &soft->putdma; | ||
| 567 | algo = &soft->algo; | ||
| 568 | |||
| 569 | soft->get_sn_irq = NULL; | ||
| 570 | soft->put_sn_irq = NULL; | ||
| 571 | soft->algo_sn_irq = NULL; | ||
| 572 | |||
| 573 | sn_irq = tiocx_irq_alloc(dev->cx_id.nasid, TIOCX_CORELET, -1, -1, -1); | ||
| 574 | if (sn_irq == NULL) | ||
| 575 | return -EAGAIN; | ||
| 576 | soft->get_sn_irq = sn_irq; | ||
| 577 | getdma->intrHostDest = sn_irq->irq_xtalkaddr; | ||
| 578 | getdma->intrVector = sn_irq->irq_irq; | ||
| 579 | if (request_irq(sn_irq->irq_irq, | ||
| 580 | (void *)mbcs_completion_intr_handler, IRQF_SHARED, | ||
| 581 | "MBCS get intr", (void *)soft)) { | ||
| 582 | tiocx_irq_free(soft->get_sn_irq); | ||
| 583 | return -EAGAIN; | ||
| 584 | } | ||
| 585 | |||
| 586 | sn_irq = tiocx_irq_alloc(dev->cx_id.nasid, TIOCX_CORELET, -1, -1, -1); | ||
| 587 | if (sn_irq == NULL) { | ||
| 588 | free_irq(soft->get_sn_irq->irq_irq, soft); | ||
| 589 | tiocx_irq_free(soft->get_sn_irq); | ||
| 590 | return -EAGAIN; | ||
| 591 | } | ||
| 592 | soft->put_sn_irq = sn_irq; | ||
| 593 | putdma->intrHostDest = sn_irq->irq_xtalkaddr; | ||
| 594 | putdma->intrVector = sn_irq->irq_irq; | ||
| 595 | if (request_irq(sn_irq->irq_irq, | ||
| 596 | (void *)mbcs_completion_intr_handler, IRQF_SHARED, | ||
| 597 | "MBCS put intr", (void *)soft)) { | ||
| 598 | tiocx_irq_free(soft->put_sn_irq); | ||
| 599 | free_irq(soft->get_sn_irq->irq_irq, soft); | ||
| 600 | tiocx_irq_free(soft->get_sn_irq); | ||
| 601 | return -EAGAIN; | ||
| 602 | } | ||
| 603 | |||
| 604 | sn_irq = tiocx_irq_alloc(dev->cx_id.nasid, TIOCX_CORELET, -1, -1, -1); | ||
| 605 | if (sn_irq == NULL) { | ||
| 606 | free_irq(soft->put_sn_irq->irq_irq, soft); | ||
| 607 | tiocx_irq_free(soft->put_sn_irq); | ||
| 608 | free_irq(soft->get_sn_irq->irq_irq, soft); | ||
| 609 | tiocx_irq_free(soft->get_sn_irq); | ||
| 610 | return -EAGAIN; | ||
| 611 | } | ||
| 612 | soft->algo_sn_irq = sn_irq; | ||
| 613 | algo->intrHostDest = sn_irq->irq_xtalkaddr; | ||
| 614 | algo->intrVector = sn_irq->irq_irq; | ||
| 615 | if (request_irq(sn_irq->irq_irq, | ||
| 616 | (void *)mbcs_completion_intr_handler, IRQF_SHARED, | ||
| 617 | "MBCS algo intr", (void *)soft)) { | ||
| 618 | tiocx_irq_free(soft->algo_sn_irq); | ||
| 619 | free_irq(soft->put_sn_irq->irq_irq, soft); | ||
| 620 | tiocx_irq_free(soft->put_sn_irq); | ||
| 621 | free_irq(soft->get_sn_irq->irq_irq, soft); | ||
| 622 | tiocx_irq_free(soft->get_sn_irq); | ||
| 623 | return -EAGAIN; | ||
| 624 | } | ||
| 625 | |||
| 626 | return 0; | ||
| 627 | } | ||
| 628 | |||
| 629 | /** | ||
| 630 | * mbcs_intr_dealloc - Remove interrupts. | ||
| 631 | * @dev: device pointer | ||
| 632 | * | ||
| 633 | */ | ||
| 634 | static void mbcs_intr_dealloc(struct cx_dev *dev) | ||
| 635 | { | ||
| 636 | struct mbcs_soft *soft; | ||
| 637 | |||
| 638 | soft = dev->soft; | ||
| 639 | |||
| 640 | free_irq(soft->get_sn_irq->irq_irq, soft); | ||
| 641 | tiocx_irq_free(soft->get_sn_irq); | ||
| 642 | free_irq(soft->put_sn_irq->irq_irq, soft); | ||
| 643 | tiocx_irq_free(soft->put_sn_irq); | ||
| 644 | free_irq(soft->algo_sn_irq->irq_irq, soft); | ||
| 645 | tiocx_irq_free(soft->algo_sn_irq); | ||
| 646 | } | ||
| 647 | |||
| 648 | static inline int mbcs_hw_init(struct mbcs_soft *soft) | ||
| 649 | { | ||
| 650 | void *mmr_base = soft->mmr_base; | ||
| 651 | union cm_control cm_control; | ||
| 652 | union cm_req_timeout cm_req_timeout; | ||
| 653 | uint64_t err_stat; | ||
| 654 | |||
| 655 | cm_req_timeout.cm_req_timeout_reg = | ||
| 656 | MBCS_MMR_GET(mmr_base, MBCS_CM_REQ_TOUT); | ||
| 657 | |||
| 658 | cm_req_timeout.time_out = MBCS_CM_CONTROL_REQ_TOUT_MASK; | ||
| 659 | MBCS_MMR_SET(mmr_base, MBCS_CM_REQ_TOUT, | ||
| 660 | cm_req_timeout.cm_req_timeout_reg); | ||
| 661 | |||
| 662 | mbcs_gscr_pioaddr_set(soft); | ||
| 663 | mbcs_debug_pioaddr_set(soft); | ||
| 664 | |||
| 665 | /* clear errors */ | ||
| 666 | err_stat = MBCS_MMR_GET(mmr_base, MBCS_CM_ERR_STAT); | ||
| 667 | MBCS_MMR_SET(mmr_base, MBCS_CM_CLR_ERR_STAT, err_stat); | ||
| 668 | MBCS_MMR_ZERO(mmr_base, MBCS_CM_ERROR_DETAIL1); | ||
| 669 | |||
| 670 | /* enable interrupts */ | ||
| 671 | /* turn off 2^23 (INT_EN_PIO_REQ_ADDR_INV) */ | ||
| 672 | MBCS_MMR_SET(mmr_base, MBCS_CM_ERR_INT_EN, 0x3ffffff7e00ffUL); | ||
| 673 | |||
| 674 | /* arm status regs and clear engines */ | ||
| 675 | cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL); | ||
| 676 | cm_control.rearm_stat_regs = 1; | ||
| 677 | cm_control.alg_clr = 1; | ||
| 678 | cm_control.wr_dma_clr = 1; | ||
| 679 | cm_control.rd_dma_clr = 1; | ||
| 680 | |||
| 681 | MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg); | ||
| 682 | |||
| 683 | return 0; | ||
| 684 | } | ||
| 685 | |||
| 686 | static ssize_t show_algo(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 687 | { | ||
| 688 | struct cx_dev *cx_dev = to_cx_dev(dev); | ||
| 689 | struct mbcs_soft *soft = cx_dev->soft; | ||
| 690 | uint64_t debug0; | ||
| 691 | |||
| 692 | /* | ||
| 693 | * By convention, the first debug register contains the | ||
| 694 | * algorithm number and revision. | ||
| 695 | */ | ||
| 696 | debug0 = *(uint64_t *) soft->debug_addr; | ||
| 697 | |||
| 698 | return sprintf(buf, "0x%x 0x%x\n", | ||
| 699 | upper_32_bits(debug0), lower_32_bits(debug0)); | ||
| 700 | } | ||
| 701 | |||
| 702 | static ssize_t store_algo(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | ||
| 703 | { | ||
| 704 | int n; | ||
| 705 | struct cx_dev *cx_dev = to_cx_dev(dev); | ||
| 706 | struct mbcs_soft *soft = cx_dev->soft; | ||
| 707 | |||
| 708 | if (count <= 0) | ||
| 709 | return 0; | ||
| 710 | |||
| 711 | n = simple_strtoul(buf, NULL, 0); | ||
| 712 | |||
| 713 | if (n == 1) { | ||
| 714 | mbcs_algo_start(soft); | ||
| 715 | if (wait_event_interruptible(soft->algo_queue, | ||
| 716 | atomic_read(&soft->algo_done))) | ||
| 717 | return -ERESTARTSYS; | ||
| 718 | } | ||
| 719 | |||
| 720 | return count; | ||
| 721 | } | ||
| 722 | |||
| 723 | DEVICE_ATTR(algo, 0644, show_algo, store_algo); | ||
| 724 | |||
| 725 | /** | ||
| 726 | * mbcs_probe - Initialize for device | ||
| 727 | * @dev: device pointer | ||
| 728 | * @device_id: id table pointer | ||
| 729 | * | ||
| 730 | */ | ||
| 731 | static int mbcs_probe(struct cx_dev *dev, const struct cx_device_id *id) | ||
| 732 | { | ||
| 733 | struct mbcs_soft *soft; | ||
| 734 | |||
| 735 | dev->soft = NULL; | ||
| 736 | |||
| 737 | soft = kzalloc(sizeof(struct mbcs_soft), GFP_KERNEL); | ||
| 738 | if (soft == NULL) | ||
| 739 | return -ENOMEM; | ||
| 740 | |||
| 741 | soft->nasid = dev->cx_id.nasid; | ||
| 742 | list_add(&soft->list, &soft_list); | ||
| 743 | soft->mmr_base = (void *)tiocx_swin_base(dev->cx_id.nasid); | ||
| 744 | dev->soft = soft; | ||
| 745 | soft->cxdev = dev; | ||
| 746 | |||
| 747 | init_waitqueue_head(&soft->dmawrite_queue); | ||
| 748 | init_waitqueue_head(&soft->dmaread_queue); | ||
| 749 | init_waitqueue_head(&soft->algo_queue); | ||
| 750 | |||
| 751 | mutex_init(&soft->dmawritelock); | ||
| 752 | mutex_init(&soft->dmareadlock); | ||
| 753 | mutex_init(&soft->algolock); | ||
| 754 | |||
| 755 | mbcs_getdma_init(&soft->getdma); | ||
| 756 | mbcs_putdma_init(&soft->putdma); | ||
| 757 | mbcs_algo_init(&soft->algo); | ||
| 758 | |||
| 759 | mbcs_hw_init(soft); | ||
| 760 | |||
| 761 | /* Allocate interrupts */ | ||
| 762 | mbcs_intr_alloc(dev); | ||
| 763 | |||
| 764 | device_create_file(&dev->dev, &dev_attr_algo); | ||
| 765 | |||
| 766 | return 0; | ||
| 767 | } | ||
| 768 | |||
| 769 | static int mbcs_remove(struct cx_dev *dev) | ||
| 770 | { | ||
| 771 | if (dev->soft) { | ||
| 772 | mbcs_intr_dealloc(dev); | ||
| 773 | kfree(dev->soft); | ||
| 774 | } | ||
| 775 | |||
| 776 | device_remove_file(&dev->dev, &dev_attr_algo); | ||
| 777 | |||
| 778 | return 0; | ||
| 779 | } | ||
| 780 | |||
| 781 | static const struct cx_device_id mbcs_id_table[] = { | ||
| 782 | { | ||
| 783 | .part_num = MBCS_PART_NUM, | ||
| 784 | .mfg_num = MBCS_MFG_NUM, | ||
| 785 | }, | ||
| 786 | { | ||
| 787 | .part_num = MBCS_PART_NUM_ALG0, | ||
| 788 | .mfg_num = MBCS_MFG_NUM, | ||
| 789 | }, | ||
| 790 | {0, 0} | ||
| 791 | }; | ||
| 792 | |||
| 793 | MODULE_DEVICE_TABLE(cx, mbcs_id_table); | ||
| 794 | |||
| 795 | static struct cx_drv mbcs_driver = { | ||
| 796 | .name = DEVICE_NAME, | ||
| 797 | .id_table = mbcs_id_table, | ||
| 798 | .probe = mbcs_probe, | ||
| 799 | .remove = mbcs_remove, | ||
| 800 | }; | ||
| 801 | |||
| 802 | static void __exit mbcs_exit(void) | ||
| 803 | { | ||
| 804 | unregister_chrdev(mbcs_major, DEVICE_NAME); | ||
| 805 | cx_driver_unregister(&mbcs_driver); | ||
| 806 | } | ||
| 807 | |||
| 808 | static int __init mbcs_init(void) | ||
| 809 | { | ||
| 810 | int rv; | ||
| 811 | |||
| 812 | if (!ia64_platform_is("sn2")) | ||
| 813 | return -ENODEV; | ||
| 814 | |||
| 815 | // Put driver into chrdevs[]. Get major number. | ||
| 816 | rv = register_chrdev(mbcs_major, DEVICE_NAME, &mbcs_ops); | ||
| 817 | if (rv < 0) { | ||
| 818 | DBG(KERN_ALERT "mbcs_init: can't get major number. %d\n", rv); | ||
| 819 | return rv; | ||
| 820 | } | ||
| 821 | mbcs_major = rv; | ||
| 822 | |||
| 823 | return cx_driver_register(&mbcs_driver); | ||
| 824 | } | ||
| 825 | |||
| 826 | module_init(mbcs_init); | ||
| 827 | module_exit(mbcs_exit); | ||
| 828 | |||
| 829 | MODULE_AUTHOR("Bruce Losure <blosure@sgi.com>"); | ||
| 830 | MODULE_DESCRIPTION("Driver for MOATB Core Services"); | ||
| 831 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/mbcs.h b/drivers/char/mbcs.h deleted file mode 100644 index 1a36884c48b5..000000000000 --- a/drivers/char/mbcs.h +++ /dev/null | |||
| @@ -1,553 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2005 Silicon Graphics, Inc. All rights reserved. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __MBCS_H__ | ||
| 10 | #define __MBCS_H__ | ||
| 11 | |||
| 12 | /* | ||
| 13 | * General macros | ||
| 14 | */ | ||
| 15 | #define MB (1024*1024) | ||
| 16 | #define MB2 (2*MB) | ||
| 17 | #define MB4 (4*MB) | ||
| 18 | #define MB6 (6*MB) | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Offsets and masks | ||
| 22 | */ | ||
| 23 | #define MBCS_CM_ID 0x0000 /* Identification */ | ||
| 24 | #define MBCS_CM_STATUS 0x0008 /* Status */ | ||
| 25 | #define MBCS_CM_ERROR_DETAIL1 0x0010 /* Error Detail1 */ | ||
| 26 | #define MBCS_CM_ERROR_DETAIL2 0x0018 /* Error Detail2 */ | ||
| 27 | #define MBCS_CM_CONTROL 0x0020 /* Control */ | ||
| 28 | #define MBCS_CM_REQ_TOUT 0x0028 /* Request Time-out */ | ||
| 29 | #define MBCS_CM_ERR_INT_DEST 0x0038 /* Error Interrupt Destination */ | ||
| 30 | #define MBCS_CM_TARG_FL 0x0050 /* Target Flush */ | ||
| 31 | #define MBCS_CM_ERR_STAT 0x0060 /* Error Status */ | ||
| 32 | #define MBCS_CM_CLR_ERR_STAT 0x0068 /* Clear Error Status */ | ||
| 33 | #define MBCS_CM_ERR_INT_EN 0x0070 /* Error Interrupt Enable */ | ||
| 34 | #define MBCS_RD_DMA_SYS_ADDR 0x0100 /* Read DMA System Address */ | ||
| 35 | #define MBCS_RD_DMA_LOC_ADDR 0x0108 /* Read DMA Local Address */ | ||
| 36 | #define MBCS_RD_DMA_CTRL 0x0110 /* Read DMA Control */ | ||
| 37 | #define MBCS_RD_DMA_AMO_DEST 0x0118 /* Read DMA AMO Destination */ | ||
| 38 | #define MBCS_RD_DMA_INT_DEST 0x0120 /* Read DMA Interrupt Destination */ | ||
| 39 | #define MBCS_RD_DMA_AUX_STAT 0x0130 /* Read DMA Auxiliary Status */ | ||
| 40 | #define MBCS_WR_DMA_SYS_ADDR 0x0200 /* Write DMA System Address */ | ||
| 41 | #define MBCS_WR_DMA_LOC_ADDR 0x0208 /* Write DMA Local Address */ | ||
| 42 | #define MBCS_WR_DMA_CTRL 0x0210 /* Write DMA Control */ | ||
| 43 | #define MBCS_WR_DMA_AMO_DEST 0x0218 /* Write DMA AMO Destination */ | ||
| 44 | #define MBCS_WR_DMA_INT_DEST 0x0220 /* Write DMA Interrupt Destination */ | ||
| 45 | #define MBCS_WR_DMA_AUX_STAT 0x0230 /* Write DMA Auxiliary Status */ | ||
| 46 | #define MBCS_ALG_AMO_DEST 0x0300 /* Algorithm AMO Destination */ | ||
| 47 | #define MBCS_ALG_INT_DEST 0x0308 /* Algorithm Interrupt Destination */ | ||
| 48 | #define MBCS_ALG_OFFSETS 0x0310 | ||
| 49 | #define MBCS_ALG_STEP 0x0318 /* Algorithm Step */ | ||
| 50 | |||
| 51 | #define MBCS_GSCR_START 0x0000000 | ||
| 52 | #define MBCS_DEBUG_START 0x0100000 | ||
| 53 | #define MBCS_RAM0_START 0x0200000 | ||
| 54 | #define MBCS_RAM1_START 0x0400000 | ||
| 55 | #define MBCS_RAM2_START 0x0600000 | ||
| 56 | |||
| 57 | #define MBCS_CM_CONTROL_REQ_TOUT_MASK 0x0000000000ffffffUL | ||
| 58 | //#define PIO_BASE_ADDR_BASE_OFFSET_MASK 0x00fffffffff00000UL | ||
| 59 | |||
| 60 | #define MBCS_SRAM_SIZE (1024*1024) | ||
| 61 | #define MBCS_CACHELINE_SIZE 128 | ||
| 62 | |||
| 63 | /* | ||
| 64 | * MMR get's and put's | ||
| 65 | */ | ||
| 66 | #define MBCS_MMR_ADDR(mmr_base, offset)((uint64_t *)(mmr_base + offset)) | ||
| 67 | #define MBCS_MMR_SET(mmr_base, offset, value) { \ | ||
| 68 | uint64_t *mbcs_mmr_set_u64p, readback; \ | ||
| 69 | mbcs_mmr_set_u64p = (uint64_t *)(mmr_base + offset); \ | ||
| 70 | *mbcs_mmr_set_u64p = value; \ | ||
| 71 | readback = *mbcs_mmr_set_u64p; \ | ||
| 72 | } | ||
| 73 | #define MBCS_MMR_GET(mmr_base, offset) *(uint64_t *)(mmr_base + offset) | ||
| 74 | #define MBCS_MMR_ZERO(mmr_base, offset) MBCS_MMR_SET(mmr_base, offset, 0) | ||
| 75 | |||
| 76 | /* | ||
| 77 | * MBCS mmr structures | ||
| 78 | */ | ||
| 79 | union cm_id { | ||
| 80 | uint64_t cm_id_reg; | ||
| 81 | struct { | ||
| 82 | uint64_t always_one:1, // 0 | ||
| 83 | mfg_id:11, // 11:1 | ||
| 84 | part_num:16, // 27:12 | ||
| 85 | bitstream_rev:8, // 35:28 | ||
| 86 | :28; // 63:36 | ||
| 87 | }; | ||
| 88 | }; | ||
| 89 | |||
| 90 | union cm_status { | ||
| 91 | uint64_t cm_status_reg; | ||
| 92 | struct { | ||
| 93 | uint64_t pending_reads:8, // 7:0 | ||
| 94 | pending_writes:8, // 15:8 | ||
| 95 | ice_rsp_credits:8, // 23:16 | ||
| 96 | ice_req_credits:8, // 31:24 | ||
| 97 | cm_req_credits:8, // 39:32 | ||
| 98 | :1, // 40 | ||
| 99 | rd_dma_in_progress:1, // 41 | ||
| 100 | rd_dma_done:1, // 42 | ||
| 101 | :1, // 43 | ||
| 102 | wr_dma_in_progress:1, // 44 | ||
| 103 | wr_dma_done:1, // 45 | ||
| 104 | alg_waiting:1, // 46 | ||
| 105 | alg_pipe_running:1, // 47 | ||
| 106 | alg_done:1, // 48 | ||
| 107 | :3, // 51:49 | ||
| 108 | pending_int_reqs:8, // 59:52 | ||
| 109 | :3, // 62:60 | ||
| 110 | alg_half_speed_sel:1; // 63 | ||
| 111 | }; | ||
| 112 | }; | ||
| 113 | |||
| 114 | union cm_error_detail1 { | ||
| 115 | uint64_t cm_error_detail1_reg; | ||
| 116 | struct { | ||
| 117 | uint64_t packet_type:4, // 3:0 | ||
| 118 | source_id:2, // 5:4 | ||
| 119 | data_size:2, // 7:6 | ||
| 120 | tnum:8, // 15:8 | ||
| 121 | byte_enable:8, // 23:16 | ||
| 122 | gfx_cred:8, // 31:24 | ||
| 123 | read_type:2, // 33:32 | ||
| 124 | pio_or_memory:1, // 34 | ||
| 125 | head_cw_error:1, // 35 | ||
| 126 | :12, // 47:36 | ||
| 127 | head_error_bit:1, // 48 | ||
| 128 | data_error_bit:1, // 49 | ||
| 129 | :13, // 62:50 | ||
| 130 | valid:1; // 63 | ||
| 131 | }; | ||
| 132 | }; | ||
| 133 | |||
| 134 | union cm_error_detail2 { | ||
| 135 | uint64_t cm_error_detail2_reg; | ||
| 136 | struct { | ||
| 137 | uint64_t address:56, // 55:0 | ||
| 138 | :8; // 63:56 | ||
| 139 | }; | ||
| 140 | }; | ||
| 141 | |||
| 142 | union cm_control { | ||
| 143 | uint64_t cm_control_reg; | ||
| 144 | struct { | ||
| 145 | uint64_t cm_id:2, // 1:0 | ||
| 146 | :2, // 3:2 | ||
| 147 | max_trans:5, // 8:4 | ||
| 148 | :3, // 11:9 | ||
| 149 | address_mode:1, // 12 | ||
| 150 | :7, // 19:13 | ||
| 151 | credit_limit:8, // 27:20 | ||
| 152 | :5, // 32:28 | ||
| 153 | rearm_stat_regs:1, // 33 | ||
| 154 | prescalar_byp:1, // 34 | ||
| 155 | force_gap_war:1, // 35 | ||
| 156 | rd_dma_go:1, // 36 | ||
| 157 | wr_dma_go:1, // 37 | ||
| 158 | alg_go:1, // 38 | ||
| 159 | rd_dma_clr:1, // 39 | ||
| 160 | wr_dma_clr:1, // 40 | ||
| 161 | alg_clr:1, // 41 | ||
| 162 | :2, // 43:42 | ||
| 163 | alg_wait_step:1, // 44 | ||
| 164 | alg_done_amo_en:1, // 45 | ||
| 165 | alg_done_int_en:1, // 46 | ||
| 166 | :1, // 47 | ||
| 167 | alg_sram0_locked:1, // 48 | ||
| 168 | alg_sram1_locked:1, // 49 | ||
| 169 | alg_sram2_locked:1, // 50 | ||
| 170 | alg_done_clr:1, // 51 | ||
| 171 | :12; // 63:52 | ||
| 172 | }; | ||
| 173 | }; | ||
| 174 | |||
| 175 | union cm_req_timeout { | ||
| 176 | uint64_t cm_req_timeout_reg; | ||
| 177 | struct { | ||
| 178 | uint64_t time_out:24, // 23:0 | ||
| 179 | :40; // 63:24 | ||
| 180 | }; | ||
| 181 | }; | ||
| 182 | |||
| 183 | union intr_dest { | ||
| 184 | uint64_t intr_dest_reg; | ||
| 185 | struct { | ||
| 186 | uint64_t address:56, // 55:0 | ||
| 187 | int_vector:8; // 63:56 | ||
| 188 | }; | ||
| 189 | }; | ||
| 190 | |||
| 191 | union cm_error_status { | ||
| 192 | uint64_t cm_error_status_reg; | ||
| 193 | struct { | ||
| 194 | uint64_t ecc_sbe:1, // 0 | ||
| 195 | ecc_mbe:1, // 1 | ||
| 196 | unsupported_req:1, // 2 | ||
| 197 | unexpected_rsp:1, // 3 | ||
| 198 | bad_length:1, // 4 | ||
| 199 | bad_datavalid:1, // 5 | ||
| 200 | buffer_overflow:1, // 6 | ||
| 201 | request_timeout:1, // 7 | ||
| 202 | :8, // 15:8 | ||
| 203 | head_inv_data_size:1, // 16 | ||
| 204 | rsp_pactype_inv:1, // 17 | ||
| 205 | head_sb_err:1, // 18 | ||
| 206 | missing_head:1, // 19 | ||
| 207 | head_inv_rd_type:1, // 20 | ||
| 208 | head_cmd_err_bit:1, // 21 | ||
| 209 | req_addr_align_inv:1, // 22 | ||
| 210 | pio_req_addr_inv:1, // 23 | ||
| 211 | req_range_dsize_inv:1, // 24 | ||
| 212 | early_term:1, // 25 | ||
| 213 | early_tail:1, // 26 | ||
| 214 | missing_tail:1, // 27 | ||
| 215 | data_flit_sb_err:1, // 28 | ||
| 216 | cm2hcm_req_cred_of:1, // 29 | ||
| 217 | cm2hcm_rsp_cred_of:1, // 30 | ||
| 218 | rx_bad_didn:1, // 31 | ||
| 219 | rd_dma_err_rsp:1, // 32 | ||
| 220 | rd_dma_tnum_tout:1, // 33 | ||
| 221 | rd_dma_multi_tnum_tou:1, // 34 | ||
| 222 | wr_dma_err_rsp:1, // 35 | ||
| 223 | wr_dma_tnum_tout:1, // 36 | ||
| 224 | wr_dma_multi_tnum_tou:1, // 37 | ||
| 225 | alg_data_overflow:1, // 38 | ||
| 226 | alg_data_underflow:1, // 39 | ||
| 227 | ram0_access_conflict:1, // 40 | ||
| 228 | ram1_access_conflict:1, // 41 | ||
| 229 | ram2_access_conflict:1, // 42 | ||
| 230 | ram0_perr:1, // 43 | ||
| 231 | ram1_perr:1, // 44 | ||
| 232 | ram2_perr:1, // 45 | ||
| 233 | int_gen_rsp_err:1, // 46 | ||
| 234 | int_gen_tnum_tout:1, // 47 | ||
| 235 | rd_dma_prog_err:1, // 48 | ||
| 236 | wr_dma_prog_err:1, // 49 | ||
| 237 | :14; // 63:50 | ||
| 238 | }; | ||
| 239 | }; | ||
| 240 | |||
| 241 | union cm_clr_error_status { | ||
| 242 | uint64_t cm_clr_error_status_reg; | ||
| 243 | struct { | ||
| 244 | uint64_t clr_ecc_sbe:1, // 0 | ||
| 245 | clr_ecc_mbe:1, // 1 | ||
| 246 | clr_unsupported_req:1, // 2 | ||
| 247 | clr_unexpected_rsp:1, // 3 | ||
| 248 | clr_bad_length:1, // 4 | ||
| 249 | clr_bad_datavalid:1, // 5 | ||
| 250 | clr_buffer_overflow:1, // 6 | ||
| 251 | clr_request_timeout:1, // 7 | ||
| 252 | :8, // 15:8 | ||
| 253 | clr_head_inv_data_siz:1, // 16 | ||
| 254 | clr_rsp_pactype_inv:1, // 17 | ||
| 255 | clr_head_sb_err:1, // 18 | ||
| 256 | clr_missing_head:1, // 19 | ||
| 257 | clr_head_inv_rd_type:1, // 20 | ||
| 258 | clr_head_cmd_err_bit:1, // 21 | ||
| 259 | clr_req_addr_align_in:1, // 22 | ||
| 260 | clr_pio_req_addr_inv:1, // 23 | ||
| 261 | clr_req_range_dsize_i:1, // 24 | ||
| 262 | clr_early_term:1, // 25 | ||
| 263 | clr_early_tail:1, // 26 | ||
| 264 | clr_missing_tail:1, // 27 | ||
| 265 | clr_data_flit_sb_err:1, // 28 | ||
| 266 | clr_cm2hcm_req_cred_o:1, // 29 | ||
| 267 | clr_cm2hcm_rsp_cred_o:1, // 30 | ||
| 268 | clr_rx_bad_didn:1, // 31 | ||
| 269 | clr_rd_dma_err_rsp:1, // 32 | ||
| 270 | clr_rd_dma_tnum_tout:1, // 33 | ||
| 271 | clr_rd_dma_multi_tnum:1, // 34 | ||
| 272 | clr_wr_dma_err_rsp:1, // 35 | ||
| 273 | clr_wr_dma_tnum_tout:1, // 36 | ||
| 274 | clr_wr_dma_multi_tnum:1, // 37 | ||
| 275 | clr_alg_data_overflow:1, // 38 | ||
| 276 | clr_alg_data_underflo:1, // 39 | ||
| 277 | clr_ram0_access_confl:1, // 40 | ||
| 278 | clr_ram1_access_confl:1, // 41 | ||
| 279 | clr_ram2_access_confl:1, // 42 | ||
| 280 | clr_ram0_perr:1, // 43 | ||
| 281 | clr_ram1_perr:1, // 44 | ||
| 282 | clr_ram2_perr:1, // 45 | ||
| 283 | clr_int_gen_rsp_err:1, // 46 | ||
| 284 | clr_int_gen_tnum_tout:1, // 47 | ||
| 285 | clr_rd_dma_prog_err:1, // 48 | ||
| 286 | clr_wr_dma_prog_err:1, // 49 | ||
| 287 | :14; // 63:50 | ||
| 288 | }; | ||
| 289 | }; | ||
| 290 | |||
| 291 | union cm_error_intr_enable { | ||
| 292 | uint64_t cm_error_intr_enable_reg; | ||
| 293 | struct { | ||
| 294 | uint64_t int_en_ecc_sbe:1, // 0 | ||
| 295 | int_en_ecc_mbe:1, // 1 | ||
| 296 | int_en_unsupported_re:1, // 2 | ||
| 297 | int_en_unexpected_rsp:1, // 3 | ||
| 298 | int_en_bad_length:1, // 4 | ||
| 299 | int_en_bad_datavalid:1, // 5 | ||
| 300 | int_en_buffer_overflo:1, // 6 | ||
| 301 | int_en_request_timeou:1, // 7 | ||
| 302 | :8, // 15:8 | ||
| 303 | int_en_head_inv_data_:1, // 16 | ||
| 304 | int_en_rsp_pactype_in:1, // 17 | ||
| 305 | int_en_head_sb_err:1, // 18 | ||
| 306 | int_en_missing_head:1, // 19 | ||
| 307 | int_en_head_inv_rd_ty:1, // 20 | ||
| 308 | int_en_head_cmd_err_b:1, // 21 | ||
| 309 | int_en_req_addr_align:1, // 22 | ||
| 310 | int_en_pio_req_addr_i:1, // 23 | ||
| 311 | int_en_req_range_dsiz:1, // 24 | ||
| 312 | int_en_early_term:1, // 25 | ||
| 313 | int_en_early_tail:1, // 26 | ||
| 314 | int_en_missing_tail:1, // 27 | ||
| 315 | int_en_data_flit_sb_e:1, // 28 | ||
| 316 | int_en_cm2hcm_req_cre:1, // 29 | ||
| 317 | int_en_cm2hcm_rsp_cre:1, // 30 | ||
| 318 | int_en_rx_bad_didn:1, // 31 | ||
| 319 | int_en_rd_dma_err_rsp:1, // 32 | ||
| 320 | int_en_rd_dma_tnum_to:1, // 33 | ||
| 321 | int_en_rd_dma_multi_t:1, // 34 | ||
| 322 | int_en_wr_dma_err_rsp:1, // 35 | ||
| 323 | int_en_wr_dma_tnum_to:1, // 36 | ||
| 324 | int_en_wr_dma_multi_t:1, // 37 | ||
| 325 | int_en_alg_data_overf:1, // 38 | ||
| 326 | int_en_alg_data_under:1, // 39 | ||
| 327 | int_en_ram0_access_co:1, // 40 | ||
| 328 | int_en_ram1_access_co:1, // 41 | ||
| 329 | int_en_ram2_access_co:1, // 42 | ||
| 330 | int_en_ram0_perr:1, // 43 | ||
| 331 | int_en_ram1_perr:1, // 44 | ||
| 332 | int_en_ram2_perr:1, // 45 | ||
| 333 | int_en_int_gen_rsp_er:1, // 46 | ||
| 334 | int_en_int_gen_tnum_t:1, // 47 | ||
| 335 | int_en_rd_dma_prog_er:1, // 48 | ||
| 336 | int_en_wr_dma_prog_er:1, // 49 | ||
| 337 | :14; // 63:50 | ||
| 338 | }; | ||
| 339 | }; | ||
| 340 | |||
| 341 | struct cm_mmr { | ||
| 342 | union cm_id id; | ||
| 343 | union cm_status status; | ||
| 344 | union cm_error_detail1 err_detail1; | ||
| 345 | union cm_error_detail2 err_detail2; | ||
| 346 | union cm_control control; | ||
| 347 | union cm_req_timeout req_timeout; | ||
| 348 | uint64_t reserved1[1]; | ||
| 349 | union intr_dest int_dest; | ||
| 350 | uint64_t reserved2[2]; | ||
| 351 | uint64_t targ_flush; | ||
| 352 | uint64_t reserved3[1]; | ||
| 353 | union cm_error_status err_status; | ||
| 354 | union cm_clr_error_status clr_err_status; | ||
| 355 | union cm_error_intr_enable int_enable; | ||
| 356 | }; | ||
| 357 | |||
| 358 | union dma_hostaddr { | ||
| 359 | uint64_t dma_hostaddr_reg; | ||
| 360 | struct { | ||
| 361 | uint64_t dma_sys_addr:56, // 55:0 | ||
| 362 | :8; // 63:56 | ||
| 363 | }; | ||
| 364 | }; | ||
| 365 | |||
| 366 | union dma_localaddr { | ||
| 367 | uint64_t dma_localaddr_reg; | ||
| 368 | struct { | ||
| 369 | uint64_t dma_ram_addr:21, // 20:0 | ||
| 370 | dma_ram_sel:2, // 22:21 | ||
| 371 | :41; // 63:23 | ||
| 372 | }; | ||
| 373 | }; | ||
| 374 | |||
| 375 | union dma_control { | ||
| 376 | uint64_t dma_control_reg; | ||
| 377 | struct { | ||
| 378 | uint64_t dma_op_length:16, // 15:0 | ||
| 379 | :18, // 33:16 | ||
| 380 | done_amo_en:1, // 34 | ||
| 381 | done_int_en:1, // 35 | ||
| 382 | :1, // 36 | ||
| 383 | pio_mem_n:1, // 37 | ||
| 384 | :26; // 63:38 | ||
| 385 | }; | ||
| 386 | }; | ||
| 387 | |||
| 388 | union dma_amo_dest { | ||
| 389 | uint64_t dma_amo_dest_reg; | ||
| 390 | struct { | ||
| 391 | uint64_t dma_amo_sys_addr:56, // 55:0 | ||
| 392 | dma_amo_mod_type:3, // 58:56 | ||
| 393 | :5; // 63:59 | ||
| 394 | }; | ||
| 395 | }; | ||
| 396 | |||
| 397 | union rdma_aux_status { | ||
| 398 | uint64_t rdma_aux_status_reg; | ||
| 399 | struct { | ||
| 400 | uint64_t op_num_pacs_left:17, // 16:0 | ||
| 401 | :5, // 21:17 | ||
| 402 | lrsp_buff_empty:1, // 22 | ||
| 403 | :17, // 39:23 | ||
| 404 | pending_reqs_left:6, // 45:40 | ||
| 405 | :18; // 63:46 | ||
| 406 | }; | ||
| 407 | }; | ||
| 408 | |||
| 409 | struct rdma_mmr { | ||
| 410 | union dma_hostaddr host_addr; | ||
| 411 | union dma_localaddr local_addr; | ||
| 412 | union dma_control control; | ||
| 413 | union dma_amo_dest amo_dest; | ||
| 414 | union intr_dest intr_dest; | ||
| 415 | union rdma_aux_status aux_status; | ||
| 416 | }; | ||
| 417 | |||
| 418 | union wdma_aux_status { | ||
| 419 | uint64_t wdma_aux_status_reg; | ||
| 420 | struct { | ||
| 421 | uint64_t op_num_pacs_left:17, // 16:0 | ||
| 422 | :4, // 20:17 | ||
| 423 | lreq_buff_empty:1, // 21 | ||
| 424 | :18, // 39:22 | ||
| 425 | pending_reqs_left:6, // 45:40 | ||
| 426 | :18; // 63:46 | ||
| 427 | }; | ||
| 428 | }; | ||
| 429 | |||
| 430 | struct wdma_mmr { | ||
| 431 | union dma_hostaddr host_addr; | ||
| 432 | union dma_localaddr local_addr; | ||
| 433 | union dma_control control; | ||
| 434 | union dma_amo_dest amo_dest; | ||
| 435 | union intr_dest intr_dest; | ||
| 436 | union wdma_aux_status aux_status; | ||
| 437 | }; | ||
| 438 | |||
| 439 | union algo_step { | ||
| 440 | uint64_t algo_step_reg; | ||
| 441 | struct { | ||
| 442 | uint64_t alg_step_cnt:16, // 15:0 | ||
| 443 | :48; // 63:16 | ||
| 444 | }; | ||
| 445 | }; | ||
| 446 | |||
| 447 | struct algo_mmr { | ||
| 448 | union dma_amo_dest amo_dest; | ||
| 449 | union intr_dest intr_dest; | ||
| 450 | union { | ||
| 451 | uint64_t algo_offset_reg; | ||
| 452 | struct { | ||
| 453 | uint64_t sram0_offset:7, // 6:0 | ||
| 454 | reserved0:1, // 7 | ||
| 455 | sram1_offset:7, // 14:8 | ||
| 456 | reserved1:1, // 15 | ||
| 457 | sram2_offset:7, // 22:16 | ||
| 458 | reserved2:14; // 63:23 | ||
| 459 | }; | ||
| 460 | } sram_offset; | ||
| 461 | union algo_step step; | ||
| 462 | }; | ||
| 463 | |||
| 464 | struct mbcs_mmr { | ||
| 465 | struct cm_mmr cm; | ||
| 466 | uint64_t reserved1[17]; | ||
| 467 | struct rdma_mmr rdDma; | ||
| 468 | uint64_t reserved2[25]; | ||
| 469 | struct wdma_mmr wrDma; | ||
| 470 | uint64_t reserved3[25]; | ||
| 471 | struct algo_mmr algo; | ||
| 472 | uint64_t reserved4[156]; | ||
| 473 | }; | ||
| 474 | |||
| 475 | /* | ||
| 476 | * defines | ||
| 477 | */ | ||
| 478 | #define DEVICE_NAME "mbcs" | ||
| 479 | #define MBCS_PART_NUM 0xfff0 | ||
| 480 | #define MBCS_PART_NUM_ALG0 0xf001 | ||
| 481 | #define MBCS_MFG_NUM 0x1 | ||
| 482 | |||
| 483 | struct algoblock { | ||
| 484 | uint64_t amoHostDest; | ||
| 485 | uint64_t amoModType; | ||
| 486 | uint64_t intrHostDest; | ||
| 487 | uint64_t intrVector; | ||
| 488 | uint64_t algoStepCount; | ||
| 489 | }; | ||
| 490 | |||
| 491 | struct getdma { | ||
| 492 | uint64_t hostAddr; | ||
| 493 | uint64_t localAddr; | ||
| 494 | uint64_t bytes; | ||
| 495 | uint64_t DoneAmoEnable; | ||
| 496 | uint64_t DoneIntEnable; | ||
| 497 | uint64_t peerIO; | ||
| 498 | uint64_t amoHostDest; | ||
| 499 | uint64_t amoModType; | ||
| 500 | uint64_t intrHostDest; | ||
| 501 | uint64_t intrVector; | ||
| 502 | }; | ||
| 503 | |||
| 504 | struct putdma { | ||
| 505 | uint64_t hostAddr; | ||
| 506 | uint64_t localAddr; | ||
| 507 | uint64_t bytes; | ||
| 508 | uint64_t DoneAmoEnable; | ||
| 509 | uint64_t DoneIntEnable; | ||
| 510 | uint64_t peerIO; | ||
| 511 | uint64_t amoHostDest; | ||
| 512 | uint64_t amoModType; | ||
| 513 | uint64_t intrHostDest; | ||
| 514 | uint64_t intrVector; | ||
| 515 | }; | ||
| 516 | |||
| 517 | struct mbcs_soft { | ||
| 518 | struct list_head list; | ||
| 519 | struct cx_dev *cxdev; | ||
| 520 | int major; | ||
| 521 | int nasid; | ||
| 522 | void *mmr_base; | ||
| 523 | wait_queue_head_t dmawrite_queue; | ||
| 524 | wait_queue_head_t dmaread_queue; | ||
| 525 | wait_queue_head_t algo_queue; | ||
| 526 | struct sn_irq_info *get_sn_irq; | ||
| 527 | struct sn_irq_info *put_sn_irq; | ||
| 528 | struct sn_irq_info *algo_sn_irq; | ||
| 529 | struct getdma getdma; | ||
| 530 | struct putdma putdma; | ||
| 531 | struct algoblock algo; | ||
| 532 | uint64_t gscr_addr; // pio addr | ||
| 533 | uint64_t ram0_addr; // pio addr | ||
| 534 | uint64_t ram1_addr; // pio addr | ||
| 535 | uint64_t ram2_addr; // pio addr | ||
| 536 | uint64_t debug_addr; // pio addr | ||
| 537 | atomic_t dmawrite_done; | ||
| 538 | atomic_t dmaread_done; | ||
| 539 | atomic_t algo_done; | ||
| 540 | struct mutex dmawritelock; | ||
| 541 | struct mutex dmareadlock; | ||
| 542 | struct mutex algolock; | ||
| 543 | }; | ||
| 544 | |||
| 545 | static int mbcs_open(struct inode *ip, struct file *fp); | ||
| 546 | static ssize_t mbcs_sram_read(struct file *fp, char __user *buf, size_t len, | ||
| 547 | loff_t * off); | ||
| 548 | static ssize_t mbcs_sram_write(struct file *fp, const char __user *buf, size_t len, | ||
| 549 | loff_t * off); | ||
| 550 | static loff_t mbcs_sram_llseek(struct file *filp, loff_t off, int whence); | ||
| 551 | static int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma); | ||
| 552 | |||
| 553 | #endif // __MBCS_H__ | ||
