Sergei Shtylyov <[email protected]> writes:
> Add the function to initialize the CPPI 4.1 subsystem along with the data
> describing CPPI 4.1 queue manager and DMA block found in DA8xx chips.
>
> Modify USB 2.0 clock entry to have the clock enabled early if we have
> CPPI 4.1 subsystem enabled.
>
> Signed-off-by: Sergei Shtylyov <[email protected]>
>
> ---
> The patch is against the recent DaVinci tree.
>
> arch/arm/mach-davinci/da830.c | 4 +
> arch/arm/mach-davinci/devices-da8xx.c | 95
> +++++++++++++++++++++++++++++
> arch/arm/mach-davinci/include/mach/da8xx.h | 6 +
> 3 files changed, 105 insertions(+)
>
> Index: linux-davinci/arch/arm/mach-davinci/da830.c
> ===================================================================
> --- linux-davinci.orig/arch/arm/mach-davinci/da830.c
> +++ linux-davinci/arch/arm/mach-davinci/da830.c
> @@ -305,6 +305,10 @@ static struct clk usb20_clk = {
> .parent = &pll0_sysclk2,
> .lpsc = DA8XX_LPSC1_USB20,
> .psc_ctlr = 1,
> +#ifdef CONFIG_CPPI41
> + /* CPPI 4.1 is clocked by USB 2.0 clock */
> + .flags = ALWAYS_ENABLED,
> +#endif
Don't like this. If CPP4.1 is clocked by USB2.0 clock, it should do a
clk_get()/clk_enable() on it. If you can't use clk_enable() there
should be detailed description as to why.
> };
>
> static struct clk aemif_clk = {
> Index: linux-davinci/arch/arm/mach-davinci/devices-da8xx.c
> ===================================================================
> --- linux-davinci.orig/arch/arm/mach-davinci/devices-da8xx.c
> +++ linux-davinci/arch/arm/mach-davinci/devices-da8xx.c
> @@ -20,6 +20,7 @@
> #include <mach/cputype.h>
> #include <mach/common.h>
> #include <mach/time.h>
> +#include <mach/cppi41.h>
> #include <mach/da8xx.h>
> #include <video/da8xx-fb.h>
>
> @@ -448,3 +449,97 @@ int __init da8xx_register_mmcsd0(struct
> da8xx_mmcsd0_device.dev.platform_data = config;
> return platform_device_register(&da8xx_mmcsd0_device);
> }
> +
> +#ifdef CONFIG_CPPI41
> +
> +static const struct cppi41_tx_ch tx_ch_info[] = {
> + [0] = {
> + .port_num = 1,
> + .num_tx_queue = 2,
> + .tx_queue = { { 0, 16 }, { 0, 17 } }
> + },
> + [1] = {
> + .port_num = 2,
> + .num_tx_queue = 2,
> + .tx_queue = { { 0, 18 }, { 0, 19 } }
> + },
> + [2] = {
> + .port_num = 3,
> + .num_tx_queue = 2,
> + .tx_queue = { { 0, 20 }, { 0, 21 } }
> + },
> + [3] = {
> + .port_num = 4,
> + .num_tx_queue = 2,
> + .tx_queue = { { 0, 22 }, { 0, 23 } }
> + }
> +};
> +
> +/* DMA block configuration */
> +const struct cppi41_dma_block cppi41_dma_block[1] = {
> + [0] = {
> + .global_ctrl_base = IO_ADDRESS(DA8XX_USB0_BASE + 0x1000),
> + .ch_ctrl_stat_base = IO_ADDRESS(DA8XX_USB0_BASE + 0x1800),
> + .sched_ctrl_base = IO_ADDRESS(DA8XX_USB0_BASE + 0x2000),
> + .sched_table_base = IO_ADDRESS(DA8XX_USB0_BASE + 0x2800),
> + .num_tx_ch = 4,
> + .num_rx_ch = 4,
> + .tx_ch_info = tx_ch_info
> + }
> +};
> +EXPORT_SYMBOL(cppi41_dma_block);
> +
> +/* Queues 0 to 27 are pre-assigned, others are spare */
> +static const u32 assigned_queues[] = { 0x0fffffff, 0 };
> +
> +/* Queue manager information */
> +const struct cppi41_queue_mgr cppi41_queue_mgr[1] = {
> + [0] = {
> + .q_mgr_rgn_base = IO_ADDRESS(DA8XX_USB0_BASE + 0x4000),
> + .desc_mem_rgn_base = IO_ADDRESS(DA8XX_USB0_BASE + 0x5000),
> + .q_mgmt_rgn_base = IO_ADDRESS(DA8XX_USB0_BASE + 0x6000),
> + .q_stat_rgn_base = IO_ADDRESS(DA8XX_USB0_BASE + 0x6800),
> +
> + .num_queue = 64,
> + .queue_types = CPPI41_FREE_DESC_BUF_QUEUE |
> + CPPI41_UNASSIGNED_QUEUE,
> + .base_fdbq_num = 0,
> + .assigned = assigned_queues
> + }
> +};
> +
> +const u8 cppi41_num_queue_mgr = 1;
> +const u8 cppi41_num_dma_block = 1;
> +
> +/* Fair DMA scheduling */
> +static const u8 dma_sched_table[] = {
> + 0x00, 0x80, 0x01, 0x81, 0x02, 0x82, 0x03, 0x83
> +};
> +
> +int __init da8xx_cppi41_init(void)
> +{
> + int ret;
> +
> + ret = cppi41_queue_mgr_init(0, 0, 0);
> + if (ret) {
> + pr_warning("%s: queue manager initialization failed: %d\n",
> + __func__, ret);
> + return ret;
> + }
> +
> + ret = cppi41_dma_ctrlr_init(0, 0, 5);
> + if (ret) {
> + pr_warning("%s: DMA controller initialization failed: %d\n",
> + __func__, ret);
> + return ret;
> + }
> +
> + ret = cppi41_dma_sched_init(0, dma_sched_table,
> + sizeof(dma_sched_table));
> + if (ret)
> + printk("%s: DMA scheduler initialization failed: %d\n",
> + __func__, ret);
checkpatch: WARNING: printk() should include KERN_ facility level
I assume you wanted pr_warning() here too.
> + return ret;
> +}
> +
> +#endif /* CONFIG_CPPI41 */
> Index: linux-davinci/arch/arm/mach-davinci/include/mach/da8xx.h
> ===================================================================
> --- linux-davinci.orig/arch/arm/mach-davinci/include/mach/da8xx.h
> +++ linux-davinci/arch/arm/mach-davinci/include/mach/da8xx.h
> @@ -68,6 +68,12 @@
> void __init da830_init(void);
> void __init da850_init(void);
>
> +#ifdef CONFIG_CPPI41
> +int da8xx_cppi41_init(void);
> +#else
> +static int da8xx_cppi41_init(void) { return 0; }
> +#endif
> +
Minor nit, but I'd rather these kinds of init function #ifdefs in the
C-code and not the header.
> int da8xx_register_edma(void);
> int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data
> *pdata);
> int da8xx_register_watchdog(void);
Kevin
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source