aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/imx-sdma.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-03-07 03:30:06 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2012-04-25 11:03:35 -0400
commit7560e3f3581ed415828d3f431b8622fa38c2d133 (patch)
tree30f51bce9a355a2fb3af7605bcd5ae48edc14903 /drivers/dma/imx-sdma.c
parent66f75a5d028beaf67c931435fdc3e7823125730c (diff)
dmaengine i.MX SDMA: do not depend on grouped clocks
the current i.MX clock support groups together unrelated clocks to a single clock which is then used by the driver. This can't be accomplished with the generic clock framework so we instead request the individual clocks in the driver. For i.MX there are generally three different clocks: ipg: bus clock (needed to access registers) ahb: dma relevant clock, sometimes referred to as hclk in the datasheet per: bit clock, pixel clock This patch changes the driver to request the individual clocks. Currently all clk_get will get the same clock until the SoCs are converted to the generic clock framework Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/dma/imx-sdma.c')
-rw-r--r--drivers/dma/imx-sdma.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index d3e38e28bb6b..fddccae6b476 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -322,7 +322,8 @@ struct sdma_engine {
322 struct sdma_context_data *context; 322 struct sdma_context_data *context;
323 dma_addr_t context_phys; 323 dma_addr_t context_phys;
324 struct dma_device dma_device; 324 struct dma_device dma_device;
325 struct clk *clk; 325 struct clk *clk_ipg;
326 struct clk *clk_ahb;
326 struct mutex channel_0_lock; 327 struct mutex channel_0_lock;
327 struct sdma_script_start_addrs *script_addrs; 328 struct sdma_script_start_addrs *script_addrs;
328}; 329};
@@ -859,7 +860,8 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
859 sdmac->peripheral_type = data->peripheral_type; 860 sdmac->peripheral_type = data->peripheral_type;
860 sdmac->event_id0 = data->dma_request; 861 sdmac->event_id0 = data->dma_request;
861 862
862 clk_enable(sdmac->sdma->clk); 863 clk_enable(sdmac->sdma->clk_ipg);
864 clk_enable(sdmac->sdma->clk_ahb);
863 865
864 ret = sdma_request_channel(sdmac); 866 ret = sdma_request_channel(sdmac);
865 if (ret) 867 if (ret)
@@ -896,7 +898,8 @@ static void sdma_free_chan_resources(struct dma_chan *chan)
896 898
897 dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys); 899 dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys);
898 900
899 clk_disable(sdma->clk); 901 clk_disable(sdma->clk_ipg);
902 clk_disable(sdma->clk_ahb);
900} 903}
901 904
902static struct dma_async_tx_descriptor *sdma_prep_slave_sg( 905static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
@@ -1169,12 +1172,14 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
1169 addr = (void *)header + header->script_addrs_start; 1172 addr = (void *)header + header->script_addrs_start;
1170 ram_code = (void *)header + header->ram_code_start; 1173 ram_code = (void *)header + header->ram_code_start;
1171 1174
1172 clk_enable(sdma->clk); 1175 clk_enable(sdma->clk_ipg);
1176 clk_enable(sdma->clk_ahb);
1173 /* download the RAM image for SDMA */ 1177 /* download the RAM image for SDMA */
1174 sdma_load_script(sdma, ram_code, 1178 sdma_load_script(sdma, ram_code,
1175 header->ram_code_size, 1179 header->ram_code_size,
1176 addr->ram_code_start_addr); 1180 addr->ram_code_start_addr);
1177 clk_disable(sdma->clk); 1181 clk_disable(sdma->clk_ipg);
1182 clk_disable(sdma->clk_ahb);
1178 1183
1179 sdma_add_scripts(sdma, addr); 1184 sdma_add_scripts(sdma, addr);
1180 1185
@@ -1216,7 +1221,8 @@ static int __init sdma_init(struct sdma_engine *sdma)
1216 return -ENODEV; 1221 return -ENODEV;
1217 } 1222 }
1218 1223
1219 clk_enable(sdma->clk); 1224 clk_enable(sdma->clk_ipg);
1225 clk_enable(sdma->clk_ahb);
1220 1226
1221 /* Be sure SDMA has not started yet */ 1227 /* Be sure SDMA has not started yet */
1222 writel_relaxed(0, sdma->regs + SDMA_H_C0PTR); 1228 writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
@@ -1269,12 +1275,14 @@ static int __init sdma_init(struct sdma_engine *sdma)
1269 /* Initializes channel's priorities */ 1275 /* Initializes channel's priorities */
1270 sdma_set_channel_priority(&sdma->channel[0], 7); 1276 sdma_set_channel_priority(&sdma->channel[0], 7);
1271 1277
1272 clk_disable(sdma->clk); 1278 clk_disable(sdma->clk_ipg);
1279 clk_disable(sdma->clk_ahb);
1273 1280
1274 return 0; 1281 return 0;
1275 1282
1276err_dma_alloc: 1283err_dma_alloc:
1277 clk_disable(sdma->clk); 1284 clk_disable(sdma->clk_ipg);
1285 clk_disable(sdma->clk_ahb);
1278 dev_err(sdma->dev, "initialisation failed with %d\n", ret); 1286 dev_err(sdma->dev, "initialisation failed with %d\n", ret);
1279 return ret; 1287 return ret;
1280} 1288}
@@ -1313,12 +1321,21 @@ static int __init sdma_probe(struct platform_device *pdev)
1313 goto err_request_region; 1321 goto err_request_region;
1314 } 1322 }
1315 1323
1316 sdma->clk = clk_get(&pdev->dev, NULL); 1324 sdma->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
1317 if (IS_ERR(sdma->clk)) { 1325 if (IS_ERR(sdma->clk_ipg)) {
1318 ret = PTR_ERR(sdma->clk); 1326 ret = PTR_ERR(sdma->clk_ipg);
1319 goto err_clk; 1327 goto err_clk;
1320 } 1328 }
1321 1329
1330 sdma->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
1331 if (IS_ERR(sdma->clk_ahb)) {
1332 ret = PTR_ERR(sdma->clk_ahb);
1333 goto err_clk;
1334 }
1335
1336 clk_prepare(sdma->clk_ipg);
1337 clk_prepare(sdma->clk_ahb);
1338
1322 sdma->regs = ioremap(iores->start, resource_size(iores)); 1339 sdma->regs = ioremap(iores->start, resource_size(iores));
1323 if (!sdma->regs) { 1340 if (!sdma->regs) {
1324 ret = -ENOMEM; 1341 ret = -ENOMEM;
@@ -1426,7 +1443,6 @@ err_alloc:
1426err_request_irq: 1443err_request_irq:
1427 iounmap(sdma->regs); 1444 iounmap(sdma->regs);
1428err_ioremap: 1445err_ioremap:
1429 clk_put(sdma->clk);
1430err_clk: 1446err_clk:
1431 release_mem_region(iores->start, resource_size(iores)); 1447 release_mem_region(iores->start, resource_size(iores));
1432err_request_region: 1448err_request_region: