[Skiboot] [PATCH 2/2] phb3: Add support for CAPP DMA mode
Frederic Barrat
fbarrat at linux.vnet.ibm.com
Thu May 26 23:03:45 AEST 2016
I've reviewed the 2 patches, and they look good to me, as far as I can tell.
Reviewed-by: Frederic Barrat <fbarrat at linux.vnet.ibm.com>
Fred
Le 24/05/2016 13:22, Ian Munsie a écrit :
> From: Ian Munsie <imunsie at au1.ibm.com>
>
> The XSL used in the Mellanox CX4 card uses a DMA mode of CAPI, which
> requires a few registers configured specially. In addition to enabling
> the mode,
>
> - The CAPP only owns some of the PHB read buffers, and must be
> configured to use the correct ones, and the self-snoop configured for
> the same ones.
>
> - The tve needs to be configured to allow the card to access all kernel
> memory as it uses DMA accesses to read the scheduled process area from
> the kernel, among other things.
>
> These cannot be configured unconditionally, as doing so will break
> existing CAPI devices that do not use DMA mode. This adds a new mode to
> the OPAL_PCI_SET_PHB_CAPI_MODE API to enable CAPI in DMA mode.
>
> Since the snoop on/off modes write to the capi snoop configuration
> register, which is configured differently in DMA mode, it uses the
> redundant bits from the apc master powerbus control register to
> determine if it should configure the register for DMA mode rather than
> requiring any more permutations of the mode parameter.
>
> Signed-off-by: Ian Munsie <imunsie at au1.ibm.com>
> ---
> hw/phb3.c | 56 ++++++++++++++++++++++++++++++++++++++++++++----------
> include/opal-api.h | 1 +
> 2 files changed, 47 insertions(+), 10 deletions(-)
>
> diff --git a/hw/phb3.c b/hw/phb3.c
> index b2be3e4..3bfa000 100644
> --- a/hw/phb3.c
> +++ b/hw/phb3.c
> @@ -3324,14 +3324,22 @@ static int64_t phb3_get_diag_data(struct phb *phb,
> return OPAL_SUCCESS;
> }
>
> -static void phb3_init_capp_regs(struct phb3 *p)
> +static void phb3_init_capp_regs(struct phb3 *p, bool dma_mode)
> {
> uint64_t reg;
> uint32_t offset;
> + uint64_t read_buffers = 0;
> +
> + if (dma_mode) {
> + /* In DMA mode, the CAPP only owns some of the PHB read buffers */
> + read_buffers = 0x1;
> + }
>
> offset = PHB3_CAPP_REG_OFFSET(p);
> xscom_read(p->chip_id, APC_MASTER_PB_CTRL + offset, ®);
> + reg &= ~PPC_BITMASK(10, 11);
> reg |= PPC_BIT(3);
> + reg |= read_buffers << PPC_BITLSHIFT(11);
> xscom_write(p->chip_id, APC_MASTER_PB_CTRL + offset, reg);
>
> /* Dynamically workout which PHB to connect to port 0 of the CAPP.
> @@ -3378,7 +3386,10 @@ static void phb3_init_capp_regs(struct phb3 *p)
> xscom_write(p->chip_id, FLUSH_UOP_CONFIG1 + offset,
> 0xB188280728000000);
> xscom_write(p->chip_id, FLUSH_UOP_CONFIG2 + offset, 0xB188400F00000000);
> - xscom_write(p->chip_id, SNOOP_CAPI_CONFIG + offset, 0xA1F0000000000000);
> +
> + reg = 0xA1F0000000000000;
> + reg |= read_buffers << PPC_BITLSHIFT(39);
> + xscom_write(p->chip_id, SNOOP_CAPI_CONFIG + offset, reg);
> }
>
> /* override some inits with CAPI defaults */
> @@ -3395,7 +3406,7 @@ static void phb3_init_capp_errors(struct phb3 *p)
> #define PE_REG_OFFSET(p) \
> ((PHB3_IS_NAPLES(p) && (p)->index) ? 0x40 : 0x0)
>
> -static int64_t enable_capi_mode(struct phb3 *p, uint64_t pe_number)
> +static int64_t enable_capi_mode(struct phb3 *p, uint64_t pe_number, bool dma_mode)
> {
> uint64_t reg;
> int i;
> @@ -3417,7 +3428,12 @@ static int64_t enable_capi_mode(struct phb3 *p, uint64_t pe_number)
> return OPAL_HARDWARE;
> }
>
> - xscom_write(p->chip_id, p->spci_xscom + 0x3, 0x8000000000000000ull);
> + /* pb aib capp enable */
> + reg = PPC_BIT(0); /* capp enable */
> + if (dma_mode)
> + reg |= PPC_BIT(1); /* capp dma mode */
> + xscom_write(p->chip_id, p->spci_xscom + 0x3, reg);
> +
> /* FIXME security timer bar
> xscom_write(p->chip_id, p->spci_xscom + 0x4, 0x8000000000000000ull);
> */
> @@ -3456,8 +3472,16 @@ static int64_t enable_capi_mode(struct phb3 *p, uint64_t pe_number)
>
> /* set tve no translate mode allow mmio window */
> memset(p->tve_cache, 0x0, sizeof(p->tve_cache));
> - /* Allow address range 0x0002000000000000: 0x0002FFFFFFFFFFF */
> - p->tve_cache[pe_number * 2] = 0x000000FFFFFF0a00ULL;
> + if (dma_mode) {
> + /*
> + * CAPP DMA mode needs access to all of memory, set address
> + * range to 0x0000000000000000: 0x0002FFFFFFFFFFF
> + */
> + p->tve_cache[pe_number * 2] = 0x000000FFFFFF0200ULL;
> + } else {
> + /* Allow address range 0x0002000000000000: 0x0002FFFFFFFFFFF */
> + p->tve_cache[pe_number * 2] = 0x000000FFFFFF0a00ULL;
> + }
>
> phb3_ioda_sel(p, IODA2_TBL_TVT, 0, true);
> for (i = 0; i < ARRAY_SIZE(p->tve_cache); i++)
> @@ -3484,7 +3508,7 @@ static int64_t enable_capi_mode(struct phb3 *p, uint64_t pe_number)
>
> phb3_init_capp_errors(p);
>
> - phb3_init_capp_regs(p);
> + phb3_init_capp_regs(p, dma_mode);
>
> if (!chiptod_capp_timebase_sync(p)) {
> PHBERR(p, "CAPP: Failed to sync timebase\n");
> @@ -3500,6 +3524,7 @@ static int64_t phb3_set_capi_mode(struct phb *phb, uint64_t mode,
> struct phb3 *p = phb_to_phb3(phb);
> struct proc_chip *chip = get_chip(p->chip_id);
> uint64_t reg;
> + uint64_t read_buffers;
> uint32_t offset;
> u8 mask;
>
> @@ -3545,7 +3570,10 @@ static int64_t phb3_set_capi_mode(struct phb *phb, uint64_t mode,
> return OPAL_UNSUPPORTED;
>
> case OPAL_PHB_CAPI_MODE_CAPI:
> - return enable_capi_mode(p, pe_number);
> + return enable_capi_mode(p, pe_number, false);
> +
> + case OPAL_PHB_CAPI_MODE_DMA:
> + return enable_capi_mode(p, pe_number, true);
>
> case OPAL_PHB_CAPI_MODE_SNOOP_OFF:
> xscom_write(p->chip_id, SNOOP_CAPI_CONFIG + offset,
> @@ -3555,8 +3583,16 @@ static int64_t phb3_set_capi_mode(struct phb *phb, uint64_t mode,
> case OPAL_PHB_CAPI_MODE_SNOOP_ON:
> xscom_write(p->chip_id, CAPP_ERR_STATUS_CTRL + offset,
> 0x0000000000000000);
> - xscom_write(p->chip_id, SNOOP_CAPI_CONFIG + offset,
> - 0xA1F0000000000000);
> + /*
> + * Make sure the PHB read buffers being snooped match those
> + * being used so we don't need another mode to set SNOOP+DMA
> + */
> + xscom_read(p->chip_id, APC_MASTER_PB_CTRL + offset, ®);
> + read_buffers = (reg >> PPC_BITLSHIFT(11)) & 0x3;
> + reg = 0xA1F0000000000000;
> + reg |= read_buffers << PPC_BITLSHIFT(39);
> + xscom_write(p->chip_id, SNOOP_CAPI_CONFIG + offset, reg);
> +
> return OPAL_SUCCESS;
> }
>
> diff --git a/include/opal-api.h b/include/opal-api.h
> index 0b7b0bb..e116207 100644
> --- a/include/opal-api.h
> +++ b/include/opal-api.h
> @@ -951,6 +951,7 @@ enum {
> OPAL_PHB_CAPI_MODE_CAPI = 1,
> OPAL_PHB_CAPI_MODE_SNOOP_OFF = 2,
> OPAL_PHB_CAPI_MODE_SNOOP_ON = 3,
> + OPAL_PHB_CAPI_MODE_DMA = 4,
> };
>
> /* CAPI feature flags (in device-tree) */
>
More information about the Skiboot
mailing list