// SPDX-License-Identifier: GPL-2.0
/*
* TI K3 NAVSS Ring Accelerator subsystem driver
*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
*/
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/sys_soc.h>
#include <linux/soc/ti/k3-ringacc.h>
#include <linux/soc/ti/ti_sci_protocol.h>
#include <linux/soc/ti/ti_sci_inta_msi.h>
#include <linux/of_irq.h>
#include <linux/irqdomain.h>
static LIST_HEAD(k3_ringacc_list);
static DEFINE_MUTEX(k3_ringacc_list_lock);
#define K3_RINGACC_CFG_RING_SIZE_ELCNT_MASK GENMASK(19, 0)
/**
* struct k3_ring_rt_regs - The RA realtime Control/Status Registers region
*
* @resv_16: Reserved
* @db: Ring Doorbell Register
* @resv_4: Reserved
* @occ: Ring Occupancy Register
* @indx: Ring Current Index Register
* @hwocc: Ring Hardware Occupancy Register
* @hwindx: Ring Hardware Current Index Register
*/
struct k3_ring_rt_regs {
u32 resv_16[4];
u32 db;
u32 resv_4[1];
u32 occ;
u32 indx;
u32 hwocc;
u32 hwindx;
};
#define K3_RINGACC_RT_REGS_STEP 0x1000
/**
* struct k3_ring_fifo_regs - The Ring Accelerator Queues Registers region
*
* @head_data: Ring Head Entry Data Registers
* @tail_data: Ring Tail Entry Data Registers
* @peek_head_data: Ring Peek Head Entry Data Regs
* @peek_tail_data: Ring Peek Tail Entry Data Regs
*/
struct k3_ring_fifo_regs {
u32 head_data[128];
u32 tail_data[128];
u32 peek_head_data[128];
u32 peek_tail_data[128];
};
/**
* struct k3_ringacc_proxy_gcfg_regs - RA Proxy Global Config MMIO Region
*
* @revision: Revision Register
* @config: Config Register
*/
struct k3_ringacc_proxy_gcfg_regs {
u32 revision;
u32 config;
};
#define K3_RINGACC_PROXY_CFG_THREADS_MASK GENMASK(15, 0)
/**
* struct k3_ringacc_proxy_target_regs - Proxy Datapath MMIO Region
*
* @control: Proxy Control Register
* @status: Proxy Status Register
* @resv_512: Reserved
* @data: Proxy Data Register
*/
struct k3_ringacc_proxy_target_regs {
u32 control;
u32 status;
u8 resv_512[504];
u32 data[128];
};
#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 K3_RINGACC_FIFO_WINDOW_SIZE_BYTES (512U)
#define K3_RINGACC_FIFO_REGS_STEP 0x1000
#define K3_RINGACC_MAX_DB_RING_CNT (127U)
struct k3_ring_ops {
int (*push_tail)(struct k3_ring *ring, void *elm);
int (*push_head)(struct k3_ring *ring, void *elm);
int (*pop_tail)(struct k3_ring *ring, void *elm);
int (*pop_head)(struct k3_ring *ring, void *elm);
};
/**
* struct k3_ring_state - Internal state tracking structure
*
* @free: Number of free entries
* @occ: Occupancy
* @windex: Write index
* @rindex: Read index
*/
struct k3_ring_state {
u32 free;
u32 occ;
u32 windex;
u32 rindex;
};
/**
* struct k3_ring - RA Ring descriptor
*
* @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
* @size: Ring size in elements
* @elm_size: Size of the ring element
* @mode: Ring mode
* @flags: flags
* @ring_id: Ring Id
* @parent: Pointer on struct @k3_ringacc
* @use_count: Use count for shared rings
* @proxy_id: RA Ring Proxy Id (only if @K3_RINGACC_RING_USE_PROXY)
*/
struct k3_ring {
struct k3_ring_rt_regs __iomem *rt;
struct k3_ring_fifo_regs __iomem *fifos;
struct k3_ringacc_proxy_target_regs __iomem