Hello,

Sergei Shtylyov <[email protected]> writes:

> Add support for Texas Instuments Communication Port Programming Interface
> 4.1
> (CPPI 4.1) used on OMAP-L137/DA830.
> 
> At this moment, only the DMA controller and queue manager are supported.
> Support for the buffer manager is lacking but this chip doesn't have it
> anyway.
> 
> ---
> As DA830/OMAP-L137 code is going to reside in arch/arm/mach-davinci/, I
> had to
> place the code into this directory by the popular demand, despite CPPI 4.1
> not
> really being arch-specific...
> 
> The patch is against the recent DaVinci tree, plus my patch adding the
> cp_intc
> support...
> 
>  arch/arm/mach-davinci/Kconfig               |    5
>  arch/arm/mach-davinci/Makefile              |    1
>  arch/arm/mach-davinci/cppi41.c              |  788
> ++++++++++++++++++++++++++++
>  arch/arm/mach-davinci/include/mach/cppi41.h |  710
> +++++++++++++++++++++++++
>  4 files changed, 1504 insertions(+)
> 
> Index: linux-davinci/arch/arm/mach-davinci/Kconfig
> ===================================================================
> --- linux-davinci.orig/arch/arm/mach-davinci/Kconfig
> +++ linux-davinci/arch/arm/mach-davinci/Kconfig
> @@ -19,6 +19,11 @@ config ARCH_DAVINCI_DM355
>          bool "DaVinci 355 based system"
>       select CPU_V5
> 
> +config CPPI41
> +     bool "CPPI 4.1 support"
> +     help
> +       Configure this option to include the CPPI 4.1 support.
> +
>  comment "DaVinci Board Type"
> 
>  config MACH_DAVINCI_EVM
> Index: linux-davinci/arch/arm/mach-davinci/Makefile
> ===================================================================
> --- linux-davinci.orig/arch/arm/mach-davinci/Makefile
> +++ linux-davinci/arch/arm/mach-davinci/Makefile
> @@ -14,6 +14,7 @@ obj-$(CONFIG_ARCH_DAVINCI_DM644x)
>  obj-$(CONFIG_ARCH_DAVINCI_DM646x)       += dm646x.o
>  obj-$(CONFIG_ARCH_DAVINCI_DM355)        += dm355.o
>  obj-$(CONFIG_CP_INTC)                        += cp_intc.o
> +obj-$(CONFIG_CPPI41)                 += cppi41.o
> 
>  # Board specific
>  obj-$(CONFIG_MACH_DAVINCI_EVM)       += board-dm644x-evm.o
> Index: linux-davinci/arch/arm/mach-davinci/cppi41.c
> ===================================================================
> --- /dev/null
> +++ linux-davinci/arch/arm/mach-davinci/cppi41.c
> @@ -0,0 +1,788 @@
> +/*
[...]
> +
> +/* First 32 packet descriptors are reserved for unallocated memory
> regions. */
> +static u32 next_desc_index[CPPI41_NUM_QUEUE_MGR] = { 1 << 5 };
> +static u8  next_mem_rgn[CPPI41_NUM_QUEUE_MGR];
> +
> +static struct {
> +     size_t rgn_size;
> +     void *virt_addr;
> +     dma_addr_t phys_addr;
> +     struct cppi41_queue_obj queue_obj;
> +     u8 mem_rgn;
> +} dma_teardown[CPPI41_NUM_DMA_BLOCK];
> +
> +/******************** CPPI 4.1 Functions (External Interface)
> *****************/
> +
> +int __init cppi41_queue_mgr_init(u8 q_mgr, dma_addr_t rgn0_base, u16
> rgn0_size)
> +{
> +     void __iomem *q_mgr_regs;
> +     void *ptr;
> +
> +     if (q_mgr >= cppi41_num_queue_mgr)
> +             return -EINVAL;
> +
> +     q_mgr_regs = cppi41_queue_mgr[q_mgr].q_mgr_rgn_base;
> +
> +     __raw_writel(rgn0_base, q_mgr_regs +
> QMGR_LINKING_RAM_RGN0_BASE_REG);
> +     DBG("Linking RAM region 0 base @ %p, value: %x\n",
> +         q_mgr_regs + QMGR_LINKING_RAM_RGN0_BASE_REG,
> +         __raw_readl(q_mgr_regs + QMGR_LINKING_RAM_RGN0_BASE_REG));
> +
> +     __raw_writel(rgn0_size, q_mgr_regs +
> QMGR_LINKING_RAM_RGN0_SIZE_REG);
> +     DBG("Linking RAM region 0 size @ %p, value: %x\n",
> +         q_mgr_regs + QMGR_LINKING_RAM_RGN0_SIZE_REG,
> +         __raw_readl(q_mgr_regs + QMGR_LINKING_RAM_RGN0_SIZE_REG));
> +
> +     ptr = dma_alloc_coherent(NULL, 0x10000 - rgn0_size * 4,
> +                              &linking_ram[q_mgr].phys_addr,
> +                              GFP_KERNEL | GFP_DMA);
[HP] Consider if region 2 allocation is really required always. Of course, this 
will need total number of descriptors in system to be known beforehand.

> +     if (ptr == NULL) {
> +             printk(KERN_ERR "ERROR: %s: Unable to allocate "
> +                    "linking RAM.\n", __func__);
> +             return -ENOMEM;
> +     }
> +     linking_ram[q_mgr].virt_addr = ptr;
> +
> +     __raw_writel(linking_ram[q_mgr].phys_addr,
> +                  q_mgr_regs + QMGR_LINKING_RAM_RGN1_BASE_REG);
> +     DBG("Linking RAM region 1 base @ %p, value: %x\n",
> +         q_mgr_regs + QMGR_LINKING_RAM_RGN1_BASE_REG,
> +         __raw_readl(q_mgr_regs + QMGR_LINKING_RAM_RGN1_BASE_REG));
> +
> +     ptr = kzalloc(BITS_TO_LONGS(cppi41_queue_mgr[q_mgr].num_queue),
> +                   GFP_KERNEL);
> +     if (ptr == NULL) {
> +             printk(KERN_ERR "ERROR: %s: Unable to allocate queue
> bitmap.\n",
> +                    __func__);
> +             dma_free_coherent(NULL, 0x10000 - rgn0_size * 4,
> +                               linking_ram[q_mgr].virt_addr,
> +                               linking_ram[q_mgr].phys_addr);
> +             return -ENOMEM;
> +     }
> +     allocated_queues[q_mgr] = ptr;
> +
> +     return 0;
> +}
[...]
> +
> +MODULE_DESCRIPTION("TI CPPI 4.1 support");
> +MODULE_AUTHOR("MontaVista Software");
> +MODULE_LICENSE("GPL");
> Index: linux-davinci/arch/arm/mach-davinci/include/mach/cppi41.h
> ===================================================================
> --- /dev/null
> +++ linux-davinci/arch/arm/mach-davinci/include/mach/cppi41.h
> @@ -0,0 +1,710 @@
> +/*
> + * CPPI 4.1 definitions
> + *
> + * Copyright (c) 2008-2009, MontaVista Software, Inc. <[email protected]>
> + *
> + * This program is free software; you can distribute 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 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.
> + *
> + * You should have received a copy of the GNU General Public License
> along
> + * with this program; if not, write to the Free Software Foundation,
> Inc.,
> + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
> + *
> + */
> +
> +#include <linux/types.h>
> +
> +/*
> + * Queue Manager - Control Registers Region
> + */
> +#define QMGR_REVISION_REG            0x00    /* Major and minor versions */
> +                                             /* of the module */
[...]

