diff options
| author | Tom Rini <[email protected]> | 2021-05-12 10:07:21 -0400 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2021-05-12 10:07:21 -0400 |
| commit | ea184cbff99ea1d82dcf94c95afe054e95da5069 (patch) | |
| tree | 48553e6cf25f0b5f34483c3fddafdebbbc240b55 /drivers/soc | |
| parent | 59a2b9e605c5a5e2dff35506a13b51f33d3051b4 (diff) | |
| parent | bbc9da58b332bd44e51ac5579040ea984b2f963b (diff) | |
Merge tag 'ti-v2021.07-rc3' of https://source.denx.de/u-boot/custodians/u-boot-ti
- Initial support for AM64 EVM and SK
- K3 DDR driver unification for J7 and AM64 platforms.
- Minor fixes for TI clock driver
Diffstat (limited to 'drivers/soc')
| -rw-r--r-- | drivers/soc/soc_ti_k3.c | 4 | ||||
| -rw-r--r-- | drivers/soc/ti/k3-navss-ringacc.c | 526 |
2 files changed, 250 insertions, 280 deletions
diff --git a/drivers/soc/soc_ti_k3.c b/drivers/soc/soc_ti_k3.c index ecc3278cb46..9abed7d490a 100644 --- a/drivers/soc/soc_ti_k3.c +++ b/drivers/soc/soc_ti_k3.c @@ -13,6 +13,7 @@ #define AM65X 0xbb5a #define J721E 0xbb64 #define J7200 0xbb6d +#define AM64X 0xbb38 #define REV_SR1_0 0 #define REV_SR2_0 1 @@ -44,6 +45,9 @@ static const char *get_family_string(u32 idreg) case J7200: family = "J7200"; break; + case AM64X: + family = "AM64X"; + break; default: family = "Unknown Silicon"; }; diff --git a/drivers/soc/ti/k3-navss-ringacc.c b/drivers/soc/ti/k3-navss-ringacc.c index c5099ad084d..b5a5c9da98a 100644 --- a/drivers/soc/ti/k3-navss-ringacc.c +++ b/drivers/soc/ti/k3-navss-ringacc.c @@ -23,6 +23,7 @@ #include <linux/err.h> #include <linux/soc/ti/k3-navss-ringacc.h> #include <linux/soc/ti/ti_sci_protocol.h> +#include <linux/soc/ti/cppi5.h> #define set_bit(bit, bitmap) __set_bit(bit, bitmap) #define clear_bit(bit, bitmap) __clear_bit(bit, bitmap) @@ -56,6 +57,7 @@ static u32 ringacc_readl(void __iomem *reg) } #define KNAV_RINGACC_CFG_RING_SIZE_ELCNT_MASK GENMASK(19, 0) +#define K3_DMARING_RING_CFG_RING_SIZE_ELCNT_MASK GENMASK(15, 0) /** * struct k3_nav_ring_rt_regs - The RA Control/Status Registers region @@ -71,6 +73,13 @@ struct k3_nav_ring_rt_regs { }; #define KNAV_RINGACC_RT_REGS_STEP 0x1000 +#define K3_DMARING_RING_RT_REGS_STEP 0x2000 +#define K3_DMARING_RING_RT_REGS_REVERSE_OFS 0x1000 +#define KNAV_RINGACC_RT_OCC_MASK GENMASK(20, 0) +#define K3_DMARING_RING_RT_OCC_TDOWN_COMPLETE BIT(31) +#define K3_DMARING_RING_RT_DB_ENTRY_MASK GENMASK(7, 0) +#define K3_DMARING_RING_RT_DB_TDOWN_ACK BIT(31) + /** * struct k3_nav_ring_fifo_regs - The Ring Accelerator Queues Registers region @@ -82,36 +91,6 @@ struct k3_nav_ring_fifo_regs { u32 peek_tail_data[128]; /* Ring Peek Tail Entry Data Regs */ }; -/** - * struct k3_ringacc_proxy_gcfg_regs - RA Proxy Global Config MMIO Region - */ -struct k3_ringacc_proxy_gcfg_regs { - u32 revision; /* Revision Register */ - u32 config; /* Config Register */ -}; - -#define K3_RINGACC_PROXY_CFG_THREADS_MASK GENMASK(15, 0) - -/** - * struct k3_ringacc_proxy_target_regs - RA Proxy Datapath MMIO Region - */ -struct k3_ringacc_proxy_target_regs { - u32 control; /* Proxy Control Register */ - u32 status; /* Proxy Status Register */ - u8 resv_512[504]; - u32 data[128]; /* Proxy Data Register */ -}; - -#define K3_RINGACC_PROXY_TARGET_STEP 0x1000 -#define K3_RINGACC_PROXY_NOT_USED (-1) - -enum k3_ringacc_proxy_access_mode { - PROXY_ACCESS_MODE_HEAD = 0, - PROXY_ACCESS_MODE_TAIL = 1, - PROXY_ACCESS_MODE_PEEK_HEAD = 2, - PROXY_ACCESS_MODE_PEEK_TAIL = 3, -}; - #define KNAV_RINGACC_FIFO_WINDOW_SIZE_BYTES (512U) #define KNAV_RINGACC_FIFO_REGS_STEP 0x1000 #define KNAV_RINGACC_MAX_DB_RING_CNT (127U) @@ -147,7 +126,6 @@ struct k3_nav_ring_state { * * @rt - Ring control/status registers * @fifos - Ring queues registers - * @proxy - Ring Proxy Datapath registers * @ring_mem_dma - Ring buffer dma address * @ring_mem_virt - Ring buffer virt address * @ops - Ring operations @@ -158,12 +136,10 @@ struct k3_nav_ring_state { * @ring_id - Ring Id * @parent - Pointer on struct @k3_nav_ringacc * @use_count - Use count for shared rings - * @proxy_id - RA Ring Proxy Id (only if @K3_NAV_RINGACC_RING_USE_PROXY) */ struct k3_nav_ring { struct k3_nav_ring_rt_regs __iomem *rt; struct k3_nav_ring_fifo_regs __iomem *fifos; - struct k3_ringacc_proxy_target_regs __iomem *proxy; dma_addr_t ring_mem_dma; void *ring_mem_virt; struct k3_nav_ring_ops *ops; @@ -173,11 +149,11 @@ struct k3_nav_ring { u32 flags; #define KNAV_RING_FLAG_BUSY BIT(1) #define K3_NAV_RING_FLAG_SHARED BIT(2) +#define K3_NAV_RING_FLAG_REVERSE BIT(3) struct k3_nav_ring_state state; u32 ring_id; struct k3_nav_ringacc *parent; u32 use_count; - int proxy_id; }; struct k3_nav_ringacc_ops { @@ -188,8 +164,6 @@ struct k3_nav_ringacc_ops { * struct k3_nav_ringacc - Rings accelerator descriptor * * @dev - pointer on RA device - * @proxy_gcfg - RA proxy global config registers - * @proxy_target_base - RA proxy datapath region * @num_rings - number of ring in RA * @rm_gp_range - general purpose rings range from tisci * @dma_ring_reset_quirk - DMA reset w/a enable @@ -200,17 +174,15 @@ struct k3_nav_ringacc_ops { * @tisci_ring_ops - ti-sci rings ops * @tisci_dev_id - ti-sci device id * @ops: SoC specific ringacc operation + * @dual_ring: indicate k3_dmaring dual ring support */ struct k3_nav_ringacc { struct udevice *dev; - struct k3_ringacc_proxy_gcfg_regs __iomem *proxy_gcfg; - void __iomem *proxy_target_base; u32 num_rings; /* number of rings in Ringacc module */ unsigned long *rings_inuse; struct ti_sci_resource *rm_gp_range; bool dma_ring_reset_quirk; u32 num_proxies; - unsigned long *proxy_inuse; struct k3_nav_ring *rings; struct list_head list; @@ -220,12 +192,22 @@ struct k3_nav_ringacc { u32 tisci_dev_id; const struct k3_nav_ringacc_ops *ops; + bool dual_ring; }; -static long k3_nav_ringacc_ring_get_fifo_pos(struct k3_nav_ring *ring) +static int k3_nav_ringacc_ring_read_occ(struct k3_nav_ring *ring) +{ + return readl(&ring->rt->occ) & KNAV_RINGACC_RT_OCC_MASK; +} + +static void k3_nav_ringacc_ring_update_occ(struct k3_nav_ring *ring) { - return KNAV_RINGACC_FIFO_WINDOW_SIZE_BYTES - - (4 << ring->elm_size); + u32 val; + + val = readl(&ring->rt->occ); + + ring->state.occ = val & KNAV_RINGACC_RT_OCC_MASK; + ring->state.tdown_complete = !!(val & K3_DMARING_RING_RT_OCC_TDOWN_COMPLETE); } static void *k3_nav_ringacc_get_elm_addr(struct k3_nav_ring *ring, u32 idx) @@ -235,38 +217,21 @@ static void *k3_nav_ringacc_get_elm_addr(struct k3_nav_ring *ring, u32 idx) static int k3_nav_ringacc_ring_push_mem(struct k3_nav_ring *ring, void *elem); static int k3_nav_ringacc_ring_pop_mem(struct k3_nav_ring *ring, void *elem); +static int k3_dmaring_ring_fwd_pop_mem(struct k3_nav_ring *ring, void *elem); +static int k3_dmaring_ring_reverse_pop_mem(struct k3_nav_ring *ring, void *elem); static struct k3_nav_ring_ops k3_nav_mode_ring_ops = { .push_tail = k3_nav_ringacc_ring_push_mem, .pop_head = k3_nav_ringacc_ring_pop_mem, }; -static int k3_nav_ringacc_ring_push_io(struct k3_nav_ring *ring, void *elem); -static int k3_nav_ringacc_ring_pop_io(struct k3_nav_ring *ring, void *elem); -static int k3_nav_ringacc_ring_push_head_io(struct k3_nav_ring *ring, - void *elem); -static int k3_nav_ringacc_ring_pop_tail_io(struct k3_nav_ring *ring, - void *elem); - -static struct k3_nav_ring_ops k3_nav_mode_msg_ops = { - .push_tail = k3_nav_ringacc_ring_push_io, - .push_head = k3_nav_ringacc_ring_push_head_io, - .pop_tail = k3_nav_ringacc_ring_pop_tail_io, - .pop_head = k3_nav_ringacc_ring_pop_io, +static struct k3_nav_ring_ops k3_dmaring_fwd_ring_ops = { + .push_tail = k3_nav_ringacc_ring_push_mem, + .pop_head = k3_dmaring_ring_fwd_pop_mem, }; -static int k3_ringacc_ring_push_head_proxy(struct k3_nav_ring *ring, - void *elem); -static int k3_ringacc_ring_push_tail_proxy(struct k3_nav_ring *ring, - void *elem); -static int k3_ringacc_ring_pop_head_proxy(struct k3_nav_ring *ring, void *elem); -static int k3_ringacc_ring_pop_tail_proxy(struct k3_nav_ring *ring, void *elem); - -static struct k3_nav_ring_ops k3_nav_mode_proxy_ops = { - .push_tail = k3_ringacc_ring_push_tail_proxy, - .push_head = k3_ringacc_ring_push_head_proxy, - .pop_tail = k3_ringacc_ring_pop_tail_proxy, - .pop_head = k3_ringacc_ring_pop_head_proxy, +static struct k3_nav_ring_ops k3_dmaring_reverse_ring_ops = { + .pop_head = k3_dmaring_ring_reverse_pop_mem, }; struct udevice *k3_nav_ringacc_get_dev(struct k3_nav_ringacc *ringacc) @@ -275,10 +240,8 @@ struct udevice *k3_nav_ringacc_get_dev(struct k3_nav_ringacc *ringacc) } struct k3_nav_ring *k3_nav_ringacc_request_ring(struct k3_nav_ringacc *ringacc, - int id, u32 flags) + int id) { - int proxy_id = K3_RINGACC_PROXY_NOT_USED; - if (id == K3_NAV_RINGACC_RING_ID_ANY) { /* Request for any general purpose ring */ struct ti_sci_resource_desc *gp_rings = @@ -300,24 +263,10 @@ struct k3_nav_ring *k3_nav_ringacc_request_ring(struct k3_nav_ringacc *ringacc, else if (ringacc->rings[id].flags & K3_NAV_RING_FLAG_SHARED) goto out; - if (flags & K3_NAV_RINGACC_RING_USE_PROXY) { - proxy_id = find_next_zero_bit(ringacc->proxy_inuse, - ringacc->num_proxies, 0); - if (proxy_id == ringacc->num_proxies) - goto error; - } - if (!try_module_get(ringacc->dev->driver->owner)) goto error; - if (proxy_id != K3_RINGACC_PROXY_NOT_USED) { - set_bit(proxy_id, ringacc->proxy_inuse); - ringacc->rings[id].proxy_id = proxy_id; - pr_debug("Giving ring#%d proxy#%d\n", - id, proxy_id); - } else { - pr_debug("Giving ring#%d\n", id); - } + pr_debug("Giving ring#%d\n", id); set_bit(id, ringacc->rings_inuse); out: @@ -328,6 +277,27 @@ error: return NULL; } +static int k3_dmaring_ring_request_rings_pair(struct k3_nav_ringacc *ringacc, + int fwd_id, int compl_id, + struct k3_nav_ring **fwd_ring, + struct k3_nav_ring **compl_ring) +{ + /* k3_dmaring: fwd_id == compl_id, so we ignore compl_id */ + if (fwd_id < 0) + return -EINVAL; + + if (test_bit(fwd_id, ringacc->rings_inuse)) + return -EBUSY; + + *fwd_ring = &ringacc->rings[fwd_id]; + *compl_ring = &ringacc->rings[fwd_id + ringacc->num_rings]; + set_bit(fwd_id, ringacc->rings_inuse); + ringacc->rings[fwd_id].use_count++; + dev_dbg(ringacc->dev, "Giving ring#%d\n", fwd_id); + + return 0; +} + int k3_nav_ringacc_request_rings_pair(struct k3_nav_ringacc *ringacc, int fwd_id, int compl_id, struct k3_nav_ring **fwd_ring, @@ -338,11 +308,15 @@ int k3_nav_ringacc_request_rings_pair(struct k3_nav_ringacc *ringacc, if (!fwd_ring || !compl_ring) return -EINVAL; - *fwd_ring = k3_nav_ringacc_request_ring(ringacc, fwd_id, 0); + if (ringacc->dual_ring) + return k3_dmaring_ring_request_rings_pair(ringacc, fwd_id, compl_id, + fwd_ring, compl_ring); + + *fwd_ring = k3_nav_ringacc_request_ring(ringacc, fwd_id); if (!(*fwd_ring)) return -ENODEV; - *compl_ring = k3_nav_ringacc_request_ring(ringacc, compl_id, 0); + *compl_ring = k3_nav_ringacc_request_ring(ringacc, compl_id); if (!(*compl_ring)) { k3_nav_ringacc_ring_free(*fwd_ring); ret = -ENODEV; @@ -493,6 +467,13 @@ int k3_nav_ringacc_ring_free(struct k3_nav_ring *ring) ringacc = ring->parent; + /* + * k3_dmaring: rings shared memory and configuration, only forward ring is + * configured and reverse ring considered as slave. + */ + if (ringacc->dual_ring && (ring->flags & K3_NAV_RING_FLAG_REVERSE)) + return 0; + pr_debug("%s flags: 0x%08x\n", __func__, ring->flags); if (!test_bit(ring->ring_id, ringacc->rings_inuse)) @@ -511,11 +492,6 @@ int k3_nav_ringacc_ring_free(struct k3_nav_ring *ring) ring->ring_mem_virt, ring->ring_mem_dma); ring->flags &= ~KNAV_RING_FLAG_BUSY; ring->ops = NULL; - if (ring->proxy_id != K3_RINGACC_PROXY_NOT_USED) { - clear_bit(ring->proxy_id, ringacc->proxy_inuse); - ring->proxy = NULL; - ring->proxy_id = K3_RINGACC_PROXY_NOT_USED; - } no_init: clear_bit(ring->ring_id, ringacc->rings_inuse); @@ -562,6 +538,75 @@ static int k3_nav_ringacc_ring_cfg_sci(struct k3_nav_ring *ring) return ret; } +static int k3_dmaring_ring_cfg(struct k3_nav_ring *ring, struct k3_nav_ring_cfg *cfg) +{ + struct k3_nav_ringacc *ringacc; + struct k3_nav_ring *reverse_ring; + int ret = 0; + + if (cfg->elm_size != K3_NAV_RINGACC_RING_ELSIZE_8 || + cfg->mode != K3_NAV_RINGACC_RING_MODE_RING || + cfg->size & ~K3_DMARING_RING_CFG_RING_SIZE_ELCNT_MASK) + return -EINVAL; + + ringacc = ring->parent; + + /* + * k3_dmaring: rings shared memory and configuration, only forward ring is + * configured and reverse ring considered as slave. + */ + if (ringacc->dual_ring && (ring->flags & K3_NAV_RING_FLAG_REVERSE)) + return 0; + + if (!test_bit(ring->ring_id, ringacc->rings_inuse)) + return -EINVAL; + + ring->size = cfg->size; + ring->elm_size = cfg->elm_size; + ring->mode = cfg->mode; + memset(&ring->state, 0, sizeof(ring->state)); + + ring->ops = &k3_dmaring_fwd_ring_ops; + + ring->ring_mem_virt = + dma_alloc_coherent(ring->size * (4 << ring->elm_size), + (unsigned long *)&ring->ring_mem_dma); + if (!ring->ring_mem_virt) { + dev_err(ringacc->dev, "Failed to alloc ring mem\n"); + ret = -ENOMEM; + goto err_free_ops; + } + + ret = k3_nav_ringacc_ring_cfg_sci(ring); + if (ret) + goto err_free_mem; + + ring->flags |= KNAV_RING_FLAG_BUSY; + + /* k3_dmaring: configure reverse ring */ + reverse_ring = &ringacc->rings[ring->ring_id + ringacc->num_rings]; + reverse_ring->size = cfg->size; + reverse_ring->elm_size = cfg->elm_size; + reverse_ring->mode = cfg->mode; + memset(&reverse_ring->state, 0, sizeof(reverse_ring->state)); + reverse_ring->ops = &k3_dmaring_reverse_ring_ops; + + reverse_ring->ring_mem_virt = ring->ring_mem_virt; + reverse_ring->ring_mem_dma = ring->ring_mem_dma; + reverse_ring->flags |= KNAV_RING_FLAG_BUSY; + + return 0; + +err_free_mem: + dma_free_coherent(ringacc->dev, + ring->size * (4 << ring->elm_size), + ring->ring_mem_virt, + ring->ring_mem_dma); +err_free_ops: + ring->ops = NULL; + return ret; +} + int k3_nav_ringacc_ring_cfg(struct k3_nav_ring *ring, struct k3_nav_ring_cfg *cfg) { @@ -570,6 +615,10 @@ int k3_nav_ringacc_ring_cfg(struct k3_nav_ring *ring, if (!ring || !cfg) return -EINVAL; + + if (ringacc->dual_ring) + return k3_dmaring_ring_cfg(ring, cfg); + if (cfg->elm_size > K3_NAV_RINGACC_RING_ELSIZE_256 || cfg->mode > K3_NAV_RINGACC_RING_MODE_QM || cfg->size & ~KNAV_RINGACC_CFG_RING_SIZE_ELCNT_MASK || @@ -584,32 +633,14 @@ int k3_nav_ringacc_ring_cfg(struct k3_nav_ring *ring, ring->mode = cfg->mode; memset(&ring->state, 0, sizeof(ring->state)); - if (ring->proxy_id != K3_RINGACC_PROXY_NOT_USED) - ring->proxy = ringacc->proxy_target_base + - ring->proxy_id * K3_RINGACC_PROXY_TARGET_STEP; - switch (ring->mode) { case K3_NAV_RINGACC_RING_MODE_RING: ring->ops = &k3_nav_mode_ring_ops; break; - case K3_NAV_RINGACC_RING_MODE_QM: - /* - * In Queue mode elm_size can be 8 only and each operation - * uses 2 element slots - */ - if (cfg->elm_size != K3_NAV_RINGACC_RING_ELSIZE_8 || - cfg->size % 2) - goto err_free_proxy; - case K3_NAV_RINGACC_RING_MODE_MESSAGE: - if (ring->proxy) - ring->ops = &k3_nav_mode_proxy_ops; - else - ring->ops = &k3_nav_mode_msg_ops; - break; default: ring->ops = NULL; ret = -EINVAL; - goto err_free_proxy; + goto err_free_ops; }; ring->ring_mem_virt = @@ -640,8 +671,6 @@ err_free_mem: ring->ring_mem_dma); err_free_ops: ring->ops = NULL; -err_free_proxy: - ring->proxy = NULL; return ret; } @@ -686,159 +715,63 @@ enum k3_ringacc_access_mode { K3_RINGACC_ACCESS_MODE_PEEK_TAIL, }; -static int k3_ringacc_ring_cfg_proxy(struct k3_nav_ring *ring, - enum k3_ringacc_proxy_access_mode mode) +static int k3_dmaring_ring_fwd_pop_mem(struct k3_nav_ring *ring, void *elem) { - u32 val; - - val = ring->ring_id; - val |= mode << 16; - val |= ring->elm_size << 24; - ringacc_writel(val, &ring->proxy->control); - return 0; -} - -static int k3_nav_ringacc_ring_access_proxy( - struct k3_nav_ring *ring, void *elem, - enum k3_ringacc_access_mode access_mode) -{ - void __iomem *ptr; + void *elem_ptr; + u32 elem_idx; - ptr = (void __iomem *)&ring->proxy->data; + /* + * k3_dmaring: forward ring is always tied DMA channel and HW does not + * maintain any state data required for POP operation and its unknown + * how much elements were consumed by HW. So, to actually + * do POP, the read pointer has to be recalculated every time. + */ + ring->state.occ = k3_nav_ringacc_ring_read_occ(ring); + if (ring->state.windex >= ring->state.occ) + elem_idx = ring->state.windex - ring->state.occ; + else + elem_idx = ring->size - (ring->state.occ - ring->state.windex); - switch (access_mode) { - case K3_RINGACC_ACCESS_MODE_PUSH_HEAD: - case K3_RINGACC_ACCESS_MODE_POP_HEAD: - k3_ringacc_ring_cfg_proxy(ring, PROXY_ACCESS_MODE_HEAD); - break; - case K3_RINGACC_ACCESS_MODE_PUSH_TAIL: - case K3_RINGACC_ACCESS_MODE_POP_TAIL: - k3_ringacc_ring_cfg_proxy(ring, PROXY_ACCESS_MODE_TAIL); - break; - default: - return -EINVAL; - } + elem_ptr = k3_nav_ringacc_get_elm_addr(ring, elem_idx); + invalidate_dcache_range((unsigned long)ring->ring_mem_virt, + ALIGN((unsigned long)ring->ring_mem_virt + + ring->size * (4 << ring->elm_size), + ARCH_DMA_MINALIGN)); - ptr += k3_nav_ringacc_ring_get_fifo_pos(ring); + memcpy(elem, elem_ptr, (4 << ring->elm_size)); - switch (access_mode) { - case K3_RINGACC_ACCESS_MODE_POP_HEAD: - case K3_RINGACC_ACCESS_MODE_POP_TAIL: - pr_debug("proxy:memcpy_fromio(x): --> ptr(%p), mode:%d\n", - ptr, access_mode); - memcpy_fromio(elem, ptr, (4 << ring->elm_size)); - ring->state.occ--; - break; - case K3_RINGACC_ACCESS_MODE_PUSH_TAIL: - case K3_RINGACC_ACCESS_MODE_PUSH_HEAD: - pr_debug("proxy:memcpy_toio(x): --> ptr(%p), mode:%d\n", - ptr, access_mode); - memcpy_toio(ptr, elem, (4 << ring->elm_size)); - ring->state.free--; - break; - default: - return -EINVAL; - } + ring->state.occ--; + writel(-1, &ring->rt->db); - pr_debug("proxy: free%d occ%d\n", - ring->state.free, ring->state.occ); + dev_dbg(ring->parent->dev, "%s: occ%d Windex%d Rindex%d pos_ptr%px\n", + __func__, ring->state.occ, ring->state.windex, elem_idx, + elem_ptr); return 0; } -static int k3_ringacc_ring_push_head_proxy(struct k3_nav_ring *ring, void *elem) +static int k3_dmaring_ring_reverse_pop_mem(struct k3_nav_ring *ring, void *elem) { - return k3_nav_ringacc_ring_access_proxy( - ring, elem, K3_RINGACC_ACCESS_MODE_PUSH_HEAD); -} - -static int k3_ringacc_ring_push_tail_proxy(struct k3_nav_ring *ring, void *elem) -{ - return k3_nav_ringacc_ring_access_proxy( - ring, elem, K3_RINGACC_ACCESS_MODE_PUSH_TAIL); -} - -static int k3_ringacc_ring_pop_head_proxy(struct k3_nav_ring *ring, void *elem) -{ - return k3_nav_ringacc_ring_access_proxy( - ring, elem, K3_RINGACC_ACCESS_MODE_POP_HEAD); -} - -static int k3_ringacc_ring_pop_tail_proxy(struct k3_nav_ring *ring, void *elem) -{ - return k3_nav_ringacc_ring_access_proxy( - ring, elem, K3_RINGACC_ACCESS_MODE_POP_HEAD); -} - -static int k3_nav_ringacc_ring_access_io( - struct k3_nav_ring *ring, void *elem, - enum k3_ringacc_access_mode access_mode) -{ - void __iomem *ptr; + void *elem_ptr; - switch (access_mode) { - case K3_RINGACC_ACCESS_MODE_PUSH_HEAD: - case K3_RINGACC_ACCESS_MODE_POP_HEAD: - ptr = (void __iomem *)&ring->fifos->head_data; - break; - case K3_RINGACC_ACCESS_MODE_PUSH_TAIL: - case K3_RINGACC_ACCESS_MODE_POP_TAIL: - ptr = (void __iomem *)&ring->fifos->tail_data; - break; - default: - return -EINVAL; - } + elem_ptr = k3_nav_ringacc_get_elm_addr(ring, ring->state.rindex); - ptr += k3_nav_ringacc_ring_get_fifo_pos(ring); + if (ring->state.occ) { + invalidate_dcache_range((unsigned long)ring->ring_mem_virt, + ALIGN((unsigned long)ring->ring_mem_virt + + ring->size * (4 << ring->elm_size), + ARCH_DMA_MINALIGN)); - switch (access_mode) { - case K3_RINGACC_ACCESS_MODE_POP_HEAD: - case K3_RINGACC_ACCESS_MODE_POP_TAIL: - pr_debug("memcpy_fromio(x): --> ptr(%p), mode:%d\n", - ptr, access_mode); - memcpy_fromio(elem, ptr, (4 << ring->elm_size)); + memcpy(elem, elem_ptr, (4 << ring->elm_size)); + ring->state.rindex = (ring->state.rindex + 1) % ring->size; ring->state.occ--; - break; - case K3_RINGACC_ACCESS_MODE_PUSH_TAIL: - case K3_RINGACC_ACCESS_MODE_PUSH_HEAD: - pr_debug("memcpy_toio(x): --> ptr(%p), mode:%d\n", - ptr, access_mode); - memcpy_toio(ptr, elem, (4 << ring->elm_size)); - ring->state.free--; - break; - default: - return -EINVAL; + writel(-1 & K3_DMARING_RING_RT_DB_ENTRY_MASK, &ring->rt->db); } - pr_debug("free%d index%d occ%d index%d\n", - ring->state.free, ring->state.windex, ring->state.occ, ring->state.rindex); + dev_dbg(ring->parent->dev, "%s: occ%d index%d pos_ptr%px\n", + __func__, ring->state.occ, ring->state.rindex, elem_ptr); return 0; } -static int k3_nav_ringacc_ring_push_head_io(struct k3_nav_ring *ring, - void *elem) -{ - return k3_nav_ringacc_ring_access_io( - ring, elem, K3_RINGACC_ACCESS_MODE_PUSH_HEAD); -} - -static int k3_nav_ringacc_ring_push_io(struct k3_nav_ring *ring, void *elem) -{ - return k3_nav_ringacc_ring_access_io( - ring, elem, K3_RINGACC_ACCESS_MODE_PUSH_TAIL); -} - -static int k3_nav_ringacc_ring_pop_io(struct k3_nav_ring *ring, void *elem) -{ - return k3_nav_ringacc_ring_access_io( - ring, elem, K3_RINGACC_ACCESS_MODE_POP_HEAD); -} - -static int k3_nav_ringacc_ring_pop_tail_io(struct k3_nav_ring *ring, void *elem) -{ - return k3_nav_ringacc_ring_access_io( - ring, elem, K3_RINGACC_ACCESS_MODE_POP_HEAD); -} - static int k3_nav_ringacc_ring_push_mem(struct k3_nav_ring *ring, void *elem) { void *elem_ptr; @@ -930,7 +863,7 @@ int k3_nav_ringacc_ring_pop(struct k3_nav_ring *ring, void *elem) return -EINVAL; if (!ring->state.occ) - ring->state.occ = k3_nav_ringacc_ring_get_occ(ring); + k3_nav_ringacc_ring_update_occ(ring); pr_debug("ring_pop%d: occ%d index%d\n", ring->ring_id, ring->state.occ, ring->state.rindex); @@ -952,7 +885,7 @@ int k3_nav_ringacc_ring_pop_tail(struct k3_nav_ring *ring, void *elem) return -EINVAL; if (!ring->state.occ) - ring->state.occ = k3_nav_ringacc_ring_get_occ(ring); + k3_nav_ringacc_ring_update_occ(ring); pr_debug("ring_pop_tail: occ%d index%d\n", ring->state.occ, ring->state.rindex); @@ -969,6 +902,7 @@ int k3_nav_ringacc_ring_pop_tail(struct k3_nav_ring *ring, void *elem) static int k3_nav_ringacc_probe_dt(struct k3_nav_ringacc *ringacc) { struct udevice *dev = ringacc->dev; + struct udevice *devp = dev; struct udevice *tisci_dev = NULL; int ret; @@ -981,7 +915,7 @@ static int k3_nav_ringacc_probe_dt(struct k3_nav_ringacc *ringacc) ringacc->dma_ring_reset_quirk = dev_read_bool(dev, "ti,dma-ring-reset-quirk"); - ret = uclass_get_device_by_phandle(UCLASS_FIRMWARE, dev, + ret = uclass_get_device_by_phandle(UCLASS_FIRMWARE, devp, "ti,sci", &tisci_dev); if (ret) { pr_debug("TISCI RA RM get failed (%d)\n", ret); @@ -991,14 +925,14 @@ static int k3_nav_ringacc_probe_dt(struct k3_nav_ringacc *ringacc) ringacc->tisci = (struct ti_sci_handle *) (ti_sci_get_handle_from_sysfw(tisci_dev)); - ret = dev_read_u32_default(dev, "ti,sci", 0); + ret = dev_read_u32_default(devp, "ti,sci", 0); if (!ret) { dev_err(dev, "TISCI RA RM disabled\n"); ringacc->tisci = NULL; return ret; } - ret = dev_read_u32(dev, "ti,sci-dev-id", &ringacc->tisci_dev_id); + ret = dev_read_u32(devp, "ti,sci-dev-id", &ringacc->tisci_dev_id); if (ret) { dev_err(dev, "ti,sci-dev-id read failure %d\n", ret); ringacc->tisci = NULL; @@ -1017,7 +951,7 @@ 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_fifo, *base_rt; + void __iomem *base_rt; int ret, i; ret = k3_nav_ringacc_probe_dt(ringacc); @@ -1029,24 +963,6 @@ static int k3_nav_ringacc_init(struct udevice *dev, struct k3_nav_ringacc *ringa if (IS_ERR(base_rt)) return PTR_ERR(base_rt); - base_fifo = (uint32_t *)devfdt_get_addr_name(dev, "fifos"); - pr_debug("fifos %p\n", base_fifo); - if (IS_ERR(base_fifo)) - return PTR_ERR(base_fifo); - - ringacc->proxy_gcfg = (struct k3_ringacc_proxy_gcfg_regs __iomem *) - devfdt_get_addr_name(dev, "proxy_gcfg"); - if (IS_ERR(ringacc->proxy_gcfg)) - return PTR_ERR(ringacc->proxy_gcfg); - ringacc->proxy_target_base = - (struct k3_ringacc_proxy_gcfg_regs __iomem *) - devfdt_get_addr_name(dev, "proxy_target"); - if (IS_ERR(ringacc->proxy_target_base)) - return PTR_ERR(ringacc->proxy_target_base); - - ringacc->num_proxies = ringacc_readl(&ringacc->proxy_gcfg->config) & - K3_RINGACC_PROXY_CFG_THREADS_MASK; - ringacc->rings = devm_kzalloc(dev, sizeof(*ringacc->rings) * ringacc->num_rings, @@ -1054,21 +970,15 @@ static int k3_nav_ringacc_init(struct udevice *dev, struct k3_nav_ringacc *ringa ringacc->rings_inuse = devm_kcalloc(dev, BITS_TO_LONGS(ringacc->num_rings), sizeof(unsigned long), GFP_KERNEL); - ringacc->proxy_inuse = devm_kcalloc(dev, - BITS_TO_LONGS(ringacc->num_proxies), - sizeof(unsigned long), GFP_KERNEL); - if (!ringacc->rings || !ringacc->rings_inuse || !ringacc->proxy_inuse) + if (!ringacc->rings || !ringacc->rings_inuse) return -ENOMEM; for (i = 0; i < ringacc->num_rings; i++) { ringacc->rings[i].rt = base_rt + KNAV_RINGACC_RT_REGS_STEP * i; - ringacc->rings[i].fifos = base_fifo + - KNAV_RINGACC_FIFO_REGS_STEP * i; ringacc->rings[i].parent = ringacc; ringacc->rings[i].ring_id = i; - ringacc->rings[i].proxy_id = K3_RINGACC_PROXY_NOT_USED; } dev_set_drvdata(dev, ringacc); @@ -1083,12 +993,68 @@ static int k3_nav_ringacc_init(struct udevice *dev, struct k3_nav_ringacc *ringa ringacc->tisci_dev_id); dev_info(dev, "dma-ring-reset-quirk: %s\n", ringacc->dma_ring_reset_quirk ? "enabled" : "disabled"); - dev_info(dev, "RA Proxy rev. %08x, num_proxies:%u\n", - ringacc_readl(&ringacc->proxy_gcfg->revision), - ringacc->num_proxies); return 0; } +struct k3_nav_ringacc *k3_ringacc_dmarings_init(struct udevice *dev, + struct k3_ringacc_init_data *data) +{ + struct k3_nav_ringacc *ringacc; + void __iomem *base_rt; + int i; + + ringacc = devm_kzalloc(dev, sizeof(*ringacc), GFP_KERNEL); + if (!ringacc) + return ERR_PTR(-ENOMEM); + + ringacc->dual_ring = true; + + ringacc->dev = dev; + ringacc->num_rings = data->num_rings; + ringacc->tisci = data->tisci; + ringacc->tisci_dev_id = data->tisci_dev_id; + + base_rt = (uint32_t *)devfdt_get_addr_name(dev, "ringrt"); + if (IS_ERR(base_rt)) + return base_rt; + + ringacc->rings = devm_kzalloc(dev, + sizeof(*ringacc->rings) * + ringacc->num_rings * 2, + GFP_KERNEL); + ringacc->rings_inuse = devm_kcalloc(dev, + BITS_TO_LONGS(ringacc->num_rings), + sizeof(unsigned long), GFP_KERNEL); + + if (!ringacc->rings || !ringacc->rings_inuse) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < ringacc->num_rings; i++) { + struct k3_nav_ring *ring = &ringacc->rings[i]; + + ring->rt = base_rt + K3_DMARING_RING_RT_REGS_STEP * i; + ring->parent = ringacc; + ring->ring_id = i; + + ring = &ringacc->rings[ringacc->num_rings + i]; + ring->rt = base_rt + K3_DMARING_RING_RT_REGS_STEP * i + + K3_DMARING_RING_RT_REGS_REVERSE_OFS; + ring->parent = ringacc; + ring->ring_id = i; + ring->flags = K3_NAV_RING_FLAG_REVERSE; + } + + ringacc->tisci_ring_ops = &ringacc->tisci->ops.rm_ring_ops; + + dev_info(dev, "k3_dmaring Ring probed rings:%u, sci-dev-id:%u\n", + ringacc->num_rings, + ringacc->tisci_dev_id); + dev_info(dev, "dma-ring-reset-quirk: %s\n", + ringacc->dma_ring_reset_quirk ? "enabled" : "disabled"); + + return ringacc; +} + struct ringacc_match_data { struct k3_nav_ringacc_ops ops; }; |
