Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

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