aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/remoteproc/omap_remoteproc.c')
-rw-r--r--drivers/remoteproc/omap_remoteproc.c73
1 files changed, 57 insertions, 16 deletions
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
index 51db2441b506..5d6f17bdfb2f 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -397,18 +397,27 @@ static void omap_rproc_kick(struct rproc *rproc, int vqid)
397 * 397 *
398 * Set boot address for a supported DSP remote processor. 398 * Set boot address for a supported DSP remote processor.
399 */ 399 */
400static void omap_rproc_write_dsp_boot_addr(struct rproc *rproc) 400static int omap_rproc_write_dsp_boot_addr(struct rproc *rproc)
401{ 401{
402 struct device *dev = rproc->dev.parent;
402 struct omap_rproc *oproc = rproc->priv; 403 struct omap_rproc *oproc = rproc->priv;
403 struct omap_rproc_boot_data *bdata = oproc->boot_data; 404 struct omap_rproc_boot_data *bdata = oproc->boot_data;
404 u32 offset = bdata->boot_reg; 405 u32 offset = bdata->boot_reg;
405 unsigned int value = rproc->bootaddr; 406 unsigned int value = rproc->bootaddr;
406 unsigned int mask = ~(SZ_1K - 1); 407 unsigned int mask = ~(SZ_1K - 1);
407 408
409 if (value & (SZ_1K - 1)) {
410 dev_err(dev, "invalid boot address 0x%x, must be aligned on a 1KB boundary\n",
411 value);
412 return -EINVAL;
413 }
414
408 value >>= bdata->boot_reg_shift; 415 value >>= bdata->boot_reg_shift;
409 mask >>= bdata->boot_reg_shift; 416 mask >>= bdata->boot_reg_shift;
410 417
411 regmap_update_bits(bdata->syscon, offset, mask, value); 418 regmap_update_bits(bdata->syscon, offset, mask, value);
419
420 return 0;
412} 421}
413 422
414/* 423/*
@@ -431,8 +440,11 @@ static int omap_rproc_start(struct rproc *rproc)
431 * We set boot address irrespective of the value of the late attach flag 440 * We set boot address irrespective of the value of the late attach flag
432 * as boot address takes effect only on a deassert of remoteproc reset. 441 * as boot address takes effect only on a deassert of remoteproc reset.
433 */ 442 */
434 if (oproc->boot_data) 443 if (oproc->boot_data) {
435 omap_rproc_write_dsp_boot_addr(rproc); 444 ret = omap_rproc_write_dsp_boot_addr(rproc);
445 if (ret)
446 return ret;
447 }
436 448
437 client->dev = dev; 449 client->dev = dev;
438 client->tx_done = NULL; 450 client->tx_done = NULL;
@@ -715,8 +727,13 @@ static int _omap_rproc_resume(struct rproc *rproc, bool auto_suspend)
715 } 727 }
716 728
717 /* boot address could be lost after suspend, so restore it */ 729 /* boot address could be lost after suspend, so restore it */
718 if (oproc->boot_data) 730 if (oproc->boot_data) {
719 omap_rproc_write_dsp_boot_addr(rproc); 731 ret = omap_rproc_write_dsp_boot_addr(rproc);
732 if (ret) {
733 dev_err(dev, "boot address restore failed %d\n", ret);
734 goto suspend_iommu;
735 }
736 }
720 737
721 ret = omap_rproc_enable_timers(pdev, false); 738 ret = omap_rproc_enable_timers(pdev, false);
722 if (ret) { 739 if (ret) {
@@ -836,6 +853,11 @@ static int omap_rproc_runtime_suspend(struct device *dev)
836 struct omap_rproc *oproc = rproc->priv; 853 struct omap_rproc *oproc = rproc->priv;
837 int ret; 854 int ret;
838 855
856 if (rproc->state == RPROC_CRASHED) {
857 dev_dbg(dev, "rproc cannot be runtime suspended when crashed!\n");
858 return -EBUSY;
859 }
860
839 if (WARN_ON(rproc->state != RPROC_RUNNING)) { 861 if (WARN_ON(rproc->state != RPROC_RUNNING)) {
840 dev_err(dev, "rproc cannot be runtime suspended when not running!\n"); 862 dev_err(dev, "rproc cannot be runtime suspended when not running!\n");
841 return -EBUSY; 863 return -EBUSY;
@@ -967,8 +989,8 @@ static int omap_rproc_get_autosuspend_delay(struct platform_device *pdev)
967 989
968 data = match->data; 990 data = match->data;
969 991
970 if (!of_device_is_compatible(np, "ti,dra7-rproc-dsp") && 992 if (!of_device_is_compatible(np, "ti,dra7-dsp") &&
971 !of_device_is_compatible(np, "ti,dra7-rproc-ipu")) { 993 !of_device_is_compatible(np, "ti,dra7-ipu")) {
972 delay = data->autosuspend_delay; 994 delay = data->autosuspend_delay;
973 goto out; 995 goto out;
974 } 996 }
@@ -1052,12 +1074,15 @@ static int omap_rproc_get_boot_data(struct platform_device *pdev,
1052static int omap_rproc_of_get_internal_memories(struct platform_device *pdev, 1074static int omap_rproc_of_get_internal_memories(struct platform_device *pdev,
1053 struct rproc *rproc) 1075 struct rproc *rproc)
1054{ 1076{
1055 static const char * const mem_names[] = {"l2ram"}; 1077 static const char * const ipu_mem_names[] = {"l2ram"};
1078 static const char * const dra7_dsp_mem_names[] = {"l2ram", "l1pram",
1079 "l1dram"};
1056 struct device_node *np = pdev->dev.of_node; 1080 struct device_node *np = pdev->dev.of_node;
1057 struct omap_rproc *oproc = rproc->priv; 1081 struct omap_rproc *oproc = rproc->priv;
1058 struct device *dev = &pdev->dev; 1082 struct device *dev = &pdev->dev;
1083 const char * const *mem_names;
1059 struct resource *res; 1084 struct resource *res;
1060 int num_mems = 0; 1085 int num_mems;
1061 const __be32 *addrp; 1086 const __be32 *addrp;
1062 u32 l4_offset = 0; 1087 u32 l4_offset = 0;
1063 u64 size; 1088 u64 size;
@@ -1068,8 +1093,15 @@ static int omap_rproc_of_get_internal_memories(struct platform_device *pdev,
1068 of_device_is_compatible(np, "ti,omap5-dsp")) 1093 of_device_is_compatible(np, "ti,omap5-dsp"))
1069 return 0; 1094 return 0;
1070 1095
1071 /* XXX: add support for DRA7 DSP L1 RAMs if needed */ 1096 /* DRA7 DSPs have two additional SRAMs at L1 level */
1072 num_mems = ARRAY_SIZE(mem_names); 1097 if (of_device_is_compatible(np, "ti,dra7-dsp")) {
1098 mem_names = dra7_dsp_mem_names;
1099 num_mems = ARRAY_SIZE(dra7_dsp_mem_names);
1100 } else {
1101 mem_names = ipu_mem_names;
1102 num_mems = ARRAY_SIZE(ipu_mem_names);
1103 }
1104
1073 oproc->mem = devm_kcalloc(dev, num_mems, sizeof(*oproc->mem), 1105 oproc->mem = devm_kcalloc(dev, num_mems, sizeof(*oproc->mem),
1074 GFP_KERNEL); 1106 GFP_KERNEL);
1075 if (!oproc->mem) 1107 if (!oproc->mem)
@@ -1218,7 +1250,9 @@ static int omap_rproc_probe(struct platform_device *pdev)
1218 oproc->num_wd_timers); 1250 oproc->num_wd_timers);
1219 oproc->num_wd_timers = 0; 1251 oproc->num_wd_timers = 0;
1220 } else { 1252 } else {
1221 if (!timer_ops || !timer_ops->get_timer_irq || 1253 if (!timer_ops || !timer_ops->request_timer ||
1254 !timer_ops->release_timer || !timer_ops->start_timer ||
1255 !timer_ops->stop_timer || !timer_ops->get_timer_irq ||
1222 !timer_ops->ack_timer_irq) { 1256 !timer_ops->ack_timer_irq) {
1223 dev_err(&pdev->dev, "device does not have required watchdog timer ops\n"); 1257 dev_err(&pdev->dev, "device does not have required watchdog timer ops\n");
1224 ret = -ENODEV; 1258 ret = -ENODEV;
@@ -1242,19 +1276,26 @@ static int omap_rproc_probe(struct platform_device *pdev)
1242 1276
1243 init_completion(&oproc->pm_comp); 1277 init_completion(&oproc->pm_comp);
1244 oproc->autosuspend_delay = omap_rproc_get_autosuspend_delay(pdev); 1278 oproc->autosuspend_delay = omap_rproc_get_autosuspend_delay(pdev);
1245 if (oproc->autosuspend_delay < 0) 1279 if (oproc->autosuspend_delay < 0) {
1280 ret = oproc->autosuspend_delay;
1246 goto free_rproc; 1281 goto free_rproc;
1282 }
1247 1283
1248 ret = of_property_read_u32(np, "ti,rproc-standby-info", &standby_addr); 1284 ret = of_property_read_u32(np, "ti,rproc-standby-info", &standby_addr);
1249 if (ret || !standby_addr) 1285 if (ret || !standby_addr) {
1286 ret = !standby_addr ? -EINVAL : ret;
1250 goto free_rproc; 1287 goto free_rproc;
1288 }
1251 1289
1252 oproc->standby_addr = devm_ioremap(&pdev->dev, standby_addr, 1290 oproc->standby_addr = devm_ioremap(&pdev->dev, standby_addr,
1253 sizeof(u32)); 1291 sizeof(u32));
1254 if (!oproc->standby_addr) 1292 if (!oproc->standby_addr) {
1293 ret = -ENOMEM;
1255 goto free_rproc; 1294 goto free_rproc;
1295 }
1256 1296
1257 if (of_reserved_mem_device_init(&pdev->dev)) { 1297 ret = of_reserved_mem_device_init(&pdev->dev);
1298 if (ret) {
1258 dev_err(&pdev->dev, "device does not have specific CMA pool\n"); 1299 dev_err(&pdev->dev, "device does not have specific CMA pool\n");
1259 goto free_rproc; 1300 goto free_rproc;
1260 } 1301 }