Add da8xx_cppi41_init() function to initialize the CPPI 4.1 subsystem along with the data describing the CPPI 4.1 queue manager and the DMA block found in OMAP-L1x/DA8xx chips.
Note that we have to modify the USB 2.0 clock entry in order to match the clock by name since we don't have a device in da8xx_cppi41_init()... Signed-off-by: Sergei Shtylyov <sshtyl...@ru.mvista.com> --- The patch is against the recent DaVinci tree. Changes since the previous take: - had to move USB 2.0 clock entry change from another patch... Argh again! :-/ arch/arm/mach-davinci/da830.c | 2 arch/arm/mach-davinci/devices-da8xx.c | 112 +++++++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/da8xx.h | 2 3 files changed, 115 insertions(+), 1 deletion(-) 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 @@ -415,7 +415,7 @@ static struct davinci_clk da830_clks[] = CLK("davinci-mcasp.0", NULL, &mcasp0_clk), CLK("davinci-mcasp.1", NULL, &mcasp1_clk), CLK("davinci-mcasp.2", NULL, &mcasp2_clk), - CLK("musb_hdrc", NULL, &usb20_clk), + CLK(NULL, "usb20", &usb20_clk), CLK(NULL, "aemif", &aemif_clk), CLK(NULL, "aintc", &aintc_clk), CLK(NULL, "secu_mgr", &secu_mgr_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 @@ -21,6 +21,7 @@ #include <mach/common.h> #include <mach/time.h> #include <mach/da8xx.h> +#include <mach/cppi41.h> #include "clock.h" @@ -488,3 +489,114 @@ int da8xx_register_rtc(void) return platform_device_register(&da8xx_rtc_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) +{ + struct clk *usb20_clk; + int ret; + + /* CPPI 4.1 is clocked by USB 2.0 clock. */ + usb20_clk = clk_get(NULL, "usb20"); + if (IS_ERR(usb20_clk)) { + ret = PTR_ERR(usb20_clk); + pr_warning("%s: clk_get() call failed: %d\n", __func__, ret); + return ret; + } + clk_enable(usb20_clk); + + /* We provide no memory for the queue manager's linking RAM region 0. */ + ret = cppi41_queue_mgr_init(0, 0, 0); + if (ret) { + pr_warning("%s: queue manager initialization failed: %d\n", + __func__, ret); + return ret; + } + + /* Allocate 32 (2^5) DMA teardown descriptors from queue manager 0. */ + 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) + pr_warning("%s: DMA scheduler initialization failed: %d\n", + __func__, ret); + return ret; +} + +#else +int __init da8xx_cppi41_init(void) +{ + return 0; +} +#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 @@ -74,6 +74,8 @@ extern void __iomem *da8xx_syscfg_base; void __init da830_init(void); void __init da850_init(void); +int da8xx_cppi41_init(void); + int da8xx_register_edma(void); int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata); int da8xx_register_watchdog(void); _______________________________________________ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source