2017-12-25 20:54:33 +01:00
// SPDX-License-Identifier: GPL-2.0
//
// Samsung's S3C64XX generic DMA support using amba-pl08x driver.
//
// Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
2013-10-16 21:10:54 +02:00
# 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 ,
}
} ;
2016-11-10 16:17:50 +01:00
static const struct dma_slave_map s3c64xx_dma0_slave_map [ ] = {
{ " s3c6400-uart.0 " , " tx " , & s3c64xx_dma0_info [ 0 ] } ,
{ " s3c6400-uart.0 " , " rx " , & s3c64xx_dma0_info [ 1 ] } ,
{ " s3c6400-uart.1 " , " tx " , & s3c64xx_dma0_info [ 2 ] } ,
{ " s3c6400-uart.1 " , " rx " , & s3c64xx_dma0_info [ 3 ] } ,
{ " s3c6400-uart.2 " , " tx " , & s3c64xx_dma0_info [ 4 ] } ,
{ " s3c6400-uart.2 " , " rx " , & s3c64xx_dma0_info [ 5 ] } ,
{ " s3c6400-uart.3 " , " tx " , & s3c64xx_dma0_info [ 6 ] } ,
{ " s3c6400-uart.3 " , " rx " , & s3c64xx_dma0_info [ 7 ] } ,
{ " samsung-pcm.0 " , " tx " , & s3c64xx_dma0_info [ 8 ] } ,
{ " samsung-pcm.0 " , " rx " , & s3c64xx_dma0_info [ 9 ] } ,
{ " samsung-i2s.0 " , " tx " , & s3c64xx_dma0_info [ 10 ] } ,
{ " samsung-i2s.0 " , " rx " , & s3c64xx_dma0_info [ 11 ] } ,
{ " s3c6410-spi.0 " , " tx " , & s3c64xx_dma0_info [ 12 ] } ,
{ " s3c6410-spi.0 " , " rx " , & s3c64xx_dma0_info [ 13 ] } ,
{ " samsung-i2s.2 " , " tx " , & s3c64xx_dma0_info [ 14 ] } ,
{ " samsung-i2s.2 " , " rx " , & s3c64xx_dma0_info [ 15 ] } ,
} ;
2013-10-16 21:10:54 +02:00
struct pl08x_platform_data s3c64xx_dma0_plat_data = {
2017-05-20 23:42:50 +02:00
. memcpy_burst_size = PL08X_BURST_SZ_4 ,
. memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS ,
. memcpy_prot_buff = true ,
. memcpy_prot_cache = true ,
2013-10-16 21:10:54 +02:00
. 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 ) ,
2016-11-10 16:17:50 +01:00
. slave_map = s3c64xx_dma0_slave_map ,
. slave_map_len = ARRAY_SIZE ( s3c64xx_dma0_slave_map ) ,
2013-10-16 21:10:54 +02:00
} ;
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 ,
} ,
} ;
2016-11-10 16:17:50 +01:00
static const struct dma_slave_map s3c64xx_dma1_slave_map [ ] = {
{ " samsung-pcm.1 " , " tx " , & s3c64xx_dma1_info [ 0 ] } ,
{ " samsung-pcm.1 " , " rx " , & s3c64xx_dma1_info [ 1 ] } ,
{ " samsung-i2s.1 " , " tx " , & s3c64xx_dma1_info [ 2 ] } ,
{ " samsung-i2s.1 " , " rx " , & s3c64xx_dma1_info [ 3 ] } ,
{ " s3c6410-spi.1 " , " tx " , & s3c64xx_dma1_info [ 4 ] } ,
{ " s3c6410-spi.1 " , " rx " , & s3c64xx_dma1_info [ 5 ] } ,
} ;
2013-10-16 21:10:54 +02:00
struct pl08x_platform_data s3c64xx_dma1_plat_data = {
2017-05-20 23:42:50 +02:00
. memcpy_burst_size = PL08X_BURST_SZ_4 ,
. memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS ,
. memcpy_prot_buff = true ,
. memcpy_prot_cache = true ,
2013-10-16 21:10:54 +02:00
. 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 ) ,
2016-11-10 16:17:50 +01:00
. slave_map = s3c64xx_dma1_slave_map ,
. slave_map_len = ARRAY_SIZE ( s3c64xx_dma1_slave_map ) ,
2013-10-16 21:10:54 +02:00
} ;
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 ) ;