mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
ARM Keystone SOC driver updates for 4.4
Documentation and support to be able to load the PDSP firmware necessary for accumulator operation. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWHW8iAAoJEHJsHOdBp5c/9ywP/3Qpvy+kcnwMvwrnq/jxLlGk qc+gQTAMMguenYGZmIqnyLVHG9B4UUNZ6e/uiukzCxMP1SWx8KmgKNFSQonJuFVV wLufo+wYBTH4P8VIM5OJNkJVPqZ8YXwtVJ09LhVxYNh1vF/l6aOEQ/kaEC22f5sD jycgKdKx3yRn67VrWiuXS1MGXIDkGR3ABCxv6iJHSKyP15HArQ6fAhyrkfP/mNkr 9YXIrX+vmMdsICfXG19R2z/lCuM+JadXz9Rjo9yMQwvUw+3QAHYy8m4JXb9cZFZq jNZnzWQj5azuxaGnLVS1UNggsEXuxmd0S1PJvdF1N2ISHVYqwCtFuLjQ2r+z4WQm uzo9DyPTaYtASO6iSq9MQVzKKW0r0a5dPlAJIYTJHR11xi8kOpu04KUkJUR4c1ly X5I9zJ7ishV1VxFUZaMJtl/nX7B18WiKZyHhtO4MqRLPFA1fjH1psA/s8vRk6l6e unawCOM5oT8KvuSyijTNq2sQlxgRJJW7S4F1P1iUxsA6nocaPdTV+Oi/aECt8mFQ Q9gFVgCTEMWBYPuVqVisfU/mmZFPRDiotknMAeM+mUF6D/DkA0NSPvNWH0LP4rrA kIGRHQWtJMBTdxdBhjKoCsEEk1DR0wOCTUqow77SR/H3wl1FL1EYDB2J15JD7vzM lVTrZzd1wRXSsHINdnY6 =T5UX -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
cfd96d3e74
5 changed files with 109 additions and 28 deletions
|
|
@ -135,9 +135,10 @@ struct knav_pdsp_info {
|
|||
};
|
||||
void __iomem *intd;
|
||||
u32 __iomem *iram;
|
||||
const char *firmware;
|
||||
u32 id;
|
||||
struct list_head list;
|
||||
bool loaded;
|
||||
bool started;
|
||||
};
|
||||
|
||||
struct knav_qmgr_info {
|
||||
|
|
|
|||
|
|
@ -482,8 +482,8 @@ struct knav_range_ops knav_acc_range_ops = {
|
|||
* Return 0 on success or error
|
||||
*/
|
||||
int knav_init_acc_range(struct knav_device *kdev,
|
||||
struct device_node *node,
|
||||
struct knav_range_info *range)
|
||||
struct device_node *node,
|
||||
struct knav_range_info *range)
|
||||
{
|
||||
struct knav_acc_channel *acc;
|
||||
struct knav_pdsp_info *pdsp;
|
||||
|
|
@ -526,6 +526,12 @@ int knav_init_acc_range(struct knav_device *kdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!pdsp->started) {
|
||||
dev_err(kdev->dev, "pdsp id %d not started for range %s\n",
|
||||
info->pdsp_id, range->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
info->pdsp = pdsp;
|
||||
channels = range->num_queues;
|
||||
if (of_get_property(node, "multi-queue", NULL)) {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,12 @@ static DEFINE_MUTEX(knav_dev_lock);
|
|||
idx < (kdev)->num_queues_in_use; \
|
||||
idx++, inst = knav_queue_idx_to_inst(kdev, idx))
|
||||
|
||||
/* All firmware file names end up here. List the firmware file names below.
|
||||
* Newest followed by older ones. Search is done from start of the array
|
||||
* until a firmware file is found.
|
||||
*/
|
||||
const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
|
||||
|
||||
/**
|
||||
* knav_queue_notify: qmss queue notfier call
|
||||
*
|
||||
|
|
@ -1439,7 +1445,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
|
|||
struct device *dev = kdev->dev;
|
||||
struct knav_pdsp_info *pdsp;
|
||||
struct device_node *child;
|
||||
int ret;
|
||||
|
||||
for_each_child_of_node(pdsps, child) {
|
||||
pdsp = devm_kzalloc(dev, sizeof(*pdsp), GFP_KERNEL);
|
||||
|
|
@ -1448,17 +1453,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
|
|||
return -ENOMEM;
|
||||
}
|
||||
pdsp->name = knav_queue_find_name(child);
|
||||
ret = of_property_read_string(child, "firmware",
|
||||
&pdsp->firmware);
|
||||
if (ret < 0 || !pdsp->firmware) {
|
||||
dev_err(dev, "unknown firmware for pdsp %s\n",
|
||||
pdsp->name);
|
||||
devm_kfree(dev, pdsp);
|
||||
continue;
|
||||
}
|
||||
dev_dbg(dev, "pdsp name %s fw name :%s\n", pdsp->name,
|
||||
pdsp->firmware);
|
||||
|
||||
pdsp->iram =
|
||||
knav_queue_map_reg(kdev, child,
|
||||
KNAV_QUEUE_PDSP_IRAM_REG_INDEX);
|
||||
|
|
@ -1489,9 +1483,9 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
|
|||
}
|
||||
of_property_read_u32(child, "id", &pdsp->id);
|
||||
list_add_tail(&pdsp->list, &kdev->pdsps);
|
||||
dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p, firmware %s\n",
|
||||
dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p\n",
|
||||
pdsp->name, pdsp->command, pdsp->iram, pdsp->regs,
|
||||
pdsp->intd, pdsp->firmware);
|
||||
pdsp->intd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1510,6 +1504,8 @@ static int knav_queue_stop_pdsp(struct knav_device *kdev,
|
|||
dev_err(kdev->dev, "timed out on pdsp %s stop\n", pdsp->name);
|
||||
return ret;
|
||||
}
|
||||
pdsp->loaded = false;
|
||||
pdsp->started = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1518,14 +1514,29 @@ static int knav_queue_load_pdsp(struct knav_device *kdev,
|
|||
{
|
||||
int i, ret, fwlen;
|
||||
const struct firmware *fw;
|
||||
bool found = false;
|
||||
u32 *fwdata;
|
||||
|
||||
ret = request_firmware(&fw, pdsp->firmware, kdev->dev);
|
||||
if (ret) {
|
||||
dev_err(kdev->dev, "failed to get firmware %s for pdsp %s\n",
|
||||
pdsp->firmware, pdsp->name);
|
||||
return ret;
|
||||
for (i = 0; i < ARRAY_SIZE(knav_acc_firmwares); i++) {
|
||||
if (knav_acc_firmwares[i]) {
|
||||
ret = request_firmware(&fw,
|
||||
knav_acc_firmwares[i],
|
||||
kdev->dev);
|
||||
if (!ret) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
dev_err(kdev->dev, "failed to get firmware for pdsp\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(kdev->dev, "firmware file %s downloaded for PDSP\n",
|
||||
knav_acc_firmwares[i]);
|
||||
|
||||
writel_relaxed(pdsp->id + 1, pdsp->command + 0x18);
|
||||
/* download the firmware */
|
||||
fwdata = (u32 *)fw->data;
|
||||
|
|
@ -1583,16 +1594,24 @@ static int knav_queue_start_pdsps(struct knav_device *kdev)
|
|||
int ret;
|
||||
|
||||
knav_queue_stop_pdsps(kdev);
|
||||
/* now load them all */
|
||||
/* now load them all. We return success even if pdsp
|
||||
* is not loaded as acc channels are optional on having
|
||||
* firmware availability in the system. We set the loaded
|
||||
* and stated flag and when initialize the acc range, check
|
||||
* it and init the range only if pdsp is started.
|
||||
*/
|
||||
for_each_pdsp(kdev, pdsp) {
|
||||
ret = knav_queue_load_pdsp(kdev, pdsp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!ret)
|
||||
pdsp->loaded = true;
|
||||
}
|
||||
|
||||
for_each_pdsp(kdev, pdsp) {
|
||||
ret = knav_queue_start_pdsp(kdev, pdsp);
|
||||
WARN_ON(ret);
|
||||
if (pdsp->loaded) {
|
||||
ret = knav_queue_start_pdsp(kdev, pdsp);
|
||||
if (!ret)
|
||||
pdsp->started = true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue