aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/soc
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2015-10-15 16:22:26 -0400
committerArnd Bergmann <arnd@arndb.de>2015-10-15 16:22:26 -0400
commitcfd96d3e74f72fff552fd996634bdf3497a8acc9 (patch)
tree6b8ce8341a4445ca0a662a0aadee5dd92d762f0b /drivers/soc
parentd72b712824ef906f548210b0012ff7c2a041ef7e (diff)
parent045016902bf7abeeb2a86fc9284c30dce228f055 (diff)
Merge tag 'keystone-driver-soc_v2' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone into next/soc
Merge "ARM Keystone SOC driver updates for 4.4" from Santosh Shilimkar: Documentation and support to be able to load the PDSP firmware necessary for accumulator operation. * tag 'keystone-driver-soc_v2' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone: soc: ti: qmss: make acc queue support optional in the driver soc: ti: add firmware file name as part of the driver Documentation: dt: soc: Add description for knav qmss driver
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/ti/knav_qmss.h3
-rw-r--r--drivers/soc/ti/knav_qmss_acc.c10
-rw-r--r--drivers/soc/ti/knav_qmss_queue.c67
3 files changed, 53 insertions, 27 deletions
diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h
index 51da2341280d..6ff936cacb70 100644
--- a/drivers/soc/ti/knav_qmss.h
+++ b/drivers/soc/ti/knav_qmss.h
@@ -135,9 +135,10 @@ struct knav_pdsp_info {
135 }; 135 };
136 void __iomem *intd; 136 void __iomem *intd;
137 u32 __iomem *iram; 137 u32 __iomem *iram;
138 const char *firmware;
139 u32 id; 138 u32 id;
140 struct list_head list; 139 struct list_head list;
140 bool loaded;
141 bool started;
141}; 142};
142 143
143struct knav_qmgr_info { 144struct knav_qmgr_info {
diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c
index ef6f69db0bd0..37c4aa95492d 100644
--- a/drivers/soc/ti/knav_qmss_acc.c
+++ b/drivers/soc/ti/knav_qmss_acc.c
@@ -482,8 +482,8 @@ struct knav_range_ops knav_acc_range_ops = {
482 * Return 0 on success or error 482 * Return 0 on success or error
483 */ 483 */
484int knav_init_acc_range(struct knav_device *kdev, 484int knav_init_acc_range(struct knav_device *kdev,
485 struct device_node *node, 485 struct device_node *node,
486 struct knav_range_info *range) 486 struct knav_range_info *range)
487{ 487{
488 struct knav_acc_channel *acc; 488 struct knav_acc_channel *acc;
489 struct knav_pdsp_info *pdsp; 489 struct knav_pdsp_info *pdsp;
@@ -526,6 +526,12 @@ int knav_init_acc_range(struct knav_device *kdev,
526 return -EINVAL; 526 return -EINVAL;
527 } 527 }
528 528
529 if (!pdsp->started) {
530 dev_err(kdev->dev, "pdsp id %d not started for range %s\n",
531 info->pdsp_id, range->name);
532 return -ENODEV;
533 }
534
529 info->pdsp = pdsp; 535 info->pdsp = pdsp;
530 channels = range->num_queues; 536 channels = range->num_queues;
531 if (of_get_property(node, "multi-queue", NULL)) { 537 if (of_get_property(node, "multi-queue", NULL)) {
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
index 6d8646db52cc..f3a0b6a4b54e 100644
--- a/drivers/soc/ti/knav_qmss_queue.c
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -68,6 +68,12 @@ static DEFINE_MUTEX(knav_dev_lock);
68 idx < (kdev)->num_queues_in_use; \ 68 idx < (kdev)->num_queues_in_use; \
69 idx++, inst = knav_queue_idx_to_inst(kdev, idx)) 69 idx++, inst = knav_queue_idx_to_inst(kdev, idx))
70 70
71/* All firmware file names end up here. List the firmware file names below.
72 * Newest followed by older ones. Search is done from start of the array
73 * until a firmware file is found.
74 */
75const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
76
71/** 77/**
72 * knav_queue_notify: qmss queue notfier call 78 * knav_queue_notify: qmss queue notfier call
73 * 79 *
@@ -1439,7 +1445,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
1439 struct device *dev = kdev->dev; 1445 struct device *dev = kdev->dev;
1440 struct knav_pdsp_info *pdsp; 1446 struct knav_pdsp_info *pdsp;
1441 struct device_node *child; 1447 struct device_node *child;
1442 int ret;
1443 1448
1444 for_each_child_of_node(pdsps, child) { 1449 for_each_child_of_node(pdsps, child) {
1445 pdsp = devm_kzalloc(dev, sizeof(*pdsp), GFP_KERNEL); 1450 pdsp = devm_kzalloc(dev, sizeof(*pdsp), GFP_KERNEL);
@@ -1448,17 +1453,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
1448 return -ENOMEM; 1453 return -ENOMEM;
1449 } 1454 }
1450 pdsp->name = knav_queue_find_name(child); 1455 pdsp->name = knav_queue_find_name(child);
1451 ret = of_property_read_string(child, "firmware",
1452 &pdsp->firmware);
1453 if (ret < 0 || !pdsp->firmware) {
1454 dev_err(dev, "unknown firmware for pdsp %s\n",
1455 pdsp->name);
1456 devm_kfree(dev, pdsp);
1457 continue;
1458 }
1459 dev_dbg(dev, "pdsp name %s fw name :%s\n", pdsp->name,
1460 pdsp->firmware);
1461
1462 pdsp->iram = 1456 pdsp->iram =
1463 knav_queue_map_reg(kdev, child, 1457 knav_queue_map_reg(kdev, child,
1464 KNAV_QUEUE_PDSP_IRAM_REG_INDEX); 1458 KNAV_QUEUE_PDSP_IRAM_REG_INDEX);
@@ -1489,9 +1483,9 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
1489 } 1483 }
1490 of_property_read_u32(child, "id", &pdsp->id); 1484 of_property_read_u32(child, "id", &pdsp->id);
1491 list_add_tail(&pdsp->list, &kdev->pdsps); 1485 list_add_tail(&pdsp->list, &kdev->pdsps);
1492 dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p, firmware %s\n", 1486 dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p\n",
1493 pdsp->name, pdsp->command, pdsp->iram, pdsp->regs, 1487 pdsp->name, pdsp->command, pdsp->iram, pdsp->regs,
1494 pdsp->intd, pdsp->firmware); 1488 pdsp->intd);
1495 } 1489 }
1496 return 0; 1490 return 0;
1497} 1491}
@@ -1510,6 +1504,8 @@ static int knav_queue_stop_pdsp(struct knav_device *kdev,
1510 dev_err(kdev->dev, "timed out on pdsp %s stop\n", pdsp->name); 1504 dev_err(kdev->dev, "timed out on pdsp %s stop\n", pdsp->name);
1511 return ret; 1505 return ret;
1512 } 1506 }
1507 pdsp->loaded = false;
1508 pdsp->started = false;
1513 return 0; 1509 return 0;
1514} 1510}
1515 1511
@@ -1518,14 +1514,29 @@ static int knav_queue_load_pdsp(struct knav_device *kdev,
1518{ 1514{
1519 int i, ret, fwlen; 1515 int i, ret, fwlen;
1520 const struct firmware *fw; 1516 const struct firmware *fw;
1517 bool found = false;
1521 u32 *fwdata; 1518 u32 *fwdata;
1522 1519
1523 ret = request_firmware(&fw, pdsp->firmware, kdev->dev); 1520 for (i = 0; i < ARRAY_SIZE(knav_acc_firmwares); i++) {
1524 if (ret) { 1521 if (knav_acc_firmwares[i]) {
1525 dev_err(kdev->dev, "failed to get firmware %s for pdsp %s\n", 1522 ret = request_firmware(&fw,
1526 pdsp->firmware, pdsp->name); 1523 knav_acc_firmwares[i],
1527 return ret; 1524 kdev->dev);
1525 if (!ret) {
1526 found = true;
1527 break;
1528 }
1529 }
1530 }
1531
1532 if (!found) {
1533 dev_err(kdev->dev, "failed to get firmware for pdsp\n");
1534 return -ENODEV;
1528 } 1535 }
1536
1537 dev_info(kdev->dev, "firmware file %s downloaded for PDSP\n",
1538 knav_acc_firmwares[i]);
1539
1529 writel_relaxed(pdsp->id + 1, pdsp->command + 0x18); 1540 writel_relaxed(pdsp->id + 1, pdsp->command + 0x18);
1530 /* download the firmware */ 1541 /* download the firmware */
1531 fwdata = (u32 *)fw->data; 1542 fwdata = (u32 *)fw->data;
@@ -1583,16 +1594,24 @@ static int knav_queue_start_pdsps(struct knav_device *kdev)
1583 int ret; 1594 int ret;
1584 1595
1585 knav_queue_stop_pdsps(kdev); 1596 knav_queue_stop_pdsps(kdev);
1586 /* now load them all */ 1597 /* now load them all. We return success even if pdsp
1598 * is not loaded as acc channels are optional on having
1599 * firmware availability in the system. We set the loaded
1600 * and stated flag and when initialize the acc range, check
1601 * it and init the range only if pdsp is started.
1602 */
1587 for_each_pdsp(kdev, pdsp) { 1603 for_each_pdsp(kdev, pdsp) {
1588 ret = knav_queue_load_pdsp(kdev, pdsp); 1604 ret = knav_queue_load_pdsp(kdev, pdsp);
1589 if (ret < 0) 1605 if (!ret)
1590 return ret; 1606 pdsp->loaded = true;
1591 } 1607 }
1592 1608
1593 for_each_pdsp(kdev, pdsp) { 1609 for_each_pdsp(kdev, pdsp) {
1594 ret = knav_queue_start_pdsp(kdev, pdsp); 1610 if (pdsp->loaded) {
1595 WARN_ON(ret); 1611 ret = knav_queue_start_pdsp(kdev, pdsp);
1612 if (!ret)
1613 pdsp->started = true;
1614 }
1596 } 1615 }
1597 return 0; 1616 return 0;
1598} 1617}