forked from Minki/linux
Merge branch 'topic/dw' into for-linus
This commit is contained in:
commit
56214883c5
@ -13,6 +13,11 @@ Required properties:
|
||||
- chan_priority: priority of channels. 0 (default): increase from chan 0->n, 1:
|
||||
increase from chan n->0
|
||||
- block_size: Maximum block size supported by the controller
|
||||
- data-width: Maximum data width supported by hardware per AHB master
|
||||
(in bytes, power of 2)
|
||||
|
||||
|
||||
Deprecated properties:
|
||||
- data_width: Maximum data width supported by hardware per AHB master
|
||||
(0 - 8bits, 1 - 16bits, ..., 5 - 256bits)
|
||||
|
||||
@ -38,7 +43,7 @@ Example:
|
||||
chan_allocation_order = <1>;
|
||||
chan_priority = <1>;
|
||||
block_size = <0xfff>;
|
||||
data_width = <3 3>;
|
||||
data-width = <8 8>;
|
||||
};
|
||||
|
||||
DMA clients connected to the Designware DMA controller must use the format
|
||||
@ -47,8 +52,8 @@ The four cells in order are:
|
||||
|
||||
1. A phandle pointing to the DMA controller
|
||||
2. The DMA request line number
|
||||
3. Source master for transfers on allocated channel
|
||||
4. Destination master for transfers on allocated channel
|
||||
3. Memory master for transfers on allocated channel
|
||||
4. Peripheral master for transfers on allocated channel
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -112,7 +112,7 @@
|
||||
chan_allocation_order = <0>;
|
||||
chan_priority = <1>;
|
||||
block_size = <0x7ff>;
|
||||
data_width = <2>;
|
||||
data-width = <4>;
|
||||
clocks = <&ahb_clk>;
|
||||
clock-names = "hclk";
|
||||
};
|
||||
|
@ -117,7 +117,7 @@
|
||||
chan_priority = <1>;
|
||||
block_size = <0xfff>;
|
||||
dma-masters = <2>;
|
||||
data_width = <3 3>;
|
||||
data-width = <8 8>;
|
||||
};
|
||||
|
||||
dma@eb000000 {
|
||||
@ -133,7 +133,7 @@
|
||||
chan_allocation_order = <1>;
|
||||
chan_priority = <1>;
|
||||
block_size = <0xfff>;
|
||||
data_width = <3 3>;
|
||||
data-width = <8 8>;
|
||||
};
|
||||
|
||||
fsmc: flash@b0000000 {
|
||||
|
@ -1365,8 +1365,8 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
|
||||
slave->dma_dev = &dw_dmac0_device.dev;
|
||||
slave->src_id = 0;
|
||||
slave->dst_id = 1;
|
||||
slave->src_master = 1;
|
||||
slave->dst_master = 0;
|
||||
slave->m_master = 1;
|
||||
slave->p_master = 0;
|
||||
|
||||
data->dma_slave = slave;
|
||||
data->dma_filter = at32_mci_dma_filter;
|
||||
@ -2061,16 +2061,16 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
|
||||
if (flags & AC97C_CAPTURE) {
|
||||
rx_dws->dma_dev = &dw_dmac0_device.dev;
|
||||
rx_dws->src_id = 3;
|
||||
rx_dws->src_master = 0;
|
||||
rx_dws->dst_master = 1;
|
||||
rx_dws->m_master = 0;
|
||||
rx_dws->p_master = 1;
|
||||
}
|
||||
|
||||
/* Check if DMA slave interface for playback should be configured. */
|
||||
if (flags & AC97C_PLAYBACK) {
|
||||
tx_dws->dma_dev = &dw_dmac0_device.dev;
|
||||
tx_dws->dst_id = 4;
|
||||
tx_dws->src_master = 0;
|
||||
tx_dws->dst_master = 1;
|
||||
tx_dws->m_master = 0;
|
||||
tx_dws->p_master = 1;
|
||||
}
|
||||
|
||||
if (platform_device_add_data(pdev, data,
|
||||
@ -2141,8 +2141,8 @@ at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data)
|
||||
|
||||
dws->dma_dev = &dw_dmac0_device.dev;
|
||||
dws->dst_id = 2;
|
||||
dws->src_master = 0;
|
||||
dws->dst_master = 1;
|
||||
dws->m_master = 0;
|
||||
dws->p_master = 1;
|
||||
|
||||
if (platform_device_add_data(pdev, data,
|
||||
sizeof(struct atmel_abdac_pdata)))
|
||||
|
@ -201,8 +201,8 @@ static struct sata_dwc_host_priv host_pvt;
|
||||
static struct dw_dma_slave sata_dwc_dma_dws = {
|
||||
.src_id = 0,
|
||||
.dst_id = 0,
|
||||
.src_master = 0,
|
||||
.dst_master = 1,
|
||||
.m_master = 1,
|
||||
.p_master = 0,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1248,7 +1248,7 @@ static int sata_dwc_probe(struct platform_device *ofdev)
|
||||
hsdev->dma->dev = &ofdev->dev;
|
||||
|
||||
/* Initialize AHB DMAC */
|
||||
err = dw_dma_probe(hsdev->dma, NULL);
|
||||
err = dw_dma_probe(hsdev->dma);
|
||||
if (err)
|
||||
goto error_dma_iomap;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,8 +17,8 @@
|
||||
|
||||
static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
|
||||
{
|
||||
const struct dw_dma_platform_data *pdata = (void *)pid->driver_data;
|
||||
struct dw_dma_chip *chip;
|
||||
struct dw_dma_platform_data *pdata = (void *)pid->driver_data;
|
||||
int ret;
|
||||
|
||||
ret = pcim_enable_device(pdev);
|
||||
@ -49,8 +49,9 @@ static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
|
||||
chip->dev = &pdev->dev;
|
||||
chip->regs = pcim_iomap_table(pdev)[0];
|
||||
chip->irq = pdev->irq;
|
||||
chip->pdata = pdata;
|
||||
|
||||
ret = dw_dma_probe(chip, pdata);
|
||||
ret = dw_dma_probe(chip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -42,13 +42,13 @@ static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
|
||||
|
||||
slave.src_id = dma_spec->args[0];
|
||||
slave.dst_id = dma_spec->args[0];
|
||||
slave.src_master = dma_spec->args[1];
|
||||
slave.dst_master = dma_spec->args[2];
|
||||
slave.m_master = dma_spec->args[1];
|
||||
slave.p_master = dma_spec->args[2];
|
||||
|
||||
if (WARN_ON(slave.src_id >= DW_DMA_MAX_NR_REQUESTS ||
|
||||
slave.dst_id >= DW_DMA_MAX_NR_REQUESTS ||
|
||||
slave.src_master >= dw->nr_masters ||
|
||||
slave.dst_master >= dw->nr_masters))
|
||||
slave.m_master >= dw->pdata->nr_masters ||
|
||||
slave.p_master >= dw->pdata->nr_masters))
|
||||
return NULL;
|
||||
|
||||
dma_cap_zero(cap);
|
||||
@ -66,8 +66,8 @@ static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
|
||||
.dma_dev = dma_spec->dev,
|
||||
.src_id = dma_spec->slave_id,
|
||||
.dst_id = dma_spec->slave_id,
|
||||
.src_master = 1,
|
||||
.dst_master = 0,
|
||||
.m_master = 0,
|
||||
.p_master = 1,
|
||||
};
|
||||
|
||||
return dw_dma_filter(chan, &slave);
|
||||
@ -103,6 +103,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct dw_dma_platform_data *pdata;
|
||||
u32 tmp, arr[DW_DMA_MAX_NR_MASTERS];
|
||||
u32 nr_masters;
|
||||
u32 nr_channels;
|
||||
|
||||
if (!np) {
|
||||
@ -110,6 +111,11 @@ dw_dma_parse_dt(struct platform_device *pdev)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (of_property_read_u32(np, "dma-masters", &nr_masters))
|
||||
return NULL;
|
||||
if (nr_masters < 1 || nr_masters > DW_DMA_MAX_NR_MASTERS)
|
||||
return NULL;
|
||||
|
||||
if (of_property_read_u32(np, "dma-channels", &nr_channels))
|
||||
return NULL;
|
||||
|
||||
@ -117,6 +123,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
|
||||
if (!pdata)
|
||||
return NULL;
|
||||
|
||||
pdata->nr_masters = nr_masters;
|
||||
pdata->nr_channels = nr_channels;
|
||||
|
||||
if (of_property_read_bool(np, "is_private"))
|
||||
@ -131,17 +138,13 @@ dw_dma_parse_dt(struct platform_device *pdev)
|
||||
if (!of_property_read_u32(np, "block_size", &tmp))
|
||||
pdata->block_size = tmp;
|
||||
|
||||
if (!of_property_read_u32(np, "dma-masters", &tmp)) {
|
||||
if (tmp > DW_DMA_MAX_NR_MASTERS)
|
||||
return NULL;
|
||||
|
||||
pdata->nr_masters = tmp;
|
||||
}
|
||||
|
||||
if (!of_property_read_u32_array(np, "data_width", arr,
|
||||
pdata->nr_masters))
|
||||
for (tmp = 0; tmp < pdata->nr_masters; tmp++)
|
||||
if (!of_property_read_u32_array(np, "data-width", arr, nr_masters)) {
|
||||
for (tmp = 0; tmp < nr_masters; tmp++)
|
||||
pdata->data_width[tmp] = arr[tmp];
|
||||
} else if (!of_property_read_u32_array(np, "data_width", arr, nr_masters)) {
|
||||
for (tmp = 0; tmp < nr_masters; tmp++)
|
||||
pdata->data_width[tmp] = BIT(arr[tmp] & 0x07);
|
||||
}
|
||||
|
||||
return pdata;
|
||||
}
|
||||
@ -158,7 +161,7 @@ static int dw_probe(struct platform_device *pdev)
|
||||
struct dw_dma_chip *chip;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *mem;
|
||||
struct dw_dma_platform_data *pdata;
|
||||
const struct dw_dma_platform_data *pdata;
|
||||
int err;
|
||||
|
||||
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
|
||||
@ -183,6 +186,7 @@ static int dw_probe(struct platform_device *pdev)
|
||||
pdata = dw_dma_parse_dt(pdev);
|
||||
|
||||
chip->dev = dev;
|
||||
chip->pdata = pdata;
|
||||
|
||||
chip->clk = devm_clk_get(chip->dev, "hclk");
|
||||
if (IS_ERR(chip->clk))
|
||||
@ -193,7 +197,7 @@ static int dw_probe(struct platform_device *pdev)
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
err = dw_dma_probe(chip, pdata);
|
||||
err = dw_dma_probe(chip);
|
||||
if (err)
|
||||
goto err_dw_dma_probe;
|
||||
|
||||
|
@ -114,10 +114,6 @@ struct dw_dma_regs {
|
||||
#define dma_writel_native writel
|
||||
#endif
|
||||
|
||||
/* To access the registers in early stage of probe */
|
||||
#define dma_read_byaddr(addr, name) \
|
||||
dma_readl_native((addr) + offsetof(struct dw_dma_regs, name))
|
||||
|
||||
/* Bitfields in DW_PARAMS */
|
||||
#define DW_PARAMS_NR_CHAN 8 /* number of channels */
|
||||
#define DW_PARAMS_NR_MASTER 11 /* number of AHB masters */
|
||||
@ -143,6 +139,10 @@ enum dw_dma_msize {
|
||||
DW_DMA_MSIZE_256,
|
||||
};
|
||||
|
||||
/* Bitfields in LLP */
|
||||
#define DWC_LLP_LMS(x) ((x) & 3) /* list master select */
|
||||
#define DWC_LLP_LOC(x) ((x) & ~3) /* next lli */
|
||||
|
||||
/* Bitfields in CTL_LO */
|
||||
#define DWC_CTLL_INT_EN (1 << 0) /* irqs enabled? */
|
||||
#define DWC_CTLL_DST_WIDTH(n) ((n)<<1) /* bytes per element */
|
||||
@ -216,6 +216,8 @@ enum dw_dma_msize {
|
||||
enum dw_dmac_flags {
|
||||
DW_DMA_IS_CYCLIC = 0,
|
||||
DW_DMA_IS_SOFT_LLP = 1,
|
||||
DW_DMA_IS_PAUSED = 2,
|
||||
DW_DMA_IS_INITIALIZED = 3,
|
||||
};
|
||||
|
||||
struct dw_dma_chan {
|
||||
@ -224,8 +226,6 @@ struct dw_dma_chan {
|
||||
u8 mask;
|
||||
u8 priority;
|
||||
enum dma_transfer_direction direction;
|
||||
bool paused;
|
||||
bool initialized;
|
||||
|
||||
/* software emulation of the LLP transfers */
|
||||
struct list_head *tx_node_active;
|
||||
@ -236,8 +236,6 @@ struct dw_dma_chan {
|
||||
unsigned long flags;
|
||||
struct list_head active_list;
|
||||
struct list_head queue;
|
||||
struct list_head free_list;
|
||||
u32 residue;
|
||||
struct dw_cyclic_desc *cdesc;
|
||||
|
||||
unsigned int descs_allocated;
|
||||
@ -249,8 +247,8 @@ struct dw_dma_chan {
|
||||
/* custom slave configuration */
|
||||
u8 src_id;
|
||||
u8 dst_id;
|
||||
u8 src_master;
|
||||
u8 dst_master;
|
||||
u8 m_master;
|
||||
u8 p_master;
|
||||
|
||||
/* configuration passed via .device_config */
|
||||
struct dma_slave_config dma_sconfig;
|
||||
@ -283,9 +281,8 @@ struct dw_dma {
|
||||
u8 all_chan_mask;
|
||||
u8 in_use;
|
||||
|
||||
/* hardware configuration */
|
||||
unsigned char nr_masters;
|
||||
unsigned char data_width[DW_DMA_MAX_NR_MASTERS];
|
||||
/* platform data */
|
||||
struct dw_dma_platform_data *pdata;
|
||||
};
|
||||
|
||||
static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw)
|
||||
@ -308,32 +305,51 @@ static inline struct dw_dma *to_dw_dma(struct dma_device *ddev)
|
||||
return container_of(ddev, struct dw_dma, dma);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
|
||||
typedef __be32 __dw32;
|
||||
#else
|
||||
typedef __le32 __dw32;
|
||||
#endif
|
||||
|
||||
/* LLI == Linked List Item; a.k.a. DMA block descriptor */
|
||||
struct dw_lli {
|
||||
/* values that are not changed by hardware */
|
||||
u32 sar;
|
||||
u32 dar;
|
||||
u32 llp; /* chain to next lli */
|
||||
u32 ctllo;
|
||||
__dw32 sar;
|
||||
__dw32 dar;
|
||||
__dw32 llp; /* chain to next lli */
|
||||
__dw32 ctllo;
|
||||
/* values that may get written back: */
|
||||
u32 ctlhi;
|
||||
__dw32 ctlhi;
|
||||
/* sstat and dstat can snapshot peripheral register state.
|
||||
* silicon config may discard either or both...
|
||||
*/
|
||||
u32 sstat;
|
||||
u32 dstat;
|
||||
__dw32 sstat;
|
||||
__dw32 dstat;
|
||||
};
|
||||
|
||||
struct dw_desc {
|
||||
/* FIRST values the hardware uses */
|
||||
struct dw_lli lli;
|
||||
|
||||
#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
|
||||
#define lli_set(d, reg, v) ((d)->lli.reg |= cpu_to_be32(v))
|
||||
#define lli_clear(d, reg, v) ((d)->lli.reg &= ~cpu_to_be32(v))
|
||||
#define lli_read(d, reg) be32_to_cpu((d)->lli.reg)
|
||||
#define lli_write(d, reg, v) ((d)->lli.reg = cpu_to_be32(v))
|
||||
#else
|
||||
#define lli_set(d, reg, v) ((d)->lli.reg |= cpu_to_le32(v))
|
||||
#define lli_clear(d, reg, v) ((d)->lli.reg &= ~cpu_to_le32(v))
|
||||
#define lli_read(d, reg) le32_to_cpu((d)->lli.reg)
|
||||
#define lli_write(d, reg, v) ((d)->lli.reg = cpu_to_le32(v))
|
||||
#endif
|
||||
|
||||
/* THEN values for driver housekeeping */
|
||||
struct list_head desc_node;
|
||||
struct list_head tx_list;
|
||||
struct dma_async_tx_descriptor txd;
|
||||
size_t len;
|
||||
size_t total_len;
|
||||
u32 residue;
|
||||
};
|
||||
|
||||
#define to_dw_desc(h) list_entry(h, struct dw_desc, desc_node)
|
||||
|
@ -144,16 +144,16 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
|
||||
struct dw_dma_slave *slave = c->tx_param;
|
||||
|
||||
slave->dma_dev = &dma_dev->dev;
|
||||
slave->src_master = 1;
|
||||
slave->dst_master = 0;
|
||||
slave->m_master = 0;
|
||||
slave->p_master = 1;
|
||||
}
|
||||
|
||||
if (c->rx_param) {
|
||||
struct dw_dma_slave *slave = c->rx_param;
|
||||
|
||||
slave->dma_dev = &dma_dev->dev;
|
||||
slave->src_master = 1;
|
||||
slave->dst_master = 0;
|
||||
slave->m_master = 0;
|
||||
slave->p_master = 1;
|
||||
}
|
||||
|
||||
spi_pdata.dma_filter = lpss_dma_filter;
|
||||
|
@ -1454,13 +1454,13 @@ byt_serial_setup(struct serial_private *priv,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rx_param->src_master = 1;
|
||||
rx_param->dst_master = 0;
|
||||
rx_param->m_master = 0;
|
||||
rx_param->p_master = 1;
|
||||
|
||||
dma->rxconf.src_maxburst = 16;
|
||||
|
||||
tx_param->src_master = 1;
|
||||
tx_param->dst_master = 0;
|
||||
tx_param->m_master = 0;
|
||||
tx_param->p_master = 1;
|
||||
|
||||
dma->txconf.dst_maxburst = 16;
|
||||
|
||||
|
@ -27,6 +27,7 @@ struct dw_dma;
|
||||
* @regs: memory mapped I/O space
|
||||
* @clk: hclk clock
|
||||
* @dw: struct dw_dma that is filed by dw_dma_probe()
|
||||
* @pdata: pointer to platform data
|
||||
*/
|
||||
struct dw_dma_chip {
|
||||
struct device *dev;
|
||||
@ -34,10 +35,12 @@ struct dw_dma_chip {
|
||||
void __iomem *regs;
|
||||
struct clk *clk;
|
||||
struct dw_dma *dw;
|
||||
|
||||
const struct dw_dma_platform_data *pdata;
|
||||
};
|
||||
|
||||
/* Export to the platform drivers */
|
||||
int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata);
|
||||
int dw_dma_probe(struct dw_dma_chip *chip);
|
||||
int dw_dma_remove(struct dw_dma_chip *chip);
|
||||
|
||||
/* DMA API extensions */
|
||||
|
@ -21,15 +21,15 @@
|
||||
* @dma_dev: required DMA master device
|
||||
* @src_id: src request line
|
||||
* @dst_id: dst request line
|
||||
* @src_master: src master for transfers on allocated channel.
|
||||
* @dst_master: dest master for transfers on allocated channel.
|
||||
* @m_master: memory master for transfers on allocated channel
|
||||
* @p_master: peripheral master for transfers on allocated channel
|
||||
*/
|
||||
struct dw_dma_slave {
|
||||
struct device *dma_dev;
|
||||
u8 src_id;
|
||||
u8 dst_id;
|
||||
u8 src_master;
|
||||
u8 dst_master;
|
||||
u8 m_master;
|
||||
u8 p_master;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -43,7 +43,7 @@ struct dw_dma_slave {
|
||||
* @block_size: Maximum block size supported by the controller
|
||||
* @nr_masters: Number of AHB masters supported by the controller
|
||||
* @data_width: Maximum data width supported by hardware per AHB master
|
||||
* (0 - 8bits, 1 - 16bits, ..., 5 - 256bits)
|
||||
* (in bytes, power of 2)
|
||||
*/
|
||||
struct dw_dma_platform_data {
|
||||
unsigned int nr_channels;
|
||||
@ -55,7 +55,7 @@ struct dw_dma_platform_data {
|
||||
#define CHAN_PRIORITY_ASCENDING 0 /* chan0 highest */
|
||||
#define CHAN_PRIORITY_DESCENDING 1 /* chan7 highest */
|
||||
unsigned char chan_priority;
|
||||
unsigned short block_size;
|
||||
unsigned int block_size;
|
||||
unsigned char nr_masters;
|
||||
unsigned char data_width[DW_DMA_MAX_NR_MASTERS];
|
||||
};
|
||||
|
@ -203,7 +203,7 @@ static struct dw_dma_chip *dw_probe(struct device *dev, struct resource *mem,
|
||||
|
||||
chip->dev = dev;
|
||||
|
||||
err = dw_dma_probe(chip, NULL);
|
||||
err = dw_dma_probe(chip);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user