diff options
author | Olof Johansson <olof@lixom.net> | 2013-06-14 19:53:54 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-06-14 19:53:54 -0400 |
commit | 2c3165ebb641e0ff3faf1c87ed1c8fbd85871da0 (patch) | |
tree | ecf0bef4ee0b56029d0f08aed941aca78da99424 | |
parent | 0d86331b4cc9b0c52d41bbe78cb4b75f40b7381c (diff) | |
parent | 499c2bc3cc89dcbbf08aa526cd4a984b92a4d2a8 (diff) |
Merge tag 'ux500-dma40-for-arm-soc-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson into next/drivers
From Linus Walleij:
Second set of DMA40 changes: refactorings and device tree
support for the DMA40. Now with MUSB and some platform
data removal.
* tag 'ux500-dma40-for-arm-soc-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson:
dmaengine: ste_dma40: Fetch disabled channels from DT
dmaengine: ste_dma40: Fetch the number of physical channels from DT
ARM: ux500: Stop passing DMA platform data though AUXDATA
dmaengine: ste_dma40: Allow memcpy channels to be configured from DT
dmaengine: ste_dma40_ll: Replace meaningless register set with comment
dmaengine: ste_dma40: Convert data_width from register bit format to value
dmaengine: ste_dma40_ll: Use the BIT macro to replace ugly '(1 << x)'s
ARM: ux500: Remove recently unused stedma40_xfer_dir enums
dmaengine: ste_dma40: Replace ST-E's home-brew DMA direction defs with generic ones
ARM: ux500: Replace ST-E's home-brew DMA direction definition with the generic one
dmaengine: ste_dma40: Use the BIT macro to replace ugly '(1 << x)'s
ARM: ux500: Remove empty function u8500_of_init_devices()
ARM: ux500: Remove ux500-musb platform registation when booting with DT
usb: musb: ux500: add device tree probing support
usb: musb: ux500: attempt to find channels by name before using pdata
usb: musb: ux500: harden checks for platform data
usb: musb: ux500: take the dma_mask from coherent_dma_mask
usb: musb: ux500: move the MUSB HDRC configuration into the driver
usb: musb: ux500: move channel number knowledge into the driver
-rw-r--r-- | Documentation/devicetree/bindings/dma/ste-dma40.txt | 4 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/usb/ux500-usb.txt | 50 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-audio.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-sdi.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500.c | 22 | ||||
-rw-r--r-- | arch/arm/mach-ux500/cpu-db8500.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-ux500/usb.c | 29 | ||||
-rw-r--r-- | drivers/dma/ste_dma40.c | 199 | ||||
-rw-r--r-- | drivers/dma/ste_dma40_ll.c | 117 | ||||
-rw-r--r-- | drivers/usb/musb/ux500.c | 61 | ||||
-rw-r--r-- | drivers/usb/musb/ux500_dma.c | 59 | ||||
-rw-r--r-- | include/linux/platform_data/dma-ste-dma40.h | 21 | ||||
-rw-r--r-- | include/linux/platform_data/usb-musb-ux500.h | 5 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_pcm.c | 10 |
14 files changed, 374 insertions, 250 deletions
diff --git a/Documentation/devicetree/bindings/dma/ste-dma40.txt b/Documentation/devicetree/bindings/dma/ste-dma40.txt index 2679a873522d..bea5b73a7390 100644 --- a/Documentation/devicetree/bindings/dma/ste-dma40.txt +++ b/Documentation/devicetree/bindings/dma/ste-dma40.txt | |||
@@ -6,10 +6,12 @@ Required properties: | |||
6 | - reg-names: Names of the above areas to use during resource look-up | 6 | - reg-names: Names of the above areas to use during resource look-up |
7 | - interrupt: Should contain the DMAC interrupt number | 7 | - interrupt: Should contain the DMAC interrupt number |
8 | - #dma-cells: must be <3> | 8 | - #dma-cells: must be <3> |
9 | - memcpy-channels: Channels to be used for memcpy | ||
9 | 10 | ||
10 | Optional properties: | 11 | Optional properties: |
11 | - dma-channels: Number of channels supported by hardware - if not present | 12 | - dma-channels: Number of channels supported by hardware - if not present |
12 | the driver will attempt to obtain the information from H/W | 13 | the driver will attempt to obtain the information from H/W |
14 | - disabled-channels: Channels which can not be used | ||
13 | 15 | ||
14 | Example: | 16 | Example: |
15 | 17 | ||
@@ -21,6 +23,8 @@ Example: | |||
21 | interrupts = <0 25 0x4>; | 23 | interrupts = <0 25 0x4>; |
22 | 24 | ||
23 | #dma-cells = <2>; | 25 | #dma-cells = <2>; |
26 | memcpy-channels = <56 57 58 59 60>; | ||
27 | disabled-channels = <12>; | ||
24 | dma-channels = <8>; | 28 | dma-channels = <8>; |
25 | }; | 29 | }; |
26 | 30 | ||
diff --git a/Documentation/devicetree/bindings/usb/ux500-usb.txt b/Documentation/devicetree/bindings/usb/ux500-usb.txt new file mode 100644 index 000000000000..330d6ec15401 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ux500-usb.txt | |||
@@ -0,0 +1,50 @@ | |||
1 | Ux500 MUSB | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : Should be "stericsson,db8500-musb" | ||
5 | - reg : Offset and length of registers | ||
6 | - interrupts : Interrupt; mode, number and trigger | ||
7 | - dr_mode : Dual-role; either host mode "host", peripheral mode "peripheral" | ||
8 | or both "otg" | ||
9 | |||
10 | Optional properties: | ||
11 | - dmas : A list of dma channels; | ||
12 | dma-controller, event-line, fixed-channel, flags | ||
13 | - dma-names : An ordered list of channel names affiliated to the above | ||
14 | |||
15 | Example: | ||
16 | |||
17 | usb_per5@a03e0000 { | ||
18 | compatible = "stericsson,db8500-musb", "mentor,musb"; | ||
19 | reg = <0xa03e0000 0x10000>; | ||
20 | interrupts = <0 23 0x4>; | ||
21 | interrupt-names = "mc"; | ||
22 | |||
23 | dr_mode = "otg"; | ||
24 | |||
25 | dmas = <&dma 38 0 0x2>, /* Logical - DevToMem */ | ||
26 | <&dma 38 0 0x0>, /* Logical - MemToDev */ | ||
27 | <&dma 37 0 0x2>, /* Logical - DevToMem */ | ||
28 | <&dma 37 0 0x0>, /* Logical - MemToDev */ | ||
29 | <&dma 36 0 0x2>, /* Logical - DevToMem */ | ||
30 | <&dma 36 0 0x0>, /* Logical - MemToDev */ | ||
31 | <&dma 19 0 0x2>, /* Logical - DevToMem */ | ||
32 | <&dma 19 0 0x0>, /* Logical - MemToDev */ | ||
33 | <&dma 18 0 0x2>, /* Logical - DevToMem */ | ||
34 | <&dma 18 0 0x0>, /* Logical - MemToDev */ | ||
35 | <&dma 17 0 0x2>, /* Logical - DevToMem */ | ||
36 | <&dma 17 0 0x0>, /* Logical - MemToDev */ | ||
37 | <&dma 16 0 0x2>, /* Logical - DevToMem */ | ||
38 | <&dma 16 0 0x0>, /* Logical - MemToDev */ | ||
39 | <&dma 39 0 0x2>, /* Logical - DevToMem */ | ||
40 | <&dma 39 0 0x0>; /* Logical - MemToDev */ | ||
41 | |||
42 | dma-names = "iep_1_9", "oep_1_9", | ||
43 | "iep_2_10", "oep_2_10", | ||
44 | "iep_3_11", "oep_3_11", | ||
45 | "iep_4_12", "oep_4_12", | ||
46 | "iep_5_13", "oep_5_13", | ||
47 | "iep_6_14", "oep_6_14", | ||
48 | "iep_7_15", "oep_7_15", | ||
49 | "iep_8", "oep_8"; | ||
50 | }; | ||
diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c index ec872622340f..bfe443daf4b0 100644 --- a/arch/arm/mach-ux500/board-mop500-audio.c +++ b/arch/arm/mach-ux500/board-mop500-audio.c | |||
@@ -21,13 +21,13 @@ | |||
21 | 21 | ||
22 | static struct stedma40_chan_cfg msp0_dma_rx = { | 22 | static struct stedma40_chan_cfg msp0_dma_rx = { |
23 | .high_priority = true, | 23 | .high_priority = true, |
24 | .dir = STEDMA40_PERIPH_TO_MEM, | 24 | .dir = DMA_DEV_TO_MEM, |
25 | .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0, | 25 | .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static struct stedma40_chan_cfg msp0_dma_tx = { | 28 | static struct stedma40_chan_cfg msp0_dma_tx = { |
29 | .high_priority = true, | 29 | .high_priority = true, |
30 | .dir = STEDMA40_MEM_TO_PERIPH, | 30 | .dir = DMA_MEM_TO_DEV, |
31 | .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0, | 31 | .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0, |
32 | }; | 32 | }; |
33 | 33 | ||
@@ -39,13 +39,13 @@ struct msp_i2s_platform_data msp0_platform_data = { | |||
39 | 39 | ||
40 | static struct stedma40_chan_cfg msp1_dma_rx = { | 40 | static struct stedma40_chan_cfg msp1_dma_rx = { |
41 | .high_priority = true, | 41 | .high_priority = true, |
42 | .dir = STEDMA40_PERIPH_TO_MEM, | 42 | .dir = DMA_DEV_TO_MEM, |
43 | .dev_type = DB8500_DMA_DEV30_MSP3, | 43 | .dev_type = DB8500_DMA_DEV30_MSP3, |
44 | }; | 44 | }; |
45 | 45 | ||
46 | static struct stedma40_chan_cfg msp1_dma_tx = { | 46 | static struct stedma40_chan_cfg msp1_dma_tx = { |
47 | .high_priority = true, | 47 | .high_priority = true, |
48 | .dir = STEDMA40_MEM_TO_PERIPH, | 48 | .dir = DMA_MEM_TO_DEV, |
49 | .dev_type = DB8500_DMA_DEV30_MSP1, | 49 | .dev_type = DB8500_DMA_DEV30_MSP1, |
50 | }; | 50 | }; |
51 | 51 | ||
@@ -57,13 +57,13 @@ struct msp_i2s_platform_data msp1_platform_data = { | |||
57 | 57 | ||
58 | static struct stedma40_chan_cfg msp2_dma_rx = { | 58 | static struct stedma40_chan_cfg msp2_dma_rx = { |
59 | .high_priority = true, | 59 | .high_priority = true, |
60 | .dir = STEDMA40_PERIPH_TO_MEM, | 60 | .dir = DMA_DEV_TO_MEM, |
61 | .dev_type = DB8500_DMA_DEV14_MSP2, | 61 | .dev_type = DB8500_DMA_DEV14_MSP2, |
62 | }; | 62 | }; |
63 | 63 | ||
64 | static struct stedma40_chan_cfg msp2_dma_tx = { | 64 | static struct stedma40_chan_cfg msp2_dma_tx = { |
65 | .high_priority = true, | 65 | .high_priority = true, |
66 | .dir = STEDMA40_MEM_TO_PERIPH, | 66 | .dir = DMA_MEM_TO_DEV, |
67 | .dev_type = DB8500_DMA_DEV14_MSP2, | 67 | .dev_type = DB8500_DMA_DEV14_MSP2, |
68 | .use_fixed_channel = true, | 68 | .use_fixed_channel = true, |
69 | .phy_channel = 1, | 69 | .phy_channel = 1, |
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 29be714b8a73..e6891d1933fa 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c | |||
@@ -34,13 +34,13 @@ | |||
34 | #ifdef CONFIG_STE_DMA40 | 34 | #ifdef CONFIG_STE_DMA40 |
35 | struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = { | 35 | struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = { |
36 | .mode = STEDMA40_MODE_LOGICAL, | 36 | .mode = STEDMA40_MODE_LOGICAL, |
37 | .dir = STEDMA40_PERIPH_TO_MEM, | 37 | .dir = DMA_DEV_TO_MEM, |
38 | .dev_type = DB8500_DMA_DEV29_SD_MM0, | 38 | .dev_type = DB8500_DMA_DEV29_SD_MM0, |
39 | }; | 39 | }; |
40 | 40 | ||
41 | static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { | 41 | static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { |
42 | .mode = STEDMA40_MODE_LOGICAL, | 42 | .mode = STEDMA40_MODE_LOGICAL, |
43 | .dir = STEDMA40_MEM_TO_PERIPH, | 43 | .dir = DMA_MEM_TO_DEV, |
44 | .dev_type = DB8500_DMA_DEV29_SD_MM0, | 44 | .dev_type = DB8500_DMA_DEV29_SD_MM0, |
45 | }; | 45 | }; |
46 | #endif | 46 | #endif |
@@ -81,13 +81,13 @@ void mop500_sdi_tc35892_init(struct device *parent) | |||
81 | #ifdef CONFIG_STE_DMA40 | 81 | #ifdef CONFIG_STE_DMA40 |
82 | static struct stedma40_chan_cfg sdi1_dma_cfg_rx = { | 82 | static struct stedma40_chan_cfg sdi1_dma_cfg_rx = { |
83 | .mode = STEDMA40_MODE_LOGICAL, | 83 | .mode = STEDMA40_MODE_LOGICAL, |
84 | .dir = STEDMA40_PERIPH_TO_MEM, | 84 | .dir = DMA_DEV_TO_MEM, |
85 | .dev_type = DB8500_DMA_DEV32_SD_MM1, | 85 | .dev_type = DB8500_DMA_DEV32_SD_MM1, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | static struct stedma40_chan_cfg sdi1_dma_cfg_tx = { | 88 | static struct stedma40_chan_cfg sdi1_dma_cfg_tx = { |
89 | .mode = STEDMA40_MODE_LOGICAL, | 89 | .mode = STEDMA40_MODE_LOGICAL, |
90 | .dir = STEDMA40_MEM_TO_PERIPH, | 90 | .dir = DMA_MEM_TO_DEV, |
91 | .dev_type = DB8500_DMA_DEV32_SD_MM1, | 91 | .dev_type = DB8500_DMA_DEV32_SD_MM1, |
92 | }; | 92 | }; |
93 | #endif | 93 | #endif |
@@ -112,13 +112,13 @@ struct mmci_platform_data mop500_sdi1_data = { | |||
112 | #ifdef CONFIG_STE_DMA40 | 112 | #ifdef CONFIG_STE_DMA40 |
113 | struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = { | 113 | struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = { |
114 | .mode = STEDMA40_MODE_LOGICAL, | 114 | .mode = STEDMA40_MODE_LOGICAL, |
115 | .dir = STEDMA40_PERIPH_TO_MEM, | 115 | .dir = DMA_DEV_TO_MEM, |
116 | .dev_type = DB8500_DMA_DEV28_SD_MM2, | 116 | .dev_type = DB8500_DMA_DEV28_SD_MM2, |
117 | }; | 117 | }; |
118 | 118 | ||
119 | static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = { | 119 | static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = { |
120 | .mode = STEDMA40_MODE_LOGICAL, | 120 | .mode = STEDMA40_MODE_LOGICAL, |
121 | .dir = STEDMA40_MEM_TO_PERIPH, | 121 | .dir = DMA_MEM_TO_DEV, |
122 | .dev_type = DB8500_DMA_DEV28_SD_MM2, | 122 | .dev_type = DB8500_DMA_DEV28_SD_MM2, |
123 | }; | 123 | }; |
124 | #endif | 124 | #endif |
@@ -144,13 +144,13 @@ struct mmci_platform_data mop500_sdi2_data = { | |||
144 | #ifdef CONFIG_STE_DMA40 | 144 | #ifdef CONFIG_STE_DMA40 |
145 | struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = { | 145 | struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = { |
146 | .mode = STEDMA40_MODE_LOGICAL, | 146 | .mode = STEDMA40_MODE_LOGICAL, |
147 | .dir = STEDMA40_PERIPH_TO_MEM, | 147 | .dir = DMA_DEV_TO_MEM, |
148 | .dev_type = DB8500_DMA_DEV42_SD_MM4, | 148 | .dev_type = DB8500_DMA_DEV42_SD_MM4, |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = { | 151 | static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = { |
152 | .mode = STEDMA40_MODE_LOGICAL, | 152 | .mode = STEDMA40_MODE_LOGICAL, |
153 | .dir = STEDMA40_MEM_TO_PERIPH, | 153 | .dir = DMA_MEM_TO_DEV, |
154 | .dev_type = DB8500_DMA_DEV42_SD_MM4, | 154 | .dev_type = DB8500_DMA_DEV42_SD_MM4, |
155 | }; | 155 | }; |
156 | #endif | 156 | #endif |
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index f59d52806afe..2d70e2b45660 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
@@ -424,19 +424,19 @@ void mop500_snowball_ethernet_clock_enable(void) | |||
424 | 424 | ||
425 | static struct cryp_platform_data u8500_cryp1_platform_data = { | 425 | static struct cryp_platform_data u8500_cryp1_platform_data = { |
426 | .mem_to_engine = { | 426 | .mem_to_engine = { |
427 | .dir = STEDMA40_MEM_TO_PERIPH, | 427 | .dir = DMA_MEM_TO_DEV, |
428 | .dev_type = DB8500_DMA_DEV48_CAC1, | 428 | .dev_type = DB8500_DMA_DEV48_CAC1, |
429 | .mode = STEDMA40_MODE_LOGICAL, | 429 | .mode = STEDMA40_MODE_LOGICAL, |
430 | }, | 430 | }, |
431 | .engine_to_mem = { | 431 | .engine_to_mem = { |
432 | .dir = STEDMA40_PERIPH_TO_MEM, | 432 | .dir = DMA_DEV_TO_MEM, |
433 | .dev_type = DB8500_DMA_DEV48_CAC1, | 433 | .dev_type = DB8500_DMA_DEV48_CAC1, |
434 | .mode = STEDMA40_MODE_LOGICAL, | 434 | .mode = STEDMA40_MODE_LOGICAL, |
435 | } | 435 | } |
436 | }; | 436 | }; |
437 | 437 | ||
438 | static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = { | 438 | static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = { |
439 | .dir = STEDMA40_MEM_TO_PERIPH, | 439 | .dir = DMA_MEM_TO_DEV, |
440 | .dev_type = DB8500_DMA_DEV50_HAC1_TX, | 440 | .dev_type = DB8500_DMA_DEV50_HAC1_TX, |
441 | .mode = STEDMA40_MODE_LOGICAL, | 441 | .mode = STEDMA40_MODE_LOGICAL, |
442 | }; | 442 | }; |
@@ -455,13 +455,13 @@ static struct platform_device *mop500_platform_devs[] __initdata = { | |||
455 | #ifdef CONFIG_STE_DMA40 | 455 | #ifdef CONFIG_STE_DMA40 |
456 | static struct stedma40_chan_cfg ssp0_dma_cfg_rx = { | 456 | static struct stedma40_chan_cfg ssp0_dma_cfg_rx = { |
457 | .mode = STEDMA40_MODE_LOGICAL, | 457 | .mode = STEDMA40_MODE_LOGICAL, |
458 | .dir = STEDMA40_PERIPH_TO_MEM, | 458 | .dir = DMA_DEV_TO_MEM, |
459 | .dev_type = DB8500_DMA_DEV8_SSP0, | 459 | .dev_type = DB8500_DMA_DEV8_SSP0, |
460 | }; | 460 | }; |
461 | 461 | ||
462 | static struct stedma40_chan_cfg ssp0_dma_cfg_tx = { | 462 | static struct stedma40_chan_cfg ssp0_dma_cfg_tx = { |
463 | .mode = STEDMA40_MODE_LOGICAL, | 463 | .mode = STEDMA40_MODE_LOGICAL, |
464 | .dir = STEDMA40_MEM_TO_PERIPH, | 464 | .dir = DMA_MEM_TO_DEV, |
465 | .dev_type = DB8500_DMA_DEV8_SSP0, | 465 | .dev_type = DB8500_DMA_DEV8_SSP0, |
466 | }; | 466 | }; |
467 | #endif | 467 | #endif |
@@ -490,37 +490,37 @@ static void __init mop500_spi_init(struct device *parent) | |||
490 | #ifdef CONFIG_STE_DMA40 | 490 | #ifdef CONFIG_STE_DMA40 |
491 | static struct stedma40_chan_cfg uart0_dma_cfg_rx = { | 491 | static struct stedma40_chan_cfg uart0_dma_cfg_rx = { |
492 | .mode = STEDMA40_MODE_LOGICAL, | 492 | .mode = STEDMA40_MODE_LOGICAL, |
493 | .dir = STEDMA40_PERIPH_TO_MEM, | 493 | .dir = DMA_DEV_TO_MEM, |
494 | .dev_type = DB8500_DMA_DEV13_UART0, | 494 | .dev_type = DB8500_DMA_DEV13_UART0, |
495 | }; | 495 | }; |
496 | 496 | ||
497 | static struct stedma40_chan_cfg uart0_dma_cfg_tx = { | 497 | static struct stedma40_chan_cfg uart0_dma_cfg_tx = { |
498 | .mode = STEDMA40_MODE_LOGICAL, | 498 | .mode = STEDMA40_MODE_LOGICAL, |
499 | .dir = STEDMA40_MEM_TO_PERIPH, | 499 | .dir = DMA_MEM_TO_DEV, |
500 | .dev_type = DB8500_DMA_DEV13_UART0, | 500 | .dev_type = DB8500_DMA_DEV13_UART0, |
501 | }; | 501 | }; |
502 | 502 | ||
503 | static struct stedma40_chan_cfg uart1_dma_cfg_rx = { | 503 | static struct stedma40_chan_cfg uart1_dma_cfg_rx = { |
504 | .mode = STEDMA40_MODE_LOGICAL, | 504 | .mode = STEDMA40_MODE_LOGICAL, |
505 | .dir = STEDMA40_PERIPH_TO_MEM, | 505 | .dir = DMA_DEV_TO_MEM, |
506 | .dev_type = DB8500_DMA_DEV12_UART1, | 506 | .dev_type = DB8500_DMA_DEV12_UART1, |
507 | }; | 507 | }; |
508 | 508 | ||
509 | static struct stedma40_chan_cfg uart1_dma_cfg_tx = { | 509 | static struct stedma40_chan_cfg uart1_dma_cfg_tx = { |
510 | .mode = STEDMA40_MODE_LOGICAL, | 510 | .mode = STEDMA40_MODE_LOGICAL, |
511 | .dir = STEDMA40_MEM_TO_PERIPH, | 511 | .dir = DMA_MEM_TO_DEV, |
512 | .dev_type = DB8500_DMA_DEV12_UART1, | 512 | .dev_type = DB8500_DMA_DEV12_UART1, |
513 | }; | 513 | }; |
514 | 514 | ||
515 | static struct stedma40_chan_cfg uart2_dma_cfg_rx = { | 515 | static struct stedma40_chan_cfg uart2_dma_cfg_rx = { |
516 | .mode = STEDMA40_MODE_LOGICAL, | 516 | .mode = STEDMA40_MODE_LOGICAL, |
517 | .dir = STEDMA40_PERIPH_TO_MEM, | 517 | .dir = DMA_DEV_TO_MEM, |
518 | .dev_type = DB8500_DMA_DEV11_UART2, | 518 | .dev_type = DB8500_DMA_DEV11_UART2, |
519 | }; | 519 | }; |
520 | 520 | ||
521 | static struct stedma40_chan_cfg uart2_dma_cfg_tx = { | 521 | static struct stedma40_chan_cfg uart2_dma_cfg_tx = { |
522 | .mode = STEDMA40_MODE_LOGICAL, | 522 | .mode = STEDMA40_MODE_LOGICAL, |
523 | .dir = STEDMA40_MEM_TO_PERIPH, | 523 | .dir = DMA_MEM_TO_DEV, |
524 | .dev_type = DB8500_DMA_DEV11_UART2, | 524 | .dev_type = DB8500_DMA_DEV11_UART2, |
525 | }; | 525 | }; |
526 | #endif | 526 | #endif |
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 243b91b66ae0..f63847dabe7d 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c | |||
@@ -215,17 +215,6 @@ struct device * __init u8500_init_devices(void) | |||
215 | } | 215 | } |
216 | 216 | ||
217 | #ifdef CONFIG_MACH_UX500_DT | 217 | #ifdef CONFIG_MACH_UX500_DT |
218 | |||
219 | /* TODO: Once all pieces are DT:ed, remove completely. */ | ||
220 | static struct device * __init u8500_of_init_devices(void) | ||
221 | { | ||
222 | struct device *parent = db8500_soc_device_init(); | ||
223 | |||
224 | db8500_add_usb(parent, usb_db8500_dma_cfg, usb_db8500_dma_cfg); | ||
225 | |||
226 | return parent; | ||
227 | } | ||
228 | |||
229 | static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { | 218 | static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { |
230 | /* Requires call-back bindings. */ | 219 | /* Requires call-back bindings. */ |
231 | OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata), | 220 | OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata), |
@@ -269,8 +258,7 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { | |||
269 | OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000, | 258 | OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000, |
270 | "ux500-msp-i2s.3", &msp3_platform_data), | 259 | "ux500-msp-i2s.3", &msp3_platform_data), |
271 | /* Requires clock name bindings and channel address lookup table. */ | 260 | /* Requires clock name bindings and channel address lookup table. */ |
272 | OF_DEV_AUXDATA("stericsson,db8500-dma40", 0x801C0000, | 261 | OF_DEV_AUXDATA("stericsson,db8500-dma40", 0x801C0000, "dma40.0", NULL), |
273 | "dma40.0", &dma40_plat_data), | ||
274 | {}, | 262 | {}, |
275 | }; | 263 | }; |
276 | 264 | ||
@@ -284,7 +272,7 @@ static const struct of_device_id u8500_local_bus_nodes[] = { | |||
284 | 272 | ||
285 | static void __init u8500_init_machine(void) | 273 | static void __init u8500_init_machine(void) |
286 | { | 274 | { |
287 | struct device *parent = NULL; | 275 | struct device *parent = db8500_soc_device_init(); |
288 | 276 | ||
289 | /* Pinmaps must be in place before devices register */ | 277 | /* Pinmaps must be in place before devices register */ |
290 | if (of_machine_is_compatible("st-ericsson,mop500")) | 278 | if (of_machine_is_compatible("st-ericsson,mop500")) |
@@ -297,9 +285,6 @@ static void __init u8500_init_machine(void) | |||
297 | else if (of_machine_is_compatible("st-ericsson,ccu9540")) {} | 285 | else if (of_machine_is_compatible("st-ericsson,ccu9540")) {} |
298 | /* TODO: Add pinmaps for ccu9540 board. */ | 286 | /* TODO: Add pinmaps for ccu9540 board. */ |
299 | 287 | ||
300 | /* TODO: Export SoC, USB, cpu-freq and DMA40 */ | ||
301 | parent = u8500_of_init_devices(); | ||
302 | |||
303 | /* automatically probe child nodes of db8500 device */ | 288 | /* automatically probe child nodes of db8500 device */ |
304 | of_platform_populate(NULL, u8500_local_bus_nodes, u8500_auxdata_lookup, parent); | 289 | of_platform_populate(NULL, u8500_local_bus_nodes, u8500_auxdata_lookup, parent); |
305 | } | 290 | } |
diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index 72754e369417..b7bd8d3a5507 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c | |||
@@ -14,15 +14,15 @@ | |||
14 | 14 | ||
15 | #define MUSB_DMA40_RX_CH { \ | 15 | #define MUSB_DMA40_RX_CH { \ |
16 | .mode = STEDMA40_MODE_LOGICAL, \ | 16 | .mode = STEDMA40_MODE_LOGICAL, \ |
17 | .dir = STEDMA40_PERIPH_TO_MEM, \ | 17 | .dir = DMA_DEV_TO_MEM, \ |
18 | } | 18 | } |
19 | 19 | ||
20 | #define MUSB_DMA40_TX_CH { \ | 20 | #define MUSB_DMA40_TX_CH { \ |
21 | .mode = STEDMA40_MODE_LOGICAL, \ | 21 | .mode = STEDMA40_MODE_LOGICAL, \ |
22 | .dir = STEDMA40_MEM_TO_PERIPH, \ | 22 | .dir = DMA_MEM_TO_DEV, \ |
23 | } | 23 | } |
24 | 24 | ||
25 | static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS] | 25 | static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] |
26 | = { | 26 | = { |
27 | MUSB_DMA40_RX_CH, | 27 | MUSB_DMA40_RX_CH, |
28 | MUSB_DMA40_RX_CH, | 28 | MUSB_DMA40_RX_CH, |
@@ -34,7 +34,7 @@ static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS] | |||
34 | MUSB_DMA40_RX_CH | 34 | MUSB_DMA40_RX_CH |
35 | }; | 35 | }; |
36 | 36 | ||
37 | static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS] | 37 | static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] |
38 | = { | 38 | = { |
39 | MUSB_DMA40_TX_CH, | 39 | MUSB_DMA40_TX_CH, |
40 | MUSB_DMA40_TX_CH, | 40 | MUSB_DMA40_TX_CH, |
@@ -46,7 +46,7 @@ static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS] | |||
46 | MUSB_DMA40_TX_CH, | 46 | MUSB_DMA40_TX_CH, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = { | 49 | static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = { |
50 | &musb_dma_rx_ch[0], | 50 | &musb_dma_rx_ch[0], |
51 | &musb_dma_rx_ch[1], | 51 | &musb_dma_rx_ch[1], |
52 | &musb_dma_rx_ch[2], | 52 | &musb_dma_rx_ch[2], |
@@ -57,7 +57,7 @@ static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = { | |||
57 | &musb_dma_rx_ch[7] | 57 | &musb_dma_rx_ch[7] |
58 | }; | 58 | }; |
59 | 59 | ||
60 | static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = { | 60 | static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = { |
61 | &musb_dma_tx_ch[0], | 61 | &musb_dma_tx_ch[0], |
62 | &musb_dma_tx_ch[1], | 62 | &musb_dma_tx_ch[1], |
63 | &musb_dma_tx_ch[2], | 63 | &musb_dma_tx_ch[2], |
@@ -71,23 +71,11 @@ static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = { | |||
71 | static struct ux500_musb_board_data musb_board_data = { | 71 | static struct ux500_musb_board_data musb_board_data = { |
72 | .dma_rx_param_array = ux500_dma_rx_param_array, | 72 | .dma_rx_param_array = ux500_dma_rx_param_array, |
73 | .dma_tx_param_array = ux500_dma_tx_param_array, | 73 | .dma_tx_param_array = ux500_dma_tx_param_array, |
74 | .num_rx_channels = UX500_MUSB_DMA_NUM_RX_CHANNELS, | ||
75 | .num_tx_channels = UX500_MUSB_DMA_NUM_TX_CHANNELS, | ||
76 | .dma_filter = stedma40_filter, | 74 | .dma_filter = stedma40_filter, |
77 | }; | 75 | }; |
78 | 76 | ||
79 | static u64 ux500_musb_dmamask = DMA_BIT_MASK(32); | ||
80 | |||
81 | static struct musb_hdrc_config musb_hdrc_config = { | ||
82 | .multipoint = true, | ||
83 | .dyn_fifo = true, | ||
84 | .num_eps = 16, | ||
85 | .ram_bits = 16, | ||
86 | }; | ||
87 | |||
88 | static struct musb_hdrc_platform_data musb_platform_data = { | 77 | static struct musb_hdrc_platform_data musb_platform_data = { |
89 | .mode = MUSB_OTG, | 78 | .mode = MUSB_OTG, |
90 | .config = &musb_hdrc_config, | ||
91 | .board_data = &musb_board_data, | 79 | .board_data = &musb_board_data, |
92 | }; | 80 | }; |
93 | 81 | ||
@@ -108,7 +96,6 @@ struct platform_device ux500_musb_device = { | |||
108 | .id = 0, | 96 | .id = 0, |
109 | .dev = { | 97 | .dev = { |
110 | .platform_data = &musb_platform_data, | 98 | .platform_data = &musb_platform_data, |
111 | .dma_mask = &ux500_musb_dmamask, | ||
112 | .coherent_dma_mask = DMA_BIT_MASK(32), | 99 | .coherent_dma_mask = DMA_BIT_MASK(32), |
113 | }, | 100 | }, |
114 | .num_resources = ARRAY_SIZE(usb_resources), | 101 | .num_resources = ARRAY_SIZE(usb_resources), |
@@ -119,7 +106,7 @@ static inline void ux500_usb_dma_update_rx_ch_config(int *dev_type) | |||
119 | { | 106 | { |
120 | u32 idx; | 107 | u32 idx; |
121 | 108 | ||
122 | for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_CHANNELS; idx++) | 109 | for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++) |
123 | musb_dma_rx_ch[idx].dev_type = dev_type[idx]; | 110 | musb_dma_rx_ch[idx].dev_type = dev_type[idx]; |
124 | } | 111 | } |
125 | 112 | ||
@@ -127,7 +114,7 @@ static inline void ux500_usb_dma_update_tx_ch_config(int *dev_type) | |||
127 | { | 114 | { |
128 | u32 idx; | 115 | u32 idx; |
129 | 116 | ||
130 | for (idx = 0; idx < UX500_MUSB_DMA_NUM_TX_CHANNELS; idx++) | 117 | for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++) |
131 | musb_dma_tx_ch[idx].dev_type = dev_type[idx]; | 118 | musb_dma_tx_ch[idx].dev_type = dev_type[idx]; |
132 | } | 119 | } |
133 | 120 | ||
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 7f23d45166c3..fa4f9a33a74d 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c | |||
@@ -54,10 +54,12 @@ | |||
54 | #define MAX_LCLA_ALLOC_ATTEMPTS 256 | 54 | #define MAX_LCLA_ALLOC_ATTEMPTS 256 |
55 | 55 | ||
56 | /* Bit markings for allocation map */ | 56 | /* Bit markings for allocation map */ |
57 | #define D40_ALLOC_FREE (1 << 31) | 57 | #define D40_ALLOC_FREE BIT(31) |
58 | #define D40_ALLOC_PHY (1 << 30) | 58 | #define D40_ALLOC_PHY BIT(30) |
59 | #define D40_ALLOC_LOG_FREE 0 | 59 | #define D40_ALLOC_LOG_FREE 0 |
60 | 60 | ||
61 | #define D40_MEMCPY_MAX_CHANS 8 | ||
62 | |||
61 | /* Reserved event lines for memcpy only. */ | 63 | /* Reserved event lines for memcpy only. */ |
62 | #define DB8500_DMA_MEMCPY_EV_0 51 | 64 | #define DB8500_DMA_MEMCPY_EV_0 51 |
63 | #define DB8500_DMA_MEMCPY_EV_1 56 | 65 | #define DB8500_DMA_MEMCPY_EV_1 56 |
@@ -78,13 +80,13 @@ static int dma40_memcpy_channels[] = { | |||
78 | /* Default configuration for physcial memcpy */ | 80 | /* Default configuration for physcial memcpy */ |
79 | struct stedma40_chan_cfg dma40_memcpy_conf_phy = { | 81 | struct stedma40_chan_cfg dma40_memcpy_conf_phy = { |
80 | .mode = STEDMA40_MODE_PHYSICAL, | 82 | .mode = STEDMA40_MODE_PHYSICAL, |
81 | .dir = STEDMA40_MEM_TO_MEM, | 83 | .dir = DMA_MEM_TO_MEM, |
82 | 84 | ||
83 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | 85 | .src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, |
84 | .src_info.psize = STEDMA40_PSIZE_PHY_1, | 86 | .src_info.psize = STEDMA40_PSIZE_PHY_1, |
85 | .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | 87 | .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, |
86 | 88 | ||
87 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | 89 | .dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, |
88 | .dst_info.psize = STEDMA40_PSIZE_PHY_1, | 90 | .dst_info.psize = STEDMA40_PSIZE_PHY_1, |
89 | .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | 91 | .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, |
90 | }; | 92 | }; |
@@ -92,13 +94,13 @@ struct stedma40_chan_cfg dma40_memcpy_conf_phy = { | |||
92 | /* Default configuration for logical memcpy */ | 94 | /* Default configuration for logical memcpy */ |
93 | struct stedma40_chan_cfg dma40_memcpy_conf_log = { | 95 | struct stedma40_chan_cfg dma40_memcpy_conf_log = { |
94 | .mode = STEDMA40_MODE_LOGICAL, | 96 | .mode = STEDMA40_MODE_LOGICAL, |
95 | .dir = STEDMA40_MEM_TO_MEM, | 97 | .dir = DMA_MEM_TO_MEM, |
96 | 98 | ||
97 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | 99 | .src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, |
98 | .src_info.psize = STEDMA40_PSIZE_LOG_1, | 100 | .src_info.psize = STEDMA40_PSIZE_LOG_1, |
99 | .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | 101 | .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, |
100 | 102 | ||
101 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | 103 | .dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE, |
102 | .dst_info.psize = STEDMA40_PSIZE_LOG_1, | 104 | .dst_info.psize = STEDMA40_PSIZE_LOG_1, |
103 | .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | 105 | .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, |
104 | }; | 106 | }; |
@@ -522,6 +524,8 @@ struct d40_gen_dmac { | |||
522 | * @phy_start: Physical memory start of the DMA registers. | 524 | * @phy_start: Physical memory start of the DMA registers. |
523 | * @phy_size: Size of the DMA register map. | 525 | * @phy_size: Size of the DMA register map. |
524 | * @irq: The IRQ number. | 526 | * @irq: The IRQ number. |
527 | * @num_memcpy_chans: The number of channels used for memcpy (mem-to-mem | ||
528 | * transfers). | ||
525 | * @num_phy_chans: The number of physical channels. Read from HW. This | 529 | * @num_phy_chans: The number of physical channels. Read from HW. This |
526 | * is the number of available channels for this driver, not counting "Secure | 530 | * is the number of available channels for this driver, not counting "Secure |
527 | * mode" allocated physical channels. | 531 | * mode" allocated physical channels. |
@@ -565,6 +569,7 @@ struct d40_base { | |||
565 | phys_addr_t phy_start; | 569 | phys_addr_t phy_start; |
566 | resource_size_t phy_size; | 570 | resource_size_t phy_size; |
567 | int irq; | 571 | int irq; |
572 | int num_memcpy_chans; | ||
568 | int num_phy_chans; | 573 | int num_phy_chans; |
569 | int num_log_chans; | 574 | int num_log_chans; |
570 | struct device_dma_parameters dma_parms; | 575 | struct device_dma_parameters dma_parms; |
@@ -843,7 +848,7 @@ static void d40_log_lli_to_lcxa(struct d40_chan *chan, struct d40_desc *desc) | |||
843 | * that uses linked lists. | 848 | * that uses linked lists. |
844 | */ | 849 | */ |
845 | if (!(chan->phy_chan->use_soft_lli && | 850 | if (!(chan->phy_chan->use_soft_lli && |
846 | chan->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)) | 851 | chan->dma_cfg.dir == DMA_DEV_TO_MEM)) |
847 | curr_lcla = d40_lcla_alloc_one(chan, desc); | 852 | curr_lcla = d40_lcla_alloc_one(chan, desc); |
848 | 853 | ||
849 | first_lcla = curr_lcla; | 854 | first_lcla = curr_lcla; |
@@ -1005,20 +1010,21 @@ static int d40_psize_2_burst_size(bool is_log, int psize) | |||
1005 | 1010 | ||
1006 | /* | 1011 | /* |
1007 | * The dma only supports transmitting packages up to | 1012 | * The dma only supports transmitting packages up to |
1008 | * STEDMA40_MAX_SEG_SIZE << data_width. Calculate the total number of | 1013 | * STEDMA40_MAX_SEG_SIZE * data_width, where data_width is stored in Bytes. |
1009 | * dma elements required to send the entire sg list | 1014 | * |
1015 | * Calculate the total number of dma elements required to send the entire sg list. | ||
1010 | */ | 1016 | */ |
1011 | static int d40_size_2_dmalen(int size, u32 data_width1, u32 data_width2) | 1017 | static int d40_size_2_dmalen(int size, u32 data_width1, u32 data_width2) |
1012 | { | 1018 | { |
1013 | int dmalen; | 1019 | int dmalen; |
1014 | u32 max_w = max(data_width1, data_width2); | 1020 | u32 max_w = max(data_width1, data_width2); |
1015 | u32 min_w = min(data_width1, data_width2); | 1021 | u32 min_w = min(data_width1, data_width2); |
1016 | u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w); | 1022 | u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE * min_w, max_w); |
1017 | 1023 | ||
1018 | if (seg_max > STEDMA40_MAX_SEG_SIZE) | 1024 | if (seg_max > STEDMA40_MAX_SEG_SIZE) |
1019 | seg_max -= (1 << max_w); | 1025 | seg_max -= max_w; |
1020 | 1026 | ||
1021 | if (!IS_ALIGNED(size, 1 << max_w)) | 1027 | if (!IS_ALIGNED(size, max_w)) |
1022 | return -EINVAL; | 1028 | return -EINVAL; |
1023 | 1029 | ||
1024 | if (size <= seg_max) | 1030 | if (size <= seg_max) |
@@ -1311,12 +1317,12 @@ static void d40_config_set_event(struct d40_chan *d40c, | |||
1311 | u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type); | 1317 | u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type); |
1312 | 1318 | ||
1313 | /* Enable event line connected to device (or memcpy) */ | 1319 | /* Enable event line connected to device (or memcpy) */ |
1314 | if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || | 1320 | if ((d40c->dma_cfg.dir == DMA_DEV_TO_MEM) || |
1315 | (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) | 1321 | (d40c->dma_cfg.dir == DMA_DEV_TO_DEV)) |
1316 | __d40_config_set_event(d40c, event_type, event, | 1322 | __d40_config_set_event(d40c, event_type, event, |
1317 | D40_CHAN_REG_SSLNK); | 1323 | D40_CHAN_REG_SSLNK); |
1318 | 1324 | ||
1319 | if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) | 1325 | if (d40c->dma_cfg.dir != DMA_DEV_TO_MEM) |
1320 | __d40_config_set_event(d40c, event_type, event, | 1326 | __d40_config_set_event(d40c, event_type, event, |
1321 | D40_CHAN_REG_SDLNK); | 1327 | D40_CHAN_REG_SDLNK); |
1322 | } | 1328 | } |
@@ -1464,7 +1470,7 @@ static u32 d40_residue(struct d40_chan *d40c) | |||
1464 | >> D40_SREG_ELEM_PHY_ECNT_POS; | 1470 | >> D40_SREG_ELEM_PHY_ECNT_POS; |
1465 | } | 1471 | } |
1466 | 1472 | ||
1467 | return num_elt * (1 << d40c->dma_cfg.dst_info.data_width); | 1473 | return num_elt * d40c->dma_cfg.dst_info.data_width; |
1468 | } | 1474 | } |
1469 | 1475 | ||
1470 | static bool d40_tx_is_linked(struct d40_chan *d40c) | 1476 | static bool d40_tx_is_linked(struct d40_chan *d40c) |
@@ -1740,7 +1746,7 @@ static irqreturn_t d40_handle_interrupt(int irq, void *data) | |||
1740 | } | 1746 | } |
1741 | 1747 | ||
1742 | /* ACK interrupt */ | 1748 | /* ACK interrupt */ |
1743 | writel(1 << idx, base->virtbase + il[row].clr); | 1749 | writel(BIT(idx), base->virtbase + il[row].clr); |
1744 | 1750 | ||
1745 | spin_lock(&d40c->lock); | 1751 | spin_lock(&d40c->lock); |
1746 | 1752 | ||
@@ -1776,7 +1782,7 @@ static int d40_validate_conf(struct d40_chan *d40c, | |||
1776 | res = -EINVAL; | 1782 | res = -EINVAL; |
1777 | } | 1783 | } |
1778 | 1784 | ||
1779 | if (conf->dir == STEDMA40_PERIPH_TO_PERIPH) { | 1785 | if (conf->dir == DMA_DEV_TO_DEV) { |
1780 | /* | 1786 | /* |
1781 | * DMAC HW supports it. Will be added to this driver, | 1787 | * DMAC HW supports it. Will be added to this driver, |
1782 | * in case any dma client requires it. | 1788 | * in case any dma client requires it. |
@@ -1786,9 +1792,9 @@ static int d40_validate_conf(struct d40_chan *d40c, | |||
1786 | } | 1792 | } |
1787 | 1793 | ||
1788 | if (d40_psize_2_burst_size(is_log, conf->src_info.psize) * | 1794 | if (d40_psize_2_burst_size(is_log, conf->src_info.psize) * |
1789 | (1 << conf->src_info.data_width) != | 1795 | conf->src_info.data_width != |
1790 | d40_psize_2_burst_size(is_log, conf->dst_info.psize) * | 1796 | d40_psize_2_burst_size(is_log, conf->dst_info.psize) * |
1791 | (1 << conf->dst_info.data_width)) { | 1797 | conf->dst_info.data_width) { |
1792 | /* | 1798 | /* |
1793 | * The DMAC hardware only supports | 1799 | * The DMAC hardware only supports |
1794 | * src (burst x width) == dst (burst x width) | 1800 | * src (burst x width) == dst (burst x width) |
@@ -1830,8 +1836,8 @@ static bool d40_alloc_mask_set(struct d40_phy_res *phy, | |||
1830 | if (phy->allocated_src == D40_ALLOC_FREE) | 1836 | if (phy->allocated_src == D40_ALLOC_FREE) |
1831 | phy->allocated_src = D40_ALLOC_LOG_FREE; | 1837 | phy->allocated_src = D40_ALLOC_LOG_FREE; |
1832 | 1838 | ||
1833 | if (!(phy->allocated_src & (1 << log_event_line))) { | 1839 | if (!(phy->allocated_src & BIT(log_event_line))) { |
1834 | phy->allocated_src |= 1 << log_event_line; | 1840 | phy->allocated_src |= BIT(log_event_line); |
1835 | goto found; | 1841 | goto found; |
1836 | } else | 1842 | } else |
1837 | goto not_found; | 1843 | goto not_found; |
@@ -1842,8 +1848,8 @@ static bool d40_alloc_mask_set(struct d40_phy_res *phy, | |||
1842 | if (phy->allocated_dst == D40_ALLOC_FREE) | 1848 | if (phy->allocated_dst == D40_ALLOC_FREE) |
1843 | phy->allocated_dst = D40_ALLOC_LOG_FREE; | 1849 | phy->allocated_dst = D40_ALLOC_LOG_FREE; |
1844 | 1850 | ||
1845 | if (!(phy->allocated_dst & (1 << log_event_line))) { | 1851 | if (!(phy->allocated_dst & BIT(log_event_line))) { |
1846 | phy->allocated_dst |= 1 << log_event_line; | 1852 | phy->allocated_dst |= BIT(log_event_line); |
1847 | goto found; | 1853 | goto found; |
1848 | } else | 1854 | } else |
1849 | goto not_found; | 1855 | goto not_found; |
@@ -1873,11 +1879,11 @@ static bool d40_alloc_mask_free(struct d40_phy_res *phy, bool is_src, | |||
1873 | 1879 | ||
1874 | /* Logical channel */ | 1880 | /* Logical channel */ |
1875 | if (is_src) { | 1881 | if (is_src) { |
1876 | phy->allocated_src &= ~(1 << log_event_line); | 1882 | phy->allocated_src &= ~BIT(log_event_line); |
1877 | if (phy->allocated_src == D40_ALLOC_LOG_FREE) | 1883 | if (phy->allocated_src == D40_ALLOC_LOG_FREE) |
1878 | phy->allocated_src = D40_ALLOC_FREE; | 1884 | phy->allocated_src = D40_ALLOC_FREE; |
1879 | } else { | 1885 | } else { |
1880 | phy->allocated_dst &= ~(1 << log_event_line); | 1886 | phy->allocated_dst &= ~BIT(log_event_line); |
1881 | if (phy->allocated_dst == D40_ALLOC_LOG_FREE) | 1887 | if (phy->allocated_dst == D40_ALLOC_LOG_FREE) |
1882 | phy->allocated_dst = D40_ALLOC_FREE; | 1888 | phy->allocated_dst = D40_ALLOC_FREE; |
1883 | } | 1889 | } |
@@ -1907,11 +1913,11 @@ static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user) | |||
1907 | phys = d40c->base->phy_res; | 1913 | phys = d40c->base->phy_res; |
1908 | num_phy_chans = d40c->base->num_phy_chans; | 1914 | num_phy_chans = d40c->base->num_phy_chans; |
1909 | 1915 | ||
1910 | if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { | 1916 | if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) { |
1911 | log_num = 2 * dev_type; | 1917 | log_num = 2 * dev_type; |
1912 | is_src = true; | 1918 | is_src = true; |
1913 | } else if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || | 1919 | } else if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV || |
1914 | d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { | 1920 | d40c->dma_cfg.dir == DMA_MEM_TO_MEM) { |
1915 | /* dst event lines are used for logical memcpy */ | 1921 | /* dst event lines are used for logical memcpy */ |
1916 | log_num = 2 * dev_type + 1; | 1922 | log_num = 2 * dev_type + 1; |
1917 | is_src = false; | 1923 | is_src = false; |
@@ -1922,7 +1928,7 @@ static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user) | |||
1922 | event_line = D40_TYPE_TO_EVENT(dev_type); | 1928 | event_line = D40_TYPE_TO_EVENT(dev_type); |
1923 | 1929 | ||
1924 | if (!is_log) { | 1930 | if (!is_log) { |
1925 | if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { | 1931 | if (d40c->dma_cfg.dir == DMA_MEM_TO_MEM) { |
1926 | /* Find physical half channel */ | 1932 | /* Find physical half channel */ |
1927 | if (d40c->dma_cfg.use_fixed_channel) { | 1933 | if (d40c->dma_cfg.use_fixed_channel) { |
1928 | i = d40c->dma_cfg.phy_channel; | 1934 | i = d40c->dma_cfg.phy_channel; |
@@ -2070,10 +2076,10 @@ static int d40_free_dma(struct d40_chan *d40c) | |||
2070 | return -EINVAL; | 2076 | return -EINVAL; |
2071 | } | 2077 | } |
2072 | 2078 | ||
2073 | if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || | 2079 | if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV || |
2074 | d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) | 2080 | d40c->dma_cfg.dir == DMA_MEM_TO_MEM) |
2075 | is_src = false; | 2081 | is_src = false; |
2076 | else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) | 2082 | else if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) |
2077 | is_src = true; | 2083 | is_src = true; |
2078 | else { | 2084 | else { |
2079 | chan_err(d40c, "Unknown direction\n"); | 2085 | chan_err(d40c, "Unknown direction\n"); |
@@ -2135,10 +2141,10 @@ static bool d40_is_paused(struct d40_chan *d40c) | |||
2135 | goto _exit; | 2141 | goto _exit; |
2136 | } | 2142 | } |
2137 | 2143 | ||
2138 | if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || | 2144 | if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV || |
2139 | d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { | 2145 | d40c->dma_cfg.dir == DMA_MEM_TO_MEM) { |
2140 | status = readl(chanbase + D40_CHAN_REG_SDLNK); | 2146 | status = readl(chanbase + D40_CHAN_REG_SDLNK); |
2141 | } else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { | 2147 | } else if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) { |
2142 | status = readl(chanbase + D40_CHAN_REG_SSLNK); | 2148 | status = readl(chanbase + D40_CHAN_REG_SSLNK); |
2143 | } else { | 2149 | } else { |
2144 | chan_err(d40c, "Unknown direction\n"); | 2150 | chan_err(d40c, "Unknown direction\n"); |
@@ -2358,7 +2364,7 @@ static void __d40_set_prio_rt(struct d40_chan *d40c, int dev_type, bool src) | |||
2358 | u32 rtreg; | 2364 | u32 rtreg; |
2359 | u32 event = D40_TYPE_TO_EVENT(dev_type); | 2365 | u32 event = D40_TYPE_TO_EVENT(dev_type); |
2360 | u32 group = D40_TYPE_TO_GROUP(dev_type); | 2366 | u32 group = D40_TYPE_TO_GROUP(dev_type); |
2361 | u32 bit = 1 << event; | 2367 | u32 bit = BIT(event); |
2362 | u32 prioreg; | 2368 | u32 prioreg; |
2363 | struct d40_gen_dmac *dmac = &d40c->base->gen_dmac; | 2369 | struct d40_gen_dmac *dmac = &d40c->base->gen_dmac; |
2364 | 2370 | ||
@@ -2389,12 +2395,12 @@ static void d40_set_prio_realtime(struct d40_chan *d40c) | |||
2389 | if (d40c->base->rev < 3) | 2395 | if (d40c->base->rev < 3) |
2390 | return; | 2396 | return; |
2391 | 2397 | ||
2392 | if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || | 2398 | if ((d40c->dma_cfg.dir == DMA_DEV_TO_MEM) || |
2393 | (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) | 2399 | (d40c->dma_cfg.dir == DMA_DEV_TO_DEV)) |
2394 | __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, true); | 2400 | __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, true); |
2395 | 2401 | ||
2396 | if ((d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH) || | 2402 | if ((d40c->dma_cfg.dir == DMA_MEM_TO_DEV) || |
2397 | (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) | 2403 | (d40c->dma_cfg.dir == DMA_DEV_TO_DEV)) |
2398 | __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, false); | 2404 | __d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, false); |
2399 | } | 2405 | } |
2400 | 2406 | ||
@@ -2425,11 +2431,11 @@ static struct dma_chan *d40_xlate(struct of_phandle_args *dma_spec, | |||
2425 | 2431 | ||
2426 | switch (D40_DT_FLAGS_DIR(flags)) { | 2432 | switch (D40_DT_FLAGS_DIR(flags)) { |
2427 | case 0: | 2433 | case 0: |
2428 | cfg.dir = STEDMA40_MEM_TO_PERIPH; | 2434 | cfg.dir = DMA_MEM_TO_DEV; |
2429 | cfg.dst_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); | 2435 | cfg.dst_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); |
2430 | break; | 2436 | break; |
2431 | case 1: | 2437 | case 1: |
2432 | cfg.dir = STEDMA40_PERIPH_TO_MEM; | 2438 | cfg.dir = DMA_DEV_TO_MEM; |
2433 | cfg.src_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); | 2439 | cfg.src_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags); |
2434 | break; | 2440 | break; |
2435 | } | 2441 | } |
@@ -2475,7 +2481,7 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) | |||
2475 | d40_set_prio_realtime(d40c); | 2481 | d40_set_prio_realtime(d40c); |
2476 | 2482 | ||
2477 | if (chan_is_logical(d40c)) { | 2483 | if (chan_is_logical(d40c)) { |
2478 | if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) | 2484 | if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) |
2479 | d40c->lcpa = d40c->base->lcpa_base + | 2485 | d40c->lcpa = d40c->base->lcpa_base + |
2480 | d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE; | 2486 | d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE; |
2481 | else | 2487 | else |
@@ -2675,33 +2681,10 @@ static void d40_terminate_all(struct dma_chan *chan) | |||
2675 | static int | 2681 | static int |
2676 | dma40_config_to_halfchannel(struct d40_chan *d40c, | 2682 | dma40_config_to_halfchannel(struct d40_chan *d40c, |
2677 | struct stedma40_half_channel_info *info, | 2683 | struct stedma40_half_channel_info *info, |
2678 | enum dma_slave_buswidth width, | ||
2679 | u32 maxburst) | 2684 | u32 maxburst) |
2680 | { | 2685 | { |
2681 | enum stedma40_periph_data_width addr_width; | ||
2682 | int psize; | 2686 | int psize; |
2683 | 2687 | ||
2684 | switch (width) { | ||
2685 | case DMA_SLAVE_BUSWIDTH_1_BYTE: | ||
2686 | addr_width = STEDMA40_BYTE_WIDTH; | ||
2687 | break; | ||
2688 | case DMA_SLAVE_BUSWIDTH_2_BYTES: | ||
2689 | addr_width = STEDMA40_HALFWORD_WIDTH; | ||
2690 | break; | ||
2691 | case DMA_SLAVE_BUSWIDTH_4_BYTES: | ||
2692 | addr_width = STEDMA40_WORD_WIDTH; | ||
2693 | break; | ||
2694 | case DMA_SLAVE_BUSWIDTH_8_BYTES: | ||
2695 | addr_width = STEDMA40_DOUBLEWORD_WIDTH; | ||
2696 | break; | ||
2697 | default: | ||
2698 | dev_err(d40c->base->dev, | ||
2699 | "illegal peripheral address width " | ||
2700 | "requested (%d)\n", | ||
2701 | width); | ||
2702 | return -EINVAL; | ||
2703 | } | ||
2704 | |||
2705 | if (chan_is_logical(d40c)) { | 2688 | if (chan_is_logical(d40c)) { |
2706 | if (maxburst >= 16) | 2689 | if (maxburst >= 16) |
2707 | psize = STEDMA40_PSIZE_LOG_16; | 2690 | psize = STEDMA40_PSIZE_LOG_16; |
@@ -2722,7 +2705,6 @@ dma40_config_to_halfchannel(struct d40_chan *d40c, | |||
2722 | psize = STEDMA40_PSIZE_PHY_1; | 2705 | psize = STEDMA40_PSIZE_PHY_1; |
2723 | } | 2706 | } |
2724 | 2707 | ||
2725 | info->data_width = addr_width; | ||
2726 | info->psize = psize; | 2708 | info->psize = psize; |
2727 | info->flow_ctrl = STEDMA40_NO_FLOW_CTRL; | 2709 | info->flow_ctrl = STEDMA40_NO_FLOW_CTRL; |
2728 | 2710 | ||
@@ -2748,12 +2730,12 @@ static int d40_set_runtime_config(struct dma_chan *chan, | |||
2748 | if (config->direction == DMA_DEV_TO_MEM) { | 2730 | if (config->direction == DMA_DEV_TO_MEM) { |
2749 | config_addr = config->src_addr; | 2731 | config_addr = config->src_addr; |
2750 | 2732 | ||
2751 | if (cfg->dir != STEDMA40_PERIPH_TO_MEM) | 2733 | if (cfg->dir != DMA_DEV_TO_MEM) |
2752 | dev_dbg(d40c->base->dev, | 2734 | dev_dbg(d40c->base->dev, |
2753 | "channel was not configured for peripheral " | 2735 | "channel was not configured for peripheral " |
2754 | "to memory transfer (%d) overriding\n", | 2736 | "to memory transfer (%d) overriding\n", |
2755 | cfg->dir); | 2737 | cfg->dir); |
2756 | cfg->dir = STEDMA40_PERIPH_TO_MEM; | 2738 | cfg->dir = DMA_DEV_TO_MEM; |
2757 | 2739 | ||
2758 | /* Configure the memory side */ | 2740 | /* Configure the memory side */ |
2759 | if (dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) | 2741 | if (dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) |
@@ -2764,12 +2746,12 @@ static int d40_set_runtime_config(struct dma_chan *chan, | |||
2764 | } else if (config->direction == DMA_MEM_TO_DEV) { | 2746 | } else if (config->direction == DMA_MEM_TO_DEV) { |
2765 | config_addr = config->dst_addr; | 2747 | config_addr = config->dst_addr; |
2766 | 2748 | ||
2767 | if (cfg->dir != STEDMA40_MEM_TO_PERIPH) | 2749 | if (cfg->dir != DMA_MEM_TO_DEV) |
2768 | dev_dbg(d40c->base->dev, | 2750 | dev_dbg(d40c->base->dev, |
2769 | "channel was not configured for memory " | 2751 | "channel was not configured for memory " |
2770 | "to peripheral transfer (%d) overriding\n", | 2752 | "to peripheral transfer (%d) overriding\n", |
2771 | cfg->dir); | 2753 | cfg->dir); |
2772 | cfg->dir = STEDMA40_MEM_TO_PERIPH; | 2754 | cfg->dir = DMA_MEM_TO_DEV; |
2773 | 2755 | ||
2774 | /* Configure the memory side */ | 2756 | /* Configure the memory side */ |
2775 | if (src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) | 2757 | if (src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) |
@@ -2806,14 +2788,24 @@ static int d40_set_runtime_config(struct dma_chan *chan, | |||
2806 | src_maxburst = dst_maxburst * dst_addr_width / src_addr_width; | 2788 | src_maxburst = dst_maxburst * dst_addr_width / src_addr_width; |
2807 | } | 2789 | } |
2808 | 2790 | ||
2791 | /* Only valid widths are; 1, 2, 4 and 8. */ | ||
2792 | if (src_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED || | ||
2793 | src_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES || | ||
2794 | dst_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED || | ||
2795 | dst_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES || | ||
2796 | ((src_addr_width > 1) && (src_addr_width & 1)) || | ||
2797 | ((dst_addr_width > 1) && (dst_addr_width & 1))) | ||
2798 | return -EINVAL; | ||
2799 | |||
2800 | cfg->src_info.data_width = src_addr_width; | ||
2801 | cfg->dst_info.data_width = dst_addr_width; | ||
2802 | |||
2809 | ret = dma40_config_to_halfchannel(d40c, &cfg->src_info, | 2803 | ret = dma40_config_to_halfchannel(d40c, &cfg->src_info, |
2810 | src_addr_width, | ||
2811 | src_maxburst); | 2804 | src_maxburst); |
2812 | if (ret) | 2805 | if (ret) |
2813 | return ret; | 2806 | return ret; |
2814 | 2807 | ||
2815 | ret = dma40_config_to_halfchannel(d40c, &cfg->dst_info, | 2808 | ret = dma40_config_to_halfchannel(d40c, &cfg->dst_info, |
2816 | dst_addr_width, | ||
2817 | dst_maxburst); | 2809 | dst_maxburst); |
2818 | if (ret) | 2810 | if (ret) |
2819 | return ret; | 2811 | return ret; |
@@ -2953,7 +2945,7 @@ static int __init d40_dmaengine_init(struct d40_base *base, | |||
2953 | } | 2945 | } |
2954 | 2946 | ||
2955 | d40_chan_init(base, &base->dma_memcpy, base->log_chans, | 2947 | d40_chan_init(base, &base->dma_memcpy, base->log_chans, |
2956 | base->num_log_chans, ARRAY_SIZE(dma40_memcpy_channels)); | 2948 | base->num_log_chans, base->num_memcpy_chans); |
2957 | 2949 | ||
2958 | dma_cap_zero(base->dma_memcpy.cap_mask); | 2950 | dma_cap_zero(base->dma_memcpy.cap_mask); |
2959 | dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask); | 2951 | dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask); |
@@ -3154,6 +3146,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) | |||
3154 | struct d40_base *base = NULL; | 3146 | struct d40_base *base = NULL; |
3155 | int num_log_chans = 0; | 3147 | int num_log_chans = 0; |
3156 | int num_phy_chans; | 3148 | int num_phy_chans; |
3149 | int num_memcpy_chans; | ||
3157 | int clk_ret = -EINVAL; | 3150 | int clk_ret = -EINVAL; |
3158 | int i; | 3151 | int i; |
3159 | u32 pid; | 3152 | u32 pid; |
@@ -3224,6 +3217,12 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) | |||
3224 | else | 3217 | else |
3225 | num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; | 3218 | num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; |
3226 | 3219 | ||
3220 | /* The number of channels used for memcpy */ | ||
3221 | if (plat_data->num_of_memcpy_chans) | ||
3222 | num_memcpy_chans = plat_data->num_of_memcpy_chans; | ||
3223 | else | ||
3224 | num_memcpy_chans = ARRAY_SIZE(dma40_memcpy_channels); | ||
3225 | |||
3227 | num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; | 3226 | num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; |
3228 | 3227 | ||
3229 | dev_info(&pdev->dev, | 3228 | dev_info(&pdev->dev, |
@@ -3231,7 +3230,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) | |||
3231 | rev, res->start, num_phy_chans, num_log_chans); | 3230 | rev, res->start, num_phy_chans, num_log_chans); |
3232 | 3231 | ||
3233 | base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + | 3232 | base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + |
3234 | (num_phy_chans + num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) * | 3233 | (num_phy_chans + num_log_chans + num_memcpy_chans) * |
3235 | sizeof(struct d40_chan), GFP_KERNEL); | 3234 | sizeof(struct d40_chan), GFP_KERNEL); |
3236 | 3235 | ||
3237 | if (base == NULL) { | 3236 | if (base == NULL) { |
@@ -3241,6 +3240,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) | |||
3241 | 3240 | ||
3242 | base->rev = rev; | 3241 | base->rev = rev; |
3243 | base->clk = clk; | 3242 | base->clk = clk; |
3243 | base->num_memcpy_chans = num_memcpy_chans; | ||
3244 | base->num_phy_chans = num_phy_chans; | 3244 | base->num_phy_chans = num_phy_chans; |
3245 | base->num_log_chans = num_log_chans; | 3245 | base->num_log_chans = num_log_chans; |
3246 | base->phy_start = res->start; | 3246 | base->phy_start = res->start; |
@@ -3484,12 +3484,8 @@ static int __init d40_of_probe(struct platform_device *pdev, | |||
3484 | struct device_node *np) | 3484 | struct device_node *np) |
3485 | { | 3485 | { |
3486 | struct stedma40_platform_data *pdata; | 3486 | struct stedma40_platform_data *pdata; |
3487 | 3487 | int num_phy = 0, num_memcpy = 0, num_disabled = 0; | |
3488 | /* | 3488 | const const __be32 *list; |
3489 | * FIXME: Fill in this routine as more support is added. | ||
3490 | * First platform enabled (u8500) doens't need any extra | ||
3491 | * properties to run, so this is fairly sparce currently. | ||
3492 | */ | ||
3493 | 3489 | ||
3494 | pdata = devm_kzalloc(&pdev->dev, | 3490 | pdata = devm_kzalloc(&pdev->dev, |
3495 | sizeof(struct stedma40_platform_data), | 3491 | sizeof(struct stedma40_platform_data), |
@@ -3497,6 +3493,41 @@ static int __init d40_of_probe(struct platform_device *pdev, | |||
3497 | if (!pdata) | 3493 | if (!pdata) |
3498 | return -ENOMEM; | 3494 | return -ENOMEM; |
3499 | 3495 | ||
3496 | /* If absent this value will be obtained from h/w. */ | ||
3497 | of_property_read_u32(np, "dma-channels", &num_phy); | ||
3498 | if (num_phy > 0) | ||
3499 | pdata->num_of_phy_chans = num_phy; | ||
3500 | |||
3501 | list = of_get_property(np, "memcpy-channels", &num_memcpy); | ||
3502 | num_memcpy /= sizeof(*list); | ||
3503 | |||
3504 | if (num_memcpy > D40_MEMCPY_MAX_CHANS || num_memcpy <= 0) { | ||
3505 | d40_err(&pdev->dev, | ||
3506 | "Invalid number of memcpy channels specified (%d)\n", | ||
3507 | num_memcpy); | ||
3508 | return -EINVAL; | ||
3509 | } | ||
3510 | pdata->num_of_memcpy_chans = num_memcpy; | ||
3511 | |||
3512 | of_property_read_u32_array(np, "memcpy-channels", | ||
3513 | dma40_memcpy_channels, | ||
3514 | num_memcpy); | ||
3515 | |||
3516 | list = of_get_property(np, "disabled-channels", &num_disabled); | ||
3517 | num_disabled /= sizeof(*list); | ||
3518 | |||
3519 | if (num_disabled > STEDMA40_MAX_PHYS || num_disabled < 0) { | ||
3520 | d40_err(&pdev->dev, | ||
3521 | "Invalid number of disabled channels specified (%d)\n", | ||
3522 | num_disabled); | ||
3523 | return -EINVAL; | ||
3524 | } | ||
3525 | |||
3526 | of_property_read_u32_array(np, "disabled-channels", | ||
3527 | pdata->disabled_channels, | ||
3528 | num_disabled); | ||
3529 | pdata->disabled_channels[num_disabled] = -1; | ||
3530 | |||
3500 | pdev->dev.platform_data = pdata; | 3531 | pdev->dev.platform_data = pdata; |
3501 | 3532 | ||
3502 | return 0; | 3533 | return 0; |
diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index ab5a2a706f7a..27b818dee7c7 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c | |||
@@ -10,6 +10,18 @@ | |||
10 | 10 | ||
11 | #include "ste_dma40_ll.h" | 11 | #include "ste_dma40_ll.h" |
12 | 12 | ||
13 | u8 d40_width_to_bits(enum dma_slave_buswidth width) | ||
14 | { | ||
15 | if (width == DMA_SLAVE_BUSWIDTH_1_BYTE) | ||
16 | return STEDMA40_ESIZE_8_BIT; | ||
17 | else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES) | ||
18 | return STEDMA40_ESIZE_16_BIT; | ||
19 | else if (width == DMA_SLAVE_BUSWIDTH_8_BYTES) | ||
20 | return STEDMA40_ESIZE_64_BIT; | ||
21 | else | ||
22 | return STEDMA40_ESIZE_32_BIT; | ||
23 | } | ||
24 | |||
13 | /* Sets up proper LCSP1 and LCSP3 register for a logical channel */ | 25 | /* Sets up proper LCSP1 and LCSP3 register for a logical channel */ |
14 | void d40_log_cfg(struct stedma40_chan_cfg *cfg, | 26 | void d40_log_cfg(struct stedma40_chan_cfg *cfg, |
15 | u32 *lcsp1, u32 *lcsp3) | 27 | u32 *lcsp1, u32 *lcsp3) |
@@ -18,32 +30,34 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg, | |||
18 | u32 l1 = 0; /* src */ | 30 | u32 l1 = 0; /* src */ |
19 | 31 | ||
20 | /* src is mem? -> increase address pos */ | 32 | /* src is mem? -> increase address pos */ |
21 | if (cfg->dir == STEDMA40_MEM_TO_PERIPH || | 33 | if (cfg->dir == DMA_MEM_TO_DEV || |
22 | cfg->dir == STEDMA40_MEM_TO_MEM) | 34 | cfg->dir == DMA_MEM_TO_MEM) |
23 | l1 |= 1 << D40_MEM_LCSP1_SCFG_INCR_POS; | 35 | l1 |= BIT(D40_MEM_LCSP1_SCFG_INCR_POS); |
24 | 36 | ||
25 | /* dst is mem? -> increase address pos */ | 37 | /* dst is mem? -> increase address pos */ |
26 | if (cfg->dir == STEDMA40_PERIPH_TO_MEM || | 38 | if (cfg->dir == DMA_DEV_TO_MEM || |
27 | cfg->dir == STEDMA40_MEM_TO_MEM) | 39 | cfg->dir == DMA_MEM_TO_MEM) |
28 | l3 |= 1 << D40_MEM_LCSP3_DCFG_INCR_POS; | 40 | l3 |= BIT(D40_MEM_LCSP3_DCFG_INCR_POS); |
29 | 41 | ||
30 | /* src is hw? -> master port 1 */ | 42 | /* src is hw? -> master port 1 */ |
31 | if (cfg->dir == STEDMA40_PERIPH_TO_MEM || | 43 | if (cfg->dir == DMA_DEV_TO_MEM || |
32 | cfg->dir == STEDMA40_PERIPH_TO_PERIPH) | 44 | cfg->dir == DMA_DEV_TO_DEV) |
33 | l1 |= 1 << D40_MEM_LCSP1_SCFG_MST_POS; | 45 | l1 |= BIT(D40_MEM_LCSP1_SCFG_MST_POS); |
34 | 46 | ||
35 | /* dst is hw? -> master port 1 */ | 47 | /* dst is hw? -> master port 1 */ |
36 | if (cfg->dir == STEDMA40_MEM_TO_PERIPH || | 48 | if (cfg->dir == DMA_MEM_TO_DEV || |
37 | cfg->dir == STEDMA40_PERIPH_TO_PERIPH) | 49 | cfg->dir == DMA_DEV_TO_DEV) |
38 | l3 |= 1 << D40_MEM_LCSP3_DCFG_MST_POS; | 50 | l3 |= BIT(D40_MEM_LCSP3_DCFG_MST_POS); |
39 | 51 | ||
40 | l3 |= 1 << D40_MEM_LCSP3_DCFG_EIM_POS; | 52 | l3 |= BIT(D40_MEM_LCSP3_DCFG_EIM_POS); |
41 | l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS; | 53 | l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS; |
42 | l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS; | 54 | l3 |= d40_width_to_bits(cfg->dst_info.data_width) |
55 | << D40_MEM_LCSP3_DCFG_ESIZE_POS; | ||
43 | 56 | ||
44 | l1 |= 1 << D40_MEM_LCSP1_SCFG_EIM_POS; | 57 | l1 |= BIT(D40_MEM_LCSP1_SCFG_EIM_POS); |
45 | l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; | 58 | l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; |
46 | l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS; | 59 | l1 |= d40_width_to_bits(cfg->src_info.data_width) |
60 | << D40_MEM_LCSP1_SCFG_ESIZE_POS; | ||
47 | 61 | ||
48 | *lcsp1 = l1; | 62 | *lcsp1 = l1; |
49 | *lcsp3 = l3; | 63 | *lcsp3 = l3; |
@@ -55,59 +69,61 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) | |||
55 | u32 src = 0; | 69 | u32 src = 0; |
56 | u32 dst = 0; | 70 | u32 dst = 0; |
57 | 71 | ||
58 | if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) || | 72 | if ((cfg->dir == DMA_DEV_TO_MEM) || |
59 | (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { | 73 | (cfg->dir == DMA_DEV_TO_DEV)) { |
60 | /* Set master port to 1 */ | 74 | /* Set master port to 1 */ |
61 | src |= 1 << D40_SREG_CFG_MST_POS; | 75 | src |= BIT(D40_SREG_CFG_MST_POS); |
62 | src |= D40_TYPE_TO_EVENT(cfg->dev_type); | 76 | src |= D40_TYPE_TO_EVENT(cfg->dev_type); |
63 | 77 | ||
64 | if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) | 78 | if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) |
65 | src |= 1 << D40_SREG_CFG_PHY_TM_POS; | 79 | src |= BIT(D40_SREG_CFG_PHY_TM_POS); |
66 | else | 80 | else |
67 | src |= 3 << D40_SREG_CFG_PHY_TM_POS; | 81 | src |= 3 << D40_SREG_CFG_PHY_TM_POS; |
68 | } | 82 | } |
69 | if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) || | 83 | if ((cfg->dir == DMA_MEM_TO_DEV) || |
70 | (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { | 84 | (cfg->dir == DMA_DEV_TO_DEV)) { |
71 | /* Set master port to 1 */ | 85 | /* Set master port to 1 */ |
72 | dst |= 1 << D40_SREG_CFG_MST_POS; | 86 | dst |= BIT(D40_SREG_CFG_MST_POS); |
73 | dst |= D40_TYPE_TO_EVENT(cfg->dev_type); | 87 | dst |= D40_TYPE_TO_EVENT(cfg->dev_type); |
74 | 88 | ||
75 | if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) | 89 | if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) |
76 | dst |= 1 << D40_SREG_CFG_PHY_TM_POS; | 90 | dst |= BIT(D40_SREG_CFG_PHY_TM_POS); |
77 | else | 91 | else |
78 | dst |= 3 << D40_SREG_CFG_PHY_TM_POS; | 92 | dst |= 3 << D40_SREG_CFG_PHY_TM_POS; |
79 | } | 93 | } |
80 | /* Interrupt on end of transfer for destination */ | 94 | /* Interrupt on end of transfer for destination */ |
81 | dst |= 1 << D40_SREG_CFG_TIM_POS; | 95 | dst |= BIT(D40_SREG_CFG_TIM_POS); |
82 | 96 | ||
83 | /* Generate interrupt on error */ | 97 | /* Generate interrupt on error */ |
84 | src |= 1 << D40_SREG_CFG_EIM_POS; | 98 | src |= BIT(D40_SREG_CFG_EIM_POS); |
85 | dst |= 1 << D40_SREG_CFG_EIM_POS; | 99 | dst |= BIT(D40_SREG_CFG_EIM_POS); |
86 | 100 | ||
87 | /* PSIZE */ | 101 | /* PSIZE */ |
88 | if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { | 102 | if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { |
89 | src |= 1 << D40_SREG_CFG_PHY_PEN_POS; | 103 | src |= BIT(D40_SREG_CFG_PHY_PEN_POS); |
90 | src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS; | 104 | src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS; |
91 | } | 105 | } |
92 | if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) { | 106 | if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) { |
93 | dst |= 1 << D40_SREG_CFG_PHY_PEN_POS; | 107 | dst |= BIT(D40_SREG_CFG_PHY_PEN_POS); |
94 | dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; | 108 | dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; |
95 | } | 109 | } |
96 | 110 | ||
97 | /* Element size */ | 111 | /* Element size */ |
98 | src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; | 112 | src |= d40_width_to_bits(cfg->src_info.data_width) |
99 | dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; | 113 | << D40_SREG_CFG_ESIZE_POS; |
114 | dst |= d40_width_to_bits(cfg->dst_info.data_width) | ||
115 | << D40_SREG_CFG_ESIZE_POS; | ||
100 | 116 | ||
101 | /* Set the priority bit to high for the physical channel */ | 117 | /* Set the priority bit to high for the physical channel */ |
102 | if (cfg->high_priority) { | 118 | if (cfg->high_priority) { |
103 | src |= 1 << D40_SREG_CFG_PRI_POS; | 119 | src |= BIT(D40_SREG_CFG_PRI_POS); |
104 | dst |= 1 << D40_SREG_CFG_PRI_POS; | 120 | dst |= BIT(D40_SREG_CFG_PRI_POS); |
105 | } | 121 | } |
106 | 122 | ||
107 | if (cfg->src_info.big_endian) | 123 | if (cfg->src_info.big_endian) |
108 | src |= 1 << D40_SREG_CFG_LBE_POS; | 124 | src |= BIT(D40_SREG_CFG_LBE_POS); |
109 | if (cfg->dst_info.big_endian) | 125 | if (cfg->dst_info.big_endian) |
110 | dst |= 1 << D40_SREG_CFG_LBE_POS; | 126 | dst |= BIT(D40_SREG_CFG_LBE_POS); |
111 | 127 | ||
112 | *src_cfg = src; | 128 | *src_cfg = src; |
113 | *dst_cfg = dst; | 129 | *dst_cfg = dst; |
@@ -133,23 +149,22 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, | |||
133 | num_elems = 2 << psize; | 149 | num_elems = 2 << psize; |
134 | 150 | ||
135 | /* Must be aligned */ | 151 | /* Must be aligned */ |
136 | if (!IS_ALIGNED(data, 0x1 << data_width)) | 152 | if (!IS_ALIGNED(data, data_width)) |
137 | return -EINVAL; | 153 | return -EINVAL; |
138 | 154 | ||
139 | /* Transfer size can't be smaller than (num_elms * elem_size) */ | 155 | /* Transfer size can't be smaller than (num_elms * elem_size) */ |
140 | if (data_size < num_elems * (0x1 << data_width)) | 156 | if (data_size < num_elems * data_width) |
141 | return -EINVAL; | 157 | return -EINVAL; |
142 | 158 | ||
143 | /* The number of elements. IE now many chunks */ | 159 | /* The number of elements. IE now many chunks */ |
144 | lli->reg_elt = (data_size >> data_width) << D40_SREG_ELEM_PHY_ECNT_POS; | 160 | lli->reg_elt = (data_size / data_width) << D40_SREG_ELEM_PHY_ECNT_POS; |
145 | 161 | ||
146 | /* | 162 | /* |
147 | * Distance to next element sized entry. | 163 | * Distance to next element sized entry. |
148 | * Usually the size of the element unless you want gaps. | 164 | * Usually the size of the element unless you want gaps. |
149 | */ | 165 | */ |
150 | if (addr_inc) | 166 | if (addr_inc) |
151 | lli->reg_elt |= (0x1 << data_width) << | 167 | lli->reg_elt |= data_width << D40_SREG_ELEM_PHY_EIDX_POS; |
152 | D40_SREG_ELEM_PHY_EIDX_POS; | ||
153 | 168 | ||
154 | /* Where the data is */ | 169 | /* Where the data is */ |
155 | lli->reg_ptr = data; | 170 | lli->reg_ptr = data; |
@@ -157,18 +172,20 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, | |||
157 | 172 | ||
158 | /* If this scatter list entry is the last one, no next link */ | 173 | /* If this scatter list entry is the last one, no next link */ |
159 | if (next_lli == 0) | 174 | if (next_lli == 0) |
160 | lli->reg_lnk = 0x1 << D40_SREG_LNK_PHY_TCP_POS; | 175 | lli->reg_lnk = BIT(D40_SREG_LNK_PHY_TCP_POS); |
161 | else | 176 | else |
162 | lli->reg_lnk = next_lli; | 177 | lli->reg_lnk = next_lli; |
163 | 178 | ||
164 | /* Set/clear interrupt generation on this link item.*/ | 179 | /* Set/clear interrupt generation on this link item.*/ |
165 | if (term_int) | 180 | if (term_int) |
166 | lli->reg_cfg |= 0x1 << D40_SREG_CFG_TIM_POS; | 181 | lli->reg_cfg |= BIT(D40_SREG_CFG_TIM_POS); |
167 | else | 182 | else |
168 | lli->reg_cfg &= ~(0x1 << D40_SREG_CFG_TIM_POS); | 183 | lli->reg_cfg &= ~BIT(D40_SREG_CFG_TIM_POS); |
169 | 184 | ||
170 | /* Post link */ | 185 | /* |
171 | lli->reg_lnk |= 0 << D40_SREG_LNK_PHY_PRE_POS; | 186 | * Post link - D40_SREG_LNK_PHY_PRE_POS = 0 |
187 | * Relink happens after transfer completion. | ||
188 | */ | ||
172 | 189 | ||
173 | return 0; | 190 | return 0; |
174 | } | 191 | } |
@@ -177,16 +194,16 @@ static int d40_seg_size(int size, int data_width1, int data_width2) | |||
177 | { | 194 | { |
178 | u32 max_w = max(data_width1, data_width2); | 195 | u32 max_w = max(data_width1, data_width2); |
179 | u32 min_w = min(data_width1, data_width2); | 196 | u32 min_w = min(data_width1, data_width2); |
180 | u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w); | 197 | u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE * min_w, max_w); |
181 | 198 | ||
182 | if (seg_max > STEDMA40_MAX_SEG_SIZE) | 199 | if (seg_max > STEDMA40_MAX_SEG_SIZE) |
183 | seg_max -= (1 << max_w); | 200 | seg_max -= max_w; |
184 | 201 | ||
185 | if (size <= seg_max) | 202 | if (size <= seg_max) |
186 | return size; | 203 | return size; |
187 | 204 | ||
188 | if (size <= 2 * seg_max) | 205 | if (size <= 2 * seg_max) |
189 | return ALIGN(size / 2, 1 << max_w); | 206 | return ALIGN(size / 2, max_w); |
190 | 207 | ||
191 | return seg_max; | 208 | return seg_max; |
192 | } | 209 | } |
@@ -352,10 +369,10 @@ static void d40_log_fill_lli(struct d40_log_lli *lli, | |||
352 | lli->lcsp13 = reg_cfg; | 369 | lli->lcsp13 = reg_cfg; |
353 | 370 | ||
354 | /* The number of elements to transfer */ | 371 | /* The number of elements to transfer */ |
355 | lli->lcsp02 = ((data_size >> data_width) << | 372 | lli->lcsp02 = ((data_size / data_width) << |
356 | D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK; | 373 | D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK; |
357 | 374 | ||
358 | BUG_ON((data_size >> data_width) > STEDMA40_MAX_SEG_SIZE); | 375 | BUG_ON((data_size / data_width) > STEDMA40_MAX_SEG_SIZE); |
359 | 376 | ||
360 | /* 16 LSBs address of the current element */ | 377 | /* 16 LSBs address of the current element */ |
361 | lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK; | 378 | lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK; |
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 2c80004e0a83..f0beee7b868e 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c | |||
@@ -25,11 +25,19 @@ | |||
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/of.h> | ||
28 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
29 | #include <linux/usb/musb-ux500.h> | 30 | #include <linux/usb/musb-ux500.h> |
30 | 31 | ||
31 | #include "musb_core.h" | 32 | #include "musb_core.h" |
32 | 33 | ||
34 | static struct musb_hdrc_config ux500_musb_hdrc_config = { | ||
35 | .multipoint = true, | ||
36 | .dyn_fifo = true, | ||
37 | .num_eps = 16, | ||
38 | .ram_bits = 16, | ||
39 | }; | ||
40 | |||
33 | struct ux500_glue { | 41 | struct ux500_glue { |
34 | struct device *dev; | 42 | struct device *dev; |
35 | struct platform_device *musb; | 43 | struct platform_device *musb; |
@@ -187,14 +195,57 @@ static const struct musb_platform_ops ux500_ops = { | |||
187 | .set_vbus = ux500_musb_set_vbus, | 195 | .set_vbus = ux500_musb_set_vbus, |
188 | }; | 196 | }; |
189 | 197 | ||
198 | static struct musb_hdrc_platform_data * | ||
199 | ux500_of_probe(struct platform_device *pdev, struct device_node *np) | ||
200 | { | ||
201 | struct musb_hdrc_platform_data *pdata; | ||
202 | const char *mode; | ||
203 | int strlen; | ||
204 | |||
205 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
206 | if (!pdata) | ||
207 | return NULL; | ||
208 | |||
209 | mode = of_get_property(np, "dr_mode", &strlen); | ||
210 | if (!mode) { | ||
211 | dev_err(&pdev->dev, "No 'dr_mode' property found\n"); | ||
212 | return NULL; | ||
213 | } | ||
214 | |||
215 | if (strlen > 0) { | ||
216 | if (!strcmp(mode, "host")) | ||
217 | pdata->mode = MUSB_HOST; | ||
218 | if (!strcmp(mode, "otg")) | ||
219 | pdata->mode = MUSB_OTG; | ||
220 | if (!strcmp(mode, "peripheral")) | ||
221 | pdata->mode = MUSB_PERIPHERAL; | ||
222 | } | ||
223 | |||
224 | return pdata; | ||
225 | } | ||
226 | |||
190 | static int ux500_probe(struct platform_device *pdev) | 227 | static int ux500_probe(struct platform_device *pdev) |
191 | { | 228 | { |
192 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; | 229 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; |
230 | struct device_node *np = pdev->dev.of_node; | ||
193 | struct platform_device *musb; | 231 | struct platform_device *musb; |
194 | struct ux500_glue *glue; | 232 | struct ux500_glue *glue; |
195 | struct clk *clk; | 233 | struct clk *clk; |
196 | int ret = -ENOMEM; | 234 | int ret = -ENOMEM; |
197 | 235 | ||
236 | if (!pdata) { | ||
237 | if (np) { | ||
238 | pdata = ux500_of_probe(pdev, np); | ||
239 | if (!pdata) | ||
240 | goto err0; | ||
241 | |||
242 | pdev->dev.platform_data = pdata; | ||
243 | } else { | ||
244 | dev_err(&pdev->dev, "no pdata or device tree found\n"); | ||
245 | goto err0; | ||
246 | } | ||
247 | } | ||
248 | |||
198 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 249 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); |
199 | if (!glue) { | 250 | if (!glue) { |
200 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | 251 | dev_err(&pdev->dev, "failed to allocate glue context\n"); |
@@ -221,14 +272,16 @@ static int ux500_probe(struct platform_device *pdev) | |||
221 | } | 272 | } |
222 | 273 | ||
223 | musb->dev.parent = &pdev->dev; | 274 | musb->dev.parent = &pdev->dev; |
224 | musb->dev.dma_mask = pdev->dev.dma_mask; | 275 | musb->dev.dma_mask = &pdev->dev.coherent_dma_mask; |
225 | musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; | 276 | musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; |
277 | musb->dev.of_node = pdev->dev.of_node; | ||
226 | 278 | ||
227 | glue->dev = &pdev->dev; | 279 | glue->dev = &pdev->dev; |
228 | glue->musb = musb; | 280 | glue->musb = musb; |
229 | glue->clk = clk; | 281 | glue->clk = clk; |
230 | 282 | ||
231 | pdata->platform_ops = &ux500_ops; | 283 | pdata->platform_ops = &ux500_ops; |
284 | pdata->config = &ux500_musb_hdrc_config; | ||
232 | 285 | ||
233 | platform_set_drvdata(pdev, glue); | 286 | platform_set_drvdata(pdev, glue); |
234 | 287 | ||
@@ -320,12 +373,18 @@ static const struct dev_pm_ops ux500_pm_ops = { | |||
320 | #define DEV_PM_OPS NULL | 373 | #define DEV_PM_OPS NULL |
321 | #endif | 374 | #endif |
322 | 375 | ||
376 | static const struct of_device_id ux500_match[] = { | ||
377 | { .compatible = "stericsson,db8500-musb", }, | ||
378 | {} | ||
379 | }; | ||
380 | |||
323 | static struct platform_driver ux500_driver = { | 381 | static struct platform_driver ux500_driver = { |
324 | .probe = ux500_probe, | 382 | .probe = ux500_probe, |
325 | .remove = ux500_remove, | 383 | .remove = ux500_remove, |
326 | .driver = { | 384 | .driver = { |
327 | .name = "musb-ux500", | 385 | .name = "musb-ux500", |
328 | .pm = DEV_PM_OPS, | 386 | .pm = DEV_PM_OPS, |
387 | .of_match_table = ux500_match, | ||
329 | }, | 388 | }, |
330 | }; | 389 | }; |
331 | 390 | ||
diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index 338120641145..7d80699a5ff7 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c | |||
@@ -34,6 +34,11 @@ | |||
34 | #include <linux/platform_data/usb-musb-ux500.h> | 34 | #include <linux/platform_data/usb-musb-ux500.h> |
35 | #include "musb_core.h" | 35 | #include "musb_core.h" |
36 | 36 | ||
37 | static const char *iep_chan_names[] = { "iep_1_9", "iep_2_10", "iep_3_11", "iep_4_12", | ||
38 | "iep_5_13", "iep_6_14", "iep_7_15", "iep_8" }; | ||
39 | static const char *oep_chan_names[] = { "oep_1_9", "oep_2_10", "oep_3_11", "oep_4_12", | ||
40 | "oep_5_13", "oep_6_14", "oep_7_15", "oep_8" }; | ||
41 | |||
37 | struct ux500_dma_channel { | 42 | struct ux500_dma_channel { |
38 | struct dma_channel channel; | 43 | struct dma_channel channel; |
39 | struct ux500_dma_controller *controller; | 44 | struct ux500_dma_controller *controller; |
@@ -48,10 +53,8 @@ struct ux500_dma_channel { | |||
48 | 53 | ||
49 | struct ux500_dma_controller { | 54 | struct ux500_dma_controller { |
50 | struct dma_controller controller; | 55 | struct dma_controller controller; |
51 | struct ux500_dma_channel rx_channel[UX500_MUSB_DMA_NUM_RX_CHANNELS]; | 56 | struct ux500_dma_channel rx_channel[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]; |
52 | struct ux500_dma_channel tx_channel[UX500_MUSB_DMA_NUM_TX_CHANNELS]; | 57 | struct ux500_dma_channel tx_channel[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]; |
53 | u32 num_rx_channels; | ||
54 | u32 num_tx_channels; | ||
55 | void *private_data; | 58 | void *private_data; |
56 | dma_addr_t phy_base; | 59 | dma_addr_t phy_base; |
57 | }; | 60 | }; |
@@ -144,19 +147,15 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c, | |||
144 | struct ux500_dma_channel *ux500_channel = NULL; | 147 | struct ux500_dma_channel *ux500_channel = NULL; |
145 | struct musb *musb = controller->private_data; | 148 | struct musb *musb = controller->private_data; |
146 | u8 ch_num = hw_ep->epnum - 1; | 149 | u8 ch_num = hw_ep->epnum - 1; |
147 | u32 max_ch; | ||
148 | 150 | ||
149 | /* Max 8 DMA channels (0 - 7). Each DMA channel can only be allocated | 151 | /* 8 DMA channels (0 - 7). Each DMA channel can only be allocated |
150 | * to specified hw_ep. For example DMA channel 0 can only be allocated | 152 | * to specified hw_ep. For example DMA channel 0 can only be allocated |
151 | * to hw_ep 1 and 9. | 153 | * to hw_ep 1 and 9. |
152 | */ | 154 | */ |
153 | if (ch_num > 7) | 155 | if (ch_num > 7) |
154 | ch_num -= 8; | 156 | ch_num -= 8; |
155 | 157 | ||
156 | max_ch = is_tx ? controller->num_tx_channels : | 158 | if (ch_num >= UX500_MUSB_DMA_NUM_RX_TX_CHANNELS) |
157 | controller->num_rx_channels; | ||
158 | |||
159 | if (ch_num >= max_ch) | ||
160 | return NULL; | 159 | return NULL; |
161 | 160 | ||
162 | ux500_channel = is_tx ? &(controller->tx_channel[ch_num]) : | 161 | ux500_channel = is_tx ? &(controller->tx_channel[ch_num]) : |
@@ -264,7 +263,7 @@ static int ux500_dma_controller_stop(struct dma_controller *c) | |||
264 | struct dma_channel *channel; | 263 | struct dma_channel *channel; |
265 | u8 ch_num; | 264 | u8 ch_num; |
266 | 265 | ||
267 | for (ch_num = 0; ch_num < controller->num_rx_channels; ch_num++) { | 266 | for (ch_num = 0; ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; ch_num++) { |
268 | channel = &controller->rx_channel[ch_num].channel; | 267 | channel = &controller->rx_channel[ch_num].channel; |
269 | ux500_channel = channel->private_data; | 268 | ux500_channel = channel->private_data; |
270 | 269 | ||
@@ -274,7 +273,7 @@ static int ux500_dma_controller_stop(struct dma_controller *c) | |||
274 | dma_release_channel(ux500_channel->dma_chan); | 273 | dma_release_channel(ux500_channel->dma_chan); |
275 | } | 274 | } |
276 | 275 | ||
277 | for (ch_num = 0; ch_num < controller->num_tx_channels; ch_num++) { | 276 | for (ch_num = 0; ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; ch_num++) { |
278 | channel = &controller->tx_channel[ch_num].channel; | 277 | channel = &controller->tx_channel[ch_num].channel; |
279 | ux500_channel = channel->private_data; | 278 | ux500_channel = channel->private_data; |
280 | 279 | ||
@@ -295,34 +294,36 @@ static int ux500_dma_controller_start(struct dma_controller *c) | |||
295 | struct musb *musb = controller->private_data; | 294 | struct musb *musb = controller->private_data; |
296 | struct device *dev = musb->controller; | 295 | struct device *dev = musb->controller; |
297 | struct musb_hdrc_platform_data *plat = dev->platform_data; | 296 | struct musb_hdrc_platform_data *plat = dev->platform_data; |
298 | struct ux500_musb_board_data *data = plat->board_data; | 297 | struct ux500_musb_board_data *data; |
299 | struct dma_channel *dma_channel = NULL; | 298 | struct dma_channel *dma_channel = NULL; |
299 | char **chan_names; | ||
300 | u32 ch_num; | 300 | u32 ch_num; |
301 | u8 dir; | 301 | u8 dir; |
302 | u8 is_tx = 0; | 302 | u8 is_tx = 0; |
303 | 303 | ||
304 | void **param_array; | 304 | void **param_array; |
305 | struct ux500_dma_channel *channel_array; | 305 | struct ux500_dma_channel *channel_array; |
306 | u32 ch_count; | ||
307 | dma_cap_mask_t mask; | 306 | dma_cap_mask_t mask; |
308 | 307 | ||
309 | if ((data->num_rx_channels > UX500_MUSB_DMA_NUM_RX_CHANNELS) || | 308 | if (!plat) { |
310 | (data->num_tx_channels > UX500_MUSB_DMA_NUM_TX_CHANNELS)) | 309 | dev_err(musb->controller, "No platform data\n"); |
311 | return -EINVAL; | 310 | return -EINVAL; |
311 | } | ||
312 | 312 | ||
313 | controller->num_rx_channels = data->num_rx_channels; | 313 | data = plat->board_data; |
314 | controller->num_tx_channels = data->num_tx_channels; | ||
315 | 314 | ||
316 | dma_cap_zero(mask); | 315 | dma_cap_zero(mask); |
317 | dma_cap_set(DMA_SLAVE, mask); | 316 | dma_cap_set(DMA_SLAVE, mask); |
318 | 317 | ||
319 | /* Prepare the loop for RX channels */ | 318 | /* Prepare the loop for RX channels */ |
320 | channel_array = controller->rx_channel; | 319 | channel_array = controller->rx_channel; |
321 | ch_count = data->num_rx_channels; | 320 | param_array = data ? data->dma_rx_param_array : NULL; |
322 | param_array = data->dma_rx_param_array; | 321 | chan_names = (char **)iep_chan_names; |
323 | 322 | ||
324 | for (dir = 0; dir < 2; dir++) { | 323 | for (dir = 0; dir < 2; dir++) { |
325 | for (ch_num = 0; ch_num < ch_count; ch_num++) { | 324 | for (ch_num = 0; |
325 | ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; | ||
326 | ch_num++) { | ||
326 | ux500_channel = &channel_array[ch_num]; | 327 | ux500_channel = &channel_array[ch_num]; |
327 | ux500_channel->controller = controller; | 328 | ux500_channel->controller = controller; |
328 | ux500_channel->ch_num = ch_num; | 329 | ux500_channel->ch_num = ch_num; |
@@ -333,9 +334,15 @@ static int ux500_dma_controller_start(struct dma_controller *c) | |||
333 | dma_channel->status = MUSB_DMA_STATUS_FREE; | 334 | dma_channel->status = MUSB_DMA_STATUS_FREE; |
334 | dma_channel->max_len = SZ_16M; | 335 | dma_channel->max_len = SZ_16M; |
335 | 336 | ||
336 | ux500_channel->dma_chan = dma_request_channel(mask, | 337 | ux500_channel->dma_chan = |
337 | data->dma_filter, | 338 | dma_request_slave_channel(dev, chan_names[ch_num]); |
338 | param_array[ch_num]); | 339 | |
340 | if (!ux500_channel->dma_chan) | ||
341 | ux500_channel->dma_chan = | ||
342 | dma_request_channel(mask, | ||
343 | data->dma_filter, | ||
344 | param_array[ch_num]); | ||
345 | |||
339 | if (!ux500_channel->dma_chan) { | 346 | if (!ux500_channel->dma_chan) { |
340 | ERR("Dma pipe allocation error dir=%d ch=%d\n", | 347 | ERR("Dma pipe allocation error dir=%d ch=%d\n", |
341 | dir, ch_num); | 348 | dir, ch_num); |
@@ -350,8 +357,8 @@ static int ux500_dma_controller_start(struct dma_controller *c) | |||
350 | 357 | ||
351 | /* Prepare the loop for TX channels */ | 358 | /* Prepare the loop for TX channels */ |
352 | channel_array = controller->tx_channel; | 359 | channel_array = controller->tx_channel; |
353 | ch_count = data->num_tx_channels; | 360 | param_array = data ? data->dma_tx_param_array : NULL; |
354 | param_array = data->dma_tx_param_array; | 361 | chan_names = (char **)oep_chan_names; |
355 | is_tx = 1; | 362 | is_tx = 1; |
356 | } | 363 | } |
357 | 364 | ||
diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h index 288dc2420ee6..1bb9b1852256 100644 --- a/include/linux/platform_data/dma-ste-dma40.h +++ b/include/linux/platform_data/dma-ste-dma40.h | |||
@@ -70,21 +70,6 @@ enum stedma40_flow_ctrl { | |||
70 | STEDMA40_FLOW_CTRL, | 70 | STEDMA40_FLOW_CTRL, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | enum stedma40_periph_data_width { | ||
74 | STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT, | ||
75 | STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT, | ||
76 | STEDMA40_WORD_WIDTH = STEDMA40_ESIZE_32_BIT, | ||
77 | STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT | ||
78 | }; | ||
79 | |||
80 | enum stedma40_xfer_dir { | ||
81 | STEDMA40_MEM_TO_MEM = 1, | ||
82 | STEDMA40_MEM_TO_PERIPH, | ||
83 | STEDMA40_PERIPH_TO_MEM, | ||
84 | STEDMA40_PERIPH_TO_PERIPH | ||
85 | }; | ||
86 | |||
87 | |||
88 | /** | 73 | /** |
89 | * struct stedma40_half_channel_info - dst/src channel configuration | 74 | * struct stedma40_half_channel_info - dst/src channel configuration |
90 | * | 75 | * |
@@ -95,7 +80,7 @@ enum stedma40_xfer_dir { | |||
95 | */ | 80 | */ |
96 | struct stedma40_half_channel_info { | 81 | struct stedma40_half_channel_info { |
97 | bool big_endian; | 82 | bool big_endian; |
98 | enum stedma40_periph_data_width data_width; | 83 | enum dma_slave_buswidth data_width; |
99 | int psize; | 84 | int psize; |
100 | enum stedma40_flow_ctrl flow_ctrl; | 85 | enum stedma40_flow_ctrl flow_ctrl; |
101 | }; | 86 | }; |
@@ -120,7 +105,7 @@ struct stedma40_half_channel_info { | |||
120 | * | 105 | * |
121 | */ | 106 | */ |
122 | struct stedma40_chan_cfg { | 107 | struct stedma40_chan_cfg { |
123 | enum stedma40_xfer_dir dir; | 108 | enum dma_transfer_direction dir; |
124 | bool high_priority; | 109 | bool high_priority; |
125 | bool realtime; | 110 | bool realtime; |
126 | enum stedma40_mode mode; | 111 | enum stedma40_mode mode; |
@@ -147,6 +132,7 @@ struct stedma40_chan_cfg { | |||
147 | * @num_of_soft_lli_chans: The number of channels that needs to be configured | 132 | * @num_of_soft_lli_chans: The number of channels that needs to be configured |
148 | * to use SoftLLI. | 133 | * to use SoftLLI. |
149 | * @use_esram_lcla: flag for mapping the lcla into esram region | 134 | * @use_esram_lcla: flag for mapping the lcla into esram region |
135 | * @num_of_memcpy_chans: The number of channels reserved for memcpy. | ||
150 | * @num_of_phy_chans: The number of physical channels implemented in HW. | 136 | * @num_of_phy_chans: The number of physical channels implemented in HW. |
151 | * 0 means reading the number of channels from DMA HW but this is only valid | 137 | * 0 means reading the number of channels from DMA HW but this is only valid |
152 | * for 'multiple of 4' channels, like 8. | 138 | * for 'multiple of 4' channels, like 8. |
@@ -156,6 +142,7 @@ struct stedma40_platform_data { | |||
156 | int *soft_lli_chans; | 142 | int *soft_lli_chans; |
157 | int num_of_soft_lli_chans; | 143 | int num_of_soft_lli_chans; |
158 | bool use_esram_lcla; | 144 | bool use_esram_lcla; |
145 | int num_of_memcpy_chans; | ||
159 | int num_of_phy_chans; | 146 | int num_of_phy_chans; |
160 | }; | 147 | }; |
161 | 148 | ||
diff --git a/include/linux/platform_data/usb-musb-ux500.h b/include/linux/platform_data/usb-musb-ux500.h index 4c1cc50a595a..dd9c83ac7de0 100644 --- a/include/linux/platform_data/usb-musb-ux500.h +++ b/include/linux/platform_data/usb-musb-ux500.h | |||
@@ -9,14 +9,11 @@ | |||
9 | 9 | ||
10 | #include <linux/dmaengine.h> | 10 | #include <linux/dmaengine.h> |
11 | 11 | ||
12 | #define UX500_MUSB_DMA_NUM_RX_CHANNELS 8 | 12 | #define UX500_MUSB_DMA_NUM_RX_TX_CHANNELS 8 |
13 | #define UX500_MUSB_DMA_NUM_TX_CHANNELS 8 | ||
14 | 13 | ||
15 | struct ux500_musb_board_data { | 14 | struct ux500_musb_board_data { |
16 | void **dma_rx_param_array; | 15 | void **dma_rx_param_array; |
17 | void **dma_tx_param_array; | 16 | void **dma_tx_param_array; |
18 | u32 num_rx_channels; | ||
19 | u32 num_tx_channels; | ||
20 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); | 17 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); |
21 | }; | 18 | }; |
22 | 19 | ||
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index b6e5ae277299..31f9bbc74521 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c | |||
@@ -76,20 +76,20 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd, | |||
76 | dma_params = snd_soc_dai_get_dma_data(dai, substream); | 76 | dma_params = snd_soc_dai_get_dma_data(dai, substream); |
77 | dma_cfg = dma_params->dma_cfg; | 77 | dma_cfg = dma_params->dma_cfg; |
78 | 78 | ||
79 | mem_data_width = STEDMA40_HALFWORD_WIDTH; | 79 | mem_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES; |
80 | 80 | ||
81 | switch (dma_params->data_size) { | 81 | switch (dma_params->data_size) { |
82 | case 32: | 82 | case 32: |
83 | per_data_width = STEDMA40_WORD_WIDTH; | 83 | per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
84 | break; | 84 | break; |
85 | case 16: | 85 | case 16: |
86 | per_data_width = STEDMA40_HALFWORD_WIDTH; | 86 | per_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES; |
87 | break; | 87 | break; |
88 | case 8: | 88 | case 8: |
89 | per_data_width = STEDMA40_BYTE_WIDTH; | 89 | per_data_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
90 | break; | 90 | break; |
91 | default: | 91 | default: |
92 | per_data_width = STEDMA40_WORD_WIDTH; | 92 | per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
93 | } | 93 | } |
94 | 94 | ||
95 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 95 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |