Commit 2c3165eb authored by Olof Johansson's avatar Olof Johansson

Merge tag 'ux500-dma40-for-arm-soc-2' of...

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
parents 0d86331b 499c2bc3
...@@ -6,10 +6,12 @@ Required properties: ...@@ -6,10 +6,12 @@ Required properties:
- reg-names: Names of the above areas to use during resource look-up - reg-names: Names of the above areas to use during resource look-up
- interrupt: Should contain the DMAC interrupt number - interrupt: Should contain the DMAC interrupt number
- #dma-cells: must be <3> - #dma-cells: must be <3>
- memcpy-channels: Channels to be used for memcpy
Optional properties: Optional properties:
- dma-channels: Number of channels supported by hardware - if not present - dma-channels: Number of channels supported by hardware - if not present
the driver will attempt to obtain the information from H/W the driver will attempt to obtain the information from H/W
- disabled-channels: Channels which can not be used
Example: Example:
...@@ -21,6 +23,8 @@ Example: ...@@ -21,6 +23,8 @@ Example:
interrupts = <0 25 0x4>; interrupts = <0 25 0x4>;
#dma-cells = <2>; #dma-cells = <2>;
memcpy-channels = <56 57 58 59 60>;
disabled-channels = <12>;
dma-channels = <8>; dma-channels = <8>;
}; };
......
Ux500 MUSB
Required properties:
- compatible : Should be "stericsson,db8500-musb"
- reg : Offset and length of registers
- interrupts : Interrupt; mode, number and trigger
- dr_mode : Dual-role; either host mode "host", peripheral mode "peripheral"
or both "otg"
Optional properties:
- dmas : A list of dma channels;
dma-controller, event-line, fixed-channel, flags
- dma-names : An ordered list of channel names affiliated to the above
Example:
usb_per5@a03e0000 {
compatible = "stericsson,db8500-musb", "mentor,musb";
reg = <0xa03e0000 0x10000>;
interrupts = <0 23 0x4>;
interrupt-names = "mc";
dr_mode = "otg";
dmas = <&dma 38 0 0x2>, /* Logical - DevToMem */
<&dma 38 0 0x0>, /* Logical - MemToDev */
<&dma 37 0 0x2>, /* Logical - DevToMem */
<&dma 37 0 0x0>, /* Logical - MemToDev */
<&dma 36 0 0x2>, /* Logical - DevToMem */
<&dma 36 0 0x0>, /* Logical - MemToDev */
<&dma 19 0 0x2>, /* Logical - DevToMem */
<&dma 19 0 0x0>, /* Logical - MemToDev */
<&dma 18 0 0x2>, /* Logical - DevToMem */
<&dma 18 0 0x0>, /* Logical - MemToDev */
<&dma 17 0 0x2>, /* Logical - DevToMem */
<&dma 17 0 0x0>, /* Logical - MemToDev */
<&dma 16 0 0x2>, /* Logical - DevToMem */
<&dma 16 0 0x0>, /* Logical - MemToDev */
<&dma 39 0 0x2>, /* Logical - DevToMem */
<&dma 39 0 0x0>; /* Logical - MemToDev */
dma-names = "iep_1_9", "oep_1_9",
"iep_2_10", "oep_2_10",
"iep_3_11", "oep_3_11",
"iep_4_12", "oep_4_12",
"iep_5_13", "oep_5_13",
"iep_6_14", "oep_6_14",
"iep_7_15", "oep_7_15",
"iep_8", "oep_8";
};
...@@ -21,13 +21,13 @@ ...@@ -21,13 +21,13 @@
static struct stedma40_chan_cfg msp0_dma_rx = { static struct stedma40_chan_cfg msp0_dma_rx = {
.high_priority = true, .high_priority = true,
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0, .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0,
}; };
static struct stedma40_chan_cfg msp0_dma_tx = { static struct stedma40_chan_cfg msp0_dma_tx = {
.high_priority = true, .high_priority = true,
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0, .dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0,
}; };
...@@ -39,13 +39,13 @@ struct msp_i2s_platform_data msp0_platform_data = { ...@@ -39,13 +39,13 @@ struct msp_i2s_platform_data msp0_platform_data = {
static struct stedma40_chan_cfg msp1_dma_rx = { static struct stedma40_chan_cfg msp1_dma_rx = {
.high_priority = true, .high_priority = true,
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV30_MSP3, .dev_type = DB8500_DMA_DEV30_MSP3,
}; };
static struct stedma40_chan_cfg msp1_dma_tx = { static struct stedma40_chan_cfg msp1_dma_tx = {
.high_priority = true, .high_priority = true,
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV30_MSP1, .dev_type = DB8500_DMA_DEV30_MSP1,
}; };
...@@ -57,13 +57,13 @@ struct msp_i2s_platform_data msp1_platform_data = { ...@@ -57,13 +57,13 @@ struct msp_i2s_platform_data msp1_platform_data = {
static struct stedma40_chan_cfg msp2_dma_rx = { static struct stedma40_chan_cfg msp2_dma_rx = {
.high_priority = true, .high_priority = true,
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV14_MSP2, .dev_type = DB8500_DMA_DEV14_MSP2,
}; };
static struct stedma40_chan_cfg msp2_dma_tx = { static struct stedma40_chan_cfg msp2_dma_tx = {
.high_priority = true, .high_priority = true,
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV14_MSP2, .dev_type = DB8500_DMA_DEV14_MSP2,
.use_fixed_channel = true, .use_fixed_channel = true,
.phy_channel = 1, .phy_channel = 1,
......
...@@ -34,13 +34,13 @@ ...@@ -34,13 +34,13 @@
#ifdef CONFIG_STE_DMA40 #ifdef CONFIG_STE_DMA40
struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = { struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV29_SD_MM0, .dev_type = DB8500_DMA_DEV29_SD_MM0,
}; };
static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV29_SD_MM0, .dev_type = DB8500_DMA_DEV29_SD_MM0,
}; };
#endif #endif
...@@ -81,13 +81,13 @@ void mop500_sdi_tc35892_init(struct device *parent) ...@@ -81,13 +81,13 @@ void mop500_sdi_tc35892_init(struct device *parent)
#ifdef CONFIG_STE_DMA40 #ifdef CONFIG_STE_DMA40
static struct stedma40_chan_cfg sdi1_dma_cfg_rx = { static struct stedma40_chan_cfg sdi1_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV32_SD_MM1, .dev_type = DB8500_DMA_DEV32_SD_MM1,
}; };
static struct stedma40_chan_cfg sdi1_dma_cfg_tx = { static struct stedma40_chan_cfg sdi1_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV32_SD_MM1, .dev_type = DB8500_DMA_DEV32_SD_MM1,
}; };
#endif #endif
...@@ -112,13 +112,13 @@ struct mmci_platform_data mop500_sdi1_data = { ...@@ -112,13 +112,13 @@ struct mmci_platform_data mop500_sdi1_data = {
#ifdef CONFIG_STE_DMA40 #ifdef CONFIG_STE_DMA40
struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = { struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV28_SD_MM2, .dev_type = DB8500_DMA_DEV28_SD_MM2,
}; };
static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = { static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV28_SD_MM2, .dev_type = DB8500_DMA_DEV28_SD_MM2,
}; };
#endif #endif
...@@ -144,13 +144,13 @@ struct mmci_platform_data mop500_sdi2_data = { ...@@ -144,13 +144,13 @@ struct mmci_platform_data mop500_sdi2_data = {
#ifdef CONFIG_STE_DMA40 #ifdef CONFIG_STE_DMA40
struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = { struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV42_SD_MM4, .dev_type = DB8500_DMA_DEV42_SD_MM4,
}; };
static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = { static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV42_SD_MM4, .dev_type = DB8500_DMA_DEV42_SD_MM4,
}; };
#endif #endif
......
...@@ -424,19 +424,19 @@ void mop500_snowball_ethernet_clock_enable(void) ...@@ -424,19 +424,19 @@ void mop500_snowball_ethernet_clock_enable(void)
static struct cryp_platform_data u8500_cryp1_platform_data = { static struct cryp_platform_data u8500_cryp1_platform_data = {
.mem_to_engine = { .mem_to_engine = {
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV48_CAC1, .dev_type = DB8500_DMA_DEV48_CAC1,
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
}, },
.engine_to_mem = { .engine_to_mem = {
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV48_CAC1, .dev_type = DB8500_DMA_DEV48_CAC1,
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
} }
}; };
static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = { static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = {
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV50_HAC1_TX, .dev_type = DB8500_DMA_DEV50_HAC1_TX,
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
}; };
...@@ -455,13 +455,13 @@ static struct platform_device *mop500_platform_devs[] __initdata = { ...@@ -455,13 +455,13 @@ static struct platform_device *mop500_platform_devs[] __initdata = {
#ifdef CONFIG_STE_DMA40 #ifdef CONFIG_STE_DMA40
static struct stedma40_chan_cfg ssp0_dma_cfg_rx = { static struct stedma40_chan_cfg ssp0_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV8_SSP0, .dev_type = DB8500_DMA_DEV8_SSP0,
}; };
static struct stedma40_chan_cfg ssp0_dma_cfg_tx = { static struct stedma40_chan_cfg ssp0_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV8_SSP0, .dev_type = DB8500_DMA_DEV8_SSP0,
}; };
#endif #endif
...@@ -490,37 +490,37 @@ static void __init mop500_spi_init(struct device *parent) ...@@ -490,37 +490,37 @@ static void __init mop500_spi_init(struct device *parent)
#ifdef CONFIG_STE_DMA40 #ifdef CONFIG_STE_DMA40
static struct stedma40_chan_cfg uart0_dma_cfg_rx = { static struct stedma40_chan_cfg uart0_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV13_UART0, .dev_type = DB8500_DMA_DEV13_UART0,
}; };
static struct stedma40_chan_cfg uart0_dma_cfg_tx = { static struct stedma40_chan_cfg uart0_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV13_UART0, .dev_type = DB8500_DMA_DEV13_UART0,
}; };
static struct stedma40_chan_cfg uart1_dma_cfg_rx = { static struct stedma40_chan_cfg uart1_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV12_UART1, .dev_type = DB8500_DMA_DEV12_UART1,
}; };
static struct stedma40_chan_cfg uart1_dma_cfg_tx = { static struct stedma40_chan_cfg uart1_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV12_UART1, .dev_type = DB8500_DMA_DEV12_UART1,
}; };
static struct stedma40_chan_cfg uart2_dma_cfg_rx = { static struct stedma40_chan_cfg uart2_dma_cfg_rx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_PERIPH_TO_MEM, .dir = DMA_DEV_TO_MEM,
.dev_type = DB8500_DMA_DEV11_UART2, .dev_type = DB8500_DMA_DEV11_UART2,
}; };
static struct stedma40_chan_cfg uart2_dma_cfg_tx = { static struct stedma40_chan_cfg uart2_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL, .mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH, .dir = DMA_MEM_TO_DEV,
.dev_type = DB8500_DMA_DEV11_UART2, .dev_type = DB8500_DMA_DEV11_UART2,
}; };
#endif #endif
......
...@@ -215,17 +215,6 @@ struct device * __init u8500_init_devices(void) ...@@ -215,17 +215,6 @@ struct device * __init u8500_init_devices(void)
} }
#ifdef CONFIG_MACH_UX500_DT #ifdef CONFIG_MACH_UX500_DT
/* TODO: Once all pieces are DT:ed, remove completely. */
static struct device * __init u8500_of_init_devices(void)
{
struct device *parent = db8500_soc_device_init();
db8500_add_usb(parent, usb_db8500_dma_cfg, usb_db8500_dma_cfg);
return parent;
}
static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
/* Requires call-back bindings. */ /* Requires call-back bindings. */
OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata), 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,8 +258,7 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000, OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000,
"ux500-msp-i2s.3", &msp3_platform_data), "ux500-msp-i2s.3", &msp3_platform_data),
/* Requires clock name bindings and channel address lookup table. */ /* Requires clock name bindings and channel address lookup table. */
OF_DEV_AUXDATA("stericsson,db8500-dma40", 0x801C0000, OF_DEV_AUXDATA("stericsson,db8500-dma40", 0x801C0000, "dma40.0", NULL),
"dma40.0", &dma40_plat_data),
{}, {},
}; };
...@@ -284,7 +272,7 @@ static const struct of_device_id u8500_local_bus_nodes[] = { ...@@ -284,7 +272,7 @@ static const struct of_device_id u8500_local_bus_nodes[] = {
static void __init u8500_init_machine(void) static void __init u8500_init_machine(void)
{ {
struct device *parent = NULL; struct device *parent = db8500_soc_device_init();
/* Pinmaps must be in place before devices register */ /* Pinmaps must be in place before devices register */
if (of_machine_is_compatible("st-ericsson,mop500")) if (of_machine_is_compatible("st-ericsson,mop500"))
...@@ -297,9 +285,6 @@ static void __init u8500_init_machine(void) ...@@ -297,9 +285,6 @@ static void __init u8500_init_machine(void)
else if (of_machine_is_compatible("st-ericsson,ccu9540")) {} else if (of_machine_is_compatible("st-ericsson,ccu9540")) {}
/* TODO: Add pinmaps for ccu9540 board. */ /* TODO: Add pinmaps for ccu9540 board. */
/* TODO: Export SoC, USB, cpu-freq and DMA40 */
parent = u8500_of_init_devices();
/* automatically probe child nodes of db8500 device */ /* automatically probe child nodes of db8500 device */
of_platform_populate(NULL, u8500_local_bus_nodes, u8500_auxdata_lookup, parent); of_platform_populate(NULL, u8500_local_bus_nodes, u8500_auxdata_lookup, parent);
} }
......
...@@ -14,15 +14,15 @@ ...@@ -14,15 +14,15 @@
#define MUSB_DMA40_RX_CH { \ #define MUSB_DMA40_RX_CH { \
.mode = STEDMA40_MODE_LOGICAL, \ .mode = STEDMA40_MODE_LOGICAL, \
.dir = STEDMA40_PERIPH_TO_MEM, \ .dir = DMA_DEV_TO_MEM, \
} }
#define MUSB_DMA40_TX_CH { \ #define MUSB_DMA40_TX_CH { \
.mode = STEDMA40_MODE_LOGICAL, \ .mode = STEDMA40_MODE_LOGICAL, \
.dir = STEDMA40_MEM_TO_PERIPH, \ .dir = DMA_MEM_TO_DEV, \
} }
static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS] static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]
= { = {
MUSB_DMA40_RX_CH, MUSB_DMA40_RX_CH,
MUSB_DMA40_RX_CH, MUSB_DMA40_RX_CH,
...@@ -34,7 +34,7 @@ static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS] ...@@ -34,7 +34,7 @@ static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS]
MUSB_DMA40_RX_CH MUSB_DMA40_RX_CH
}; };
static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS] static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]
= { = {
MUSB_DMA40_TX_CH, MUSB_DMA40_TX_CH,
MUSB_DMA40_TX_CH, MUSB_DMA40_TX_CH,
...@@ -46,7 +46,7 @@ static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS] ...@@ -46,7 +46,7 @@ static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS]
MUSB_DMA40_TX_CH, MUSB_DMA40_TX_CH,
}; };
static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = { static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = {
&musb_dma_rx_ch[0], &musb_dma_rx_ch[0],
&musb_dma_rx_ch[1], &musb_dma_rx_ch[1],
&musb_dma_rx_ch[2], &musb_dma_rx_ch[2],
...@@ -57,7 +57,7 @@ static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = { ...@@ -57,7 +57,7 @@ static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = {
&musb_dma_rx_ch[7] &musb_dma_rx_ch[7]
}; };
static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = { static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = {
&musb_dma_tx_ch[0], &musb_dma_tx_ch[0],
&musb_dma_tx_ch[1], &musb_dma_tx_ch[1],
&musb_dma_tx_ch[2], &musb_dma_tx_ch[2],
...@@ -71,23 +71,11 @@ static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = { ...@@ -71,23 +71,11 @@ static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = {
static struct ux500_musb_board_data musb_board_data = { static struct ux500_musb_board_data musb_board_data = {
.dma_rx_param_array = ux500_dma_rx_param_array, .dma_rx_param_array = ux500_dma_rx_param_array,
.dma_tx_param_array = ux500_dma_tx_param_array, .dma_tx_param_array = ux500_dma_tx_param_array,
.num_rx_channels = UX500_MUSB_DMA_NUM_RX_CHANNELS,
.num_tx_channels = UX500_MUSB_DMA_NUM_TX_CHANNELS,
.dma_filter = stedma40_filter, .dma_filter = stedma40_filter,
}; };
static u64 ux500_musb_dmamask = DMA_BIT_MASK(32);
static struct musb_hdrc_config musb_hdrc_config = {
.multipoint = true,
.dyn_fifo = true,
.num_eps = 16,
.ram_bits = 16,
};
static struct musb_hdrc_platform_data musb_platform_data = { static struct musb_hdrc_platform_data musb_platform_data = {
.mode = MUSB_OTG, .mode = MUSB_OTG,
.config = &musb_hdrc_config,
.board_data = &musb_board_data, .board_data = &musb_board_data,
}; };
...@@ -108,7 +96,6 @@ struct platform_device ux500_musb_device = { ...@@ -108,7 +96,6 @@ struct platform_device ux500_musb_device = {
.id = 0, .id = 0,
.dev = { .dev = {
.platform_data = &musb_platform_data, .platform_data = &musb_platform_data,
.dma_mask = &ux500_musb_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32), .coherent_dma_mask = DMA_BIT_MASK(32),
}, },
.num_resources = ARRAY_SIZE(usb_resources), .num_resources = ARRAY_SIZE(usb_resources),
...@@ -119,7 +106,7 @@ static inline void ux500_usb_dma_update_rx_ch_config(int *dev_type) ...@@ -119,7 +106,7 @@ static inline void ux500_usb_dma_update_rx_ch_config(int *dev_type)
{ {
u32 idx; u32 idx;
for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_CHANNELS; idx++) for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++)
musb_dma_rx_ch[idx].dev_type = dev_type[idx]; musb_dma_rx_ch[idx].dev_type = dev_type[idx];
} }
...@@ -127,7 +114,7 @@ static inline void ux500_usb_dma_update_tx_ch_config(int *dev_type) ...@@ -127,7 +114,7 @@ static inline void ux500_usb_dma_update_tx_ch_config(int *dev_type)
{ {
u32 idx; u32 idx;
for (idx = 0; idx < UX500_MUSB_DMA_NUM_TX_CHANNELS; idx++) for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++)
musb_dma_tx_ch[idx].dev_type = dev_type[idx]; musb_dma_tx_ch[idx].dev_type = dev_type[idx];
} }
......
This diff is collapsed.
...@@ -10,6 +10,18 @@ ...@@ -10,6 +10,18 @@
#include "ste_dma40_ll.h" #include "ste_dma40_ll.h"
u8 d40_width_to_bits(enum dma_slave_buswidth width)
{
if (width == DMA_SLAVE_BUSWIDTH_1_BYTE)
return STEDMA40_ESIZE_8_BIT;
else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES)
return STEDMA40_ESIZE_16_BIT;
else if (width == DMA_SLAVE_BUSWIDTH_8_BYTES)
return STEDMA40_ESIZE_64_BIT;
else
return STEDMA40_ESIZE_32_BIT;
}
/* Sets up proper LCSP1 and LCSP3 register for a logical channel */ /* Sets up proper LCSP1 and LCSP3 register for a logical channel */
void d40_log_cfg(struct stedma40_chan_cfg *cfg, void d40_log_cfg(struct stedma40_chan_cfg *cfg,
u32 *lcsp1, u32 *lcsp3) u32 *lcsp1, u32 *lcsp3)
...@@ -18,32 +30,34 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg, ...@@ -18,32 +30,34 @@ void d40_log_cfg(struct stedma40_chan_cfg *cfg,
u32 l1 = 0; /* src */ u32 l1 = 0; /* src */
/* src is mem? -> increase address pos */ /* src is mem? -> increase address pos */
if (cfg->dir == STEDMA40_MEM_TO_PERIPH || if (cfg->dir == DMA_MEM_TO_DEV ||
cfg->dir == STEDMA40_MEM_TO_MEM) cfg->dir == DMA_MEM_TO_MEM)
l1 |= 1 << D40_MEM_LCSP1_SCFG_INCR_POS; l1 |= BIT(D40_MEM_LCSP1_SCFG_INCR_POS);
/* dst is mem? -> increase address pos */ /* dst is mem? -> increase address pos */
if (cfg->dir == STEDMA40_PERIPH_TO_MEM || if (cfg->dir == DMA_DEV_TO_MEM ||
cfg->dir == STEDMA40_MEM_TO_MEM) cfg->dir == DMA_MEM_TO_MEM)
l3 |= 1 << D40_MEM_LCSP3_DCFG_INCR_POS; l3 |= BIT(D40_MEM_LCSP3_DCFG_INCR_POS);
/* src is hw? -> master port 1 */ /* src is hw? -> master port 1 */
if (cfg->dir == STEDMA40_PERIPH_TO_MEM || if (cfg->dir == DMA_DEV_TO_MEM ||
cfg->dir == STEDMA40_PERIPH_TO_PERIPH) cfg->dir == DMA_DEV_TO_DEV)
l1 |= 1 << D40_MEM_LCSP1_SCFG_MST_POS; l1 |= BIT(D40_MEM_LCSP1_SCFG_MST_POS);
/* dst is hw? -> master port 1 */ /* dst is hw? -> master port 1 */
if (cfg->dir == STEDMA40_MEM_TO_PERIPH || if (cfg->dir == DMA_MEM_TO_DEV ||
cfg->dir == STEDMA40_PERIPH_TO_PERIPH) cfg->dir == DMA_DEV_TO_DEV)
l3 |= 1 << D40_MEM_LCSP3_DCFG_MST_POS; l3 |= BIT(D40_MEM_LCSP3_DCFG_MST_POS);
l3 |= 1 << D40_MEM_LCSP3_DCFG_EIM_POS; l3 |= BIT(D40_MEM_LCSP3_DCFG_EIM_POS);
l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS; l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS;
l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS; l3 |= d40_width_to_bits(cfg->dst_info.data_width)
<< D40_MEM_LCSP3_DCFG_ESIZE_POS;
l1 |= 1 << D40_MEM_LCSP1_SCFG_EIM_POS; l1 |= BIT(D40_MEM_LCSP1_SCFG_EIM_POS);
l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS;
l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS; l1 |= d40_width_to_bits(cfg->src_info.data_width)
<< D40_MEM_LCSP1_SCFG_ESIZE_POS;
*lcsp1 = l1; *lcsp1 = l1;
*lcsp3 = l3; *lcsp3 = l3;
...@@ -55,59 +69,61 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg) ...@@ -55,59 +69,61 @@ void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg)
u32 src = 0; u32 src = 0;
u32 dst = 0; u32 dst = 0;
if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) || if ((cfg->dir == DMA_DEV_TO_MEM) ||
(cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { (cfg->dir == DMA_DEV_TO_DEV)) {
/* Set master port to 1 */ /* Set master port to 1 */
src |= 1 << D40_SREG_CFG_MST_POS; src |= BIT(D40_SREG_CFG_MST_POS);
src |= D40_TYPE_TO_EVENT(cfg->dev_type); src |= D40_TYPE_TO_EVENT(cfg->dev_type);
if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
src |= 1 << D40_SREG_CFG_PHY_TM_POS; src |= BIT(D40_SREG_CFG_PHY_TM_POS);
else else
src |= 3 << D40_SREG_CFG_PHY_TM_POS; src |= 3 << D40_SREG_CFG_PHY_TM_POS;
} }
if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) || if ((cfg->dir == DMA_MEM_TO_DEV) ||
(cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { (cfg->dir == DMA_DEV_TO_DEV)) {
/* Set master port to 1 */ /* Set master port to 1 */
dst |= 1 << D40_SREG_CFG_MST_POS; dst |= BIT(D40_SREG_CFG_MST_POS);
dst |= D40_TYPE_TO_EVENT(cfg->dev_type); dst |= D40_TYPE_TO_EVENT(cfg->dev_type);
if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
dst |= 1 << D40_SREG_CFG_PHY_TM_POS; dst |= BIT(D40_SREG_CFG_PHY_TM_POS);
else else
dst |= 3 << D40_SREG_CFG_PHY_TM_POS; dst |= 3 << D40_SREG_CFG_PHY_TM_POS;
} }
/* Interrupt on end of transfer for destination */ /* Interrupt on end of transfer for destination */
dst |= 1 << D40_SREG_CFG_TIM_POS; dst |= BIT(D40_SREG_CFG_TIM_POS);
/* Generate interrupt on error */ /* Generate interrupt on error */
src |= 1 << D40_SREG_CFG_EIM_POS; src |= BIT(D40_SREG_CFG_EIM_POS);
dst |= 1 << D40_SREG_CFG_EIM_POS; dst |= BIT(D40_SREG_CFG_EIM_POS);
/* PSIZE */ /* PSIZE */
if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) {
src |= 1 << D40_SREG_CFG_PHY_PEN_POS; src |= BIT(D40_SREG_CFG_PHY_PEN_POS);
src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS; src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS;
} }
if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) { if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) {
dst |= 1 << D40_SREG_CFG_PHY_PEN_POS; dst |= BIT(D40_SREG_CFG_PHY_PEN_POS);
dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS;
} }
/* Element size */ /* Element size */
src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; src |= d40_width_to_bits(cfg->src_info.data_width)
dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; << D40_SREG_CFG_ESIZE_POS;
dst |= d40_width_to_bits(cfg->dst_info.data_width)
<< D40_SREG_CFG_ESIZE_POS;
/* Set the priority bit to high for the physical channel */ /* Set the priority bit to high for the physical channel */
if (cfg->high_priority) { if (cfg->high_priority) {
src |= 1 << D40_SREG_CFG_PRI_POS; src |= BIT(D40_SREG_CFG_PRI_POS);
dst |= 1 << D40_SREG_CFG_PRI_POS; dst |= BIT(D40_SREG_CFG_PRI_POS);
} }
if (cfg->src_info.big_endian) if (cfg->src_info.big_endian)
src |= 1 << D40_SREG_CFG_LBE_POS; src |= BIT(D40_SREG_CFG_LBE_POS);
if (cfg->dst_info.big_endian) if (cfg->dst_info.big_endian)
dst |= 1 << D40_SREG_CFG_LBE_POS; dst |= BIT(D40_SREG_CFG_LBE_POS);
*src_cfg = src; *src_cfg = src;
*dst_cfg = dst; *dst_cfg = dst;
...@@ -133,23 +149,22 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, ...@@ -133,23 +149,22 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli,
num_elems = 2 << psize; num_elems = 2 << psize;
/* Must be aligned */ /* Must be aligned */
if (!IS_ALIGNED(data, 0x1 << data_width)) if (!IS_ALIGNED(data, data_width))
return -EINVAL; return -EINVAL;
/* Transfer size can't be smaller than (num_elms * elem_size) */ /* Transfer size can't be smaller than (num_elms * elem_size) */
if (data_size < num_elems * (0x1 << data_width)) if (data_size < num_elems * data_width)
return -EINVAL; return -EINVAL;
/* The number of elements. IE now many chunks */ /* The number of elements. IE now many chunks */
lli->reg_elt = (data_size >> data_width) << D40_SREG_ELEM_PHY_ECNT_POS; lli->reg_elt = (data_size / data_width) << D40_SREG_ELEM_PHY_ECNT_POS;
/* /*
* Distance to next element sized entry. * Distance to next element sized entry.
* Usually the size of the element unless you want gaps. * Usually the size of the element unless you want gaps.
*/ */
if (addr_inc) if (addr_inc)
lli->reg_elt |= (0x1 << data_width) << lli->reg_elt |= data_width << D40_SREG_ELEM_PHY_EIDX_POS;
D40_SREG_ELEM_PHY_EIDX_POS;
/* Where the data is */ /* Where the data is */
lli->reg_ptr = data; lli->reg_ptr = data;
...@@ -157,18 +172,20 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli, ...@@ -157,18 +172,20 @@ static int d40_phy_fill_lli(struct d40_phy_lli *lli,
/* If this scatter list entry is the last one, no next link */ /* If this scatter list entry is the last one, no next link */
if (next_lli == 0) if (next_lli == 0)
lli->reg_lnk = 0x1 << D40_SREG_LNK_PHY_TCP_POS; lli->reg_lnk = BIT(D40_SREG_LNK_PHY_TCP_POS);
else else
lli->reg_lnk = next_lli; lli->reg_lnk = next_lli;
/* Set/clear interrupt generation on this link item.*/ /* Set/clear interrupt generation on this link item.*/
if (term_int) if (term_int)
lli->reg_cfg |= 0x1 << D40_SREG_CFG_TIM_POS; lli->reg_cfg |= BIT(D40_SREG_CFG_TIM_POS);
else else
lli->reg_cfg &= ~(0x1 << D40_SREG_CFG_TIM_POS); lli->reg_cfg &= ~BIT(D40_SREG_CFG_TIM_POS);
/* Post link */ /*
lli->reg_lnk |= 0 << D40_SREG_LNK_PHY_PRE_POS; * Post link - D40_SREG_LNK_PHY_PRE_POS = 0
* Relink happens after transfer completion.
*/
return 0; return 0;
} }
...@@ -177,16 +194,16 @@ static int d40_seg_size(int size, int data_width1, int data_width2) ...@@ -177,16 +194,16 @@ static int d40_seg_size(int size, int data_width1, int data_width2)
{ {
u32 max_w = max(data_width1, data_width2); u32 max_w = max(data_width1, data_width2);
u32 min_w = min(data_width1, data_width2); u32 min_w = min(data_width1, data_width2);
u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w); u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE * min_w, max_w);
if (seg_max > STEDMA40_MAX_SEG_SIZE) if (seg_max > STEDMA40_MAX_SEG_SIZE)
seg_max -= (1 << max_w); seg_max -= max_w;
if (size <= seg_max) if (size <= seg_max)
return size; return size;
if (size <= 2 * seg_max) if (size <= 2 * seg_max)
return ALIGN(size / 2, 1 << max_w); return ALIGN(size / 2, max_w);
return seg_max; return seg_max;
} }
...@@ -352,10 +369,10 @@ static void d40_log_fill_lli(struct d40_log_lli *lli, ...@@ -352,10 +369,10 @@ static void d40_log_fill_lli(struct d40_log_lli *lli,
lli->lcsp13 = reg_cfg; lli->lcsp13 = reg_cfg;
/* The number of elements to transfer */ /* The number of elements to transfer */
lli->lcsp02 = ((data_size >> data_width) << lli->lcsp02 = ((data_size / data_width) <<
D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK; D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK;
BUG_ON((data_size >> data_width) > STEDMA40_MAX_SEG_SIZE); BUG_ON((data_size / data_width) > STEDMA40_MAX_SEG_SIZE);
/* 16 LSBs address of the current element */ /* 16 LSBs address of the current element */
lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK; lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK;
......
...@@ -25,11 +25,19 @@ ...@@ -25,11 +25,19 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/usb/musb-ux500.h> #include <linux/usb/musb-ux500.h>
#include "musb_core.h" #include "musb_core.h"
static struct musb_hdrc_config ux500_musb_hdrc_config = {
.multipoint = true,
.dyn_fifo = true,
.num_eps = 16,
.ram_bits = 16,
};
struct ux500_glue { struct ux500_glue {
struct device *dev; struct device *dev;
struct platform_device *musb; struct platform_device *musb;
...@@ -187,14 +195,57 @@ static const struct musb_platform_ops ux500_ops = { ...@@ -187,14 +195,57 @@ static const struct musb_platform_ops ux500_ops = {
.set_vbus = ux500_musb_set_vbus, .set_vbus = ux500_musb_set_vbus,
}; };
static struct musb_hdrc_platform_data *
ux500_of_probe(struct platform_device *pdev, struct device_node *np)
{
struct musb_hdrc_platform_data *pdata;
const char *mode;
int strlen;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return NULL;
mode = of_get_property(np, "dr_mode", &strlen);
if (!mode) {
dev_err(&pdev->dev, "No 'dr_mode' property found\n");
return NULL;
}
if (strlen > 0) {
if (!strcmp(mode, "host"))
pdata->mode = MUSB_HOST;
if (!strcmp(mode, "otg"))
pdata->mode = MUSB_OTG;
if (!strcmp(mode, "peripheral"))
pdata->mode = MUSB_PERIPHERAL;
}
return pdata;
}
static int ux500_probe(struct platform_device *pdev) static int ux500_probe(struct platform_device *pdev)
{ {
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
struct device_node *np = pdev->dev.of_node;
struct platform_device *musb; struct platform_device *musb;
struct ux500_glue *glue; struct ux500_glue *glue;
struct clk *clk; struct clk *clk;
int ret = -ENOMEM; int ret = -ENOMEM;
if (!pdata) {
if (np) {
pdata = ux500_of_probe(pdev, np);
if (!pdata)
goto err0;
pdev->dev.platform_data = pdata;
} else {
dev_err(&pdev->dev, "no pdata or device tree found\n");
goto err0;
}
}
glue = kzalloc(sizeof(*glue), GFP_KERNEL); glue = kzalloc(sizeof(*glue), GFP_KERNEL);
if (!glue) { if (!glue) {
dev_err(&pdev->dev, "failed to allocate glue context\n"); dev_err(&pdev->dev, "failed to allocate glue context\n");
...@@ -221,14 +272,16 @@ static int ux500_probe(struct platform_device *pdev) ...@@ -221,14 +272,16 @@ static int ux500_probe(struct platform_device *pdev)
} }
musb->dev.parent = &pdev->dev; musb->dev.parent = &pdev->dev;
musb->dev.dma_mask = pdev->dev.dma_mask; musb->dev.dma_mask = &pdev->dev.coherent_dma_mask;
musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
musb->dev.of_node = pdev->dev.of_node;
glue->dev = &pdev->dev; glue->dev = &pdev->dev;
glue->musb = musb; glue->musb = musb;
glue->clk = clk; glue->clk = clk;
pdata->platform_ops = &ux500_ops; pdata->platform_ops = &ux500_ops;
pdata->config = &ux500_musb_hdrc_config;
platform_set_drvdata(pdev, glue); platform_set_drvdata(pdev, glue);
...@@ -320,12 +373,18 @@ static const struct dev_pm_ops ux500_pm_ops = { ...@@ -320,12 +373,18 @@ static const struct dev_pm_ops ux500_pm_ops = {
#define DEV_PM_OPS NULL #define DEV_PM_OPS NULL
#endif #endif
static const struct of_device_id ux500_match[] = {
{ .compatible = "stericsson,db8500-musb", },
{}
};
static struct platform_driver ux500_driver = { static struct platform_driver ux500_driver = {
.probe = ux500_probe, .probe = ux500_probe,
.remove = ux500_remove, .remove = ux500_remove,
.driver = { .driver = {
.name = "musb-ux500", .name = "musb-ux500",
.pm = DEV_PM_OPS, .pm = DEV_PM_OPS,
.of_match_table = ux500_match,
}, },
}; };
......
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
#include <linux/platform_data/usb-musb-ux500.h> #include <linux/platform_data/usb-musb-ux500.h>
#include "musb_core.h" #include "musb_core.h"
static const char *iep_chan_names[] = { "iep_1_9", "iep_2_10", "iep_3_11", "iep_4_12",
"iep_5_13", "iep_6_14", "iep_7_15", "iep_8" };
static const char *oep_chan_names[] = { "oep_1_9", "oep_2_10", "oep_3_11", "oep_4_12",
"oep_5_13", "oep_6_14", "oep_7_15", "oep_8" };
struct ux500_dma_channel { struct ux500_dma_channel {
struct dma_channel channel; struct dma_channel channel;
struct ux500_dma_controller *controller; struct ux500_dma_controller *controller;
...@@ -48,10 +53,8 @@ struct ux500_dma_channel { ...@@ -48,10 +53,8 @@ struct ux500_dma_channel {
struct ux500_dma_controller { struct ux500_dma_controller {
struct dma_controller controller; struct dma_controller controller;
struct ux500_dma_channel rx_channel[UX500_MUSB_DMA_NUM_RX_CHANNELS]; struct ux500_dma_channel rx_channel[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS];
struct ux500_dma_channel tx_channel[UX500_MUSB_DMA_NUM_TX_CHANNELS]; struct ux500_dma_channel tx_channel[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS];
u32 num_rx_channels;
u32 num_tx_channels;
void *private_data; void *private_data;
dma_addr_t phy_base; dma_addr_t phy_base;
}; };
...@@ -144,19 +147,15 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c, ...@@ -144,19 +147,15 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c,
struct ux500_dma_channel *ux500_channel = NULL; struct ux500_dma_channel *ux500_channel = NULL;
struct musb *musb = controller->private_data; struct musb *musb = controller->private_data;
u8 ch_num = hw_ep->epnum - 1; u8 ch_num = hw_ep->epnum - 1;
u32 max_ch;
/* Max 8 DMA channels (0 - 7). Each DMA channel can only be allocated /* 8 DMA channels (0 - 7). Each DMA channel can only be allocated
* to specified hw_ep. For example DMA channel 0 can only be allocated * to specified hw_ep. For example DMA channel 0 can only be allocated
* to hw_ep 1 and 9. * to hw_ep 1 and 9.
*/ */
if (ch_num > 7) if (ch_num > 7)
ch_num -= 8; ch_num -= 8;
max_ch = is_tx ? controller->num_tx_channels : if (ch_num >= UX500_MUSB_DMA_NUM_RX_TX_CHANNELS)
controller->num_rx_channels;
if (ch_num >= max_ch)
return NULL; return NULL;
ux500_channel = is_tx ? &(controller->tx_channel[ch_num]) : ux500_channel = is_tx ? &(controller->tx_channel[ch_num]) :
...@@ -264,7 +263,7 @@ static int ux500_dma_controller_stop(struct dma_controller *c) ...@@ -264,7 +263,7 @@ static int ux500_dma_controller_stop(struct dma_controller *c)
struct dma_channel *channel; struct dma_channel *channel;
u8 ch_num; u8 ch_num;
for (ch_num = 0; ch_num < controller->num_rx_channels; ch_num++) { for (ch_num = 0; ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; ch_num++) {
channel = &controller->rx_channel[ch_num].channel; channel = &controller->rx_channel[ch_num].channel;
ux500_channel = channel->private_data; ux500_channel = channel->private_data;
...@@ -274,7 +273,7 @@ static int ux500_dma_controller_stop(struct dma_controller *c) ...@@ -274,7 +273,7 @@ static int ux500_dma_controller_stop(struct dma_controller *c)
dma_release_channel(ux500_channel->dma_chan); dma_release_channel(ux500_channel->dma_chan);
} }
for (ch_num = 0; ch_num < controller->num_tx_channels; ch_num++) { for (ch_num = 0; ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; ch_num++) {
channel = &controller->tx_channel[ch_num].channel; channel = &controller->tx_channel[ch_num].channel;
ux500_channel = channel->private_data; ux500_channel = channel->private_data;
...@@ -295,34 +294,36 @@ static int ux500_dma_controller_start(struct dma_controller *c) ...@@ -295,34 +294,36 @@ static int ux500_dma_controller_start(struct dma_controller *c)
struct musb *musb = controller->private_data; struct musb *musb = controller->private_data;
struct device *dev = musb->controller; struct device *dev = musb->controller;
struct musb_hdrc_platform_data *plat = dev->platform_data; struct musb_hdrc_platform_data *plat = dev->platform_data;
struct ux500_musb_board_data *data = plat->board_data; struct ux500_musb_board_data *data;
struct dma_channel *dma_channel = NULL; struct dma_channel *dma_channel = NULL;
char **chan_names;
u32 ch_num; u32 ch_num;
u8 dir; u8 dir;
u8 is_tx = 0; u8 is_tx = 0;
void **param_array; void **param_array;
struct ux500_dma_channel *channel_array; struct ux500_dma_channel *channel_array;
u32 ch_count;
dma_cap_mask_t mask; dma_cap_mask_t mask;
if ((data->num_rx_channels > UX500_MUSB_DMA_NUM_RX_CHANNELS) || if (!plat) {
(data->num_tx_channels > UX500_MUSB_DMA_NUM_TX_CHANNELS)) dev_err(musb->controller, "No platform data\n");
return -EINVAL; return -EINVAL;
}
controller->num_rx_channels = data->num_rx_channels; data = plat->board_data;
controller->num_tx_channels = data->num_tx_channels;
dma_cap_zero(mask); dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask); dma_cap_set(DMA_SLAVE, mask);
/* Prepare the loop for RX channels */ /* Prepare the loop for RX channels */
channel_array = controller->rx_channel; channel_array = controller->rx_channel;
ch_count = data->num_rx_channels; param_array = data ? data->dma_rx_param_array : NULL;
param_array = data->dma_rx_param_array; chan_names = (char **)iep_chan_names;
for (dir = 0; dir < 2; dir++) { for (dir = 0; dir < 2; dir++) {
for (ch_num = 0; ch_num < ch_count; ch_num++) { for (ch_num = 0;
ch_num < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS;
ch_num++) {
ux500_channel = &channel_array[ch_num]; ux500_channel = &channel_array[ch_num];
ux500_channel->controller = controller; ux500_channel->controller = controller;
ux500_channel->ch_num = ch_num; ux500_channel->ch_num = ch_num;
...@@ -333,9 +334,15 @@ static int ux500_dma_controller_start(struct dma_controller *c) ...@@ -333,9 +334,15 @@ static int ux500_dma_controller_start(struct dma_controller *c)
dma_channel->status = MUSB_DMA_STATUS_FREE; dma_channel->status = MUSB_DMA_STATUS_FREE;
dma_channel->max_len = SZ_16M; dma_channel->max_len = SZ_16M;
ux500_channel->dma_chan = dma_request_channel(mask, ux500_channel->dma_chan =
data->dma_filter, dma_request_slave_channel(dev, chan_names[ch_num]);
param_array[ch_num]);
if (!ux500_channel->dma_chan)
ux500_channel->dma_chan =
dma_request_channel(mask,
data->dma_filter,
param_array[ch_num]);
if (!ux500_channel->dma_chan) { if (!ux500_channel->dma_chan) {
ERR("Dma pipe allocation error dir=%d ch=%d\n", ERR("Dma pipe allocation error dir=%d ch=%d\n",
dir, ch_num); dir, ch_num);
...@@ -350,8 +357,8 @@ static int ux500_dma_controller_start(struct dma_controller *c) ...@@ -350,8 +357,8 @@ static int ux500_dma_controller_start(struct dma_controller *c)
/* Prepare the loop for TX channels */ /* Prepare the loop for TX channels */
channel_array = controller->tx_channel; channel_array = controller->tx_channel;
ch_count = data->num_tx_channels; param_array = data ? data->dma_tx_param_array : NULL;
param_array = data->dma_tx_param_array; chan_names = (char **)oep_chan_names;
is_tx = 1; is_tx = 1;
} }
......
...@@ -70,21 +70,6 @@ enum stedma40_flow_ctrl { ...@@ -70,21 +70,6 @@ enum stedma40_flow_ctrl {
STEDMA40_FLOW_CTRL, STEDMA40_FLOW_CTRL,
}; };
enum stedma40_periph_data_width {
STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT,
STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT,
STEDMA40_WORD_WIDTH = STEDMA40_ESIZE_32_BIT,
STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT
};
enum stedma40_xfer_dir {
STEDMA40_MEM_TO_MEM = 1,
STEDMA40_MEM_TO_PERIPH,
STEDMA40_PERIPH_TO_MEM,
STEDMA40_PERIPH_TO_PERIPH
};
/** /**
* struct stedma40_half_channel_info - dst/src channel configuration * struct stedma40_half_channel_info - dst/src channel configuration
* *
...@@ -95,7 +80,7 @@ enum stedma40_xfer_dir { ...@@ -95,7 +80,7 @@ enum stedma40_xfer_dir {
*/ */
struct stedma40_half_channel_info { struct stedma40_half_channel_info {
bool big_endian; bool big_endian;
enum stedma40_periph_data_width data_width; enum dma_slave_buswidth data_width;
int psize; int psize;
enum stedma40_flow_ctrl flow_ctrl; enum stedma40_flow_ctrl flow_ctrl;
}; };
...@@ -120,7 +105,7 @@ struct stedma40_half_channel_info { ...@@ -120,7 +105,7 @@ struct stedma40_half_channel_info {
* *
*/ */
struct stedma40_chan_cfg { struct stedma40_chan_cfg {
enum stedma40_xfer_dir dir; enum dma_transfer_direction dir;
bool high_priority; bool high_priority;
bool realtime; bool realtime;
enum stedma40_mode mode; enum stedma40_mode mode;
...@@ -147,6 +132,7 @@ struct stedma40_chan_cfg { ...@@ -147,6 +132,7 @@ struct stedma40_chan_cfg {
* @num_of_soft_lli_chans: The number of channels that needs to be configured * @num_of_soft_lli_chans: The number of channels that needs to be configured
* to use SoftLLI. * to use SoftLLI.
* @use_esram_lcla: flag for mapping the lcla into esram region * @use_esram_lcla: flag for mapping the lcla into esram region
* @num_of_memcpy_chans: The number of channels reserved for memcpy.
* @num_of_phy_chans: The number of physical channels implemented in HW. * @num_of_phy_chans: The number of physical channels implemented in HW.
* 0 means reading the number of channels from DMA HW but this is only valid * 0 means reading the number of channels from DMA HW but this is only valid
* for 'multiple of 4' channels, like 8. * for 'multiple of 4' channels, like 8.
...@@ -156,6 +142,7 @@ struct stedma40_platform_data { ...@@ -156,6 +142,7 @@ struct stedma40_platform_data {
int *soft_lli_chans; int *soft_lli_chans;
int num_of_soft_lli_chans; int num_of_soft_lli_chans;
bool use_esram_lcla; bool use_esram_lcla;
int num_of_memcpy_chans;
int num_of_phy_chans; int num_of_phy_chans;
}; };
......
...@@ -9,14 +9,11 @@ ...@@ -9,14 +9,11 @@
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#define UX500_MUSB_DMA_NUM_RX_CHANNELS 8 #define UX500_MUSB_DMA_NUM_RX_TX_CHANNELS 8
#define UX500_MUSB_DMA_NUM_TX_CHANNELS 8
struct ux500_musb_board_data { struct ux500_musb_board_data {
void **dma_rx_param_array; void **dma_rx_param_array;
void **dma_tx_param_array; void **dma_tx_param_array;
u32 num_rx_channels;
u32 num_tx_channels;
bool (*dma_filter)(struct dma_chan *chan, void *filter_param); bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
}; };
......
...@@ -76,20 +76,20 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd, ...@@ -76,20 +76,20 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
dma_params = snd_soc_dai_get_dma_data(dai, substream); dma_params = snd_soc_dai_get_dma_data(dai, substream);
dma_cfg = dma_params->dma_cfg; dma_cfg = dma_params->dma_cfg;
mem_data_width = STEDMA40_HALFWORD_WIDTH; mem_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
switch (dma_params->data_size) { switch (dma_params->data_size) {
case 32: case 32:
per_data_width = STEDMA40_WORD_WIDTH; per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
break; break;
case 16: case 16:
per_data_width = STEDMA40_HALFWORD_WIDTH; per_data_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
break; break;
case 8: case 8:
per_data_width = STEDMA40_BYTE_WIDTH; per_data_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
break; break;
default: default:
per_data_width = STEDMA40_WORD_WIDTH; per_data_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
} }
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment