Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xcap
xcap-capability-linux
Commits
6971071c
Commit
6971071c
authored
Dec 21, 2010
by
Tony Lindgren
Browse files
Merge branch 'devel-dma' into omap-for-linus
parents
4584acc3
f31cc962
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
arch/arm/mach-omap1/Makefile
View file @
6971071c
...
...
@@ -3,7 +3,7 @@
#
# Common support
obj-y
:=
io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o
obj-y
:=
io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o
dma.o
obj-y
+=
clock.o clock_data.o opp_data.o
obj-$(CONFIG_OMAP_MCBSP)
+=
mcbsp.o
...
...
arch/arm/mach-omap1/dma.c
0 → 100644
View file @
6971071c
/*
* OMAP1/OMAP7xx - specific DMA driver
*
* Copyright (C) 2003 - 2008 Nokia Corporation
* Author: Juha Yrjölä <juha.yrjola@nokia.com>
* DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
* Graphics DMA and LCD DMA graphics tranformations
* by Imre Deak <imre.deak@nokia.com>
* OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
* Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
* Converted DMA library into platform driver
* - G, Manjunath Kondaiah <manjugk@ti.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/err.h>
#include
<linux/io.h>
#include
<linux/slab.h>
#include
<linux/module.h>
#include
<linux/init.h>
#include
<linux/device.h>
#include
<plat/dma.h>
#include
<plat/tc.h>
#include
<plat/irqs.h>
#define OMAP1_DMA_BASE (0xfffed800)
#define OMAP1_LOGICAL_DMA_CH_COUNT 17
#define OMAP1_DMA_STRIDE 0x40
static
u32
errata
;
static
u32
enable_1510_mode
;
static
u8
dma_stride
;
static
enum
omap_reg_offsets
dma_common_ch_start
,
dma_common_ch_end
;
static
u16
reg_map
[]
=
{
[
GCR
]
=
0x400
,
[
GSCR
]
=
0x404
,
[
GRST1
]
=
0x408
,
[
HW_ID
]
=
0x442
,
[
PCH2_ID
]
=
0x444
,
[
PCH0_ID
]
=
0x446
,
[
PCH1_ID
]
=
0x448
,
[
PCHG_ID
]
=
0x44a
,
[
PCHD_ID
]
=
0x44c
,
[
CAPS_0
]
=
0x44e
,
[
CAPS_1
]
=
0x452
,
[
CAPS_2
]
=
0x456
,
[
CAPS_3
]
=
0x458
,
[
CAPS_4
]
=
0x45a
,
[
PCH2_SR
]
=
0x460
,
[
PCH0_SR
]
=
0x480
,
[
PCH1_SR
]
=
0x482
,
[
PCHD_SR
]
=
0x4c0
,
/* Common Registers */
[
CSDP
]
=
0x00
,
[
CCR
]
=
0x02
,
[
CICR
]
=
0x04
,
[
CSR
]
=
0x06
,
[
CEN
]
=
0x10
,
[
CFN
]
=
0x12
,
[
CSFI
]
=
0x14
,
[
CSEI
]
=
0x16
,
[
CPC
]
=
0x18
,
/* 15xx only */
[
CSAC
]
=
0x18
,
[
CDAC
]
=
0x1a
,
[
CDEI
]
=
0x1c
,
[
CDFI
]
=
0x1e
,
[
CLNK_CTRL
]
=
0x28
,
/* Channel specific register offsets */
[
CSSA
]
=
0x08
,
[
CDSA
]
=
0x0c
,
[
COLOR
]
=
0x20
,
[
CCR2
]
=
0x24
,
[
LCH_CTRL
]
=
0x2a
,
};
static
struct
resource
res
[]
__initdata
=
{
[
0
]
=
{
.
start
=
OMAP1_DMA_BASE
,
.
end
=
OMAP1_DMA_BASE
+
SZ_2K
-
1
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
name
=
"0"
,
.
start
=
INT_DMA_CH0_6
,
.
flags
=
IORESOURCE_IRQ
,
},
[
2
]
=
{
.
name
=
"1"
,
.
start
=
INT_DMA_CH1_7
,
.
flags
=
IORESOURCE_IRQ
,
},
[
3
]
=
{
.
name
=
"2"
,
.
start
=
INT_DMA_CH2_8
,
.
flags
=
IORESOURCE_IRQ
,
},
[
4
]
=
{
.
name
=
"3"
,
.
start
=
INT_DMA_CH3
,
.
flags
=
IORESOURCE_IRQ
,
},
[
5
]
=
{
.
name
=
"4"
,
.
start
=
INT_DMA_CH4
,
.
flags
=
IORESOURCE_IRQ
,
},
[
6
]
=
{
.
name
=
"5"
,
.
start
=
INT_DMA_CH5
,
.
flags
=
IORESOURCE_IRQ
,
},
/* Handled in lcd_dma.c */
[
7
]
=
{
.
name
=
"6"
,
.
start
=
INT_1610_DMA_CH6
,
.
flags
=
IORESOURCE_IRQ
,
},
/* irq's for omap16xx and omap7xx */
[
8
]
=
{
.
name
=
"7"
,
.
start
=
INT_1610_DMA_CH7
,
.
flags
=
IORESOURCE_IRQ
,
},
[
9
]
=
{
.
name
=
"8"
,
.
start
=
INT_1610_DMA_CH8
,
.
flags
=
IORESOURCE_IRQ
,
},
[
10
]
=
{
.
name
=
"9"
,
.
start
=
INT_1610_DMA_CH9
,
.
flags
=
IORESOURCE_IRQ
,
},
[
11
]
=
{
.
name
=
"10"
,
.
start
=
INT_1610_DMA_CH10
,
.
flags
=
IORESOURCE_IRQ
,
},
[
12
]
=
{
.
name
=
"11"
,
.
start
=
INT_1610_DMA_CH11
,
.
flags
=
IORESOURCE_IRQ
,
},
[
13
]
=
{
.
name
=
"12"
,
.
start
=
INT_1610_DMA_CH12
,
.
flags
=
IORESOURCE_IRQ
,
},
[
14
]
=
{
.
name
=
"13"
,
.
start
=
INT_1610_DMA_CH13
,
.
flags
=
IORESOURCE_IRQ
,
},
[
15
]
=
{
.
name
=
"14"
,
.
start
=
INT_1610_DMA_CH14
,
.
flags
=
IORESOURCE_IRQ
,
},
[
16
]
=
{
.
name
=
"15"
,
.
start
=
INT_1610_DMA_CH15
,
.
flags
=
IORESOURCE_IRQ
,
},
[
17
]
=
{
.
name
=
"16"
,
.
start
=
INT_DMA_LCD
,
.
flags
=
IORESOURCE_IRQ
,
},
};
static
void
__iomem
*
dma_base
;
static
inline
void
dma_write
(
u32
val
,
int
reg
,
int
lch
)
{
u8
stride
;
u32
offset
;
stride
=
(
reg
>=
dma_common_ch_start
)
?
dma_stride
:
0
;
offset
=
reg_map
[
reg
]
+
(
stride
*
lch
);
__raw_writew
(
val
,
dma_base
+
offset
);
if
((
reg
>
CLNK_CTRL
&&
reg
<
CCEN
)
||
(
reg
>
PCHD_ID
&&
reg
<
CAPS_2
))
{
u32
offset2
=
reg_map
[
reg
]
+
2
+
(
stride
*
lch
);
__raw_writew
(
val
>>
16
,
dma_base
+
offset2
);
}
}
static
inline
u32
dma_read
(
int
reg
,
int
lch
)
{
u8
stride
;
u32
offset
,
val
;
stride
=
(
reg
>=
dma_common_ch_start
)
?
dma_stride
:
0
;
offset
=
reg_map
[
reg
]
+
(
stride
*
lch
);
val
=
__raw_readw
(
dma_base
+
offset
);
if
((
reg
>
CLNK_CTRL
&&
reg
<
CCEN
)
||
(
reg
>
PCHD_ID
&&
reg
<
CAPS_2
))
{
u16
upper
;
u32
offset2
=
reg_map
[
reg
]
+
2
+
(
stride
*
lch
);
upper
=
__raw_readw
(
dma_base
+
offset2
);
val
|=
(
upper
<<
16
);
}
return
val
;
}
static
void
omap1_clear_lch_regs
(
int
lch
)
{
int
i
=
dma_common_ch_start
;
for
(;
i
<=
dma_common_ch_end
;
i
+=
1
)
dma_write
(
0
,
i
,
lch
);
}
static
void
omap1_clear_dma
(
int
lch
)
{
u32
l
;
l
=
dma_read
(
CCR
,
lch
);
l
&=
~
OMAP_DMA_CCR_EN
;
dma_write
(
l
,
CCR
,
lch
);
/* Clear pending interrupts */
l
=
dma_read
(
CSR
,
lch
);
}
static
void
omap1_show_dma_caps
(
void
)
{
if
(
enable_1510_mode
)
{
printk
(
KERN_INFO
"DMA support for OMAP15xx initialized
\n
"
);
}
else
{
u16
w
;
printk
(
KERN_INFO
"OMAP DMA hardware version %d
\n
"
,
dma_read
(
HW_ID
,
0
));
printk
(
KERN_INFO
"DMA capabilities: %08x:%08x:%04x:%04x:%04x
\n
"
,
dma_read
(
CAPS_0
,
0
),
dma_read
(
CAPS_1
,
0
),
dma_read
(
CAPS_2
,
0
),
dma_read
(
CAPS_3
,
0
),
dma_read
(
CAPS_4
,
0
));
/* Disable OMAP 3.0/3.1 compatibility mode. */
w
=
dma_read
(
GSCR
,
0
);
w
|=
1
<<
3
;
dma_write
(
w
,
GSCR
,
0
);
}
return
;
}
static
u32
configure_dma_errata
(
void
)
{
/*
* Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
* read before the DMA controller finished disabling the channel.
*/
if
(
!
cpu_is_omap15xx
())
SET_DMA_ERRATA
(
DMA_ERRATA_3_3
);
return
errata
;
}
static
int
__init
omap1_system_dma_init
(
void
)
{
struct
omap_system_dma_plat_info
*
p
;
struct
omap_dma_dev_attr
*
d
;
struct
platform_device
*
pdev
;
int
ret
;
pdev
=
platform_device_alloc
(
"omap_dma_system"
,
0
);
if
(
!
pdev
)
{
pr_err
(
"%s: Unable to device alloc for dma
\n
"
,
__func__
);
return
-
ENOMEM
;
}
dma_base
=
ioremap
(
res
[
0
].
start
,
resource_size
(
&
res
[
0
]));
if
(
!
dma_base
)
{
pr_err
(
"%s: Unable to ioremap
\n
"
,
__func__
);
return
-
ENODEV
;
}
ret
=
platform_device_add_resources
(
pdev
,
res
,
ARRAY_SIZE
(
res
));
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Unable to add resources for %s%d
\n
"
,
__func__
,
pdev
->
name
,
pdev
->
id
);
goto
exit_device_del
;
}
p
=
kzalloc
(
sizeof
(
struct
omap_system_dma_plat_info
),
GFP_KERNEL
);
if
(
!
p
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Unable to allocate 'p' for %s
\n
"
,
__func__
,
pdev
->
name
);
ret
=
-
ENOMEM
;
goto
exit_device_put
;
}
d
=
kzalloc
(
sizeof
(
struct
omap_dma_dev_attr
),
GFP_KERNEL
);
if
(
!
d
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Unable to allocate 'd' for %s
\n
"
,
__func__
,
pdev
->
name
);
ret
=
-
ENOMEM
;
goto
exit_release_p
;
}
d
->
lch_count
=
OMAP1_LOGICAL_DMA_CH_COUNT
;
/* Valid attributes for omap1 plus processors */
if
(
cpu_is_omap15xx
())
d
->
dev_caps
=
ENABLE_1510_MODE
;
enable_1510_mode
=
d
->
dev_caps
&
ENABLE_1510_MODE
;
d
->
dev_caps
|=
SRC_PORT
;
d
->
dev_caps
|=
DST_PORT
;
d
->
dev_caps
|=
SRC_INDEX
;
d
->
dev_caps
|=
DST_INDEX
;
d
->
dev_caps
|=
IS_BURST_ONLY4
;
d
->
dev_caps
|=
CLEAR_CSR_ON_READ
;
d
->
dev_caps
|=
IS_WORD_16
;
d
->
chan
=
kzalloc
(
sizeof
(
struct
omap_dma_lch
)
*
(
d
->
lch_count
),
GFP_KERNEL
);
if
(
!
d
->
chan
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Memory allocation failed"
"for d->chan!!!
\n
"
,
__func__
);
goto
exit_release_d
;
}
if
(
cpu_is_omap15xx
())
d
->
chan_count
=
9
;
else
if
(
cpu_is_omap16xx
()
||
cpu_is_omap7xx
())
{
if
(
!
(
d
->
dev_caps
&
ENABLE_1510_MODE
))
d
->
chan_count
=
16
;
else
d
->
chan_count
=
9
;
}
p
->
dma_attr
=
d
;
p
->
show_dma_caps
=
omap1_show_dma_caps
;
p
->
clear_lch_regs
=
omap1_clear_lch_regs
;
p
->
clear_dma
=
omap1_clear_dma
;
p
->
dma_write
=
dma_write
;
p
->
dma_read
=
dma_read
;
p
->
disable_irq_lch
=
NULL
;
p
->
errata
=
configure_dma_errata
();
ret
=
platform_device_add_data
(
pdev
,
p
,
sizeof
(
*
p
));
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Unable to add resources for %s%d
\n
"
,
__func__
,
pdev
->
name
,
pdev
->
id
);
goto
exit_release_chan
;
}
ret
=
platform_device_add
(
pdev
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Unable to add resources for %s%d
\n
"
,
__func__
,
pdev
->
name
,
pdev
->
id
);
goto
exit_release_chan
;
}
dma_stride
=
OMAP1_DMA_STRIDE
;
dma_common_ch_start
=
CPC
;
dma_common_ch_end
=
COLOR
;
return
ret
;
exit_release_chan:
kfree
(
d
->
chan
);
exit_release_d:
kfree
(
d
);
exit_release_p:
kfree
(
p
);
exit_device_put:
platform_device_put
(
pdev
);
exit_device_del:
platform_device_del
(
pdev
);
return
ret
;
}
arch_initcall
(
omap1_system_dma_init
);
arch/arm/mach-omap2/Makefile
View file @
6971071c
...
...
@@ -4,7 +4,7 @@
# Common support
obj-y
:=
id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o
\
common.o gpio.o
common.o gpio.o
dma.o
omap-2-3-common
=
irq.o sdrc.o prm2xxx_3xxx.o
hwmod-common
=
omap_hwmod.o
\
...
...
arch/arm/mach-omap2/dma.c
0 → 100644
View file @
6971071c
/*
* OMAP2+ DMA driver
*
* Copyright (C) 2003 - 2008 Nokia Corporation
* Author: Juha Yrjölä <juha.yrjola@nokia.com>
* DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
* Graphics DMA and LCD DMA graphics tranformations
* by Imre Deak <imre.deak@nokia.com>
* OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
* Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
*
* Copyright (C) 2009 Texas Instruments
* Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
* Converted DMA library into platform driver
* - G, Manjunath Kondaiah <manjugk@ti.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/err.h>
#include
<linux/io.h>
#include
<linux/slab.h>
#include
<linux/module.h>
#include
<linux/init.h>
#include
<linux/device.h>
#include
<plat/omap_hwmod.h>
#include
<plat/omap_device.h>
#include
<plat/dma.h>
#define OMAP2_DMA_STRIDE 0x60
static
u32
errata
;
static
u8
dma_stride
;
static
struct
omap_dma_dev_attr
*
d
;
static
enum
omap_reg_offsets
dma_common_ch_start
,
dma_common_ch_end
;
static
u16
reg_map
[]
=
{
[
REVISION
]
=
0x00
,
[
GCR
]
=
0x78
,
[
IRQSTATUS_L0
]
=
0x08
,
[
IRQSTATUS_L1
]
=
0x0c
,
[
IRQSTATUS_L2
]
=
0x10
,
[
IRQSTATUS_L3
]
=
0x14
,
[
IRQENABLE_L0
]
=
0x18
,
[
IRQENABLE_L1
]
=
0x1c
,
[
IRQENABLE_L2
]
=
0x20
,
[
IRQENABLE_L3
]
=
0x24
,
[
SYSSTATUS
]
=
0x28
,
[
OCP_SYSCONFIG
]
=
0x2c
,
[
CAPS_0
]
=
0x64
,
[
CAPS_2
]
=
0x6c
,
[
CAPS_3
]
=
0x70
,
[
CAPS_4
]
=
0x74
,
/* Common register offsets */
[
CCR
]
=
0x80
,
[
CLNK_CTRL
]
=
0x84
,
[
CICR
]
=
0x88
,
[
CSR
]
=
0x8c
,
[
CSDP
]
=
0x90
,
[
CEN
]
=
0x94
,
[
CFN
]
=
0x98
,
[
CSEI
]
=
0xa4
,
[
CSFI
]
=
0xa8
,
[
CDEI
]
=
0xac
,
[
CDFI
]
=
0xb0
,
[
CSAC
]
=
0xb4
,
[
CDAC
]
=
0xb8
,
/* Channel specific register offsets */
[
CSSA
]
=
0x9c
,
[
CDSA
]
=
0xa0
,
[
CCEN
]
=
0xbc
,
[
CCFN
]
=
0xc0
,
[
COLOR
]
=
0xc4
,
/* OMAP4 specific registers */
[
CDP
]
=
0xd0
,
[
CNDP
]
=
0xd4
,
[
CCDN
]
=
0xd8
,
};
static
struct
omap_device_pm_latency
omap2_dma_latency
[]
=
{
{
.
deactivate_func
=
omap_device_idle_hwmods
,
.
activate_func
=
omap_device_enable_hwmods
,
.
flags
=
OMAP_DEVICE_LATENCY_AUTO_ADJUST
,
},
};
static
void
__iomem
*
dma_base
;
static
inline
void
dma_write
(
u32
val
,
int
reg
,
int
lch
)
{
u8
stride
;
u32
offset
;
stride
=
(
reg
>=
dma_common_ch_start
)
?
dma_stride
:
0
;
offset
=
reg_map
[
reg
]
+
(
stride
*
lch
);
__raw_writel
(
val
,
dma_base
+
offset
);
}
static
inline
u32
dma_read
(
int
reg
,
int
lch
)
{
u8
stride
;
u32
offset
,
val
;
stride
=
(
reg
>=
dma_common_ch_start
)
?
dma_stride
:
0
;
offset
=
reg_map
[
reg
]
+
(
stride
*
lch
);
val
=
__raw_readl
(
dma_base
+
offset
);
return
val
;
}
static
inline
void
omap2_disable_irq_lch
(
int
lch
)
{
u32
val
;
val
=
dma_read
(
IRQENABLE_L0
,
lch
);
val
&=
~
(
1
<<
lch
);
dma_write
(
val
,
IRQENABLE_L0
,
lch
);
}
static
void
omap2_clear_dma
(
int
lch
)
{
int
i
=
dma_common_ch_start
;
for
(;
i
<=
dma_common_ch_end
;
i
+=
1
)
dma_write
(
0
,
i
,
lch
);
}
static
void
omap2_show_dma_caps
(
void
)
{
u8
revision
=
dma_read
(
REVISION
,
0
)
&
0xff
;
printk
(
KERN_INFO
"OMAP DMA hardware revision %d.%d
\n
"
,
revision
>>
4
,
revision
&
0xf
);
return
;
}
static
u32
configure_dma_errata
(
void
)
{
/*
* Errata applicable for OMAP2430ES1.0 and all omap2420
*
* I.
* Erratum ID: Not Available
* Inter Frame DMA buffering issue DMA will wrongly
* buffer elements if packing and bursting is enabled. This might
* result in data gets stalled in FIFO at the end of the block.
* Workaround: DMA channels must have BUFFERING_DISABLED bit set to
* guarantee no data will stay in the DMA FIFO in case inter frame
* buffering occurs
*
* II.
* Erratum ID: Not Available
* DMA may hang when several channels are used in parallel
* In the following configuration, DMA channel hanging can occur:
* a. Channel i, hardware synchronized, is enabled
* b. Another channel (Channel x), software synchronized, is enabled.
* c. Channel i is disabled before end of transfer
* d. Channel i is reenabled.
* e. Steps 1 to 4 are repeated a certain number of times.
* f. A third channel (Channel y), software synchronized, is enabled.
* Channel x and Channel y may hang immediately after step 'f'.
* Workaround:
* For any channel used - make sure NextLCH_ID is set to the value j.
*/
if
(
cpu_is_omap2420
()
||
(
cpu_is_omap2430
()
&&
(
omap_type
()
==
OMAP2430_REV_ES1_0
)))
{
SET_DMA_ERRATA
(
DMA_ERRATA_IFRAME_BUFFERING
);
SET_DMA_ERRATA
(
DMA_ERRATA_PARALLEL_CHANNELS
);
}
/*
* Erratum ID: i378: OMAP2+: sDMA Channel is not disabled
* after a transaction error.
* Workaround: SW should explicitely disable the channel.
*/
if
(
cpu_class_is_omap2
())
SET_DMA_ERRATA
(
DMA_ERRATA_i378
);
/*
* Erratum ID: i541: sDMA FIFO draining does not finish
* If sDMA channel is disabled on the fly, sDMA enters standby even
* through FIFO Drain is still in progress
* Workaround: Put sDMA in NoStandby more before a logical channel is
* disabled, then put it back to SmartStandby right after the channel
* finishes FIFO draining.
*/
if
(
cpu_is_omap34xx
())
SET_DMA_ERRATA
(
DMA_ERRATA_i541
);
/*
* Erratum ID: i88 : Special programming model needed to disable DMA
* before end of block.
* Workaround: software must ensure that the DMA is configured in No
* Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01")
*/
if
(
omap_type
()
==
OMAP3430_REV_ES1_0
)
SET_DMA_ERRATA
(
DMA_ERRATA_i88
);
/*
* Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
* read before the DMA controller finished disabling the channel.
*/
SET_DMA_ERRATA
(
DMA_ERRATA_3_3
);