Commit 37309643 authored by Olof Johansson's avatar Olof Johansson

Merge tag 'drivers-soc-ti-v2' of...

Merge tag 'drivers-soc-ti-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone into next/drivers

Merge "soc: Keystone SOC Navigator drivers for 3.18" from Santosh Shilimkar:

Keystone SOC Navigator drivers for 3.18

The Keystone Multi-core Navigator contains QMSS and packet DMA
subsystems which interwork together to form the Navigator cloud
used by various subsystems like NetCP, SRIO, SideBand Crypto
engines etc.

* tag 'drivers-soc-ti-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone:
  MAINTAINERS: Add Keystone Multicore Navigator drivers entry
  soc: ti: add Keystone Navigator DMA support
  Documentation: dt: soc: add Keystone Navigator DMA bindings
  soc: ti: add Keystone Navigator QMSS driver
  Documentation: dt: soc: add Keystone Navigator QMSS bindings
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents 791cc88c e0c52404
Keystone Navigator DMA Controller
This document explains the device tree bindings for the packet dma
on keystone devices. The Keystone Navigator DMA driver sets up the dma
channels and flows for the QMSS(Queue Manager SubSystem) who triggers
the actual data movements across clients using destination queues. Every
client modules like NETCP(Network Coprocessor), SRIO(Serial Rapid IO),
CRYPTO Engines etc has its own instance of dma hardware. QMSS has also
an internal packet DMA module which is used as an infrastructure DMA
with zero copy.
Navigator DMA cloud layout:
------------------
| Navigator DMAs |
------------------
|
|-> DMA instance #0
|
|-> DMA instance #1
.
.
|
|-> DMA instance #n
Navigator DMA properties:
Required properties:
- compatible: Should be "ti,keystone-navigator-dma"
- clocks: phandle to dma instances clocks. The clock handles can be as
many as the dma instances. The order should be maintained as per
the dma instances.
- ti,navigator-cloud-address: Should contain base address for the multi-core
navigator cloud and number of addresses depends on SOC integration
configuration.. Navigator cloud global address needs to be programmed
into DMA and the DMA uses it as the physical addresses to reach queue
managers. Note that these addresses though points to queue managers,
they are relevant only from DMA perspective. The QMSS may not choose to
use them since it has a different address space view to reach all
its components.
DMA instance properties:
Required properties:
- reg: Should contain register location and length of the following dma
register regions. Register regions should be specified in the following
order.
- Global control register region (global).
- Tx DMA channel configuration register region (txchan).
- Rx DMA channel configuration register region (rxchan).
- Tx DMA channel Scheduler configuration register region (txsched).
- Rx DMA flow configuration register region (rxflow).
Optional properties:
- reg-names: Names for the register regions.
- ti,enable-all: Enable all DMA channels vs clients opening specific channels
what they need. This property is useful for the userspace fast path
case where the linux drivers enables the channels used by userland
stack.
- ti,loop-back: To loopback Tx streaming I/F to Rx streaming I/F. Used for
infrastructure transfers.
- ti,rx-retry-timeout: Number of dma cycles to wait before retry on buffer
starvation.
Example:
knav_dmas: knav_dmas@0 {
compatible = "ti,keystone-navigator-dma";
clocks = <&papllclk>, <&clkxge>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
ti,navigator-cloud-address = <0x23a80000 0x23a90000
0x23aa0000 0x23ab0000>;
dma_gbe: dma_gbe@0 {
reg = <0x2004000 0x100>,
<0x2004400 0x120>,
<0x2004800 0x300>,
<0x2004c00 0x120>,
<0x2005000 0x400>;
reg-names = "global", "txchan", "rxchan",
"txsched", "rxflow";
};
dma_xgbe: dma_xgbe@0 {
reg = <0x2fa1000 0x100>,
<0x2fa1400 0x200>,
<0x2fa1800 0x200>,
<0x2fa1c00 0x200>,
<0x2fa2000 0x400>;
reg-names = "global", "txchan", "rxchan",
"txsched", "rxflow";
};
};
Navigator DMA client:
Required properties:
- ti,navigator-dmas: List of one or more DMA specifiers, each consisting of
- A phandle pointing to DMA instance node
- A DMA channel number as a phandle arg.
- ti,navigator-dma-names: Contains dma channel name for each DMA specifier in
the 'ti,navigator-dmas' property.
Example:
netcp: netcp@2090000 {
..
ti,navigator-dmas = <&dma_gbe 22>,
<&dma_gbe 23>,
<&dma_gbe 8>;
ti,navigator-dma-names = "netrx0", "netrx1", "nettx";
..
};
* Texas Instruments Keystone Navigator Queue Management SubSystem driver
The QMSS (Queue Manager Sub System) found on Keystone SOCs is one of
the main hardware sub system which forms the backbone of the Keystone
multi-core Navigator. QMSS consist of queue managers, packed-data structure
processors(PDSP), linking RAM, descriptor pools and infrastructure
Packet DMA.
The Queue Manager is a hardware module that is responsible for accelerating
management of the packet queues. Packets are queued/de-queued by writing or
reading descriptor address to a particular memory mapped location. The PDSPs
perform QMSS related functions like accumulation, QoS, or event management.
Linking RAM registers are used to link the descriptors which are stored in
descriptor RAM. Descriptor RAM is configurable as internal or external memory.
The QMSS driver manages the PDSP setups, linking RAM regions,
queue pool management (allocation, push, pop and notify) and descriptor
pool management.
Required properties:
- compatible : Must be "ti,keystone-navigator-qmss";
- clocks : phandle to the reference clock for this device.
- queue-range : <start number> total range of queue numbers for the device.
- linkram0 : <address size> for internal link ram, where size is the total
link ram entries.
- linkram1 : <address size> for external link ram, where size is the total
external link ram entries. If the address is specified as "0"
driver will allocate memory.
- qmgrs : child node describing the individual queue managers on the
SoC. On keystone 1 devices there should be only one node.
On keystone 2 devices there can be more than 1 node.
-- managed-queues : the actual queues managed by each queue manager
instance, specified as <"base queue #" "# of queues">.
-- reg : Address and size of the register set for the device.
Register regions should be specified in the following
order
- Queue Peek region.
- Queue status RAM.
- Queue configuration region.
- Descriptor memory setup region.
- Queue Management/Queue Proxy region for queue Push.
- Queue Management/Queue Proxy region for queue Pop.
- queue-pools : child node classifying the queue ranges into pools.
Queue ranges are grouped into 3 type of pools:
- qpend : pool of qpend(interruptible) queues
- general-purpose : pool of general queues, primarly used
as free descriptor queues or the
transmit DMA queues.
- accumulator : pool of queues on PDSP accumulator channel
Each range can have the following properties:
-- qrange : number of queues to use per queue range, specified as
<"base queue #" "# of queues">.
-- interrupts : Optional property to specify the interrupt mapping
for interruptible queues. The driver additionaly sets
the interrupt affinity hint based on the cpu mask.
-- qalloc-by-id : Optional property to specify that the queues in this
range can only be allocated by queue id.
-- accumulator : Accumulator channel specification. Any of the PDSPs in
QMSS can be loaded with the accumulator firmware. The
accumulator firmware’s job is to poll a select number of
queues looking for descriptors that have been pushed
into them. Descriptors are popped from the queue and
placed in a buffer provided by the host. When the list
becomes full or a programmed time period expires, the
accumulator triggers an interrupt to the host to read
the buffer for descriptor information. This firmware
comes in 16, 32, and 48 channel builds. Each of these
channels can be configured to monitor 32 contiguous
queues. Accumulator channel property is specified as:
<pdsp-id, channel, entries, pacing mode, latency>
pdsp-id : QMSS PDSP running accumulator firmware
on which the channel has to be
configured
channel : Accumulator channel number
entries : Size of the accumulator descriptor list
pacing mode : Interrupt pacing mode
0 : None, i.e interrupt on list full only
1 : Time delay since last interrupt
2 : Time delay since first new packet
3 : Time delay since last new packet
latency : time to delay the interrupt, specified
in microseconds.
-- multi-queue : Optional property to specify that the channel has to
monitor upto 32 queues starting at the base queue #.
- descriptor-regions : child node describing the memory regions for keystone
navigator packet DMA descriptors. The memory for
descriptors will be allocated by the driver.
-- id : region number in QMSS.
-- region-spec : specifies the number of descriptors in the
region, specified as
<"# of descriptors" "descriptor size">.
-- link-index : start index, i.e. index of the first
descriptor in the region.
Optional properties:
- dma-coherent : Present if DMA operations are coherent.
- pdsps : child node describing the PDSP configuration.
-- firmware : firmware to be loaded on the PDSP.
-- id : the qmss pdsp that will run the firmware.
-- reg : Address and size of the register set for the PDSP.
Register regions should be specified in the following
order
- PDSP internal RAM region.
- PDSP control/status region registers.
- QMSS interrupt distributor registers.
- PDSP command interface region.
Example:
qmss: qmss@2a40000 {
compatible = "ti,keystone-qmss";
dma-coherent;
#address-cells = <1>;
#size-cells = <1>;
clocks = <&chipclk13>;
ranges;
queue-range = <0 0x4000>;
linkram0 = <0x100000 0x8000>;
linkram1 = <0x0 0x10000>;
qmgrs {
#address-cells = <1>;
#size-cells = <1>;
ranges;
qmgr0 {
managed-queues = <0 0x2000>;
reg = <0x2a40000 0x20000>,
<0x2a06000 0x400>,
<0x2a02000 0x1000>,
<0x2a03000 0x1000>,
<0x23a80000 0x20000>,
<0x2a80000 0x20000>;
};
qmgr1 {
managed-queues = <0x2000 0x2000>;
reg = <0x2a60000 0x20000>,
<0x2a06400 0x400>,
<0x2a04000 0x1000>,
<0x2a05000 0x1000>,
<0x23aa0000 0x20000>,
<0x2aa0000 0x20000>;
};
};
queue-pools {
qpend {
qpend-0 {
qrange = <658 8>;
interrupts =<0 40 0xf04 0 41 0xf04 0 42 0xf04
0 43 0xf04 0 44 0xf04 0 45 0xf04
0 46 0xf04 0 47 0xf04>;
};
qpend-1 {
qrange = <8704 16>;
interrupts = <0 48 0xf04 0 49 0xf04 0 50 0xf04
0 51 0xf04 0 52 0xf04 0 53 0xf04
0 54 0xf04 0 55 0xf04 0 56 0xf04
0 57 0xf04 0 58 0xf04 0 59 0xf04
0 60 0xf04 0 61 0xf04 0 62 0xf04
0 63 0xf04>;
qalloc-by-id;
};
qpend-2 {
qrange = <8720 16>;
interrupts = <0 64 0xf04 0 65 0xf04 0 66 0xf04
0 59 0xf04 0 68 0xf04 0 69 0xf04
0 70 0xf04 0 71 0xf04 0 72 0xf04
0 73 0xf04 0 74 0xf04 0 75 0xf04
0 76 0xf04 0 77 0xf04 0 78 0xf04
0 79 0xf04>;
};
};
general-purpose {
gp-0 {
qrange = <4000 64>;
};
netcp-tx {
qrange = <640 9>;
qalloc-by-id;
};
};
accumulator {
acc-0 {
qrange = <128 32>;
accumulator = <0 36 16 2 50>;
interrupts = <0 215 0xf01>;
multi-queue;
qalloc-by-id;
};
acc-1 {
qrange = <160 32>;
accumulator = <0 37 16 2 50>;
interrupts = <0 216 0xf01>;
multi-queue;
};
acc-2 {
qrange = <192 32>;
accumulator = <0 38 16 2 50>;
interrupts = <0 217 0xf01>;
multi-queue;
};
acc-3 {
qrange = <224 32>;
accumulator = <0 39 16 2 50>;
interrupts = <0 218 0xf01>;
multi-queue;
};
};
};
descriptor-regions {
#address-cells = <1>;
#size-cells = <1>;
ranges;
region-12 {
id = <12>;
region-spec = <8192 128>; /* num_desc desc_size */
link-index = <0x4000>;
};
};
pdsps {
#address-cells = <1>;
#size-cells = <1>;
ranges;
pdsp0@0x2a10000 {
firmware = "keystone/qmss_pdsp_acc48_k2_le_1_0_0_8.fw";
reg = <0x2a10000 0x1000>,
<0x2a0f000 0x100>,
<0x2a0c000 0x3c8>,
<0x2a20000 0x4000>;
id = <0>;
};
};
}; /* qmss */
......@@ -9138,6 +9138,15 @@ F: drivers/misc/tifm*
F: drivers/mmc/host/tifm_sd.c
F: include/linux/tifm.h
TI KEYSTONE MULTICORE NAVIGATOR DRIVERS
M: Santosh Shilimkar <santosh.shilimkar@ti.com>
L: linux-kernel@vger.kernel.org
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: drivers/soc/ti/*
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
TI LM49xxx FAMILY ASoC CODEC DRIVERS
M: M R Swami Reddy <mr.swami.reddy@ti.com>
M: Vishwas A Deshpande <vishwas.a.deshpande@ti.com>
......
......@@ -148,6 +148,8 @@ source "drivers/remoteproc/Kconfig"
source "drivers/rpmsg/Kconfig"
source "drivers/soc/Kconfig"
source "drivers/devfreq/Kconfig"
source "drivers/extcon/Kconfig"
......
menu "SOC (System On Chip) specific Drivers"
source "drivers/soc/qcom/Kconfig"
source "drivers/soc/ti/Kconfig"
endmenu
......@@ -4,3 +4,4 @@
obj-$(CONFIG_ARCH_QCOM) += qcom/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_SOC_TI) += ti/
#
# TI SOC drivers
#
menuconfig SOC_TI
bool "TI SOC drivers support"
if SOC_TI
config KEYSTONE_NAVIGATOR_QMSS
tristate "Keystone Queue Manager Sub System"
depends on ARCH_KEYSTONE
help
Say y here to support the Keystone multicore Navigator Queue
Manager support. The Queue Manager is a hardware module that
is responsible for accelerating management of the packet queues.
Packets are queued/de-queued by writing/reading descriptor address
to a particular memory mapped location in the Queue Manager module.
If unsure, say N.
config KEYSTONE_NAVIGATOR_DMA
tristate "TI Keystone Navigator Packet DMA support"
depends on ARCH_KEYSTONE
help
Say y tp enable support for the Keystone Navigator Packet DMA on
on Keystone family of devices. It sets up the dma channels for the
Queue Manager Sub System.
If unsure, say N.
endif # SOC_TI
#
# TI Keystone SOC drivers
#
obj-$(CONFIG_KEYSTONE_NAVIGATOR_QMSS) += knav_qmss_queue.o knav_qmss_acc.o
obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA) += knav_dma.o
This diff is collapsed.
/*
* Keystone Navigator QMSS driver internal header
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
* Author: Sandeep Nair <sandeep_n@ti.com>
* Cyril Chemparathy <cyril@ti.com>
* Santosh Shilimkar <santosh.shilimkar@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#ifndef __KNAV_QMSS_H__
#define __KNAV_QMSS_H__
#define THRESH_GTE BIT(7)
#define THRESH_LT 0
#define PDSP_CTRL_PC_MASK 0xffff0000
#define PDSP_CTRL_SOFT_RESET BIT(0)
#define PDSP_CTRL_ENABLE BIT(1)
#define PDSP_CTRL_RUNNING BIT(15)
#define ACC_MAX_CHANNEL 48
#define ACC_DEFAULT_PERIOD 25 /* usecs */
#define ACC_CHANNEL_INT_BASE 2
#define ACC_LIST_ENTRY_TYPE 1
#define ACC_LIST_ENTRY_WORDS (1 << ACC_LIST_ENTRY_TYPE)
#define ACC_LIST_ENTRY_QUEUE_IDX 0
#define ACC_LIST_ENTRY_DESC_IDX (ACC_LIST_ENTRY_WORDS - 1)
#define ACC_CMD_DISABLE_CHANNEL 0x80
#define ACC_CMD_ENABLE_CHANNEL 0x81
#define ACC_CFG_MULTI_QUEUE BIT(21)
#define ACC_INTD_OFFSET_EOI (0x0010)
#define ACC_INTD_OFFSET_COUNT(ch) (0x0300 + 4 * (ch))
#define ACC_INTD_OFFSET_STATUS(ch) (0x0200 + 4 * ((ch) / 32))
#define RANGE_MAX_IRQS 64
#define ACC_DESCS_MAX SZ_1K
#define ACC_DESCS_MASK (ACC_DESCS_MAX - 1)
#define DESC_SIZE_MASK 0xful
#define DESC_PTR_MASK (~DESC_SIZE_MASK)
#define KNAV_NAME_SIZE 32
enum knav_acc_result {
ACC_RET_IDLE,
ACC_RET_SUCCESS,
ACC_RET_INVALID_COMMAND,
ACC_RET_INVALID_CHANNEL,
ACC_RET_INACTIVE_CHANNEL,
ACC_RET_ACTIVE_CHANNEL,
ACC_RET_INVALID_QUEUE,
ACC_RET_INVALID_RET,
};
struct knav_reg_config {
u32 revision;
u32 __pad1;
u32 divert;
u32 link_ram_base0;
u32 link_ram_size0;
u32 link_ram_base1;
u32 __pad2[2];
u32 starvation[0];
};
struct knav_reg_region {
u32 base;
u32 start_index;
u32 size_count;
u32 __pad;
};
struct knav_reg_pdsp_regs {
u32 control;
u32 status;
u32 cycle_count;
u32 stall_count;
};
struct knav_reg_acc_command {
u32 command;
u32 queue_mask;
u32 list_phys;
u32 queue_num;
u32 timer_config;
};
struct knav_link_ram_block {
dma_addr_t phys;
void *virt;
size_t size;
};
struct knav_acc_info {
u32 pdsp_id;
u32 start_channel;
u32 list_entries;
u32 pacing_mode;
u32 timer_count;
int mem_size;
int list_size;
struct knav_pdsp_info *pdsp;
};
struct knav_acc_channel {
u32 channel;
u32 list_index;
u32 open_mask;
u32 *list_cpu[2];
dma_addr_t list_dma[2];
char name[KNAV_NAME_SIZE];
atomic_t retrigger_count;
};
struct knav_pdsp_info {
const char *name;
struct knav_reg_pdsp_regs __iomem *regs;
union {
void __iomem *command;
struct knav_reg_acc_command __iomem *acc_command;
u32 __iomem *qos_command;
};
void __iomem *intd;
u32 __iomem *iram;
const char *firmware;
u32 id;
struct list_head list;
};
struct knav_qmgr_info {
unsigned start_queue;
unsigned num_queues;
struct knav_reg_config __iomem *reg_config;
struct knav_reg_region __iomem *reg_region;
struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
void __iomem *reg_status;
struct list_head list;
};
#define KNAV_NUM_LINKRAM 2
/**
* struct knav_queue_stats: queue statistics
* pushes: number of push operations
* pops: number of pop operations
* push_errors: number of push errors
* pop_errors: number of pop errors
* notifies: notifier counts
*/
struct knav_queue_stats {
atomic_t pushes;
atomic_t pops;
atomic_t push_errors;
atomic_t pop_errors;
atomic_t notifies;
};
/**
* struct knav_reg_queue: queue registers
* @entry_count: valid entries in the queue
* @byte_count: total byte count in thhe queue
* @packet_size: packet size for the queue
* @ptr_size_thresh: packet pointer size threshold
*/
struct knav_reg_queue {
u32 entry_count;
u32 byte_count;
u32 packet_size;
u32 ptr_size_thresh;
};
/**
* struct knav_region: qmss region info
* @dma_start, dma_end: start and end dma address
* @virt_start, virt_end: start and end virtual address
* @desc_size: descriptor size
* @used_desc: consumed descriptors
* @id: region number
* @num_desc: total descriptors
* @link_index: index of the first descriptor
* @name: region name
* @list: instance in the device's region list
* @pools: list of descriptor pools in the region
*/
struct knav_region {
dma_addr_t dma_start, dma_end;
void *virt_start, *virt_end;
unsigned desc_size;
unsigned used_desc;
unsigned id;
unsigned num_desc;
unsigned link_index;
const char *name;
struct list_head list;
struct list_head pools;
};
/**
* struct knav_pool: qmss pools
* @dev: device pointer
* @region: qmss region info
* @queue: queue registers
* @kdev: qmss device pointer
* @region_offset: offset from the base
* @num_desc: total descriptors
* @desc_size: descriptor size
* @region_id: region number
* @name: pool name
* @list: list head
* @region_inst: instance in the region's pool list
*/
struct knav_pool {
struct device *dev;
struct knav_region *region;
struct knav_queue *queue;
struct knav_device *kdev;
int region_offset;
int num_desc;
int desc_size;
int region_id;
const char *name;
struct list_head list;
struct list_head region_inst;
};
/**
* struct knav_queue_inst: qmss queue instace properties
* @descs: descriptor pointer
* @desc_head, desc_tail, desc_count: descriptor counters
* @acc: accumulator channel pointer
* @kdev: qmss device pointer
* @range: range info
* @qmgr: queue manager info
* @id: queue instace id
* @irq_num: irq line number
* @notify_needed: notifier needed based on queue type
* @num_notifiers: total notifiers
* @handles: list head
* @name: queue instance name
* @irq_name: irq line name
*/
struct knav_queue_inst {
u32 *descs;
atomic_t desc_head, desc_tail, desc_count;
struct knav_acc_channel *acc;
struct knav_device *kdev;
struct knav_range_info *range;
struct knav_qmgr_info *qmgr;
u32 id;
int irq_num;
int notify_needed;
atomic_t num_notifiers;
struct list_head handles;
const char *name;
const char *irq_name;
};
/**
* struct knav_queue: qmss queue properties
* @reg_push, reg_pop, reg_peek: push, pop queue registers
* @inst: qmss queue instace properties
* @notifier_fn: notifier function
* @notifier_fn_arg: notifier function argument
* @notifier_enabled: notier enabled for a give queue
* @rcu: rcu head
* @flags: queue flags
* @list: list head
*/
struct knav_queue {
struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
struct knav_queue_inst *inst;
struct knav_queue_stats stats;
knav_queue_notify_fn notifier_fn;
void *notifier_fn_arg;
atomic_t notifier_enabled;
struct rcu_head rcu;
unsigned flags;
struct list_head list;
};
struct knav_device {
struct device *dev;
unsigned base_id;
unsigned num_queues;
unsigned num_queues_in_use;
unsigned inst_shift;
struct knav_link_ram_block link_rams[KNAV_NUM_LINKRAM];
void *instances;
struct list_head regions;
struct list_head queue_ranges;
struct list_head pools;
struct list_head pdsps;
struct list_head qmgrs;
};
struct knav_range_ops {
int (*init_range)(struct knav_range_info *range);
int (*free_range)(struct knav_range_info *range);
int (*init_queue)(struct knav_range_info *range,
struct knav_queue_inst *inst);
int (*open_queue)(struct knav_range_info *range,
struct knav_queue_inst *inst, unsigned flags);
int (*close_queue)(struct knav_range_info *range,
struct knav_queue_inst *inst);
int (*set_notify)(struct knav_range_info *range,
struct knav_queue_inst *inst, bool enabled);
};
struct knav_irq_info {
int irq;
u32 cpu_map;
};
struct knav_range_info {
const char *name;
struct knav_device *kdev;
unsigned queue_base;
unsigned num_queues;
void *queue_base_inst;
unsigned flags;
struct list_head list;
struct knav_range_ops *ops;
struct knav_acc_info acc_info;
struct knav_acc_channel *acc;
unsigned num_irqs;
struct knav_irq_info irqs[RANGE_MAX_IRQS];
};
#define RANGE_RESERVED BIT(0)
#define RANGE_HAS_IRQ BIT(1)
#define RANGE_HAS_ACCUMULATOR BIT(2)
#define RANGE_MULTI_QUEUE BIT(3)
#define for_each_region(kdev, region) \
list_for_each_entry(region, &kdev->regions, list)
#define first_region(kdev) \
list_first_entry(&kdev->regions, \
struct knav_region, list)
#define for_each_queue_range(kdev, range) \
list_for_each_entry(range, &kdev->queue_ranges, list)
#define first_queue_range(kdev) \
list_first_entry(&kdev->queue_ranges, \
struct knav_range_info, list)
#define for_each_pool(kdev, pool) \
list_for_each_entry(pool, &kdev->pools, list)
#define for_each_pdsp(kdev, pdsp) \
list_for_each_entry(pdsp, &kdev->pdsps, list)
#define for_each_qmgr(kdev, qmgr) \
list_for_each_entry(qmgr, &kdev->qmgrs, list)
static inline struct knav_pdsp_info *
knav_find_pdsp(struct knav_device *kdev, unsigned pdsp_id)
{
struct knav_pdsp_info *pdsp;
for_each_pdsp(kdev, pdsp)
if (pdsp_id == pdsp->id)
return pdsp;
return NULL;
}
extern int knav_init_acc_range(struct knav_device *kdev,
struct device_node *node,
struct knav_range_info *range);
extern void knav_queue_notify(struct knav_queue_inst *inst);
#endif /* __KNAV_QMSS_H__ */
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) 2014 Texas Instruments Incorporated
* Authors: Sandeep Nair <sandeep_n@ti.com
* Cyril Chemparathy <cyril@ti.com
Santosh Shilimkar <santosh.shilimkar@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__
#define __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__
/*
* PKTDMA descriptor manipulation macros for host packet descriptor
*/
#define MASK(x) (BIT(x) - 1)
#define KNAV_DMA_DESC_PKT_LEN_MASK MASK(22)
#define KNAV_DMA_DESC_PKT_LEN_SHIFT 0
#define KNAV_DMA_DESC_PS_INFO_IN_SOP BIT(22)
#define KNAV_DMA_DESC_PS_INFO_IN_DESC 0
#define KNAV_DMA_DESC_TAG_MASK MASK(8)
#define KNAV_DMA_DESC_SAG_HI_SHIFT 24
#define KNAV_DMA_DESC_STAG_LO_SHIFT 16
#define KNAV_DMA_DESC_DTAG_HI_SHIFT 8
#define KNAV_DMA_DESC_DTAG_LO_SHIFT 0
#define KNAV_DMA_DESC_HAS_EPIB BIT(31)
#define KNAV_DMA_DESC_NO_EPIB 0
#define KNAV_DMA_DESC_PSLEN_SHIFT 24
#define KNAV_DMA_DESC_PSLEN_MASK MASK(6)
#define KNAV_DMA_DESC_ERR_FLAG_SHIFT 20
#define KNAV_DMA_DESC_ERR_FLAG_MASK MASK(4)
#define KNAV_DMA_DESC_PSFLAG_SHIFT 16
#define KNAV_DMA_DESC_PSFLAG_MASK MASK(4)
#define KNAV_DMA_DESC_RETQ_SHIFT 0
#define KNAV_DMA_DESC_RETQ_MASK MASK(14)
#define KNAV_DMA_DESC_BUF_LEN_MASK MASK(22)
#define KNAV_DMA_NUM_EPIB_WORDS 4
#define KNAV_DMA_NUM_PS_WORDS 16
#define KNAV_DMA_FDQ_PER_CHAN 4
/* Tx channel scheduling priority */
enum knav_dma_tx_priority {
DMA_PRIO_HIGH = 0,
DMA_PRIO_MED_H,
DMA_PRIO_MED_L,
DMA_PRIO_LOW
};
/* Rx channel error handling mode during buffer starvation */
enum knav_dma_rx_err_mode {
DMA_DROP = 0,
DMA_RETRY
};
/* Rx flow size threshold configuration */
enum knav_dma_rx_thresholds {
DMA_THRESH_NONE = 0,
DMA_THRESH_0 = 1,
DMA_THRESH_0_1 = 3,
DMA_THRESH_0_1_2 = 7
};
/* Descriptor type */
enum knav_dma_desc_type {
DMA_DESC_HOST = 0,
DMA_DESC_MONOLITHIC = 2
};
/**
* struct knav_dma_tx_cfg: Tx channel configuration
* @filt_einfo: Filter extended packet info
* @filt_pswords: Filter PS words present
* @knav_dma_tx_priority: Tx channel scheduling priority
*/
struct knav_dma_tx_cfg {
bool filt_einfo;
bool filt_pswords;
enum knav_dma_tx_priority priority;
};
/**
* struct knav_dma_rx_cfg: Rx flow configuration
* @einfo_present: Extended packet info present
* @psinfo_present: PS words present
* @knav_dma_rx_err_mode: Error during buffer starvation
* @knav_dma_desc_type: Host or Monolithic desc
* @psinfo_at_sop: PS word located at start of packet
* @sop_offset: Start of packet offset
* @dst_q: Destination queue for a given flow
* @thresh: Rx flow size threshold
* @fdq[]: Free desc Queue array
* @sz_thresh0: RX packet size threshold 0
* @sz_thresh1: RX packet size threshold 1
* @sz_thresh2: RX packet size threshold 2
*/
struct knav_dma_rx_cfg {
bool einfo_present;
bool psinfo_present;
enum knav_dma_rx_err_mode err_mode;
enum knav_dma_desc_type desc_type;
bool psinfo_at_sop;
unsigned int sop_offset;
unsigned int dst_q;
enum knav_dma_rx_thresholds thresh;
unsigned int fdq[KNAV_DMA_FDQ_PER_CHAN];
unsigned int sz_thresh0;
unsigned int sz_thresh1;
unsigned int sz_thresh2;
};
/**
* struct knav_dma_cfg: Pktdma channel configuration
* @sl_cfg: Slave configuration
* @tx: Tx channel configuration
* @rx: Rx flow configuration
*/
struct knav_dma_cfg {
enum dma_transfer_direction direction;
union {
struct knav_dma_tx_cfg tx;
struct knav_dma_rx_cfg rx;
} u;
};
/**
* struct knav_dma_desc: Host packet descriptor layout
* @desc_info: Descriptor information like id, type, length
* @tag_info: Flow tag info written in during RX
* @packet_info: Queue Manager, policy, flags etc
* @buff_len: Buffer length in bytes
* @buff: Buffer pointer
* @next_desc: For chaining the descriptors
* @orig_len: length since 'buff_len' can be overwritten
* @orig_buff: buff pointer since 'buff' can be overwritten
* @epib: Extended packet info block
* @psdata: Protocol specific
*/
struct knav_dma_desc {
u32 desc_info;
u32 tag_info;
u32 packet_info;
u32 buff_len;
u32 buff;
u32 next_desc;
u32 orig_len;
u32 orig_buff;
u32 epib[KNAV_DMA_NUM_EPIB_WORDS];
u32 psdata[KNAV_DMA_NUM_PS_WORDS];
u32 pad[4];
} ____cacheline_aligned;
#ifdef CONFIG_KEYSTONE_NAVIGATOR_DMA
void *knav_dma_open_channel(struct device *dev, const char *name,
struct knav_dma_cfg *config);
void knav_dma_close_channel(void *channel);
#else
static inline void *knav_dma_open_channel(struct device *dev, const char *name,
struct knav_dma_cfg *config)
{
return (void *) NULL;
}
static inline void knav_dma_close_channel(void *channel)
{}
#endif
#endif /* __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__ */
/*
* Keystone Navigator Queue Management Sub-System header
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
* Author: Sandeep Nair <sandeep_n@ti.com>
* Cyril Chemparathy <cyril@ti.com>
* Santosh Shilimkar <santosh.shilimkar@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __SOC_TI_KNAV_QMSS_H__
#define __SOC_TI_KNAV_QMSS_H__
#include <linux/err.h>
#include <linux/time.h>
#include <linux/atomic.h>
#include <linux/device.h>
#include <linux/fcntl.h>
#include <linux/dma-mapping.h>
/* queue types */
#define KNAV_QUEUE_QPEND ((unsigned)-2) /* interruptible qpend queue */
#define KNAV_QUEUE_ACC ((unsigned)-3) /* Accumulated queue */
#define KNAV_QUEUE_GP ((unsigned)-4) /* General purpose queue */
/* queue flags */
#define KNAV_QUEUE_SHARED 0x0001 /* Queue can be shared */
/**
* enum knav_queue_ctrl_cmd - queue operations.
* @KNAV_QUEUE_GET_ID: Get the ID number for an open queue
* @KNAV_QUEUE_FLUSH: forcibly empty a queue if possible
* @KNAV_QUEUE_SET_NOTIFIER: Set a notifier callback to a queue handle.
* @KNAV_QUEUE_ENABLE_NOTIFY: Enable notifier callback for a queue handle.
* @KNAV_QUEUE_DISABLE_NOTIFY: Disable notifier callback for a queue handle.
* @KNAV_QUEUE_GET_COUNT: Get number of queues.
*/
enum knav_queue_ctrl_cmd {
KNAV_QUEUE_GET_ID,
KNAV_QUEUE_FLUSH,
KNAV_QUEUE_SET_NOTIFIER,
KNAV_QUEUE_ENABLE_NOTIFY,
KNAV_QUEUE_DISABLE_NOTIFY,
KNAV_QUEUE_GET_COUNT
};
/* Queue notifier callback prototype */
typedef void (*knav_queue_notify_fn)(void *arg);
/**
* struct knav_queue_notify_config: Notifier configuration
* @fn: Notifier function
* @fn_arg: Notifier function arguments
*/
struct knav_queue_notify_config {
knav_queue_notify_fn fn;
void *fn_arg;
};
void *knav_queue_open(const char *name, unsigned id,
unsigned flags);
void knav_queue_close(void *qhandle);
int knav_queue_device_control(void *qhandle,
enum knav_queue_ctrl_cmd cmd,
unsigned long arg);
dma_addr_t knav_queue_pop(void *qhandle, unsigned *size);
int knav_queue_push(void *qhandle, dma_addr_t dma,
unsigned size, unsigned flags);
void *knav_pool_create(const char *name,
int num_desc, int region_id);
void knav_pool_destroy(void *ph);
int knav_pool_count(void *ph);
void *knav_pool_desc_get(void *ph);
void knav_pool_desc_put(void *ph, void *desc);
int knav_pool_desc_map(void *ph, void *desc, unsigned size,
dma_addr_t *dma, unsigned *dma_sz);
void *knav_pool_desc_unmap(void *ph, dma_addr_t dma, unsigned dma_sz);
dma_addr_t knav_pool_desc_virt_to_dma(void *ph, void *virt);
void *knav_pool_desc_dma_to_virt(void *ph, dma_addr_t dma);
#endif /* __SOC_TI_KNAV_QMSS_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment