diff options
author | Alexey Kardashevskiy <aik@ozlabs.ru> | 2019-12-02 16:42:40 +1100 |
---|---|---|
committer | Oliver O'Halloran <oohall@gmail.com> | 2019-12-04 14:19:24 +1100 |
commit | 08cd61e9d078419af6ef96ad7e626ae4ed5de9b6 (patch) | |
tree | 632530bcf2265dd88d6c5190bff681250a3d62f6 | |
parent | 7853fc53cfccc20e7cca0b0bf18c5e84cd5d306c (diff) | |
download | skiboot-08cd61e9d078419af6ef96ad7e626ae4ed5de9b6.zip skiboot-08cd61e9d078419af6ef96ad7e626ae4ed5de9b6.tar.gz skiboot-08cd61e9d078419af6ef96ad7e626ae4ed5de9b6.tar.bz2 |
phb4: Add PHB options get/set OPAL calls
These are new OPAL calls to tweak various PHB parameters.
The first two are:
- TVT Select 'GTE4GB' Option of the PHB control register to enable use
of the second TVE for DMA trafic just above 4GB;
- MMIO EEH Disable to disable EEH for all MMIO commands.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
-rw-r--r-- | core/pci-opal.c | 40 | ||||
-rw-r--r-- | doc/opal-api/index.rst | 4 | ||||
-rw-r--r-- | doc/opal-api/opal-phb-flag-set-get-179-180.rst | 63 | ||||
-rw-r--r-- | hw/phb4.c | 59 | ||||
-rw-r--r-- | include/opal-api.h | 9 | ||||
-rw-r--r-- | include/pci.h | 5 |
6 files changed, 179 insertions, 1 deletions
diff --git a/core/pci-opal.c b/core/pci-opal.c index 828ce8a..ce8de63 100644 --- a/core/pci-opal.c +++ b/core/pci-opal.c @@ -461,6 +461,46 @@ static int64_t opal_pci_map_pe_dma_window_real(uint64_t phb_id, } opal_call(OPAL_PCI_MAP_PE_DMA_WINDOW_REAL, opal_pci_map_pe_dma_window_real, 5); +static int64_t opal_phb_set_option(uint64_t phb_id, uint64_t opt, + uint64_t setting) +{ + struct phb *phb = pci_get_phb(phb_id); + int64_t rc; + + if (!phb) + return OPAL_PARAMETER; + + if (!phb->ops->set_option) + return OPAL_UNSUPPORTED; + + phb_lock(phb); + rc = phb->ops->set_option(phb, opt, setting); + phb_unlock(phb); + + return rc; +} +opal_call(OPAL_PHB_SET_OPTION, opal_phb_set_option, 3); + +static int64_t opal_phb_get_option(uint64_t phb_id, uint64_t opt, + uint64_t *setting) +{ + struct phb *phb = pci_get_phb(phb_id); + int64_t rc; + + if (!phb || !setting) + return OPAL_PARAMETER; + + if (!phb->ops->get_option) + return OPAL_UNSUPPORTED; + + phb_lock(phb); + rc = phb->ops->get_option(phb, opt, setting); + phb_unlock(phb); + + return rc; +} +opal_call(OPAL_PHB_GET_OPTION, opal_phb_get_option, 3); + static int64_t opal_pci_reset(uint64_t id, uint8_t reset_scope, uint8_t assert_state) { diff --git a/doc/opal-api/index.rst b/doc/opal-api/index.rst index 96ce62a..6631088 100644 --- a/doc/opal-api/index.rst +++ b/doc/opal-api/index.rst @@ -390,6 +390,10 @@ The OPAL API is the interface between an Operating System and OPAL. +---------------------------------------------+--------------+------------------------+----------+-----------------+ | :ref:`OPAL_MPIPL_QUERY_TAG` | 175 | Future, likely 6.4 | POWER9 | | +---------------------------------------------+--------------+------------------------+----------+-----------------+ +| :ref:`OPAL_PHB_SET_OPTION` | 179 | Future, likely 6.6 | POWER9 | | ++---------------------------------------------+--------------+------------------------+----------+-----------------+ +| :ref:`OPAL_PHB_GET_OPTION` | 180 | Future, likely 6.6 | POWER9 | | ++---------------------------------------------+--------------+------------------------+----------+-----------------+ .. toctree:: :maxdepth: 1 diff --git a/doc/opal-api/opal-phb-flag-set-get-179-180.rst b/doc/opal-api/opal-phb-flag-set-get-179-180.rst new file mode 100644 index 0000000..babc837 --- /dev/null +++ b/doc/opal-api/opal-phb-flag-set-get-179-180.rst @@ -0,0 +1,63 @@ +.. _OPAL_PHB_SET_OPTION: + +OPAL_PHB_SET_OPTION +=================== + +.. code-block:: c + + #define OPAL_PHB_SET_OPTION 179 + + int64_t opal_phb_set_option(uint64_t phb_id, uint64_t opt, uint64_t setting); + + +This call translate an PHB option to a PHB flag for specific PHB model and +writes it to the hardware. + +Supported options are: + +.. code-block:: c + + enum OpalPhbOption { + OPAL_PHB_OPTION_TVE1_4GB = 0x1, + OPAL_PHB_OPTION_MMIO_EEH_DISABLE = 0x2 + }; + +OPAL_PHB_OPTION_TVE1_4GB: If set, uses TVE#1 for DMA access above 4GB; allowed setting 0 or 1. + +OPAL_PHB_OPTION_MMIO_EEH_DISABLE: Disables EEH for all MMIO commands; allowed setting 0 or 1. + +Returns +------- + +:ref:`OPAL_SUCCESS` + Success +:ref:`OPAL_UNSUPPORTED` + if either the call or the option is not supported +:ref:`OPAL_PARAMETER` + if PHB is unknown or a new setting is out of range + +.. _OPAL_PHB_GET_OPTION: + +OPAL_PHB_GET_OPTION +=================== + +.. code-block:: c + + #define OPAL_PHB_GET_OPTION 180 + + int64_t opal_phb_get_option(uint64_t phb_id, uint64_t opt, uint64_t *setting); + +This call reads the hardware specific PHB flag and translates to a PHB option. + +For the list of supported options refer to OPAL_PHB_SET_OPTION above. + +Returns +------- + +:ref:`OPAL_SUCCESS` + Success +:ref:`OPAL_UNSUPPORTED` + if either the call or the option is not supported +:ref:`OPAL_PARAMETER` + if PHB is unknown or a new setting is out of range or no memory + allocated for the return value @@ -1534,6 +1534,63 @@ static int64_t phb4_map_pe_dma_window_real(struct phb *phb, return OPAL_SUCCESS; } +static int64_t phb4_set_option(struct phb *phb, enum OpalPhbOption opt, + uint64_t setting) +{ + struct phb4 *p = phb_to_phb4(phb); + uint64_t data64; + + data64 = phb4_read_reg(p, PHB_CTRLR); + switch (opt) { + case OPAL_PHB_OPTION_TVE1_4GB: + if (setting > 1) + return OPAL_PARAMETER; + + PHBDBG(p, "4GB bypass mode = %lld\n", setting); + if (setting) + data64 |= PPC_BIT(24); + else + data64 &= ~PPC_BIT(24); + break; + case OPAL_PHB_OPTION_MMIO_EEH_DISABLE: + if (setting > 1) + return OPAL_PARAMETER; + + PHBDBG(p, "MMIO EEH Disable = %lld\n", setting); + if (setting) + data64 |= PPC_BIT(14); + else + data64 &= ~PPC_BIT(14); + break; + default: + return OPAL_UNSUPPORTED; + } + phb4_write_reg(p, PHB_CTRLR, data64); + + return OPAL_SUCCESS; +} + +static int64_t phb4_get_option(struct phb *phb, enum OpalPhbOption opt, + uint64_t *setting) +{ + struct phb4 *p = phb_to_phb4(phb); + uint64_t data64; + + data64 = phb4_read_reg(p, PHB_CTRLR); + switch (opt) { + case OPAL_PHB_OPTION_TVE1_4GB: + *setting = (data64 & PPC_BIT(24)) ? 1 : 0; + break; + case OPAL_PHB_OPTION_MMIO_EEH_DISABLE: + *setting = (data64 & PPC_BIT(14)) ? 1 : 0; + break; + default: + return OPAL_UNSUPPORTED; + } + + return OPAL_SUCCESS; +} + static int64_t phb4_set_ive_pe(struct phb *phb, uint64_t pe_number, uint32_t ive_num) @@ -4796,6 +4853,8 @@ static const struct phb_ops phb4_ops = { .map_pe_mmio_window = phb4_map_pe_mmio_window, .map_pe_dma_window = phb4_map_pe_dma_window, .map_pe_dma_window_real = phb4_map_pe_dma_window_real, + .set_option = phb4_set_option, + .get_option = phb4_get_option, .set_xive_pe = phb4_set_ive_pe, .get_msi_32 = phb4_get_msi_32, .get_msi_64 = phb4_get_msi_64, diff --git a/include/opal-api.h b/include/opal-api.h index b577952..d92ecf5 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -225,7 +225,9 @@ #define OPAL_SECVAR_GET 176 #define OPAL_SECVAR_GET_NEXT 177 #define OPAL_SECVAR_ENQUEUE_UPDATE 178 -#define OPAL_LAST 178 +#define OPAL_PHB_SET_OPTION 179 +#define OPAL_PHB_GET_OPTION 180 +#define OPAL_LAST 180 #define QUIESCE_HOLD 1 /* Spin all calls at entry */ #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ @@ -524,6 +526,11 @@ enum OpalCheckTokenStatus { OPAL_TOKEN_PRESENT = 1 }; +enum OpalPhbOption { + OPAL_PHB_OPTION_TVE1_4GB = 0x1, + OPAL_PHB_OPTION_MMIO_EEH_DISABLE = 0x2, +}; + /* * Address cycle types for LPC accesses. These also correspond * to the content of the first cell of the "reg" property for diff --git a/include/pci.h b/include/pci.h index fb91d79..a808b68 100644 --- a/include/pci.h +++ b/include/pci.h @@ -291,6 +291,11 @@ struct phb_ops { uint64_t pci_start_addr, uint64_t pci_mem_size); + int64_t (*set_option)(struct phb *phb, enum OpalPhbOption opt, + uint64_t setting); + int64_t (*get_option)(struct phb *phb, enum OpalPhbOption opt, + uint64_t *setting); + int64_t (*set_mve)(struct phb *phb, uint32_t mve_number, uint64_t pe_number); |