2013-10-16 21:10:54 +02:00
/*
* Samsung ' s S3C64XX generic DMA support using amba - pl08x driver .
*
* Copyright ( c ) 2013 Tomasz Figa < tomasz . figa @ gmail . 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 .
*/
# include <linux/kernel.h>
# include <linux/amba/bus.h>
# include <linux/amba/pl080.h>
# include <linux/amba/pl08x.h>
# include <linux/of.h>
2015-02-27 20:31:51 +01:00
# include <plat/cpu.h>
2013-10-16 21:10:54 +02:00
# include <mach/irqs.h>
# include <mach/map.h>
# include "regs-sys.h"
static int pl08x_get_xfer_signal ( const struct pl08x_channel_data * cd )
{
return cd - > min_signal ;
}
static void pl08x_put_xfer_signal ( const struct pl08x_channel_data * cd , int ch )
{
}
/*
* DMA0
*/
static struct pl08x_channel_data s3c64xx_dma0_info [ ] = {
{
. bus_id = " uart0_tx " ,
. min_signal = 0 ,
. max_signal = 0 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " uart0_rx " ,
. min_signal = 1 ,
. max_signal = 1 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " uart1_tx " ,
. min_signal = 2 ,
. max_signal = 2 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " uart1_rx " ,
. min_signal = 3 ,
. max_signal = 3 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " uart2_tx " ,
. min_signal = 4 ,
. max_signal = 4 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " uart2_rx " ,
. min_signal = 5 ,
. max_signal = 5 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " uart3_tx " ,
. min_signal = 6 ,
. max_signal = 6 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " uart3_rx " ,
. min_signal = 7 ,
. max_signal = 7 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " pcm0_tx " ,
. min_signal = 8 ,
. max_signal = 8 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " pcm0_rx " ,
. min_signal = 9 ,
. max_signal = 9 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " i2s0_tx " ,
. min_signal = 10 ,
. max_signal = 10 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " i2s0_rx " ,
. min_signal = 11 ,
. max_signal = 11 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " spi0_tx " ,
. min_signal = 12 ,
. max_signal = 12 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " spi0_rx " ,
. min_signal = 13 ,
. max_signal = 13 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " i2s2_tx " ,
. min_signal = 14 ,
. max_signal = 14 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " i2s2_rx " ,
. min_signal = 15 ,
. max_signal = 15 ,
. periph_buses = PL08X_AHB2 ,
}
} ;
struct pl08x_platform_data s3c64xx_dma0_plat_data = {
. memcpy_channel = {
. bus_id = " memcpy " ,
. cctl_memcpy =
( PL080_BSIZE_4 < < PL080_CONTROL_SB_SIZE_SHIFT |
PL080_BSIZE_4 < < PL080_CONTROL_DB_SIZE_SHIFT |
PL080_WIDTH_32BIT < < PL080_CONTROL_SWIDTH_SHIFT |
PL080_WIDTH_32BIT < < PL080_CONTROL_DWIDTH_SHIFT |
PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
PL080_CONTROL_PROT_SYS ) ,
} ,
. lli_buses = PL08X_AHB1 ,
. mem_buses = PL08X_AHB1 ,
. get_xfer_signal = pl08x_get_xfer_signal ,
. put_xfer_signal = pl08x_put_xfer_signal ,
. slave_channels = s3c64xx_dma0_info ,
. num_slave_channels = ARRAY_SIZE ( s3c64xx_dma0_info ) ,
} ;
static AMBA_AHB_DEVICE ( s3c64xx_dma0 , " dma-pl080s.0 " , 0 ,
0x75000000 , { IRQ_DMA0 } , & s3c64xx_dma0_plat_data ) ;
/*
* DMA1
*/
static struct pl08x_channel_data s3c64xx_dma1_info [ ] = {
{
. bus_id = " pcm1_tx " ,
. min_signal = 0 ,
. max_signal = 0 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " pcm1_rx " ,
. min_signal = 1 ,
. max_signal = 1 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " i2s1_tx " ,
. min_signal = 2 ,
. max_signal = 2 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " i2s1_rx " ,
. min_signal = 3 ,
. max_signal = 3 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " spi1_tx " ,
. min_signal = 4 ,
. max_signal = 4 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " spi1_rx " ,
. min_signal = 5 ,
. max_signal = 5 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " ac97_out " ,
. min_signal = 6 ,
. max_signal = 6 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " ac97_in " ,
. min_signal = 7 ,
. max_signal = 7 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " ac97_mic " ,
. min_signal = 8 ,
. max_signal = 8 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " pwm " ,
. min_signal = 9 ,
. max_signal = 9 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " irda " ,
. min_signal = 10 ,
. max_signal = 10 ,
. periph_buses = PL08X_AHB2 ,
} , {
. bus_id = " external " ,
. min_signal = 11 ,
. max_signal = 11 ,
. periph_buses = PL08X_AHB2 ,
} ,
} ;
struct pl08x_platform_data s3c64xx_dma1_plat_data = {
. memcpy_channel = {
. bus_id = " memcpy " ,
. cctl_memcpy =
( PL080_BSIZE_4 < < PL080_CONTROL_SB_SIZE_SHIFT |
PL080_BSIZE_4 < < PL080_CONTROL_DB_SIZE_SHIFT |
PL080_WIDTH_32BIT < < PL080_CONTROL_SWIDTH_SHIFT |
PL080_WIDTH_32BIT < < PL080_CONTROL_DWIDTH_SHIFT |
PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
PL080_CONTROL_PROT_SYS ) ,
} ,
. lli_buses = PL08X_AHB1 ,
. mem_buses = PL08X_AHB1 ,
. get_xfer_signal = pl08x_get_xfer_signal ,
. put_xfer_signal = pl08x_put_xfer_signal ,
. slave_channels = s3c64xx_dma1_info ,
. num_slave_channels = ARRAY_SIZE ( s3c64xx_dma1_info ) ,
} ;
static AMBA_AHB_DEVICE ( s3c64xx_dma1 , " dma-pl080s.1 " , 0 ,
0x75100000 , { IRQ_DMA1 } , & s3c64xx_dma1_plat_data ) ;
static int __init s3c64xx_pl080_init ( void )
{
2015-02-27 20:31:51 +01:00
if ( ! soc_is_s3c64xx ( ) )
return 0 ;
2013-10-16 21:10:54 +02:00
/* Set all DMA configuration to be DMA, not SDMA */
writel ( 0xffffff , S3C64XX_SDMA_SEL ) ;
if ( of_have_populated_dt ( ) )
return 0 ;
amba_device_register ( & s3c64xx_dma0_device , & iomem_resource ) ;
amba_device_register ( & s3c64xx_dma1_device , & iomem_resource ) ;
return 0 ;
}
arch_initcall ( s3c64xx_pl080_init ) ;