Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v4.11 599 lines 15 kB view raw
1/* 2 * Intel MIC Platform Software Stack (MPSS) 3 * 4 * Copyright(c) 2013 Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License, version 2, as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * The full GNU General Public License is included in this distribution in 16 * the file called "COPYING". 17 * 18 * Intel MIC Host driver. 19 * 20 */ 21#include <linux/delay.h> 22#include <linux/firmware.h> 23#include <linux/pci.h> 24#include <linux/kmod.h> 25#include <linux/mic_common.h> 26#include <linux/mic_bus.h> 27#include "../bus/scif_bus.h" 28#include "../bus/vop_bus.h" 29#include "../common/mic_dev.h" 30#include "mic_device.h" 31#include "mic_smpt.h" 32 33static inline struct mic_device *vpdev_to_mdev(struct device *dev) 34{ 35 return dev_get_drvdata(dev->parent); 36} 37 38static dma_addr_t 39_mic_dma_map_page(struct device *dev, struct page *page, 40 unsigned long offset, size_t size, 41 enum dma_data_direction dir, unsigned long attrs) 42{ 43 void *va = phys_to_virt(page_to_phys(page)) + offset; 44 struct mic_device *mdev = vpdev_to_mdev(dev); 45 46 return mic_map_single(mdev, va, size); 47} 48 49static void _mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, 50 size_t size, enum dma_data_direction dir, 51 unsigned long attrs) 52{ 53 struct mic_device *mdev = vpdev_to_mdev(dev); 54 55 mic_unmap_single(mdev, dma_addr, size); 56} 57 58static const struct dma_map_ops _mic_dma_ops = { 59 .map_page = _mic_dma_map_page, 60 .unmap_page = _mic_dma_unmap_page, 61}; 62 63static struct mic_irq * 64__mic_request_irq(struct vop_device *vpdev, 65 irqreturn_t (*func)(int irq, void *data), 66 const char *name, void *data, int intr_src) 67{ 68 struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); 69 70 return mic_request_threaded_irq(mdev, func, NULL, name, data, 71 intr_src, MIC_INTR_DB); 72} 73 74static void __mic_free_irq(struct vop_device *vpdev, 75 struct mic_irq *cookie, void *data) 76{ 77 struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); 78 79 mic_free_irq(mdev, cookie, data); 80} 81 82static void __mic_ack_interrupt(struct vop_device *vpdev, int num) 83{ 84 struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); 85 86 mdev->ops->intr_workarounds(mdev); 87} 88 89static int __mic_next_db(struct vop_device *vpdev) 90{ 91 struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); 92 93 return mic_next_db(mdev); 94} 95 96static void *__mic_get_dp(struct vop_device *vpdev) 97{ 98 struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); 99 100 return mdev->dp; 101} 102 103static void __iomem *__mic_get_remote_dp(struct vop_device *vpdev) 104{ 105 return NULL; 106} 107 108static void __mic_send_intr(struct vop_device *vpdev, int db) 109{ 110 struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); 111 112 mdev->ops->send_intr(mdev, db); 113} 114 115static void __iomem *__mic_ioremap(struct vop_device *vpdev, 116 dma_addr_t pa, size_t len) 117{ 118 struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); 119 120 return mdev->aper.va + pa; 121} 122 123static void __mic_iounmap(struct vop_device *vpdev, void __iomem *va) 124{ 125 /* nothing to do */ 126} 127 128static struct vop_hw_ops vop_hw_ops = { 129 .request_irq = __mic_request_irq, 130 .free_irq = __mic_free_irq, 131 .ack_interrupt = __mic_ack_interrupt, 132 .next_db = __mic_next_db, 133 .get_dp = __mic_get_dp, 134 .get_remote_dp = __mic_get_remote_dp, 135 .send_intr = __mic_send_intr, 136 .ioremap = __mic_ioremap, 137 .iounmap = __mic_iounmap, 138}; 139 140static inline struct mic_device *scdev_to_mdev(struct scif_hw_dev *scdev) 141{ 142 return dev_get_drvdata(scdev->dev.parent); 143} 144 145static void *__mic_dma_alloc(struct device *dev, size_t size, 146 dma_addr_t *dma_handle, gfp_t gfp, 147 unsigned long attrs) 148{ 149 struct scif_hw_dev *scdev = dev_get_drvdata(dev); 150 struct mic_device *mdev = scdev_to_mdev(scdev); 151 dma_addr_t tmp; 152 void *va = kmalloc(size, gfp); 153 154 if (va) { 155 tmp = mic_map_single(mdev, va, size); 156 if (dma_mapping_error(dev, tmp)) { 157 kfree(va); 158 va = NULL; 159 } else { 160 *dma_handle = tmp; 161 } 162 } 163 return va; 164} 165 166static void __mic_dma_free(struct device *dev, size_t size, void *vaddr, 167 dma_addr_t dma_handle, unsigned long attrs) 168{ 169 struct scif_hw_dev *scdev = dev_get_drvdata(dev); 170 struct mic_device *mdev = scdev_to_mdev(scdev); 171 172 mic_unmap_single(mdev, dma_handle, size); 173 kfree(vaddr); 174} 175 176static dma_addr_t 177__mic_dma_map_page(struct device *dev, struct page *page, unsigned long offset, 178 size_t size, enum dma_data_direction dir, 179 unsigned long attrs) 180{ 181 void *va = phys_to_virt(page_to_phys(page)) + offset; 182 struct scif_hw_dev *scdev = dev_get_drvdata(dev); 183 struct mic_device *mdev = scdev_to_mdev(scdev); 184 185 return mic_map_single(mdev, va, size); 186} 187 188static void 189__mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, 190 size_t size, enum dma_data_direction dir, 191 unsigned long attrs) 192{ 193 struct scif_hw_dev *scdev = dev_get_drvdata(dev); 194 struct mic_device *mdev = scdev_to_mdev(scdev); 195 196 mic_unmap_single(mdev, dma_addr, size); 197} 198 199static int __mic_dma_map_sg(struct device *dev, struct scatterlist *sg, 200 int nents, enum dma_data_direction dir, 201 unsigned long attrs) 202{ 203 struct scif_hw_dev *scdev = dev_get_drvdata(dev); 204 struct mic_device *mdev = scdev_to_mdev(scdev); 205 struct scatterlist *s; 206 int i, j, ret; 207 dma_addr_t da; 208 209 ret = dma_map_sg(&mdev->pdev->dev, sg, nents, dir); 210 if (ret <= 0) 211 return 0; 212 213 for_each_sg(sg, s, nents, i) { 214 da = mic_map(mdev, sg_dma_address(s) + s->offset, s->length); 215 if (!da) 216 goto err; 217 sg_dma_address(s) = da; 218 } 219 return nents; 220err: 221 for_each_sg(sg, s, i, j) { 222 mic_unmap(mdev, sg_dma_address(s), s->length); 223 sg_dma_address(s) = mic_to_dma_addr(mdev, sg_dma_address(s)); 224 } 225 dma_unmap_sg(&mdev->pdev->dev, sg, nents, dir); 226 return 0; 227} 228 229static void __mic_dma_unmap_sg(struct device *dev, 230 struct scatterlist *sg, int nents, 231 enum dma_data_direction dir, 232 unsigned long attrs) 233{ 234 struct scif_hw_dev *scdev = dev_get_drvdata(dev); 235 struct mic_device *mdev = scdev_to_mdev(scdev); 236 struct scatterlist *s; 237 dma_addr_t da; 238 int i; 239 240 for_each_sg(sg, s, nents, i) { 241 da = mic_to_dma_addr(mdev, sg_dma_address(s)); 242 mic_unmap(mdev, sg_dma_address(s), s->length); 243 sg_dma_address(s) = da; 244 } 245 dma_unmap_sg(&mdev->pdev->dev, sg, nents, dir); 246} 247 248static const struct dma_map_ops __mic_dma_ops = { 249 .alloc = __mic_dma_alloc, 250 .free = __mic_dma_free, 251 .map_page = __mic_dma_map_page, 252 .unmap_page = __mic_dma_unmap_page, 253 .map_sg = __mic_dma_map_sg, 254 .unmap_sg = __mic_dma_unmap_sg, 255}; 256 257static struct mic_irq * 258___mic_request_irq(struct scif_hw_dev *scdev, 259 irqreturn_t (*func)(int irq, void *data), 260 const char *name, 261 void *data, int db) 262{ 263 struct mic_device *mdev = scdev_to_mdev(scdev); 264 265 return mic_request_threaded_irq(mdev, func, NULL, name, data, 266 db, MIC_INTR_DB); 267} 268 269static void 270___mic_free_irq(struct scif_hw_dev *scdev, 271 struct mic_irq *cookie, void *data) 272{ 273 struct mic_device *mdev = scdev_to_mdev(scdev); 274 275 mic_free_irq(mdev, cookie, data); 276} 277 278static void ___mic_ack_interrupt(struct scif_hw_dev *scdev, int num) 279{ 280 struct mic_device *mdev = scdev_to_mdev(scdev); 281 282 mdev->ops->intr_workarounds(mdev); 283} 284 285static int ___mic_next_db(struct scif_hw_dev *scdev) 286{ 287 struct mic_device *mdev = scdev_to_mdev(scdev); 288 289 return mic_next_db(mdev); 290} 291 292static void ___mic_send_intr(struct scif_hw_dev *scdev, int db) 293{ 294 struct mic_device *mdev = scdev_to_mdev(scdev); 295 296 mdev->ops->send_intr(mdev, db); 297} 298 299static void __iomem *___mic_ioremap(struct scif_hw_dev *scdev, 300 phys_addr_t pa, size_t len) 301{ 302 struct mic_device *mdev = scdev_to_mdev(scdev); 303 304 return mdev->aper.va + pa; 305} 306 307static void ___mic_iounmap(struct scif_hw_dev *scdev, void __iomem *va) 308{ 309 /* nothing to do */ 310} 311 312static struct scif_hw_ops scif_hw_ops = { 313 .request_irq = ___mic_request_irq, 314 .free_irq = ___mic_free_irq, 315 .ack_interrupt = ___mic_ack_interrupt, 316 .next_db = ___mic_next_db, 317 .send_intr = ___mic_send_intr, 318 .ioremap = ___mic_ioremap, 319 .iounmap = ___mic_iounmap, 320}; 321 322static inline struct mic_device *mbdev_to_mdev(struct mbus_device *mbdev) 323{ 324 return dev_get_drvdata(mbdev->dev.parent); 325} 326 327static dma_addr_t 328mic_dma_map_page(struct device *dev, struct page *page, 329 unsigned long offset, size_t size, enum dma_data_direction dir, 330 unsigned long attrs) 331{ 332 void *va = phys_to_virt(page_to_phys(page)) + offset; 333 struct mic_device *mdev = dev_get_drvdata(dev->parent); 334 335 return mic_map_single(mdev, va, size); 336} 337 338static void 339mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, 340 size_t size, enum dma_data_direction dir, 341 unsigned long attrs) 342{ 343 struct mic_device *mdev = dev_get_drvdata(dev->parent); 344 mic_unmap_single(mdev, dma_addr, size); 345} 346 347static const struct dma_map_ops mic_dma_ops = { 348 .map_page = mic_dma_map_page, 349 .unmap_page = mic_dma_unmap_page, 350}; 351 352static struct mic_irq * 353_mic_request_threaded_irq(struct mbus_device *mbdev, 354 irq_handler_t handler, irq_handler_t thread_fn, 355 const char *name, void *data, int intr_src) 356{ 357 return mic_request_threaded_irq(mbdev_to_mdev(mbdev), handler, 358 thread_fn, name, data, 359 intr_src, MIC_INTR_DMA); 360} 361 362static void _mic_free_irq(struct mbus_device *mbdev, 363 struct mic_irq *cookie, void *data) 364{ 365 mic_free_irq(mbdev_to_mdev(mbdev), cookie, data); 366} 367 368static void _mic_ack_interrupt(struct mbus_device *mbdev, int num) 369{ 370 struct mic_device *mdev = mbdev_to_mdev(mbdev); 371 mdev->ops->intr_workarounds(mdev); 372} 373 374static struct mbus_hw_ops mbus_hw_ops = { 375 .request_threaded_irq = _mic_request_threaded_irq, 376 .free_irq = _mic_free_irq, 377 .ack_interrupt = _mic_ack_interrupt, 378}; 379 380/* Initialize the MIC bootparams */ 381void mic_bootparam_init(struct mic_device *mdev) 382{ 383 struct mic_bootparam *bootparam = mdev->dp; 384 385 bootparam->magic = cpu_to_le32(MIC_MAGIC); 386 bootparam->h2c_config_db = -1; 387 bootparam->node_id = mdev->id + 1; 388 bootparam->scif_host_dma_addr = 0x0; 389 bootparam->scif_card_dma_addr = 0x0; 390 bootparam->c2h_scif_db = -1; 391 bootparam->h2c_scif_db = -1; 392} 393 394static inline struct mic_device *cosmdev_to_mdev(struct cosm_device *cdev) 395{ 396 return dev_get_drvdata(cdev->dev.parent); 397} 398 399static void _mic_reset(struct cosm_device *cdev) 400{ 401 struct mic_device *mdev = cosmdev_to_mdev(cdev); 402 403 mdev->ops->reset_fw_ready(mdev); 404 mdev->ops->reset(mdev); 405} 406 407static bool _mic_ready(struct cosm_device *cdev) 408{ 409 struct mic_device *mdev = cosmdev_to_mdev(cdev); 410 411 return mdev->ops->is_fw_ready(mdev); 412} 413 414/** 415 * mic_request_dma_chans - Request DMA channels 416 * @mdev: pointer to mic_device instance 417 * 418 * returns number of DMA channels acquired 419 */ 420static int mic_request_dma_chans(struct mic_device *mdev) 421{ 422 dma_cap_mask_t mask; 423 struct dma_chan *chan; 424 425 dma_cap_zero(mask); 426 dma_cap_set(DMA_MEMCPY, mask); 427 428 do { 429 chan = dma_request_channel(mask, mdev->ops->dma_filter, 430 &mdev->pdev->dev); 431 if (chan) { 432 mdev->dma_ch[mdev->num_dma_ch++] = chan; 433 if (mdev->num_dma_ch >= MIC_MAX_DMA_CHAN) 434 break; 435 } 436 } while (chan); 437 dev_info(&mdev->pdev->dev, "DMA channels # %d\n", mdev->num_dma_ch); 438 return mdev->num_dma_ch; 439} 440 441/** 442 * mic_free_dma_chans - release DMA channels 443 * @mdev: pointer to mic_device instance 444 * 445 * returns none 446 */ 447static void mic_free_dma_chans(struct mic_device *mdev) 448{ 449 int i = 0; 450 451 for (i = 0; i < mdev->num_dma_ch; i++) { 452 dma_release_channel(mdev->dma_ch[i]); 453 mdev->dma_ch[i] = NULL; 454 } 455 mdev->num_dma_ch = 0; 456} 457 458/** 459 * _mic_start - Start the MIC. 460 * @cdev: pointer to cosm_device instance 461 * @id: MIC device id/index provided by COSM used in other drivers like SCIF 462 * 463 * This function prepares an MIC for boot and initiates boot. 464 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 465 * 466 * For all cosm_hw_ops the caller holds a mutex to ensure serialization. 467 */ 468static int _mic_start(struct cosm_device *cdev, int id) 469{ 470 struct mic_device *mdev = cosmdev_to_mdev(cdev); 471 int rc; 472 473 mic_bootparam_init(mdev); 474 mdev->dma_mbdev = mbus_register_device(&mdev->pdev->dev, 475 MBUS_DEV_DMA_HOST, &mic_dma_ops, 476 &mbus_hw_ops, id, mdev->mmio.va); 477 if (IS_ERR(mdev->dma_mbdev)) { 478 rc = PTR_ERR(mdev->dma_mbdev); 479 goto unlock_ret; 480 } 481 if (!mic_request_dma_chans(mdev)) { 482 rc = -ENODEV; 483 goto dma_remove; 484 } 485 mdev->scdev = scif_register_device(&mdev->pdev->dev, MIC_SCIF_DEV, 486 &__mic_dma_ops, &scif_hw_ops, 487 id + 1, 0, &mdev->mmio, 488 &mdev->aper, mdev->dp, NULL, 489 mdev->dma_ch, mdev->num_dma_ch, 490 true); 491 if (IS_ERR(mdev->scdev)) { 492 rc = PTR_ERR(mdev->scdev); 493 goto dma_free; 494 } 495 496 mdev->vpdev = vop_register_device(&mdev->pdev->dev, 497 VOP_DEV_TRNSP, &_mic_dma_ops, 498 &vop_hw_ops, id + 1, &mdev->aper, 499 mdev->dma_ch[0]); 500 if (IS_ERR(mdev->vpdev)) { 501 rc = PTR_ERR(mdev->vpdev); 502 goto scif_remove; 503 } 504 505 rc = mdev->ops->load_mic_fw(mdev, NULL); 506 if (rc) 507 goto vop_remove; 508 mic_smpt_restore(mdev); 509 mic_intr_restore(mdev); 510 mdev->intr_ops->enable_interrupts(mdev); 511 mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr); 512 mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32); 513 mdev->ops->send_firmware_intr(mdev); 514 goto unlock_ret; 515vop_remove: 516 vop_unregister_device(mdev->vpdev); 517scif_remove: 518 scif_unregister_device(mdev->scdev); 519dma_free: 520 mic_free_dma_chans(mdev); 521dma_remove: 522 mbus_unregister_device(mdev->dma_mbdev); 523unlock_ret: 524 return rc; 525} 526 527/** 528 * _mic_stop - Prepare the MIC for reset and trigger reset. 529 * @cdev: pointer to cosm_device instance 530 * @force: force a MIC to reset even if it is already offline. 531 * 532 * RETURNS: None. 533 */ 534static void _mic_stop(struct cosm_device *cdev, bool force) 535{ 536 struct mic_device *mdev = cosmdev_to_mdev(cdev); 537 538 /* 539 * Since SCIF handles card shutdown and reset (using COSM), it will 540 * will be the first to be registered and the last to be 541 * unregistered. 542 */ 543 vop_unregister_device(mdev->vpdev); 544 scif_unregister_device(mdev->scdev); 545 mic_free_dma_chans(mdev); 546 mbus_unregister_device(mdev->dma_mbdev); 547 mic_bootparam_init(mdev); 548} 549 550static ssize_t _mic_family(struct cosm_device *cdev, char *buf) 551{ 552 struct mic_device *mdev = cosmdev_to_mdev(cdev); 553 static const char *family[MIC_FAMILY_LAST] = { "x100", "Unknown" }; 554 555 return scnprintf(buf, PAGE_SIZE, "%s\n", family[mdev->family]); 556} 557 558static ssize_t _mic_stepping(struct cosm_device *cdev, char *buf) 559{ 560 struct mic_device *mdev = cosmdev_to_mdev(cdev); 561 const char *string = "??"; 562 563 switch (mdev->stepping) { 564 case MIC_A0_STEP: 565 string = "A0"; 566 break; 567 case MIC_B0_STEP: 568 string = "B0"; 569 break; 570 case MIC_B1_STEP: 571 string = "B1"; 572 break; 573 case MIC_C0_STEP: 574 string = "C0"; 575 break; 576 default: 577 break; 578 } 579 return scnprintf(buf, PAGE_SIZE, "%s\n", string); 580} 581 582static struct mic_mw *_mic_aper(struct cosm_device *cdev) 583{ 584 struct mic_device *mdev = cosmdev_to_mdev(cdev); 585 586 return &mdev->aper; 587} 588 589struct cosm_hw_ops cosm_hw_ops = { 590 .reset = _mic_reset, 591 .force_reset = _mic_reset, 592 .post_reset = NULL, 593 .ready = _mic_ready, 594 .start = _mic_start, 595 .stop = _mic_stop, 596 .family = _mic_family, 597 .stepping = _mic_stepping, 598 .aper = _mic_aper, 599};