aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2010-10-06 09:41:15 -0400
committerSascha Hauer <s.hauer@pengutronix.de>2010-12-03 05:04:54 -0500
commit5b28aa319bba96987316425a1131813d87cbab35 (patch)
tree7fac8d3e54717355d83ac3d3fd1e4ec7440d7126 /drivers/dma
parent9ab4650f718a0e1cb8792bab4ef97efca4ac75c2 (diff)
dmaengine i.MX SDMA: Allow to run without firmware
The SDMA firmware consists of a ROM part and a RAM part. The ROM part is always present in the SDMA engine and is sufficient for many cases. This patch allows to pass in platform data containing the script addresses in ROM, so loading a firmware is optional now. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Acked-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/imx-sdma.c174
1 files changed, 78 insertions, 96 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 0834323a0599..01166a9c3241 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -273,50 +273,6 @@ struct sdma_channel {
273#define MXC_SDMA_MIN_PRIORITY 1 273#define MXC_SDMA_MIN_PRIORITY 1
274#define MXC_SDMA_MAX_PRIORITY 7 274#define MXC_SDMA_MAX_PRIORITY 7
275 275
276/**
277 * struct sdma_script_start_addrs - SDMA script start pointers
278 *
279 * start addresses of the different functions in the physical
280 * address space of the SDMA engine.
281 */
282struct sdma_script_start_addrs {
283 u32 ap_2_ap_addr;
284 u32 ap_2_bp_addr;
285 u32 ap_2_ap_fixed_addr;
286 u32 bp_2_ap_addr;
287 u32 loopback_on_dsp_side_addr;
288 u32 mcu_interrupt_only_addr;
289 u32 firi_2_per_addr;
290 u32 firi_2_mcu_addr;
291 u32 per_2_firi_addr;
292 u32 mcu_2_firi_addr;
293 u32 uart_2_per_addr;
294 u32 uart_2_mcu_addr;
295 u32 per_2_app_addr;
296 u32 mcu_2_app_addr;
297 u32 per_2_per_addr;
298 u32 uartsh_2_per_addr;
299 u32 uartsh_2_mcu_addr;
300 u32 per_2_shp_addr;
301 u32 mcu_2_shp_addr;
302 u32 ata_2_mcu_addr;
303 u32 mcu_2_ata_addr;
304 u32 app_2_per_addr;
305 u32 app_2_mcu_addr;
306 u32 shp_2_per_addr;
307 u32 shp_2_mcu_addr;
308 u32 mshc_2_mcu_addr;
309 u32 mcu_2_mshc_addr;
310 u32 spdif_2_mcu_addr;
311 u32 mcu_2_spdif_addr;
312 u32 asrc_2_mcu_addr;
313 u32 ext_mem_2_ipu_addr;
314 u32 descrambler_addr;
315 u32 dptc_dvfs_addr;
316 u32 utra_addr;
317 u32 ram_code_start_addr;
318};
319
320#define SDMA_FIRMWARE_MAGIC 0x414d4453 276#define SDMA_FIRMWARE_MAGIC 0x414d4453
321 277
322/** 278/**
@@ -1127,8 +1083,74 @@ static void sdma_issue_pending(struct dma_chan *chan)
1127 */ 1083 */
1128} 1084}
1129 1085
1130static int __init sdma_init(struct sdma_engine *sdma, 1086#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1 34
1131 void *ram_code, int ram_code_size) 1087
1088static void sdma_add_scripts(struct sdma_engine *sdma,
1089 const struct sdma_script_start_addrs *addr)
1090{
1091 s32 *addr_arr = (u32 *)addr;
1092 s32 *saddr_arr = (u32 *)sdma->script_addrs;
1093 int i;
1094
1095 for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++)
1096 if (addr_arr[i] > 0)
1097 saddr_arr[i] = addr_arr[i];
1098}
1099
1100static int __init sdma_get_firmware(struct sdma_engine *sdma,
1101 const char *cpu_name, int to_version)
1102{
1103 const struct firmware *fw;
1104 char *fwname;
1105 const struct sdma_firmware_header *header;
1106 int ret;
1107 const struct sdma_script_start_addrs *addr;
1108 unsigned short *ram_code;
1109
1110 fwname = kasprintf(GFP_KERNEL, "sdma-%s-to%d.bin", cpu_name, to_version);
1111 if (!fwname)
1112 return -ENOMEM;
1113
1114 ret = request_firmware(&fw, fwname, sdma->dev);
1115 if (ret) {
1116 kfree(fwname);
1117 return ret;
1118 }
1119 kfree(fwname);
1120
1121 if (fw->size < sizeof(*header))
1122 goto err_firmware;
1123
1124 header = (struct sdma_firmware_header *)fw->data;
1125
1126 if (header->magic != SDMA_FIRMWARE_MAGIC)
1127 goto err_firmware;
1128 if (header->ram_code_start + header->ram_code_size > fw->size)
1129 goto err_firmware;
1130
1131 addr = (void *)header + header->script_addrs_start;
1132 ram_code = (void *)header + header->ram_code_start;
1133
1134 clk_enable(sdma->clk);
1135 /* download the RAM image for SDMA */
1136 sdma_load_script(sdma, ram_code,
1137 header->ram_code_size,
1138 sdma->script_addrs->ram_code_start_addr);
1139 clk_disable(sdma->clk);
1140
1141 sdma_add_scripts(sdma, addr);
1142
1143 dev_info(sdma->dev, "loaded firmware %d.%d\n",
1144 header->version_major,
1145 header->version_minor);
1146
1147err_firmware:
1148 release_firmware(fw);
1149
1150 return ret;
1151}
1152
1153static int __init sdma_init(struct sdma_engine *sdma)
1132{ 1154{
1133 int i, ret; 1155 int i, ret;
1134 dma_addr_t ccb_phys; 1156 dma_addr_t ccb_phys;
@@ -1192,11 +1214,6 @@ static int __init sdma_init(struct sdma_engine *sdma,
1192 1214
1193 __raw_writel(ccb_phys, sdma->regs + SDMA_H_C0PTR); 1215 __raw_writel(ccb_phys, sdma->regs + SDMA_H_C0PTR);
1194 1216
1195 /* download the RAM image for SDMA */
1196 sdma_load_script(sdma, ram_code,
1197 ram_code_size,
1198 sdma->script_addrs->ram_code_start_addr);
1199
1200 /* Set bits of CONFIG register with given context switching mode */ 1217 /* Set bits of CONFIG register with given context switching mode */
1201 __raw_writel(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG); 1218 __raw_writel(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG);
1202 1219
@@ -1216,14 +1233,9 @@ err_dma_alloc:
1216static int __init sdma_probe(struct platform_device *pdev) 1233static int __init sdma_probe(struct platform_device *pdev)
1217{ 1234{
1218 int ret; 1235 int ret;
1219 const struct firmware *fw;
1220 const struct sdma_firmware_header *header;
1221 const struct sdma_script_start_addrs *addr;
1222 int irq; 1236 int irq;
1223 unsigned short *ram_code;
1224 struct resource *iores; 1237 struct resource *iores;
1225 struct sdma_platform_data *pdata = pdev->dev.platform_data; 1238 struct sdma_platform_data *pdata = pdev->dev.platform_data;
1226 char *fwname;
1227 int i; 1239 int i;
1228 dma_cap_mask_t mask; 1240 dma_cap_mask_t mask;
1229 struct sdma_engine *sdma; 1241 struct sdma_engine *sdma;
@@ -1262,38 +1274,9 @@ static int __init sdma_probe(struct platform_device *pdev)
1262 if (ret) 1274 if (ret)
1263 goto err_request_irq; 1275 goto err_request_irq;
1264 1276
1265 fwname = kasprintf(GFP_KERNEL, "sdma-%s-to%d.bin", 1277 sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL);
1266 pdata->cpu_name, pdata->to_version);
1267 if (!fwname) {
1268 ret = -ENOMEM;
1269 goto err_cputype;
1270 }
1271
1272 ret = request_firmware(&fw, fwname, &pdev->dev);
1273 if (ret) {
1274 dev_err(&pdev->dev, "request firmware \"%s\" failed with %d\n",
1275 fwname, ret);
1276 kfree(fwname);
1277 goto err_cputype;
1278 }
1279 kfree(fwname);
1280
1281 if (fw->size < sizeof(*header))
1282 goto err_firmware;
1283
1284 header = (struct sdma_firmware_header *)fw->data;
1285
1286 if (header->magic != SDMA_FIRMWARE_MAGIC)
1287 goto err_firmware;
1288 if (header->ram_code_start + header->ram_code_size > fw->size)
1289 goto err_firmware;
1290
1291 addr = (void *)header + header->script_addrs_start;
1292 ram_code = (void *)header + header->ram_code_start;
1293 sdma->script_addrs = kmalloc(sizeof(*addr), GFP_KERNEL);
1294 if (!sdma->script_addrs) 1278 if (!sdma->script_addrs)
1295 goto err_firmware; 1279 goto err_alloc;
1296 memcpy(sdma->script_addrs, addr, sizeof(*addr));
1297 1280
1298 sdma->version = pdata->sdma_version; 1281 sdma->version = pdata->sdma_version;
1299 1282
@@ -1316,10 +1299,15 @@ static int __init sdma_probe(struct platform_device *pdev)
1316 list_add_tail(&sdmac->chan.device_node, &sdma->dma_device.channels); 1299 list_add_tail(&sdmac->chan.device_node, &sdma->dma_device.channels);
1317 } 1300 }
1318 1301
1319 ret = sdma_init(sdma, ram_code, header->ram_code_size); 1302 ret = sdma_init(sdma);
1320 if (ret) 1303 if (ret)
1321 goto err_init; 1304 goto err_init;
1322 1305
1306 if (pdata->script_addrs)
1307 sdma_add_scripts(sdma, pdata->script_addrs);
1308
1309 sdma_get_firmware(sdma, pdata->cpu_name, pdata->to_version);
1310
1323 sdma->dma_device.dev = &pdev->dev; 1311 sdma->dma_device.dev = &pdev->dev;
1324 1312
1325 sdma->dma_device.device_alloc_chan_resources = sdma_alloc_chan_resources; 1313 sdma->dma_device.device_alloc_chan_resources = sdma_alloc_chan_resources;
@@ -1336,10 +1324,6 @@ static int __init sdma_probe(struct platform_device *pdev)
1336 goto err_init; 1324 goto err_init;
1337 } 1325 }
1338 1326
1339 dev_info(&pdev->dev, "initialized (firmware %d.%d)\n",
1340 header->version_major,
1341 header->version_minor);
1342
1343 /* request channel 0. This is an internal control channel 1327 /* request channel 0. This is an internal control channel
1344 * to the SDMA engine and not available to clients. 1328 * to the SDMA engine and not available to clients.
1345 */ 1329 */
@@ -1347,15 +1331,13 @@ static int __init sdma_probe(struct platform_device *pdev)
1347 dma_cap_set(DMA_SLAVE, mask); 1331 dma_cap_set(DMA_SLAVE, mask);
1348 dma_request_channel(mask, NULL, NULL); 1332 dma_request_channel(mask, NULL, NULL);
1349 1333
1350 release_firmware(fw); 1334 dev_info(sdma->dev, "initialized\n");
1351 1335
1352 return 0; 1336 return 0;
1353 1337
1354err_init: 1338err_init:
1355 kfree(sdma->script_addrs); 1339 kfree(sdma->script_addrs);
1356err_firmware: 1340err_alloc:
1357 release_firmware(fw);
1358err_cputype:
1359 free_irq(irq, sdma); 1341 free_irq(irq, sdma);
1360err_request_irq: 1342err_request_irq:
1361 iounmap(sdma->regs); 1343 iounmap(sdma->regs);