[Skiboot] [PATCH 3/5] NX: Add P9 NX support for 842 compression engine
Sukadev Bhattiprolu
sukadev at linux.vnet.ibm.com
Wed Feb 22 07:07:09 AEDT 2017
Haren Myneni [haren at linux.vnet.ibm.com] wrote:
>
> This patch adds changes needed for 842 compression engine on power 9.
> Virtual Accelerator Switch (VAS) is used to access NX 842 engine on P9
> and the chasnnel setup be will done with receive FIFO. So RxFIFO
> address, logical partition ID (lpid), process ID (pid) and thread ID
> (tid) are used for this setup. p9 NX supports high and normal priority
> FIFOs. skiboot is not involved to process data with 842 engine, but
> configures User Mode Access Control (UMAC) registers with these values
> and provide them to kernel.
>
> Also configures registers to setup and enable / disable the engine with
nit: /configures/configure the/
> the appropriate registers. Creates the following device-tree entries to
> provide RxFIFO address, lpid, pid and tid values so that kernel can
> drive P9 NX 842 engine.
>
> /ibm,nx-842-high : High priority 842 RxFIFO
> /ibm,nx-842-normal : Normal priority 842 RxFIFO
These nodes are in the xscom* directory? Would be useful to mention that.
>
> Each RxFIFO node contains:
> rx-fifo-address : Address represents for RxFIFO buffer
nit: s/represents for/of/
Maybe a note to say that we want to allocate a large contiguous buffer
so we allocate in skiboot and pass address to kernel?
> lpid : Chip ID
> pid : 842 coprocessor type
> tid : Priority (either high or normal)
Does the hardware require these mapping or is it just a simple way of
finding unique values for LPID/PID/TID? If so, see also the GCID2LPID()
suggestion below.
>
> Signed-off-by: Haren Myneni <haren at us.ibm.com>
> ---
> hw/nx-842.c | 68 ++++++++++++++++++--
> hw/nx-compress.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
> include/nx.h | 4 +
> 3 files changed, 242 insertions(+), 8 deletions(-)
>
> diff --git a/hw/nx-842.c b/hw/nx-842.c
> index 3ccb549..a284803 100644
> --- a/hw/nx-842.c
> +++ b/hw/nx-842.c
> @@ -20,12 +20,13 @@
> #include <io.h>
> #include <cpu.h>
> #include <nx.h>
> +#include <vas.h>
>
> /* Configuration settings */
> #define CFG_842_FC_ENABLE (0x1f) /* enable all 842 functions */
> #define CFG_842_ENABLE (1) /* enable 842 engines */
> -#define DMA_COMPRESS_PREFETCH (1) /* enable prefetching (on P8) */
> -#define DMA_DECOMPRESS_PREFETCH (1) /* enable prefetching (on P8) */
> +#define DMA_COMPRESS_PREFETCH (1) /* enable prefetching (on P8 or P9) */
> +#define DMA_DECOMPRESS_PREFETCH (1) /* enable prefetching (on P8 or P9) */
> #define DMA_COMPRESS_MAX_RR (15) /* range 1-15 */
> #define DMA_DECOMPRESS_MAX_RR (15) /* range 1-15 */
> #define DMA_SPBC (1) /* write SPBC in CPB */
> @@ -90,6 +91,32 @@ static int nx_cfg_842(u32 gcid, u64 xcfg)
> return rc;
> }
>
> +static int nx_cfg_842_umac(struct dt_node *node, u32 gcid, u32 pb_base)
> +{
> + int rc;
> + u64 umac_bar, umac_ctrl, umac_notify;
> + struct dt_node *nx_node;
> +
> + nx_node = dt_new(node, "ibm,nx-842-high");
> + umac_bar = pb_base + NX_P9_842_HIGH_PRI_RX_FIFO_BAR;
> + umac_ctrl = pb_base + NX_P9_842_HIGH_PRI_RX_FIFO_CTRL;
> + umac_notify = pb_base + NX_P9_842_HIGH_PRI_RX_FIFO_NOTIFY_MATCH;
> + rc = nx_set_rx_fifo(nx_node, gcid, umac_bar, umac_notify, umac_ctrl,
> + NX_CT_842, RX_FIFO_HIGH_PRIORITY);
> + if (rc)
> + return rc;
> +
> + nx_node= dt_new(node, "ibm,nx-842-normal");
> + umac_bar = pb_base + NX_P9_842_NORMAL_PRI_RX_FIFO_BAR;
> + umac_ctrl = pb_base + NX_P9_842_NORMAL_PRI_RX_FIFO_CTRL;
> + umac_notify = pb_base + NX_P9_842_NORMAL_PRI_RX_FIFO_NOTIFY_MATCH;
> + rc = nx_set_rx_fifo(nx_node, gcid, umac_bar, umac_notify, umac_ctrl,
> + NX_CT_842, RX_FIFO_NORMAL_PRIORITY);
> +
nit: extra new line.
> +
> + return rc;
> +}
> +
> static int nx_cfg_842_dma(u32 gcid, u64 xcfg)
> {
> u64 cfg;
> @@ -99,7 +126,7 @@ static int nx_cfg_842_dma(u32 gcid, u64 xcfg)
> if (rc)
> return rc;
>
> - if (proc_gen == proc_gen_p8) {
> + if (proc_gen >= proc_gen_p8) {
> cfg = SETFIELD(NX_DMA_CFG_842_COMPRESS_PREFETCH, cfg,
> DMA_COMPRESS_PREFETCH);
> cfg = SETFIELD(NX_DMA_CFG_842_DECOMPRESS_PREFETCH, cfg,
> @@ -112,14 +139,16 @@ static int nx_cfg_842_dma(u32 gcid, u64 xcfg)
> DMA_DECOMPRESS_MAX_RR);
> cfg = SETFIELD(NX_DMA_CFG_842_SPBC, cfg,
> DMA_SPBC);
> - cfg = SETFIELD(NX_DMA_CFG_842_CSB_WR, cfg,
> + if (proc_gen < proc_gen_p9) {
> + cfg = SETFIELD(NX_DMA_CFG_842_CSB_WR, cfg,
> DMA_CSB_WR);
> - cfg = SETFIELD(NX_DMA_CFG_842_COMPLETION_MODE, cfg,
> + cfg = SETFIELD(NX_DMA_CFG_842_COMPLETION_MODE, cfg,
> DMA_COMPLETION_MODE);
> - cfg = SETFIELD(NX_DMA_CFG_842_CPB_WR, cfg,
> + cfg = SETFIELD(NX_DMA_CFG_842_CPB_WR, cfg,
> DMA_CPB_WR);
> - cfg = SETFIELD(NX_DMA_CFG_842_OUTPUT_DATA_WR, cfg,
> + cfg = SETFIELD(NX_DMA_CFG_842_OUTPUT_DATA_WR, cfg,
> DMA_OUTPUT_DATA_WR);
> + }
>
> rc = xscom_write(gcid, xcfg, cfg);
> if (rc)
> @@ -188,3 +217,28 @@ void nx_enable_842(struct dt_node *node, u32 gcid, u32 pb_base)
> dt_add_property_cells(node, "ibm,842-coprocessor-type", NX_CT_842);
> dt_add_property_cells(node, "ibm,842-coprocessor-instance", gcid + 1);
> }
> +
> +void p9_nx_enable_842(struct dt_node *node, u32 gcid, u32 pb_base)
> +{
> + u64 cfg_dma, cfg_ee;
> + int rc;
> +
> + cfg_dma = pb_base + NX_P9_DMA_CFG;
> + cfg_ee = pb_base + NX_P9_EE_CFG;
> +
> + rc = nx_cfg_842_dma(gcid, cfg_dma);
> + if (rc)
> + return;
> +
> + rc = nx_cfg_842_umac(node, gcid, pb_base);
> + if (rc)
> + return;
> +
> + rc = nx_cfg_842_ee(gcid, cfg_ee);
> + if (rc)
> + return;
> +
> + prlog(PR_INFO, "NX%d: 842 Coprocessor Enabled\n", gcid);
> +
> +}
> +
> diff --git a/hw/nx-compress.c b/hw/nx-compress.c
> index 2ea2734..b4abe9e 100644
> --- a/hw/nx-compress.c
> +++ b/hw/nx-compress.c
> @@ -20,15 +20,191 @@
> #include <io.h>
> #include <cpu.h>
> #include <nx.h>
> +#include <vas.h>
> +
> +static int nx_cfg_umac_tx_wc(u32 gcid, u64 xcfg)
> +{
> + int rc = 0;
> + u64 cfg;
> +
> + cfg = vas_get_wcbs_bar(gcid);
> + if (!cfg) {
> + prerror("NX%d: ERROR finding WC Backing store BAR\n", gcid);
> + return -ENOMEM;
> + }
> +
> + /*
> + * NOTE: Write the entire bar address to SCOM. VAS/NX will extract
> + * the relevant (NX_P9_UMAC_TX_WINDOW_CONTEXT_ADDR) bits.
> + * IOW, _don't_:
s/:/just write the bit field like:/
> + *
> + * cfg = SETFIELD(NX_P9_UMAC_TX_WINDOW_CONTEXT_ADDR, 0ULL, cfg);
> + */
> + rc = xscom_write (gcid, xcfg, cfg);
> +
> + if (rc)
> + prerror("NX%d: ERROR: UMAC SEND WC BAR, %d\n", gcid, rc);
> + else
> + prlog(PR_DEBUG,"NX%d: UMAC SEND WC BAR, 0x%016lx, "
> + "xcfg 0x%llx\n",
> + gcid, (unsigned long)cfg, xcfg);
> +
> + return rc;
> +}
> +
> +static int nx_cfg_umac_vas_mmio(u32 gcid, u64 xcfg)
> +{
> + int rc = 0;
> + u64 cfg;
> +
> + cfg = vas_get_hvwc_mmio_bar(gcid);
> + /*
> + * NOTE: Write the entire bar address to SCOM. VAS/NX will extract
> + * the relevant (NX_P9_UMAC_VAS_MMIO_ADDR) bits. IOW, _don't_:
s/:/just write the bit field like:/
> + *
> + * cfg = SETFIELD(NX_P9_UMAC_VAS_MMIO_ADDR, 0ULL, cfg);
> + */
> + rc = xscom_write (gcid, xcfg, cfg);
> +
> + if (rc)
> + prerror("NX%d: ERROR: UMAC VAS MMIO BAR, %d\n", gcid, rc);
> + else
> + prlog(PR_DEBUG, "NX%d: UMAC VAS MMIO BAR, 0x%016lx, "
> + "xcfg 0x%llx\n",
> + gcid, (unsigned long)cfg, xcfg);
> +
> + return rc;
> +}
> +
> +static int nx_cfg_umac_status_ctrl(u32 gcid, u64 xcfg)
> +{
> + u64 uctrl;
> + int rc;
> +#define CRB_ENABLE 1
> +
> + rc = xscom_read(gcid, xcfg, &uctrl);
> + if (rc)
> + return rc;
> +
> + uctrl = SETFIELD(NX_P9_UMAC_STATUS_CTRL_CRB_ENABLE, uctrl, CRB_ENABLE);
> + rc = xscom_write(gcid, xcfg, uctrl);
> + if (rc)
> + prerror("NX%d: ERROR: Setting UMAC Status Control failure %d\n",
> + gcid, rc);
> + else
> + prlog(PR_DEBUG, "NX%d: Setting UMAC FIFO bar 0x%016lx\n",
> + gcid, (unsigned long)uctrl);
> +
> + return rc;
> +}
> +
> +int nx_set_rx_fifo(struct dt_node *node, u32 gcid, u64 umac_bar,
s/nx_set_rx_fifo/nx_cfg_rx_fifo/ for consistency?
> + u64 umac_notify, u64 umac_ctrl,
> + u32 ct_type, u32 priority)
s/ct_type/ct/?
> +{
> + u64 cfg;
> + int rc;
> + uint64_t fifo;
> +#define MATCH_ENABLE 1
> +#define MAX_QUEUED 256
> +#define HPRI_MAX_READ 256
> +
> + fifo = (uint64_t) local_alloc(gcid, RX_FIFO_SIZE, RX_FIFO_SIZE);
> + assert(fifo);
> +
> + rc = xscom_read(gcid, umac_bar, &cfg);
> + if (rc)
> + return rc;
> +
> + cfg = SETFIELD(NX_P9_RX_FIFO_BAR_ADDR, cfg, fifo);
> + cfg = SETFIELD(NX_P9_RX_FIFO_BAR_SIZE, cfg, RX_FIFO_MAX_CRB);
According to the spec, I think we need to replace RX_FIFO_MAX_CRB with 0x5.
Basically, the
log(RX_FIFO_MAX_CRB/1024)
> +
> + rc = xscom_write(gcid, umac_bar, cfg);
> + if (rc) {
> + prerror("NX%d: ERROR: Setting UMAC FIFO bar failure %d\n",
> + gcid, rc);
> + return rc;
> + } else
> + prlog(PR_DEBUG, "NX%d: Setting UMAC FIFO bar 0x%016lx\n",
> + gcid, (unsigned long)cfg);
> +
> + rc = xscom_read(gcid, umac_notify, &cfg);
> + if (rc)
> + return rc;
> +
> + prerror(" Skiboot1 RX fifo address 0x%Lx lpid %d pid %d tid %d\n",
> + fifo, gcid + 1, ct_type, priority);
> +
> + cfg = SETFIELD(NX_P9_RX_FIFO_NOTIFY_MATCH_LPID, cfg, gcid + 1);
> + cfg = SETFIELD(NX_P9_RX_FIFO_NOTIFY_MATCH_PID, cfg, ct_type);
> + cfg = SETFIELD(NX_P9_RX_FIFO_NOTIFY_MATCH_TID, cfg, priority);
We are using gcid, ct_type and priority as LPID/PID/TID in multiple
places. Maybe good to add a comment or use simple wrappers like
GCID2LPID(gcid), CT2PID(ct), PRI2TID(priority)
> + cfg = SETFIELD(NX_P9_RX_FIFO_NOTIFY_MATCH_MATCH_ENABLE, cfg,
> + MATCH_ENABLE);
> +
> + rc = xscom_write(gcid, umac_notify, cfg);
> + if (rc) {
> + prerror("NX%d: ERROR: Setting UMAC notify match failure %d\n",
> + gcid, rc);
> + return rc;
> + } else
> + prlog(PR_DEBUG, "NX%d: Setting UMAC notify match 0x%016lx\n",
> + gcid, (unsigned long)cfg);
> +
> + rc = xscom_read(gcid, umac_ctrl, &cfg);
> + if (rc)
> + return rc;
> +
> + cfg = SETFIELD(NX_P9_RX_FIFO_CTRL_QUEUED, cfg, MAX_QUEUED);
> + cfg = SETFIELD(NX_P9_RX_FIFO_CTRL_HPRI_MAX_READ, cfg, HPRI_MAX_READ);
> +
> + rc = xscom_write(gcid, umac_ctrl, cfg);
> + if (rc) {
> + prerror("NX%d: ERROR: Setting UMAC control failure %d\n",
> + gcid, rc);
> + return rc;
> + } else
> + prlog(PR_DEBUG, "NX%d: Setting UMAC control 0x%016lx\n",
> + gcid, (unsigned long)cfg);
> +
> + dt_add_property_u64(node, "rx-fifo-address", fifo);
> + dt_add_property_cells(node, "lpid", gcid + 1);
> + dt_add_property_cells(node, "pid", ct_type);
> + dt_add_property_cells(node, "tid", priority);
> +
> + return 0;
> +}
>
> void nx_create_compress_node(struct dt_node *node)
> {
> u32 gcid, pb_base;
> + int rc;
>
> gcid = dt_get_chip_id(node);
> pb_base = dt_get_address(node, 0, NULL);
>
> prlog(PR_INFO, "NX%d: 842 at 0x%x\n", gcid, pb_base);
>
> - nx_enable_842(node, gcid, pb_base);
> + if (dt_node_is_compatible(node, "ibm,power9-nx")) {
> + u64 cfg_mmio, cfg_txwc, cfg_uctrl;
> +
> + printf("Found ibm,power9-nx\n");
> + cfg_mmio = pb_base + NX_P9_UMAC_VAS_MMIO_BAR;
> + cfg_txwc = pb_base + NX_P9_UMAC_TX_WINDOW_CONTEXT_BAR;
> + cfg_uctrl = pb_base + NX_P9_UMAC_STATUS_CTRL;
> +
> + rc = nx_cfg_umac_vas_mmio(gcid, cfg_mmio);
> + if (rc)
> + return;
> +
> + rc = nx_cfg_umac_tx_wc(gcid, cfg_txwc);
> + if (rc)
> + return;
> +
> + rc = nx_cfg_umac_status_ctrl(gcid, cfg_uctrl);
> + if (rc)
> + return;
> +
> + p9_nx_enable_842(node, gcid, pb_base);
> + } else
> + nx_enable_842(node, gcid, pb_base);
> }
> diff --git a/include/nx.h b/include/nx.h
> index 0a7b1b0..18fa91f 100644
> --- a/include/nx.h
> +++ b/include/nx.h
> @@ -381,7 +381,11 @@ extern void nx_create_crypto_node(struct dt_node *);
> extern void nx_create_compress_node(struct dt_node *);
>
> extern void nx_enable_842(struct dt_node *, u32 gcid, u32 pb_base);
> +extern void p9_nx_enable_842(struct dt_node *, u32 gcid, u32 pb_base);
>
> +extern int nx_set_rx_fifo(struct dt_node *node, u32 gcid, u64 umac_bar,
> + u64 umac_notify, u64 umac_ctrl, u32 ct_type,
> + u32 priority);
> extern void nx_init(void);
>
> #endif /* __NX_H */
> --
> 1.7.1
>
>
More information about the Skiboot
mailing list