From: Ryan Grimm <hidden> Date: 2015-01-15 02:56:50
Add reset_loads_image and reset_image_select to sysfs.
reset_image_select identifies which image will be loaded to the card on the
next PERST. Valid entries are: "user" and "factory".
reset_loads_image defines functionality on a PERST. Value of 0 means PERST
will not cause image load. A power cycle is required to load the image. Value
of 1 means PERST will cause image load.
sysfs updates the cxl struct in the driver then calls cxl_update_image_control
to write the vals in the VSEC.
Signed-off-by: Ryan Grimm <redacted>
---
Documentation/ABI/testing/sysfs-class-cxl | 15 ++++++++
drivers/misc/cxl/cxl.h | 1 +
drivers/misc/cxl/pci.c | 35 ++++++++++++++++++
drivers/misc/cxl/sysfs.c | 60 +++++++++++++++++++++++++++++++
4 files changed, 111 insertions(+)
@@ -127,3 +127,18 @@ Contact: linuxppc-dev@lists.ozlabs.org Description: read only Will return "user" or "factory" depending on the image loaded onto the card.++What: /sys/class/cxl/<card>/reset_image_select+Date: December 2014+Contact: linuxppc-dev@lists.ozlabs.org+Description: read/write+ Identifies which image will be loaded to the card on the next+ PERST. Valid entries are: "user" and "factory".++What: /sys/class/cxl/<card>/reset_loads_image+Date: December 2014+Contact: linuxppc-dev@lists.ozlabs.org+Description: read/write+ Value of 0 means PERST will not cause image load. A power+ cycle is required to load the image. Value of 1 means PERST+ will cause image load.
@@ -362,6 +362,41 @@ int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq,returnpnv_cxl_ioda_msi_setup(dev,hwirq,virq);}+intcxl_update_image_control(structcxl*adapter)+{+structpci_dev*dev=to_pci_dev(adapter->dev.parent);+intrc;+intvsec;+u8image_state;++if(!(vsec=find_cxl_vsec(dev))){+dev_err(&dev->dev,"ABORTING: CXL VSEC not found!\n");+return-ENODEV;+}++if((rc=CXL_READ_VSEC_IMAGE_STATE(dev,vsec,&image_state))){+dev_err(&dev->dev,"failed to read image state: %i\n",rc);+returnrc;+}++if(adapter->perst_loads_image)+image_state|=CXL_VSEC_PERST_LOADS_IMAGE;+else+image_state&=~CXL_VSEC_PERST_LOADS_IMAGE;++if(adapter->perst_select_user)+image_state|=CXL_VSEC_PERST_SELECT_USER;+else+image_state&=~CXL_VSEC_PERST_SELECT_USER;++if((rc=CXL_WRITE_VSEC_IMAGE_STATE(dev,vsec,image_state))){+dev_err(&dev->dev,"failed to update image control: %i\n",rc);+returnrc;+}++return0;+}+intcxl_alloc_one_irq(structcxl*adapter){structpci_dev*dev=to_pci_dev(adapter->dev.parent);
From: Ryan Grimm <hidden> Date: 2015-01-15 02:56:50
Add mode to opal call. SNOOP control turns CAPP unit snooping on/off. This is
needed for the following reset patch, which turns snoops off in the CAPP
recovery path.
Signed-off-by: Ryan Grimm <redacted>
---
arch/powerpc/include/asm/opal.h | 12 ++++++++++++
arch/powerpc/include/asm/pnv-pci.h | 2 +-
arch/powerpc/platforms/powernv/pci-ioda.c | 4 ++--
drivers/misc/cxl/pci.c | 6 +++++-
4 files changed, 20 insertions(+), 4 deletions(-)
From: Ian Munsie <hidden> Date: 2015-01-15 05:16:57
Excerpts from Ryan Grimm's message of 2015-01-15 13:56:40 +1100:
Add mode to opal call. SNOOP control turns CAPP unit snooping on/off. This is
needed for the following reset patch, which turns snoops off in the CAPP
recovery path.
Looking at patch 3 in this series I think this description needs to be
updated, as it doesn't seem to turn off snoops?
Ok, we turn on snooping here, but I don't see where we turned it off -
has patch 3 changed so that never happens?
Also - why this late in in the init sequence? Not saying it's wrong, just
wondering if this has to happen after all the AFUs have been initialised, or if
it can happen earlier in the adapter initialisation, like when we set
the PHB to capi mode?
Cheers,
-Ian
From: Ryan Grimm <hidden> Date: 2015-01-15 21:46:31
On 01/15/2015 12:16 AM, Ian Munsie wrote:
Excerpts from Ryan Grimm's message of 2015-01-15 13:56:40 +1100:
quoted
Add mode to opal call. SNOOP control turns CAPP unit snooping on/off. This is
needed for the following reset patch, which turns snoops off in the CAPP
recovery path.
Looking at patch 3 in this series I think this description needs to be
updated, as it doesn't seem to turn off snoops?
OK, will make commit message more clear.
Maybe I'll rename the first line to CXL: Enable CAPP recovery, since
that's what it does.
Ok, we turn on snooping here, but I don't see where we turned it off -
has patch 3 changed so that never happens?
snoops are disabled by Sapphire in the CAPP recovery path.
Also - why this late in in the init sequence? Not saying it's wrong, just
wondering if this has to happen after all the AFUs have been initialised, or if
it can happen earlier in the adapter initialisation, like when we set
the PHB to capi mode?
It has no effect when the driver is bound initially since Sapphire
already turns on snoops as part of the phb to cxl procedure.
I did it this way to handle CAPP recovery. The driver doesn't know that
capp recovery happened...EEH unbinds the driver, Sapphire does the CAPP
recovery procedure, then EEH rebinds the driver.
The last step in capp recovery is to turn on snoops. I'll put a comment
to explain that better...but, sure it could be earlier in the sequence.
-Ryan
From: Ryan Grimm <hidden> Date: 2015-01-15 02:56:51
This allows an image to be downloaded to the flash without rebooting the
machine. The driver perform a PERST, which results in FPGA image downloaded to
flash and the CAPP unit enters recovery. CAPP recovery triggers an HMI, which
is handled by EEH in Linux. EEH removes the driver, calls into Sapphire to
reinitialize the PHB, and then loads the driver.
reset_image_select must be set to "user" and reset_load_image set to 1. The
driver writes "user" to the vsec if a user image was loaded. It writes 1 to
reset_load_image on initialization by default. Other values could be used by
hand for debugging purposes.
Signed-off-by: Ryan Grimm <redacted>
---
Documentation/ABI/testing/sysfs-class-cxl | 6 +++++
drivers/misc/cxl/cxl.h | 1 +
drivers/misc/cxl/pci.c | 38 +++++++++++++++++++++++++++++--
drivers/misc/cxl/sysfs.c | 13 +++++++++++
4 files changed, 56 insertions(+), 2 deletions(-)
@@ -142,3 +142,9 @@ Description: read/write Value of 0 means PERST will not cause image load. A power cycle is required to load the image. Value of 1 means PERST will cause image load.++What: /sys/class/cxl/<card>/reset+Date: October 2014+Contact: linuxppc-dev@lists.ozlabs.org+Description: write only+ Writing 1 here will issue a PERST to card.
@@ -21,6 +21,7 @@#include<asm/msi_bitmap.h>#include<asm/pci-bridge.h> /* for struct pci_controller */#include<asm/pnv-pci.h>+#include<asm/io.h>#include"cxl.h"
@@ -742,6 +743,36 @@ static void cxl_remove_afu(struct cxl_afu *afu)device_unregister(&afu->dev);}+intcxl_reset(structcxl*adapter)+{+structpci_dev*dev=to_pci_dev(adapter->dev.parent);+intrc;+inti;+u32val;++dev_info(&dev->dev,"CXL reset\n");++for(i=0;i<adapter->slices;i++)+cxl_remove_afu(adapter->afu[i]);++if((rc=pci_set_pcie_reset_state(dev,pcie_warm_reset))){+dev_err(&dev->dev,"cxl: pcie_warm_reset failed\n");+returnrc;+}++/* Do mmio read to trigger EEH. Retry for a few seconds. */+i=0;+while((val=mmio_read32be(adapter->p1_mmio)!=0xffffffff)&&+(i<5)){+msleep(500);+i++;+}++if(val!=0xffffffff)+dev_err(&dev->dev,"cxl: PERST failed to trigger EEH\n");++returnrc;+}staticintcxl_map_adapter_regs(structcxl*adapter,structpci_dev*dev){
From: Ian Munsie <hidden> Date: 2015-01-15 05:42:36
Excerpts from Ryan Grimm's message of 2015-01-15 13:56:41 +1100:
This allows an image to be downloaded to the flash without rebooting the
machine. The driver perform a PERST, which results in FPGA image downloaded to
flash and the CAPP unit enters recovery. CAPP recovery triggers an HMI, which
is handled by EEH in Linux. EEH removes the driver, calls into Sapphire to
reinitialize the PHB, and then loads the driver.
reset_image_select must be set to "user" and reset_load_image set to 1. The
driver writes "user" to the vsec if a user image was loaded. It writes 1 to
reset_load_image on initialization by default. Other values could be used by
hand for debugging purposes.
That last paragraph will need to be updated if we merge those two sysfs
files into one. Might as well mention an example of why someone might do
a reset with no image selected for reload, e.g. the PSL trace arrays are
preserved, which can be read out through debugfs after the card comes
back up.
+What: /sys/class/cxl/<card>/reset
+Date: October 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: write only
+ Writing 1 here will issue a PERST to card.
"..., which may cause the card to reload the FPGA image depending on the
settings of reset_image_select."
+ if ((rc = pci_set_pcie_reset_state(dev, pcie_warm_reset))) {
Can you add a comment here to explain why we first do a warm reset?
+ dev_err(&dev->dev, "cxl: pcie_warm_reset failed\n");
+ return rc;
+ }
+
+ /* Do mmio read to trigger EEH. Retry for a few seconds. */
This seems a little unusual - can you expand this comment a little to
explain *why* we are using this method to trigger an EEH and reset the
card?
+ i = 0;
+ while ((val = mmio_read32be(adapter->p1_mmio) != 0xffffffff) &&
+ (i < 5)) {
+ msleep(500);
+ i++;
+ }
+
+ if (val != 0xffffffff)
+ dev_err(&dev->dev, "cxl: PERST failed to trigger EEH\n");
+
+ return rc;
Some of the indentation here is a bit funky - some lines are using tabs,
others are using spaces.
+ if ((rc = cxl_update_image_control(adapter)))
+ goto err2;
Thanks - that seems like a better default than what we had before,
should make things more stable :)
In fact, would you mind pulling this part out into a separate patch? It
seems like a serious contender to go to stable as it might help with
cards that get into a funny state and don't come back up properly after
a reboot (symptoms are that the adapter wide tlbia / slbia times out and
the driver aborts initialisation).
Cheers,
-Ian
From: Ryan Grimm <hidden> Date: 2015-01-15 21:58:43
On 01/15/2015 12:42 AM, Ian Munsie wrote:
Excerpts from Ryan Grimm's message of 2015-01-15 13:56:41 +1100:
quoted
This allows an image to be downloaded to the flash without rebooting the
machine. The driver perform a PERST, which results in FPGA image downloaded to
flash and the CAPP unit enters recovery. CAPP recovery triggers an HMI, which
is handled by EEH in Linux. EEH removes the driver, calls into Sapphire to
reinitialize the PHB, and then loads the driver.
reset_image_select must be set to "user" and reset_load_image set to 1. The
driver writes "user" to the vsec if a user image was loaded. It writes 1 to
reset_load_image on initialization by default. Other values could be used by
hand for debugging purposes.
That last paragraph will need to be updated if we merge those two sysfs
files into one. Might as well mention an example of why someone might do
a reset with no image selected for reload, e.g. the PSL trace arrays are
preserved, which can be read out through debugfs after the card comes
back up.
OK, fixed that up a bit. Let me know if the commit logs and
documentations make sense. There's a bit of overlap and hopefully it's
clear now.
quoted
+What: /sys/class/cxl/<card>/reset
+Date: October 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: write only
+ Writing 1 here will issue a PERST to card.
"..., which may cause the card to reload the FPGA image depending on the
settings of reset_image_select."
Sure, can be explicit about that.
quoted
+ if ((rc = pci_set_pcie_reset_state(dev, pcie_warm_reset))) {
Can you add a comment here to explain why we first do a warm reset?
quoted
+ dev_err(&dev->dev, "cxl: pcie_warm_reset failed\n");
+ return rc;
+ }
+
+ /* Do mmio read to trigger EEH. Retry for a few seconds. */
This seems a little unusual - can you expand this comment a little to
explain *why* we are using this method to trigger an EEH and reset the
card?
Added better commenting to both above.
quoted
+ i = 0;
+ while ((val = mmio_read32be(adapter->p1_mmio) != 0xffffffff) &&
+ (i < 5)) {
+ msleep(500);
+ i++;
+ }
+
+ if (val != 0xffffffff)
+ dev_err(&dev->dev, "cxl: PERST failed to trigger EEH\n");
+
+ return rc;
Some of the indentation here is a bit funky - some lines are using tabs,
others are using spaces.
From: Ian Munsie <hidden> Date: 2015-01-15 05:51:52
Excerpts from Ryan Grimm's message of 2015-01-15 13:56:41 +1100:
+What: /sys/class/cxl/<card>/reset
+Date: October 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: write only
+ Writing 1 here will issue a PERST to card.
Looks like we reset the card no matter what is written to that file?
I like the description better - add a test here to match what it says.
Cheers,
-Ian
From: Ian Munsie <hidden> Date: 2015-01-15 04:41:31
Excerpts from Ryan Grimm's message of 2015-01-15 13:56:39 +1100:
Add reset_loads_image and reset_image_select to sysfs.
reset_image_select identifies which image will be loaded to the card on the
next PERST. Valid entries are: "user" and "factory".
reset_loads_image defines functionality on a PERST. Value of 0 means PERST
will not cause image load. A power cycle is required to load the image. Value
of 1 means PERST will cause image load.
sysfs updates the cxl struct in the driver then calls cxl_update_image_control
to write the vals in the VSEC.
Let's combine both of these into a single sysfs file, with "none",
"user" and "factory" options and have the show & read functions handle
mapping those three options to the two bits in the register.
Of the two names I'd probably go with reset_image_select.
+What: /sys/class/cxl/<card>/reset_loads_image
+Date: December 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read/write
+ Value of 0 means PERST will not cause image load. A power
+ cycle is required to load the image. Value of 1 means PERST
+ will cause image load.
It also seems to be that having this disabled also means that PERST
doesn't fully reset the card. Might want to clarify that somewhat and
recommend it only be disabled for debugging purposes (e.g. to retain
the contents of the PSL trace arrays across a reset), and to always
enable it for production.
At the moment we don't set it at boot - we just go with whatever the
card is already set to do. I'm thinking it might be a good idea to
always set this bit on boot so the only time it's disabled is if a user
has explicitly gone and disabled it.
From: Ian Munsie <hidden> Date: 2015-01-15 04:46:15
Excerpts from Ian Munsie's message of 2015-01-15 15:41:24 +1100:
At the moment we don't set it at boot - we just go with whatever the
card is already set to do. I'm thinking it might be a good idea to
always set this bit on boot so the only time it's disabled is if a user
has explicitly gone and disabled it.
While I think of it - if we change this on boot we should also change
reset_image_select to match the currently loaded image. e.g. if
reset_loads_image has defaulted to off and reset_image_select has
defaulted to factory, but the user image has been loaded - that way we
avoid unexpectedly switching to factory if the card gets reset.
Cheers,
-Ian
From: Ian Munsie <hidden> Date: 2015-01-15 04:54:33
While I think of it - if we change this on boot we should also change
reset_image_select to match the currently loaded image. e.g. if
reset_loads_image has defaulted to off and reset_image_select has
defaulted to factory, but the user image has been loaded - that way we
avoid unexpectedly switching to factory if the card gets reset.
Nevermind - I see you have done exactly this in patch 3 :-)
-Ian
From: Michael Ellerman <hidden> Date: 2015-01-15 05:07:18
On Thu, 2015-01-15 at 15:41 +1100, Ian Munsie wrote:
Excerpts from Ryan Grimm's message of 2015-01-15 13:56:39 +1100:
quoted
Add reset_loads_image and reset_image_select to sysfs.
reset_image_select identifies which image will be loaded to the card on the
next PERST. Valid entries are: "user" and "factory".
reset_loads_image defines functionality on a PERST. Value of 0 means PERST
will not cause image load. A power cycle is required to load the image. Value
of 1 means PERST will cause image load.
sysfs updates the cxl struct in the driver then calls cxl_update_image_control
to write the vals in the VSEC.
Let's combine both of these into a single sysfs file, with "none",
"user" and "factory" options and have the show & read functions handle
mapping those three options to the two bits in the register.
Of the two names I'd probably go with reset_image_select.
Three words, all can be verbs, two can be nouns, it's not too clear.
Maybe "load_image_on_perst" ?
cheers
From: Ryan Grimm <hidden> Date: 2015-01-15 21:45:59
Ian,
Thanks for reviewing!
On 01/14/2015 11:41 PM, Ian Munsie wrote:
Excerpts from Ryan Grimm's message of 2015-01-15 13:56:39 +1100:
quoted
Add reset_loads_image and reset_image_select to sysfs.
reset_image_select identifies which image will be loaded to the card on the
next PERST. Valid entries are: "user" and "factory".
reset_loads_image defines functionality on a PERST. Value of 0 means PERST
will not cause image load. A power cycle is required to load the image. Value
of 1 means PERST will cause image load.
sysfs updates the cxl struct in the driver then calls cxl_update_image_control
to write the vals in the VSEC.
Let's combine both of these into a single sysfs file, with "none",
"user" and "factory" options and have the show & read functions handle
mapping those three options to the two bits in the register.
I like that idea!
Of the two names I'd probably go with reset_image_select.
quoted
+What: /sys/class/cxl/<card>/reset_loads_image
+Date: December 2014
+Contact: linuxppc-dev@lists.ozlabs.org
+Description: read/write
+ Value of 0 means PERST will not cause image load. A power
+ cycle is required to load the image. Value of 1 means PERST
+ will cause image load.
It also seems to be that having this disabled also means that PERST
doesn't fully reset the card. Might want to clarify that somewhat and
recommend it only be disabled for debugging purposes (e.g. to retain
the contents of the PSL trace arrays across a reset), and to always
enable it for production.
Yeah, that is the main reason you'd disable it. Will add that info to
the doc.
At the moment we don't set it at boot - we just go with whatever the
card is already set to do. I'm thinking it might be a good idea to
always set this bit on boot so the only time it's disabled is if a user
has explicitly gone and disabled it.