> +enum cppi41_rx_desc_type {
> +     cppi41_rx_embed_desc,
> +     cppi41_rx_host_desc,
> +     cppi41_rx_mono_desc,
> +};
> +
> +/**
> + * struct cppi41_rx_ch_cfg - Rx Channel Configuration
> + *
> + * Must be allocated and filled by the caller of
> cppi41_rx_ch_configure().
> + *
> + * The same channel can be configured to receive different descripor type
> + * packets (not simaltaneously). When the Rx packets on a port need to be
> sent
> + * to the SR, the channels default descriptor type is set to Embedded and
> the
> + * Rx completion queue is set to the queue which CPU polls for input
> packets.
> + * When in SR bypass mode, the same channel's default descriptor type
> will be
> + * set to Host and the Rx completion queue set to one of the queues which
> host
> + * can get interrupted on (via the Queuing proxy/accumulator). In this
> example,
> + * the embedded mode configuration fetches free descriptor from the Free
> + * descriptor queue (as defined by struct cppi41_embed_pkt_cfg) and host
> + * mode configuration fetches free descriptors/buffers from the free
> descriptor/
> + * buffer queue (as defined by struct cppi41_host_pkt_cfg).
> + *
> + * NOTE: There seems to be no separate configuration for teardown
> completion
> + * descriptor. The assumption is rxQueue tuple is used for this purpose
> as well.
> + */
[HP] Replace reference to SR with generic term ('embedded processor'?)

> +struct cppi41_rx_ch_cfg {
> +     enum cppi41_rx_desc_type default_desc_type; /* Describes which queue
> */
> +                             /* configuration is used for the free */
> +                             /* descriptors and/or buffers */
> +     u8 sop_offset;          /* Number of bytes to skip in SOP buffer */
> +                             /* before writing payload */
> +     u8 retry_starved;       /* 0 = Drop packet on descriptor/buffer */
> +                             /* starvartion, 1 = DMA retries FIFO block */
> +                             /* transfer at a later time */
> +     struct cppi41_queue rx_queue; /* Rx complete packets queue */
> +     union {
> +             struct cppi41_host_pkt_cfg host_pkt; /* Host packet */
> +                             /* configuration. This defines where channel */
> +                             /* picks free descriptors from. */
> +             struct cppi41_embed_pkt_cfg embed_pkt; /* Embedded packet */
> +                             /* configuration. This defines where channel */
> +                             /* picks free descriptors/buffers from. */
> +                             /* from. */
> +             struct cppi41_mono_pkt_cfg mono_pkt; /* Monolithic packet */
> +                             /* configuration. This defines where channel */
> +                             /* picks free descriptors from. */
> +     } cfg;                  /* Union of packet configuration structures
> */
> +                             /* to be filled in depending on the */
> +                             /* defDescType field. */
> +};
> +
[...]
> +
> +/*
> + * CPPI 4.1 Miscellaneous APIs
> + */
> +
> +/**
> + * cppi41_get_teardown_info - CPPI 4.1 teardown completion processing
> function
> + *
> + * @addr:    physical address of teardown descriptor
> + * @info:    pointer to the teardown information word
> + *
> + * This function is called to complete the teardown processing on a
> channel
> + * and provides teardown information from the teardown descriptor passed
> to it.
> + * It also recycles the teardown descriptor back to the teardown
> descriptor
> + * queue.
> + *
> + * Returns 0 if valid descriptor, -EINVAL otherwise.
> + */
> +int cppi41_get_teardown_info(unsigned long addr, u32 *info);
[HP] A more specific name as this is not just a 'get' function?

Thanks,
Hemant
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to