diff options
author | Ryan Grimm <grimm@linux.vnet.ibm.com> | 2015-01-19 12:52:48 -0500 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2015-01-22 01:31:51 -0500 |
commit | 4beb5421babee1204757b877622830c6aa31be6d (patch) | |
tree | 2562ab502196b3b5247b90940e6e8c1ede351af2 | |
parent | 49fd644c3b0014fb80c2b1db7d8c86a75c4c6b1f (diff) |
cxl: Use image state defaults for reloading FPGA
Select defaults such that a PERST causes flash image reload. Select which
image based on what the card is set up to load.
CXL_VSEC_PERST_LOADS_IMAGE selects whether PERST assertion causes flash image
load.
CXL_VSEC_PERST_SELECT_USER selects which image is loaded on the next PERST.
cxl_update_image_control writes these bits into the VSEC.
Signed-off-by: Ryan Grimm <grimm@linux.vnet.ibm.com>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | drivers/misc/cxl/cxl.h | 1 | ||||
-rw-r--r-- | drivers/misc/cxl/pci.c | 42 |
2 files changed, 41 insertions, 2 deletions
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 0df04380bfd6..518c4c6e6151 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h | |||
@@ -488,6 +488,7 @@ void cxl_release_one_irq(struct cxl *adapter, int hwirq); | |||
488 | int cxl_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num); | 488 | int cxl_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num); |
489 | void cxl_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter); | 489 | void cxl_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter); |
490 | int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq); | 490 | int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq); |
491 | int cxl_update_image_control(struct cxl *adapter); | ||
491 | 492 | ||
492 | /* common == phyp + powernv */ | 493 | /* common == phyp + powernv */ |
493 | struct cxl_process_element_common { | 494 | struct cxl_process_element_common { |
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 2ccd0a91d486..014f4c928e4c 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c | |||
@@ -361,6 +361,41 @@ int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq, | |||
361 | return pnv_cxl_ioda_msi_setup(dev, hwirq, virq); | 361 | return pnv_cxl_ioda_msi_setup(dev, hwirq, virq); |
362 | } | 362 | } |
363 | 363 | ||
364 | int cxl_update_image_control(struct cxl *adapter) | ||
365 | { | ||
366 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); | ||
367 | int rc; | ||
368 | int vsec; | ||
369 | u8 image_state; | ||
370 | |||
371 | if (!(vsec = find_cxl_vsec(dev))) { | ||
372 | dev_err(&dev->dev, "ABORTING: CXL VSEC not found!\n"); | ||
373 | return -ENODEV; | ||
374 | } | ||
375 | |||
376 | if ((rc = CXL_READ_VSEC_IMAGE_STATE(dev, vsec, &image_state))) { | ||
377 | dev_err(&dev->dev, "failed to read image state: %i\n", rc); | ||
378 | return rc; | ||
379 | } | ||
380 | |||
381 | if (adapter->perst_loads_image) | ||
382 | image_state |= CXL_VSEC_PERST_LOADS_IMAGE; | ||
383 | else | ||
384 | image_state &= ~CXL_VSEC_PERST_LOADS_IMAGE; | ||
385 | |||
386 | if (adapter->perst_select_user) | ||
387 | image_state |= CXL_VSEC_PERST_SELECT_USER; | ||
388 | else | ||
389 | image_state &= ~CXL_VSEC_PERST_SELECT_USER; | ||
390 | |||
391 | if ((rc = CXL_WRITE_VSEC_IMAGE_STATE(dev, vsec, image_state))) { | ||
392 | dev_err(&dev->dev, "failed to update image control: %i\n", rc); | ||
393 | return rc; | ||
394 | } | ||
395 | |||
396 | return 0; | ||
397 | } | ||
398 | |||
364 | int cxl_alloc_one_irq(struct cxl *adapter) | 399 | int cxl_alloc_one_irq(struct cxl *adapter) |
365 | { | 400 | { |
366 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); | 401 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); |
@@ -770,8 +805,8 @@ static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev) | |||
770 | CXL_READ_VSEC_BASE_IMAGE(dev, vsec, &adapter->base_image); | 805 | CXL_READ_VSEC_BASE_IMAGE(dev, vsec, &adapter->base_image); |
771 | CXL_READ_VSEC_IMAGE_STATE(dev, vsec, &image_state); | 806 | CXL_READ_VSEC_IMAGE_STATE(dev, vsec, &image_state); |
772 | adapter->user_image_loaded = !!(image_state & CXL_VSEC_USER_IMAGE_LOADED); | 807 | adapter->user_image_loaded = !!(image_state & CXL_VSEC_USER_IMAGE_LOADED); |
773 | adapter->perst_loads_image = !!(image_state & CXL_VSEC_PERST_LOADS_IMAGE); | 808 | adapter->perst_loads_image = true; |
774 | adapter->perst_select_user = !!(image_state & CXL_VSEC_PERST_SELECT_USER); | 809 | adapter->perst_select_user = !!(image_state & CXL_VSEC_USER_IMAGE_LOADED); |
775 | 810 | ||
776 | CXL_READ_VSEC_NAFUS(dev, vsec, &adapter->slices); | 811 | CXL_READ_VSEC_NAFUS(dev, vsec, &adapter->slices); |
777 | CXL_READ_VSEC_AFU_DESC_OFF(dev, vsec, &afu_desc_off); | 812 | CXL_READ_VSEC_AFU_DESC_OFF(dev, vsec, &afu_desc_off); |
@@ -879,6 +914,9 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev) | |||
879 | if ((rc = cxl_vsec_looks_ok(adapter, dev))) | 914 | if ((rc = cxl_vsec_looks_ok(adapter, dev))) |
880 | goto err2; | 915 | goto err2; |
881 | 916 | ||
917 | if ((rc = cxl_update_image_control(adapter))) | ||
918 | goto err2; | ||
919 | |||
882 | if ((rc = cxl_map_adapter_regs(adapter, dev))) | 920 | if ((rc = cxl_map_adapter_regs(adapter, dev))) |
883 | goto err2; | 921 | goto err2; |
884 | 922 | ||