diff options
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/ti/k3-navss-ringacc-u-boot.c | 61 | ||||
-rw-r--r-- | drivers/soc/ti/k3-navss-ringacc.c | 36 |
2 files changed, 94 insertions, 3 deletions
diff --git a/drivers/soc/ti/k3-navss-ringacc-u-boot.c b/drivers/soc/ti/k3-navss-ringacc-u-boot.c new file mode 100644 index 0000000000..f958239c2a --- /dev/null +++ b/drivers/soc/ti/k3-navss-ringacc-u-boot.c @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * U-Boot specific helpers for TI K3 AM65x NAVSS Ring accelerator + * Manager (RA) subsystem driver + * + * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com + */ + +struct k3_nav_ring_cfg_regs { + u32 resv_64[16]; + u32 ba_lo; /* Ring Base Address Lo Register */ + u32 ba_hi; /* Ring Base Address Hi Register */ + u32 size; /* Ring Size Register */ + u32 event; /* Ring Event Register */ + u32 orderid; /* Ring OrderID Register */ +}; + +#define KNAV_RINGACC_CFG_REGS_STEP 0x100 + +#define KNAV_RINGACC_CFG_RING_BA_HI_ADDR_HI_MASK GENMASK(15, 0) + +#define KNAV_RINGACC_CFG_RING_SIZE_QMODE_MASK GENMASK(31, 30) +#define KNAV_RINGACC_CFG_RING_SIZE_QMODE_SHIFT (30) + +#define KNAV_RINGACC_CFG_RING_SIZE_ELSIZE_MASK GENMASK(26, 24) +#define KNAV_RINGACC_CFG_RING_SIZE_ELSIZE_SHIFT (24) + +static void k3_ringacc_ring_reset_raw(struct k3_nav_ring *ring) +{ + writel(0, &ring->cfg->size); +} + +static void k3_ringacc_ring_reconfig_qmode_raw(struct k3_nav_ring *ring, enum k3_nav_ring_mode mode) +{ + u32 val; + + val = readl(&ring->cfg->size); + val &= KNAV_RINGACC_CFG_RING_SIZE_QMODE_MASK; + val |= mode << KNAV_RINGACC_CFG_RING_SIZE_QMODE_SHIFT; + writel(val, &ring->cfg->size); +} + +static void k3_ringacc_ring_free_raw(struct k3_nav_ring *ring) +{ + writel(0, &ring->cfg->ba_hi); + writel(0, &ring->cfg->ba_lo); + writel(0, &ring->cfg->size); +} + +static void k3_nav_ringacc_ring_cfg_raw(struct k3_nav_ring *ring) +{ + u32 val; + + writel(lower_32_bits(ring->ring_mem_dma), &ring->cfg->ba_lo); + writel(upper_32_bits(ring->ring_mem_dma), &ring->cfg->ba_hi); + + val = ring->mode << KNAV_RINGACC_CFG_RING_SIZE_QMODE_SHIFT | + ring->elm_size << KNAV_RINGACC_CFG_RING_SIZE_ELSIZE_SHIFT | + ring->size; + writel(val, &ring->cfg->size); +} diff --git a/drivers/soc/ti/k3-navss-ringacc.c b/drivers/soc/ti/k3-navss-ringacc.c index b5a5c9da98..f110d78ce1 100644 --- a/drivers/soc/ti/k3-navss-ringacc.c +++ b/drivers/soc/ti/k3-navss-ringacc.c @@ -124,6 +124,7 @@ struct k3_nav_ring_state { /** * struct k3_nav_ring - RA Ring descriptor * + * @cfg - Ring configuration registers * @rt - Ring control/status registers * @fifos - Ring queues registers * @ring_mem_dma - Ring buffer dma address @@ -138,6 +139,7 @@ struct k3_nav_ring_state { * @use_count - Use count for shared rings */ struct k3_nav_ring { + struct k3_nav_ring_cfg_regs __iomem *cfg; struct k3_nav_ring_rt_regs __iomem *rt; struct k3_nav_ring_fifo_regs __iomem *fifos; dma_addr_t ring_mem_dma; @@ -195,6 +197,8 @@ struct k3_nav_ringacc { bool dual_ring; }; +#include "k3-navss-ringacc-u-boot.c" + static int k3_nav_ringacc_ring_read_occ(struct k3_nav_ring *ring) { return readl(&ring->rt->occ) & KNAV_RINGACC_RT_OCC_MASK; @@ -330,6 +334,9 @@ static void k3_ringacc_ring_reset_sci(struct k3_nav_ring *ring) struct k3_nav_ringacc *ringacc = ring->parent; int ret; + if (IS_ENABLED(CONFIG_K3_DM_FW)) + return k3_ringacc_ring_reset_raw(ring); + ret = ringacc->tisci_ring_ops->config( ringacc->tisci, TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID, @@ -362,6 +369,9 @@ static void k3_ringacc_ring_reconfig_qmode_sci(struct k3_nav_ring *ring, struct k3_nav_ringacc *ringacc = ring->parent; int ret; + if (IS_ENABLED(CONFIG_K3_DM_FW)) + return k3_ringacc_ring_reconfig_qmode_raw(ring, mode); + ret = ringacc->tisci_ring_ops->config( ringacc->tisci, TI_SCI_MSG_VALUE_RM_RING_MODE_VALID, @@ -442,6 +452,9 @@ static void k3_ringacc_ring_free_sci(struct k3_nav_ring *ring) struct k3_nav_ringacc *ringacc = ring->parent; int ret; + if (IS_ENABLED(CONFIG_K3_DM_FW)) + return k3_ringacc_ring_free_raw(ring); + ret = ringacc->tisci_ring_ops->config( ringacc->tisci, TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER, @@ -531,11 +544,21 @@ static int k3_nav_ringacc_ring_cfg_sci(struct k3_nav_ring *ring) ring->mode, ring->elm_size, 0); - if (ret) + if (ret) { dev_err(ringacc->dev, "TISCI config ring fail (%d) ring_idx %d\n", ret, ring_idx); + return ret; + } - return ret; + /* + * Above TI SCI call handles firewall configuration, cfg + * register configuration still has to be done locally in + * absence of RM services. + */ + if (IS_ENABLED(CONFIG_K3_DM_FW)) + k3_nav_ringacc_ring_cfg_raw(ring); + + return 0; } static int k3_dmaring_ring_cfg(struct k3_nav_ring *ring, struct k3_nav_ring_cfg *cfg) @@ -951,13 +974,18 @@ static int k3_nav_ringacc_probe_dt(struct k3_nav_ringacc *ringacc) static int k3_nav_ringacc_init(struct udevice *dev, struct k3_nav_ringacc *ringacc) { - void __iomem *base_rt; + void __iomem *base_cfg, *base_rt; int ret, i; ret = k3_nav_ringacc_probe_dt(ringacc); if (ret) return ret; + base_cfg = dev_remap_addr_name(dev, "cfg"); + pr_debug("cfg %p\n", base_cfg); + if (!base_cfg) + return -EINVAL; + base_rt = (uint32_t *)devfdt_get_addr_name(dev, "rt"); pr_debug("rt %p\n", base_rt); if (IS_ERR(base_rt)) @@ -975,6 +1003,8 @@ static int k3_nav_ringacc_init(struct udevice *dev, struct k3_nav_ringacc *ringa return -ENOMEM; for (i = 0; i < ringacc->num_rings; i++) { + ringacc->rings[i].cfg = base_cfg + + KNAV_RINGACC_CFG_REGS_STEP * i; ringacc->rings[i].rt = base_rt + KNAV_RINGACC_RT_REGS_STEP * i; ringacc->rings[i].parent = ringacc; |