aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2012-05-09 18:23:26 -0400
committerShawn Guo <shawn.guo@linaro.org>2012-05-12 01:32:17 -0400
commit8c92013643f5c40633d61ae331cef49c1069af10 (patch)
tree7c385fabafab5ded73621c42639b61e06fa94f6e /drivers/dma
parentbb11fb63fc2e5d1092f17d91790bb4aede6d3ef2 (diff)
dma: mxs-dma: make platform_device_id more generic
Rewrite mxs_dma_is_apbh and mxs_dma_is_apbx in order to support other SoCs like imx6q and reform the platform_device_id for the better further dt support. Cc: Dan Williams <dan.j.williams@intel.com> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Huang Shijie <b32955@freescale.com> Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org> Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Marek Vasut <marex@denx.de> Acked-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/mxs-dma.c115
1 files changed, 79 insertions, 36 deletions
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index c93f9fa08caf..b1cab087cd04 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -36,12 +36,8 @@
36 * dma can program the controller registers of peripheral devices. 36 * dma can program the controller registers of peripheral devices.
37 */ 37 */
38 38
39#define MXS_DMA_APBH 0 39#define dma_is_apbh(mxs_dma) ((mxs_dma)->type == MXS_DMA_APBH)
40#define MXS_DMA_APBX 1 40#define apbh_is_old(mxs_dma) ((mxs_dma)->dev_id == IMX23_DMA)
41#define dma_is_apbh(mxs_dma) ((mxs_dma)->dev_id == MXS_DMA_APBH)
42
43#define APBH_VERSION_LATEST 3
44#define apbh_is_old(mxs_dma) ((mxs_dma)->version < APBH_VERSION_LATEST)
45 41
46#define HW_APBHX_CTRL0 0x000 42#define HW_APBHX_CTRL0 0x000
47#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29) 43#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29)
@@ -51,9 +47,6 @@
51#define HW_APBHX_CTRL2 0x020 47#define HW_APBHX_CTRL2 0x020
52#define HW_APBHX_CHANNEL_CTRL 0x030 48#define HW_APBHX_CHANNEL_CTRL 0x030
53#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16 49#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16
54#define HW_APBH_VERSION (cpu_is_mx23() ? 0x3f0 : 0x800)
55#define HW_APBX_VERSION 0x800
56#define BP_APBHX_VERSION_MAJOR 24
57/* 50/*
58 * The offset of NXTCMDAR register is different per both dma type and version, 51 * The offset of NXTCMDAR register is different per both dma type and version,
59 * while stride for each channel is all the same 0x70. 52 * while stride for each channel is all the same 0x70.
@@ -125,9 +118,19 @@ struct mxs_dma_chan {
125#define MXS_DMA_CHANNELS 16 118#define MXS_DMA_CHANNELS 16
126#define MXS_DMA_CHANNELS_MASK 0xffff 119#define MXS_DMA_CHANNELS_MASK 0xffff
127 120
121enum mxs_dma_devtype {
122 MXS_DMA_APBH,
123 MXS_DMA_APBX,
124};
125
126enum mxs_dma_id {
127 IMX23_DMA,
128 IMX28_DMA,
129};
130
128struct mxs_dma_engine { 131struct mxs_dma_engine {
129 int dev_id; 132 enum mxs_dma_id dev_id;
130 unsigned int version; 133 enum mxs_dma_devtype type;
131 void __iomem *base; 134 void __iomem *base;
132 struct clk *clk; 135 struct clk *clk;
133 struct dma_device dma_device; 136 struct dma_device dma_device;
@@ -135,6 +138,66 @@ struct mxs_dma_engine {
135 struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS]; 138 struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS];
136}; 139};
137 140
141struct mxs_dma_type {
142 enum mxs_dma_id id;
143 enum mxs_dma_devtype type;
144};
145
146static struct mxs_dma_type mxs_dma_types[] = {
147 {
148 .id = IMX23_DMA,
149 .type = MXS_DMA_APBH,
150 }, {
151 .id = IMX23_DMA,
152 .type = MXS_DMA_APBX,
153 }, {
154 .id = IMX28_DMA,
155 .type = MXS_DMA_APBH,
156 }, {
157 .id = IMX28_DMA,
158 .type = MXS_DMA_APBX,
159 }
160};
161
162static struct platform_device_id mxs_dma_ids[] = {
163 {
164 .name = "imx23-dma-apbh",
165 .driver_data = (kernel_ulong_t) &mxs_dma_types[0],
166 }, {
167 .name = "imx23-dma-apbx",
168 .driver_data = (kernel_ulong_t) &mxs_dma_types[1],
169 }, {
170 .name = "imx28-dma-apbh",
171 .driver_data = (kernel_ulong_t) &mxs_dma_types[2],
172 }, {
173 .name = "imx28-dma-apbx",
174 .driver_data = (kernel_ulong_t) &mxs_dma_types[3],
175 }, {
176 /* end of list */
177 }
178};
179
180static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
181{
182 return container_of(chan, struct mxs_dma_chan, chan);
183}
184
185int mxs_dma_is_apbh(struct dma_chan *chan)
186{
187 struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
188 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
189
190 return dma_is_apbh(mxs_dma);
191}
192
193int mxs_dma_is_apbx(struct dma_chan *chan)
194{
195 struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
196 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
197
198 return !dma_is_apbh(mxs_dma);
199}
200
138static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan) 201static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan)
139{ 202{
140 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; 203 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
@@ -198,11 +261,6 @@ static void mxs_dma_resume_chan(struct mxs_dma_chan *mxs_chan)
198 mxs_chan->status = DMA_IN_PROGRESS; 261 mxs_chan->status = DMA_IN_PROGRESS;
199} 262}
200 263
201static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
202{
203 return container_of(chan, struct mxs_dma_chan, chan);
204}
205
206static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx) 264static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx)
207{ 265{
208 return dma_cookie_assign(tx); 266 return dma_cookie_assign(tx);
@@ -575,12 +633,6 @@ static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
575 if (ret) 633 if (ret)
576 goto err_out; 634 goto err_out;
577 635
578 /* only major version matters */
579 mxs_dma->version = readl(mxs_dma->base +
580 ((mxs_dma->dev_id == MXS_DMA_APBX) ?
581 HW_APBX_VERSION : HW_APBH_VERSION)) >>
582 BP_APBHX_VERSION_MAJOR;
583
584 /* enable apbh burst */ 636 /* enable apbh burst */
585 if (dma_is_apbh(mxs_dma)) { 637 if (dma_is_apbh(mxs_dma)) {
586 writel(BM_APBH_CTRL0_APB_BURST_EN, 638 writel(BM_APBH_CTRL0_APB_BURST_EN,
@@ -602,6 +654,8 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
602{ 654{
603 const struct platform_device_id *id_entry = 655 const struct platform_device_id *id_entry =
604 platform_get_device_id(pdev); 656 platform_get_device_id(pdev);
657 const struct mxs_dma_type *dma_type =
658 (struct mxs_dma_type *)id_entry->driver_data;
605 struct mxs_dma_engine *mxs_dma; 659 struct mxs_dma_engine *mxs_dma;
606 struct resource *iores; 660 struct resource *iores;
607 int ret, i; 661 int ret, i;
@@ -610,7 +664,8 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
610 if (!mxs_dma) 664 if (!mxs_dma)
611 return -ENOMEM; 665 return -ENOMEM;
612 666
613 mxs_dma->dev_id = id_entry->driver_data; 667 mxs_dma->dev_id = dma_type->id;
668 mxs_dma->type = dma_type->type;
614 669
615 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 670 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
616 671
@@ -693,23 +748,11 @@ err_request_region:
693 return ret; 748 return ret;
694} 749}
695 750
696static struct platform_device_id mxs_dma_type[] = {
697 {
698 .name = "mxs-dma-apbh",
699 .driver_data = MXS_DMA_APBH,
700 }, {
701 .name = "mxs-dma-apbx",
702 .driver_data = MXS_DMA_APBX,
703 }, {
704 /* end of list */
705 }
706};
707
708static struct platform_driver mxs_dma_driver = { 751static struct platform_driver mxs_dma_driver = {
709 .driver = { 752 .driver = {
710 .name = "mxs-dma", 753 .name = "mxs-dma",
711 }, 754 },
712 .id_table = mxs_dma_type, 755 .id_table = mxs_dma_ids,
713}; 756};
714 757
715static int __init mxs_dma_module_init(void) 758static int __init mxs_dma_module_init(void)