mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
TI SoC driver updates for v7.2
TI K3 TISCI: - ti_sci: Add BOARDCFG_MANAGED mode for support system suspend/resume cycles - ti_sci: Add support for restoring IRQ and clock contexts during resume. - clk: keystone: sci-clk: Add clock restoration support. SoC Drivers: - k3-socinfo: Add support for identifying AM62P silicon variants via NVMEM, along with corresponding dt-bindings update for nvmem-cells support - k3-ringacc: Fix incorrect access mode for ring pop tail IO/proxy operations Keystone Navigator (knav) Cleanup and Fixes: - knav_qmss: Multiple code quality improvements - knav_qmss_queue: Implement proper resource cleanup in the remove() path General Cleanups: - k3-ringacc: Use str_enabled_disabled() helper for consistency - knav_qmss: Use %pe format specifier for PTR_ERR() printing -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE+KKGk1TrgjIXoxo03bWEnRc2JJ0FAmogRt8ACgkQ3bWEnRc2 JJ34qg/9G4HWCfLWqkNr9xgL3YW6/zSkj6CE47ZK+Ku7O6FZprmLZ8OtyrVZMNNp MFv/51SVN++whZULMkr2FTjlK4BIVqnjo9smTs2timvBjoCIJuLRkIolWlob4aEF V4+f7cW31bD3BgtxftWKWJSbRpnk2jRue8esAyVSl/N4E4/w+uEYhC0MU6gwuU3P rZJJ+Am/4+8xri7sKD+9GXM8255T7wA92P3piQBeZXFC8r0oNsFvIkkkQ5kJe+K6 P84qkz2gxUdutlPRL6vAvxofqNF8GT0hGLM5nPGYf2NIaergUxl8ydtJWGw+x2Xw QTWXqzETEqUdBSl/JUJHSCnxt793V8WDBAzu0Ka9UhtXnlcqAlTe46QfV5LWslaa HOJknSvMF/6k+/5HBnS+TI8O2u+koQGlVTZnXoL/E035tXSXH8dFoeXUt1PixYDf 346cz40LNn7iry1HVuOKRtfX4+D+ZH0KqbelYSEUyPgXIt/d+rcUdZKWgCtjNDmg GobjiSnsoAmTWA8HKDnLxaF62bUXIRJNlRfjIJ6oL8i4IQtnqU/d92ABYIQwMh+Z yiwuJmkK7Qd6Lx0CraW9drIiSgYn9gEWGZW1JbJnoW72HP9hkjRjU6rkcKFxLckf sQE/xdZu/unO2Zq2WxGAFAgVwJ6AyQlbpVu+kQHlJNdQYanpDfw= =JSdI -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmooKk0ACgkQmmx57+YA GNmFtg//QosIGaXc8MBeU+0o2qaoHZhOxlG8Z/QppdNQ0BazlTSGJK3q9CdwDyn1 25L93bSr75z0Lf57qvA2qw/esRMmCl2Hgf/xux42sWvielUXPs1/bN4IQmUoux/f MZ8G2tPQnuOajep6wtMfr+cSqwUTPzItyOYBF6XTYOIjUnrBpzlEkHGNHXDEonu7 l3QJi6yOiOFl1MGyQLYJ1a6j+xBkD/2a7qmbuEXyKKL0DNMyGnqeSDDxbONVWQPE +5Vu8k42Cadz68YpN6ZI7R2zrNl6m1QQEip7pYAjGI6ddM5Axy0PV6odh9ASM2Ur vk8cicKbeyZ6Q5rmz33dxvSJYQYY0h5gZR0KBv6pX9sKiWIexUH07YiLJkcghD6i s15IvcgXSfDfBd5hXnhYnL6XyZ4rfAtkW/PxaPi9vvUyakwnzR7WceEc0wMHGO3T nYrhzNQAMfsbq0U3gMBPWlp55pAu0DGzg5ZnUU0WHFGiu7HUv1/oe1j8+eJSKSgF 5GcaQXQ0zH2J4D/ppC+jLOnOWbdTICVdryfU/9yNvB2ZMNMzU4uNSv8E6+ww3H3m jSDuDnjRuD4P1nuI7zyC+xfSVxlOBcVYVGj623ODBxBpsZaCIBvbdcqocULIVAng osK+Ouv1ymsKe1MU3MvpyFP8I5nNmv23bb1M8NzshndOylnGdo0= =Xyhg -----END PGP SIGNATURE----- Merge tag 'ti-driver-soc-for-v7.2' of https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux into soc/drivers TI SoC driver updates for v7.2 TI K3 TISCI: - ti_sci: Add BOARDCFG_MANAGED mode for support system suspend/resume cycles - ti_sci: Add support for restoring IRQ and clock contexts during resume. - clk: keystone: sci-clk: Add clock restoration support. SoC Drivers: - k3-socinfo: Add support for identifying AM62P silicon variants via NVMEM, along with corresponding dt-bindings update for nvmem-cells support - k3-ringacc: Fix incorrect access mode for ring pop tail IO/proxy operations Keystone Navigator (knav) Cleanup and Fixes: - knav_qmss: Multiple code quality improvements - knav_qmss_queue: Implement proper resource cleanup in the remove() path General Cleanups: - k3-ringacc: Use str_enabled_disabled() helper for consistency - knav_qmss: Use %pe format specifier for PTR_ERR() printing * tag 'ti-driver-soc-for-v7.2' of https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux: firmware: ti_sci: Add support for restoring clock context during resume clk: keystone: sci-clk: Add restore_context() operation firmware: ti_sci: Add support for restoring IRQs during resume firmware: ti_sci: Add BOARDCFG_MANAGED mode support soc: ti: k3-ringacc: Use str_enabled_disabled() helper soc: ti: knav_dma: Use IOMEM_ERR_PTR() in pktdma_get_regs() soc: ti: knav_dma: Remove dead check on unsigned args.args[0] soc: ti: knav_dma: Remove unused DMA_PRIO_MASK macro soc: ti: knav_qmss_acc: Fix kernel-doc Return: tag soc: ti: knav_qmss: Fix __iomem annotations and __be32 type soc: ti: knav_qmss: Use %pe to print PTR_ERR() soc: ti: knav_qmss: Fix kernel-doc Return: tags soc: ti: knav_qmss: Inline lockdep condition in for_each_handle_rcu soc: ti: knav_qmss: Rename global kdev to knav_qdev to fix -Wshadow soc: ti: knav_qmss: Remove remaining redundant ENOMEM printks soc: ti: knav_qmss_queue: Implement resource cleanup in remove() soc: ti: k3-ringacc: Fix access mode for k3_ringacc_ring_pop_tail_io/proxy soc: ti: knav_dma: fix all kernel-doc warnings in knav_dma.h soc: ti: k3-socinfo: Add support for AM62P variants via NVMEM dt-bindings: hwinfo: ti,k3-socinfo: Add nvmem-cells support Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
10c24a2a37
|
|
@ -15,6 +15,9 @@ description: |
|
|||
represented by CTRLMMR_xxx_JTAGID register which contains information about
|
||||
SoC id and revision.
|
||||
|
||||
On some SoCs like AM62P, the silicon revision is determined by reading
|
||||
alternative registers via NVMEM cells.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^chipid@[0-9a-f]+$"
|
||||
|
|
@ -26,6 +29,14 @@ properties:
|
|||
reg:
|
||||
maxItems: 1
|
||||
|
||||
nvmem-cells:
|
||||
items:
|
||||
- description: Alternate silicon revision register
|
||||
|
||||
nvmem-cell-names:
|
||||
items:
|
||||
- const: gpsw1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ struct sci_clk_provider {
|
|||
* @node: Link for handling clocks probed via DT
|
||||
* @cached_req: Cached requested freq for determine rate calls
|
||||
* @cached_res: Cached result freq for determine rate calls
|
||||
* @parent_id: Parent index for this clock
|
||||
* @rate: Clock rate
|
||||
*/
|
||||
struct sci_clk {
|
||||
struct clk_hw hw;
|
||||
|
|
@ -58,6 +60,8 @@ struct sci_clk {
|
|||
struct list_head node;
|
||||
unsigned long cached_req;
|
||||
unsigned long cached_res;
|
||||
int parent_id;
|
||||
unsigned long rate;
|
||||
};
|
||||
|
||||
#define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
|
||||
|
|
@ -150,6 +154,8 @@ static unsigned long sci_clk_recalc_rate(struct clk_hw *hw,
|
|||
return 0;
|
||||
}
|
||||
|
||||
clk->rate = freq;
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
|
|
@ -210,10 +216,15 @@ static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
unsigned long parent_rate)
|
||||
{
|
||||
struct sci_clk *clk = to_sci_clk(hw);
|
||||
int ret;
|
||||
|
||||
return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id,
|
||||
clk->clk_id, rate / 10 * 9, rate,
|
||||
rate / 10 * 11);
|
||||
ret = clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id,
|
||||
clk->clk_id, rate / 10 * 9, rate,
|
||||
rate / 10 * 11);
|
||||
if (!ret)
|
||||
clk->rate = rate;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -234,12 +245,13 @@ static u8 sci_clk_get_parent(struct clk_hw *hw)
|
|||
dev_err(clk->provider->dev,
|
||||
"get-parent failed for dev=%d, clk=%d, ret=%d\n",
|
||||
clk->dev_id, clk->clk_id, ret);
|
||||
clk->parent_id = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
parent_id = parent_id - clk->clk_id - 1;
|
||||
clk->parent_id = parent_id - clk->clk_id - 1;
|
||||
|
||||
return (u8)parent_id;
|
||||
return (u8)clk->parent_id;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -252,12 +264,28 @@ static u8 sci_clk_get_parent(struct clk_hw *hw)
|
|||
static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct sci_clk *clk = to_sci_clk(hw);
|
||||
int ret;
|
||||
|
||||
clk->cached_req = 0;
|
||||
|
||||
return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
|
||||
clk->clk_id,
|
||||
index + 1 + clk->clk_id);
|
||||
ret = clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
|
||||
clk->clk_id,
|
||||
index + 1 + clk->clk_id);
|
||||
if (!ret)
|
||||
clk->parent_id = index;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sci_clk_restore_context(struct clk_hw *hw)
|
||||
{
|
||||
struct sci_clk *clk = to_sci_clk(hw);
|
||||
|
||||
if (clk->num_parents > 1 && clk->parent_id >= 0)
|
||||
sci_clk_set_parent(hw, (u8)clk->parent_id);
|
||||
|
||||
if (clk->rate)
|
||||
sci_clk_set_rate(hw, clk->rate, 0);
|
||||
}
|
||||
|
||||
static const struct clk_ops sci_clk_ops = {
|
||||
|
|
@ -269,6 +297,7 @@ static const struct clk_ops sci_clk_ops = {
|
|||
.set_rate = sci_clk_set_rate,
|
||||
.get_parent = sci_clk_get_parent,
|
||||
.set_parent = sci_clk_set_parent,
|
||||
.restore_context = sci_clk_restore_context,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -9,14 +9,17 @@
|
|||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/hashtable.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mailbox_client.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
|
@ -87,6 +90,16 @@ struct ti_sci_desc {
|
|||
int max_msg_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ti_sci_irq - Description of allocated irqs
|
||||
* @node: Link to hash table
|
||||
* @desc: Description of the irq
|
||||
*/
|
||||
struct ti_sci_irq {
|
||||
struct hlist_node node;
|
||||
struct ti_sci_msg_req_manage_irq desc;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ti_sci_info - Structure representing a TI SCI instance
|
||||
* @dev: Device pointer
|
||||
|
|
@ -101,6 +114,8 @@ struct ti_sci_desc {
|
|||
* @chan_rx: Receive mailbox channel
|
||||
* @minfo: Message info
|
||||
* @node: list head
|
||||
* @irqs: List of allocated irqs
|
||||
* @irq_lock: Protection for irq hash list
|
||||
* @host_id: Host ID
|
||||
* @fw_caps: FW/SoC low power capabilities
|
||||
* @users: Number of users of this instance
|
||||
|
|
@ -118,6 +133,8 @@ struct ti_sci_info {
|
|||
struct mbox_chan *chan_rx;
|
||||
struct ti_sci_xfers_info minfo;
|
||||
struct list_head node;
|
||||
DECLARE_HASHTABLE(irqs, 8);
|
||||
struct mutex irq_lock;
|
||||
u8 host_id;
|
||||
u64 fw_caps;
|
||||
/* protected by ti_sci_list_mutex */
|
||||
|
|
@ -2299,6 +2316,32 @@ static int ti_sci_manage_irq(const struct ti_sci_handle *handle,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_irq_hash() - Helper API to compute irq hash for the hash table.
|
||||
* @irq: irq to hash
|
||||
*
|
||||
* Return: the computed hash value.
|
||||
*/
|
||||
static int ti_sci_irq_hash(struct ti_sci_msg_req_manage_irq *irq)
|
||||
{
|
||||
return irq->src_id ^ irq->src_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_irq_equal() - Helper API to compare two irqs (generic headers are not
|
||||
* compared)
|
||||
* @irq_a: irq_a to compare
|
||||
* @irq_b: irq_b to compare
|
||||
*
|
||||
* Return: true if the two irqs are equal, else false.
|
||||
*/
|
||||
static bool ti_sci_irq_equal(struct ti_sci_msg_req_manage_irq *irq_a,
|
||||
struct ti_sci_msg_req_manage_irq *irq_b)
|
||||
{
|
||||
return !memcmp(&irq_a->valid_params, &irq_b->valid_params,
|
||||
sizeof(*irq_a) - sizeof(irq_a->hdr));
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_set_irq() - Helper api to configure the irq route between the
|
||||
* requested source and destination
|
||||
|
|
@ -2322,15 +2365,53 @@ static int ti_sci_set_irq(const struct ti_sci_handle *handle, u32 valid_params,
|
|||
u16 dst_host_irq, u16 ia_id, u16 vint,
|
||||
u16 global_event, u8 vint_status_bit, u8 s_host)
|
||||
{
|
||||
struct ti_sci_info *info = handle_to_ti_sci_info(handle);
|
||||
struct ti_sci_msg_req_manage_irq *desc;
|
||||
struct ti_sci_irq *irq;
|
||||
int ret;
|
||||
|
||||
/* Lock for set_irq() and free_irq() to keep the IRQ hash list consistent */
|
||||
guard(mutex)(&info->irq_lock);
|
||||
|
||||
pr_debug("%s: IRQ set with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
|
||||
__func__, valid_params, src_id, src_index,
|
||||
dst_id, dst_host_irq, ia_id, vint, global_event,
|
||||
vint_status_bit);
|
||||
|
||||
return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
|
||||
dst_id, dst_host_irq, ia_id, vint,
|
||||
global_event, vint_status_bit, s_host,
|
||||
TI_SCI_MSG_SET_IRQ);
|
||||
ret = ti_sci_manage_irq(handle, valid_params, src_id, src_index,
|
||||
dst_id, dst_host_irq, ia_id, vint,
|
||||
global_event, vint_status_bit, s_host,
|
||||
TI_SCI_MSG_SET_IRQ);
|
||||
|
||||
if (ret || !(info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST))
|
||||
goto end;
|
||||
|
||||
irq = kzalloc_obj(*irq, GFP_KERNEL);
|
||||
if (!irq) {
|
||||
ti_sci_manage_irq(handle, valid_params, src_id, src_index,
|
||||
dst_id, dst_host_irq, ia_id, vint,
|
||||
global_event, vint_status_bit, s_host,
|
||||
TI_SCI_MSG_FREE_IRQ);
|
||||
ret = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
desc = &irq->desc;
|
||||
desc->valid_params = valid_params;
|
||||
desc->src_id = src_id;
|
||||
desc->src_index = src_index;
|
||||
desc->dst_id = dst_id;
|
||||
desc->dst_host_irq = dst_host_irq;
|
||||
desc->ia_id = ia_id;
|
||||
desc->vint = vint;
|
||||
desc->global_event = global_event;
|
||||
desc->vint_status_bit = vint_status_bit;
|
||||
desc->secondary_host = s_host;
|
||||
|
||||
hash_add(info->irqs, &irq->node, ti_sci_irq_hash(desc));
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2356,15 +2437,53 @@ static int ti_sci_free_irq(const struct ti_sci_handle *handle, u32 valid_params,
|
|||
u16 dst_host_irq, u16 ia_id, u16 vint,
|
||||
u16 global_event, u8 vint_status_bit, u8 s_host)
|
||||
{
|
||||
struct ti_sci_info *info = handle_to_ti_sci_info(handle);
|
||||
struct ti_sci_msg_req_manage_irq irq_desc;
|
||||
struct device *dev = info->dev;
|
||||
struct ti_sci_irq *this_irq;
|
||||
struct hlist_node *tmp_node;
|
||||
int ret;
|
||||
|
||||
guard(mutex)(&info->irq_lock);
|
||||
|
||||
pr_debug("%s: IRQ release with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
|
||||
__func__, valid_params, src_id, src_index,
|
||||
dst_id, dst_host_irq, ia_id, vint, global_event,
|
||||
vint_status_bit);
|
||||
|
||||
return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
|
||||
dst_id, dst_host_irq, ia_id, vint,
|
||||
global_event, vint_status_bit, s_host,
|
||||
TI_SCI_MSG_FREE_IRQ);
|
||||
ret = ti_sci_manage_irq(handle, valid_params, src_id, src_index,
|
||||
dst_id, dst_host_irq, ia_id, vint,
|
||||
global_event, vint_status_bit, s_host,
|
||||
TI_SCI_MSG_FREE_IRQ);
|
||||
|
||||
if (ret || !(info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST))
|
||||
goto end;
|
||||
|
||||
irq_desc.valid_params = valid_params;
|
||||
irq_desc.src_id = src_id;
|
||||
irq_desc.src_index = src_index;
|
||||
irq_desc.dst_id = dst_id;
|
||||
irq_desc.dst_host_irq = dst_host_irq;
|
||||
irq_desc.ia_id = ia_id;
|
||||
irq_desc.vint = vint;
|
||||
irq_desc.global_event = global_event;
|
||||
irq_desc.vint_status_bit = vint_status_bit;
|
||||
irq_desc.secondary_host = s_host;
|
||||
|
||||
hash_for_each_possible_safe(info->irqs, this_irq, tmp_node, node,
|
||||
ti_sci_irq_hash(&irq_desc)) {
|
||||
if (ti_sci_irq_equal(&irq_desc, &this_irq->desc)) {
|
||||
hlist_del(&this_irq->node);
|
||||
kfree(this_irq);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
dev_warn(dev, "%s: should not be here, IRQ was not found in hash list\n",
|
||||
__func__);
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3770,8 +3889,11 @@ static int ti_sci_prepare_system_suspend(struct ti_sci_info *info)
|
|||
return ti_sci_cmd_prepare_sleep(&info->handle,
|
||||
TISCI_MSG_VALUE_SLEEP_MODE_DM_MANAGED,
|
||||
0, 0, 0);
|
||||
} else if (info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED) {
|
||||
/* Nothing to do in the BOARDCFG_MANAGED mode */
|
||||
return 0;
|
||||
} else {
|
||||
/* DM Managed is not supported by the firmware. */
|
||||
/* DM Managed and BoardCfg Managed are not supported by the firmware. */
|
||||
dev_err(info->dev, "Suspend to memory is not supported by the firmware\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
|
@ -3842,7 +3964,10 @@ static int ti_sci_suspend_noirq(struct device *dev)
|
|||
static int ti_sci_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct ti_sci_info *info = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
struct ti_sci_msg_req_manage_irq *irq_desc;
|
||||
struct ti_sci_irq *irq;
|
||||
struct hlist_node *tmp_node;
|
||||
int ret = 0, err = 0, i;
|
||||
u32 source;
|
||||
u64 time;
|
||||
u8 pin;
|
||||
|
|
@ -3854,13 +3979,53 @@ static int ti_sci_resume_noirq(struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
switch (pm_suspend_target_state) {
|
||||
case PM_SUSPEND_MEM:
|
||||
if (info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST) {
|
||||
hash_for_each_safe(info->irqs, i, tmp_node, irq, node) {
|
||||
irq_desc = &irq->desc;
|
||||
ret = ti_sci_manage_irq(&info->handle,
|
||||
irq_desc->valid_params,
|
||||
irq_desc->src_id,
|
||||
irq_desc->src_index,
|
||||
irq_desc->dst_id,
|
||||
irq_desc->dst_host_irq,
|
||||
irq_desc->ia_id,
|
||||
irq_desc->vint,
|
||||
irq_desc->global_event,
|
||||
irq_desc->vint_status_bit,
|
||||
irq_desc->secondary_host,
|
||||
TI_SCI_MSG_SET_IRQ);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to restore IRQ with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d, via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
|
||||
irq_desc->valid_params,
|
||||
irq_desc->src_id,
|
||||
irq_desc->src_index,
|
||||
irq_desc->dst_id,
|
||||
irq_desc->dst_host_irq,
|
||||
irq_desc->ia_id,
|
||||
irq_desc->vint,
|
||||
irq_desc->global_event,
|
||||
irq_desc->vint_status_bit);
|
||||
err = ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (info->fw_caps & MSG_FLAG_CAPS_LPM_CLK_CONTEXT_LOST)
|
||||
clk_restore_context();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = ti_sci_msg_cmd_lpm_wake_reason(&info->handle, &source, &time, &pin, &mode);
|
||||
/* Do not fail to resume on error as the wake reason is not critical */
|
||||
if (!ret)
|
||||
dev_info(dev, "ti_sci: wakeup source:0x%x, pin:0x%x, mode:0x%x\n",
|
||||
source, pin, mode);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ti_sci_pm_complete(struct device *dev)
|
||||
|
|
@ -4009,12 +4174,15 @@ static int ti_sci_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps);
|
||||
dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s\n",
|
||||
dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s%s%s%s\n",
|
||||
info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "",
|
||||
info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "",
|
||||
info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "",
|
||||
info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "",
|
||||
info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : ""
|
||||
info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : "",
|
||||
info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED ? " BoardConfig-Managed" : "",
|
||||
info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST ? " IRQ-Context-Lost" : "",
|
||||
info->fw_caps & MSG_FLAG_CAPS_LPM_CLK_CONTEXT_LOST ? " Clk-Context-Lost" : ""
|
||||
);
|
||||
|
||||
ti_sci_setup_ops(info);
|
||||
|
|
@ -4047,6 +4215,13 @@ static int ti_sci_probe(struct platform_device *pdev)
|
|||
list_add_tail(&info->node, &ti_sci_list);
|
||||
mutex_unlock(&ti_sci_list_mutex);
|
||||
|
||||
ret = devm_mutex_init(dev, &info->irq_lock);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST)
|
||||
hash_init(info->irqs);
|
||||
|
||||
ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "platform_populate failed %pe\n", ERR_PTR(ret));
|
||||
|
|
|
|||
|
|
@ -150,6 +150,12 @@ struct ti_sci_msg_req_reboot {
|
|||
* MSG_FLAG_CAPS_LPM_DM_MANAGED: LPM can be managed by DM
|
||||
* MSG_FLAG_CAPS_LPM_ABORT: Abort entry to LPM
|
||||
* MSG_FLAG_CAPS_IO_ISOLATION: IO Isolation support
|
||||
* MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED: LPM config done statically
|
||||
* for the DM via boardcfg
|
||||
* MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST: DM is not able to restore IRQ
|
||||
* context
|
||||
* MSG_FLAG_CAPS_LPM_CLK_CONTEXT_LOST: DM is not able to restore
|
||||
* Clock context
|
||||
*
|
||||
* Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS
|
||||
* providing currently available SOC/firmware capabilities. SoC that don't
|
||||
|
|
@ -162,6 +168,9 @@ struct ti_sci_msg_resp_query_fw_caps {
|
|||
#define MSG_FLAG_CAPS_LPM_DM_MANAGED TI_SCI_MSG_FLAG(5)
|
||||
#define MSG_FLAG_CAPS_LPM_ABORT TI_SCI_MSG_FLAG(9)
|
||||
#define MSG_FLAG_CAPS_IO_ISOLATION TI_SCI_MSG_FLAG(7)
|
||||
#define MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED TI_SCI_MSG_FLAG(12)
|
||||
#define MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST TI_SCI_MSG_FLAG(14)
|
||||
#define MSG_FLAG_CAPS_LPM_CLK_CONTEXT_LOST TI_SCI_MSG_FLAG(15)
|
||||
#define MSG_MASK_CAPS_LPM GENMASK_ULL(4, 1)
|
||||
u64 fw_caps;
|
||||
} __packed;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/sys_soc.h>
|
||||
#include <linux/dma/ti-cppi5.h>
|
||||
#include <linux/soc/ti/k3-ringacc.h>
|
||||
|
|
@ -1012,7 +1013,7 @@ static int k3_ringacc_ring_pop_head_proxy(struct k3_ring *ring, void *elem)
|
|||
static int k3_ringacc_ring_pop_tail_proxy(struct k3_ring *ring, void *elem)
|
||||
{
|
||||
return k3_ringacc_ring_access_proxy(ring, elem,
|
||||
K3_RINGACC_ACCESS_MODE_POP_HEAD);
|
||||
K3_RINGACC_ACCESS_MODE_POP_TAIL);
|
||||
}
|
||||
|
||||
static int k3_ringacc_ring_access_io(struct k3_ring *ring, void *elem,
|
||||
|
|
@ -1083,7 +1084,7 @@ static int k3_ringacc_ring_pop_io(struct k3_ring *ring, void *elem)
|
|||
static int k3_ringacc_ring_pop_tail_io(struct k3_ring *ring, void *elem)
|
||||
{
|
||||
return k3_ringacc_ring_access_io(ring, elem,
|
||||
K3_RINGACC_ACCESS_MODE_POP_HEAD);
|
||||
K3_RINGACC_ACCESS_MODE_POP_TAIL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1436,7 +1437,7 @@ static int k3_ringacc_init(struct platform_device *pdev,
|
|||
ringacc->rm_gp_range->desc[0].num,
|
||||
ringacc->tisci_dev_id);
|
||||
dev_info(dev, "dma-ring-reset-quirk: %s\n",
|
||||
ringacc->dma_ring_reset_quirk ? "enabled" : "disabled");
|
||||
str_enabled_disabled(ringacc->dma_ring_reset_quirk));
|
||||
dev_info(dev, "RA Proxy rev. %08x, num_proxies:%u\n",
|
||||
readl(&ringacc->proxy_gcfg->revision), ringacc->num_proxies);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/regmap.h>
|
||||
|
|
@ -25,6 +26,8 @@
|
|||
#define CTRLMMR_WKUP_JTAGID_VARIANT_SHIFT (28)
|
||||
#define CTRLMMR_WKUP_JTAGID_VARIANT_MASK GENMASK(31, 28)
|
||||
|
||||
#define GP_SW1_ADR_MASK GENMASK(3, 0)
|
||||
|
||||
#define CTRLMMR_WKUP_JTAGID_PARTNO_SHIFT (12)
|
||||
#define CTRLMMR_WKUP_JTAGID_PARTNO_MASK GENMASK(27, 12)
|
||||
|
||||
|
|
@ -70,6 +73,23 @@ static const char * const am62lx_rev_string_map[] = {
|
|||
"1.0", "1.1",
|
||||
};
|
||||
|
||||
static const char * const am62p_gpsw_rev_string_map[] = {
|
||||
"1.0", "1.1", "1.2",
|
||||
};
|
||||
|
||||
static int
|
||||
k3_chipinfo_get_gpsw_variant(struct device *dev)
|
||||
{
|
||||
u32 gpsw_val = 0;
|
||||
int ret;
|
||||
|
||||
ret = nvmem_cell_read_u32(dev, "gpsw1", &gpsw_val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return gpsw_val & GP_SW1_ADR_MASK;
|
||||
}
|
||||
|
||||
static int
|
||||
k3_chipinfo_partno_to_names(unsigned int partno,
|
||||
struct soc_device_attribute *soc_dev_attr)
|
||||
|
|
@ -86,9 +106,11 @@ k3_chipinfo_partno_to_names(unsigned int partno,
|
|||
}
|
||||
|
||||
static int
|
||||
k3_chipinfo_variant_to_sr(unsigned int partno, unsigned int variant,
|
||||
struct soc_device_attribute *soc_dev_attr)
|
||||
k3_chipinfo_variant_to_sr(struct device *dev, unsigned int partno,
|
||||
unsigned int variant, struct soc_device_attribute *soc_dev_attr)
|
||||
{
|
||||
int gpsw_variant = 0;
|
||||
|
||||
switch (partno) {
|
||||
case JTAG_ID_PARTNO_J721E:
|
||||
if (variant >= ARRAY_SIZE(j721e_rev_string_map))
|
||||
|
|
@ -102,6 +124,19 @@ k3_chipinfo_variant_to_sr(unsigned int partno, unsigned int variant,
|
|||
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "SR%s",
|
||||
am62lx_rev_string_map[variant]);
|
||||
break;
|
||||
case JTAG_ID_PARTNO_AM62PX:
|
||||
/* Check GP_SW1 for silicon revision */
|
||||
gpsw_variant = k3_chipinfo_get_gpsw_variant(dev);
|
||||
if (gpsw_variant == -EPROBE_DEFER)
|
||||
return gpsw_variant;
|
||||
if (gpsw_variant < 0 || gpsw_variant >= ARRAY_SIZE(am62p_gpsw_rev_string_map)) {
|
||||
dev_warn(dev, "Failed to get silicon variant (%d), set SR1.0\n",
|
||||
gpsw_variant);
|
||||
gpsw_variant = 0;
|
||||
}
|
||||
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "SR%s",
|
||||
am62p_gpsw_rev_string_map[gpsw_variant]);
|
||||
break;
|
||||
default:
|
||||
variant++;
|
||||
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "SR%x.0",
|
||||
|
|
@ -173,7 +208,7 @@ static int k3_chipinfo_probe(struct platform_device *pdev)
|
|||
goto err;
|
||||
}
|
||||
|
||||
ret = k3_chipinfo_variant_to_sr(partno_id, variant, soc_dev_attr);
|
||||
ret = k3_chipinfo_variant_to_sr(dev, partno_id, variant, soc_dev_attr);
|
||||
if (ret) {
|
||||
dev_err(dev, "Unknown SoC SR[0x%08X]: %d\n", jtag_id, ret);
|
||||
goto err;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#define DMA_TX_FILT_EINFO BIT(30)
|
||||
#define DMA_TX_PRIO_SHIFT 0
|
||||
#define DMA_RX_PRIO_SHIFT 16
|
||||
#define DMA_PRIO_MASK GENMASK(3, 0)
|
||||
#define DMA_PRIO_DEFAULT 0
|
||||
#define DMA_RX_TIMEOUT_DEFAULT 17500 /* cycles */
|
||||
#define DMA_RX_TIMEOUT_MASK GENMASK(16, 0)
|
||||
|
|
@ -388,11 +387,6 @@ static int of_channel_match_helper(struct device_node *np, const char *name,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (args.args[0] < 0) {
|
||||
dev_err(kdev->dev, "Missing args for %s\n", name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return args.args[0];
|
||||
}
|
||||
|
||||
|
|
@ -526,7 +520,7 @@ static void __iomem *pktdma_get_regs(struct knav_dma_device *dma,
|
|||
if (ret) {
|
||||
dev_err(dev, "Can't translate of node(%pOFn) address for index(%d)\n",
|
||||
node, index);
|
||||
return ERR_PTR(ret);
|
||||
return IOMEM_ERR_PTR(ret);
|
||||
}
|
||||
|
||||
regs = devm_ioremap_resource(kdev->dev, &res);
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ struct knav_pdsp_info {
|
|||
const char *name;
|
||||
struct knav_reg_pdsp_regs __iomem *regs;
|
||||
union {
|
||||
void __iomem *command;
|
||||
u32 __iomem *command;
|
||||
struct knav_reg_acc_command __iomem *acc_command;
|
||||
u32 __iomem *qos_command;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ static const struct knav_range_ops knav_acc_range_ops = {
|
|||
* @node: device node
|
||||
* @range: qmms range information
|
||||
*
|
||||
* Return 0 on success or error
|
||||
* Return: 0 on success, errno otherwise.
|
||||
*/
|
||||
int knav_init_acc_range(struct knav_device *kdev,
|
||||
struct device_node *node,
|
||||
|
|
|
|||
|
|
@ -25,11 +25,8 @@
|
|||
|
||||
#include "knav_qmss.h"
|
||||
|
||||
static struct knav_device *kdev;
|
||||
static struct knav_device *knav_qdev;
|
||||
static DEFINE_MUTEX(knav_dev_lock);
|
||||
#define knav_dev_lock_held() \
|
||||
lockdep_is_held(&knav_dev_lock)
|
||||
|
||||
/* Queue manager register indices in DTS */
|
||||
#define KNAV_QUEUE_PEEK_REG_INDEX 0
|
||||
#define KNAV_QUEUE_STATUS_REG_INDEX 1
|
||||
|
|
@ -58,7 +55,7 @@ static DEFINE_MUTEX(knav_dev_lock);
|
|||
|
||||
#define for_each_handle_rcu(qh, inst) \
|
||||
list_for_each_entry_rcu(qh, &inst->handles, list, \
|
||||
knav_dev_lock_held())
|
||||
lockdep_is_held(&knav_dev_lock))
|
||||
|
||||
#define for_each_instance(idx, inst, kdev) \
|
||||
for (idx = 0, inst = kdev->instances; \
|
||||
|
|
@ -205,10 +202,10 @@ knav_queue_match_id_to_inst(struct knav_device *kdev, unsigned id)
|
|||
|
||||
static inline struct knav_queue_inst *knav_queue_find_by_id(int id)
|
||||
{
|
||||
if (kdev->base_id <= id &&
|
||||
kdev->base_id + kdev->num_queues > id) {
|
||||
id -= kdev->base_id;
|
||||
return knav_queue_match_id_to_inst(kdev, id);
|
||||
if (knav_qdev->base_id <= id &&
|
||||
knav_qdev->base_id + knav_qdev->num_queues > id) {
|
||||
id -= knav_qdev->base_id;
|
||||
return knav_queue_match_id_to_inst(knav_qdev, id);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -296,7 +293,7 @@ static struct knav_queue *knav_queue_open_by_type(const char *name,
|
|||
|
||||
mutex_lock(&knav_dev_lock);
|
||||
|
||||
for_each_instance(idx, inst, kdev) {
|
||||
for_each_instance(idx, inst, knav_qdev) {
|
||||
if (knav_queue_is_reserved(inst))
|
||||
continue;
|
||||
if (!knav_queue_match_type(inst, type))
|
||||
|
|
@ -469,9 +466,9 @@ static int knav_queue_debug_show(struct seq_file *s, void *v)
|
|||
|
||||
mutex_lock(&knav_dev_lock);
|
||||
seq_printf(s, "%s: %u-%u\n",
|
||||
dev_name(kdev->dev), kdev->base_id,
|
||||
kdev->base_id + kdev->num_queues - 1);
|
||||
for_each_instance(idx, inst, kdev)
|
||||
dev_name(knav_qdev->dev), knav_qdev->base_id,
|
||||
knav_qdev->base_id + knav_qdev->num_queues - 1);
|
||||
for_each_instance(idx, inst, knav_qdev)
|
||||
knav_queue_debug_show_instance(s, inst);
|
||||
mutex_unlock(&knav_dev_lock);
|
||||
|
||||
|
|
@ -480,8 +477,8 @@ static int knav_queue_debug_show(struct seq_file *s, void *v)
|
|||
|
||||
DEFINE_SHOW_ATTRIBUTE(knav_queue_debug);
|
||||
|
||||
static inline int knav_queue_pdsp_wait(u32 * __iomem addr, unsigned timeout,
|
||||
u32 flags)
|
||||
static inline int knav_queue_pdsp_wait(u32 __iomem *addr, unsigned int timeout,
|
||||
u32 flags)
|
||||
{
|
||||
unsigned long end;
|
||||
u32 val = 0;
|
||||
|
|
@ -520,7 +517,7 @@ static int knav_queue_flush(struct knav_queue *qh)
|
|||
* Subsequent attempts to open a shared queue should
|
||||
* also have this flag.
|
||||
*
|
||||
* Returns a handle to the open hardware queue if successful. Use IS_ERR()
|
||||
* Return: handle to the open hardware queue on success. Use IS_ERR()
|
||||
* to check the returned value for error codes.
|
||||
*/
|
||||
void *knav_queue_open(const char *name, unsigned id,
|
||||
|
|
@ -576,7 +573,7 @@ EXPORT_SYMBOL_GPL(knav_queue_close);
|
|||
* @cmd: - control commands
|
||||
* @arg: - command argument
|
||||
*
|
||||
* Returns 0 on success, errno otherwise.
|
||||
* Return: 0 on success, errno otherwise.
|
||||
*/
|
||||
int knav_queue_device_control(void *qhandle, enum knav_queue_ctrl_cmd cmd,
|
||||
unsigned long arg)
|
||||
|
|
@ -628,7 +625,7 @@ EXPORT_SYMBOL_GPL(knav_queue_device_control);
|
|||
* @size: - size of data to push
|
||||
* @flags: - can be used to pass additional information
|
||||
*
|
||||
* Returns 0 on success, errno otherwise.
|
||||
* Return: 0 on success, errno otherwise.
|
||||
*/
|
||||
int knav_queue_push(void *qhandle, dma_addr_t dma,
|
||||
unsigned size, unsigned flags)
|
||||
|
|
@ -649,7 +646,7 @@ EXPORT_SYMBOL_GPL(knav_queue_push);
|
|||
* @qhandle: - hardware queue handle
|
||||
* @size: - (optional) size of the data pop'ed.
|
||||
*
|
||||
* Returns a DMA address on success, 0 on failure.
|
||||
* Return: DMA address on success, 0 on failure.
|
||||
*/
|
||||
dma_addr_t knav_queue_pop(void *qhandle, unsigned *size)
|
||||
{
|
||||
|
|
@ -750,8 +747,8 @@ EXPORT_SYMBOL_GPL(knav_pool_desc_dma_to_virt);
|
|||
* @region_id: - QMSS region id from which the descriptors are to be
|
||||
* allocated.
|
||||
*
|
||||
* Returns a pool handle on success.
|
||||
* Use IS_ERR_OR_NULL() to identify error values on return.
|
||||
* Return: pool handle on success. Use IS_ERR_OR_NULL() to identify
|
||||
* error values on return.
|
||||
*/
|
||||
void *knav_pool_create(const char *name,
|
||||
int num_desc, int region_id)
|
||||
|
|
@ -762,19 +759,17 @@ void *knav_pool_create(const char *name,
|
|||
unsigned last_offset;
|
||||
int ret;
|
||||
|
||||
if (!kdev)
|
||||
if (!knav_qdev)
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
if (!kdev->dev)
|
||||
if (!knav_qdev->dev)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
pool = devm_kzalloc(kdev->dev, sizeof(*pool), GFP_KERNEL);
|
||||
if (!pool) {
|
||||
dev_err(kdev->dev, "out of memory allocating pool\n");
|
||||
pool = devm_kzalloc(knav_qdev->dev, sizeof(*pool), GFP_KERNEL);
|
||||
if (!pool)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
for_each_region(kdev, reg_itr) {
|
||||
for_each_region(knav_qdev, reg_itr) {
|
||||
if (reg_itr->id != region_id)
|
||||
continue;
|
||||
region = reg_itr;
|
||||
|
|
@ -782,28 +777,28 @@ void *knav_pool_create(const char *name,
|
|||
}
|
||||
|
||||
if (!region) {
|
||||
dev_err(kdev->dev, "region-id(%d) not found\n", region_id);
|
||||
dev_err(knav_qdev->dev, "region-id(%d) not found\n", region_id);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
pool->queue = knav_queue_open(name, KNAV_QUEUE_GP, 0);
|
||||
if (IS_ERR(pool->queue)) {
|
||||
dev_err(kdev->dev,
|
||||
"failed to open queue for pool(%s), error %ld\n",
|
||||
name, PTR_ERR(pool->queue));
|
||||
dev_err(knav_qdev->dev,
|
||||
"failed to open queue for pool(%s), error %pe\n",
|
||||
name, pool->queue);
|
||||
ret = PTR_ERR(pool->queue);
|
||||
goto err;
|
||||
}
|
||||
|
||||
pool->name = kstrndup(name, KNAV_NAME_SIZE - 1, GFP_KERNEL);
|
||||
pool->kdev = kdev;
|
||||
pool->dev = kdev->dev;
|
||||
pool->kdev = knav_qdev;
|
||||
pool->dev = knav_qdev->dev;
|
||||
|
||||
mutex_lock(&knav_dev_lock);
|
||||
|
||||
if (num_desc > (region->num_desc - region->used_desc)) {
|
||||
dev_err(kdev->dev, "out of descs in region(%d) for pool(%s)\n",
|
||||
dev_err(knav_qdev->dev, "out of descs in region(%d) for pool(%s)\n",
|
||||
region_id, name);
|
||||
ret = -ENOMEM;
|
||||
goto err_unlock;
|
||||
|
|
@ -829,10 +824,10 @@ void *knav_pool_create(const char *name,
|
|||
pool->num_desc = num_desc;
|
||||
pool->region_offset = last_offset;
|
||||
region->used_desc += num_desc;
|
||||
list_add_tail(&pool->list, &kdev->pools);
|
||||
list_add_tail(&pool->list, &knav_qdev->pools);
|
||||
list_add_tail(&pool->region_inst, node);
|
||||
} else {
|
||||
dev_err(kdev->dev, "pool(%s) create failed: fragmented desc pool in region(%d)\n",
|
||||
dev_err(knav_qdev->dev, "pool(%s) create failed: fragmented desc pool in region(%d)\n",
|
||||
name, region_id);
|
||||
ret = -ENOMEM;
|
||||
goto err_unlock;
|
||||
|
|
@ -846,7 +841,7 @@ void *knav_pool_create(const char *name,
|
|||
mutex_unlock(&knav_dev_lock);
|
||||
err:
|
||||
kfree(pool->name);
|
||||
devm_kfree(kdev->dev, pool);
|
||||
devm_kfree(knav_qdev->dev, pool);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(knav_pool_create);
|
||||
|
|
@ -874,7 +869,7 @@ void knav_pool_destroy(void *ph)
|
|||
|
||||
mutex_unlock(&knav_dev_lock);
|
||||
kfree(pool->name);
|
||||
devm_kfree(kdev->dev, pool);
|
||||
devm_kfree(knav_qdev->dev, pool);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(knav_pool_destroy);
|
||||
|
||||
|
|
@ -883,7 +878,7 @@ EXPORT_SYMBOL_GPL(knav_pool_destroy);
|
|||
* knav_pool_desc_get() - Get a descriptor from the pool
|
||||
* @ph: - pool handle
|
||||
*
|
||||
* Returns descriptor from the pool.
|
||||
* Return: descriptor from the pool on success, error pointer otherwise.
|
||||
*/
|
||||
void *knav_pool_desc_get(void *ph)
|
||||
{
|
||||
|
|
@ -922,7 +917,7 @@ EXPORT_SYMBOL_GPL(knav_pool_desc_put);
|
|||
* @dma: - DMA address return pointer
|
||||
* @dma_sz: - adjusted return pointer
|
||||
*
|
||||
* Returns 0 on success, errno otherwise.
|
||||
* Return: 0 on success, errno otherwise.
|
||||
*/
|
||||
int knav_pool_desc_map(void *ph, void *desc, unsigned size,
|
||||
dma_addr_t *dma, unsigned *dma_sz)
|
||||
|
|
@ -947,7 +942,7 @@ EXPORT_SYMBOL_GPL(knav_pool_desc_map);
|
|||
* @dma: - DMA address of descriptor to unmap
|
||||
* @dma_sz: - size of descriptor to unmap
|
||||
*
|
||||
* Returns descriptor address on success, Use IS_ERR_OR_NULL() to identify
|
||||
* Return: descriptor address on success. Use IS_ERR_OR_NULL() to identify
|
||||
* error values on return.
|
||||
*/
|
||||
void *knav_pool_desc_unmap(void *ph, dma_addr_t dma, unsigned dma_sz)
|
||||
|
|
@ -967,7 +962,8 @@ EXPORT_SYMBOL_GPL(knav_pool_desc_unmap);
|
|||
/**
|
||||
* knav_pool_count() - Get the number of descriptors in pool.
|
||||
* @ph: - pool handle
|
||||
* Returns number of elements in the pool.
|
||||
*
|
||||
* Return: number of elements in the pool.
|
||||
*/
|
||||
int knav_pool_count(void *ph)
|
||||
{
|
||||
|
|
@ -1025,10 +1021,8 @@ static void knav_queue_setup_region(struct knav_device *kdev,
|
|||
region->dma_end = region->dma_start + size;
|
||||
|
||||
pool = devm_kzalloc(kdev->dev, sizeof(*pool), GFP_KERNEL);
|
||||
if (!pool) {
|
||||
dev_err(kdev->dev, "out of memory allocating dummy pool\n");
|
||||
if (!pool)
|
||||
goto fail;
|
||||
}
|
||||
pool->num_desc = 0;
|
||||
pool->region_offset = region->num_desc;
|
||||
list_add(&pool->region_inst, ®ion->pools);
|
||||
|
|
@ -1211,10 +1205,8 @@ static int knav_setup_queue_range(struct knav_device *kdev,
|
|||
int ret, i;
|
||||
|
||||
range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL);
|
||||
if (!range) {
|
||||
dev_err(dev, "out of memory allocating range\n");
|
||||
if (!range)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
range->kdev = kdev;
|
||||
range->name = knav_queue_find_name(node);
|
||||
|
|
@ -1376,7 +1368,7 @@ static void __iomem *knav_queue_map_reg(struct knav_device *kdev,
|
|||
if (ret) {
|
||||
dev_err(kdev->dev, "Can't translate of node(%pOFn) address for index(%d)\n",
|
||||
node, index);
|
||||
return ERR_PTR(ret);
|
||||
return IOMEM_ERR_PTR(ret);
|
||||
}
|
||||
|
||||
regs = devm_ioremap_resource(kdev->dev, &res);
|
||||
|
|
@ -1564,7 +1556,7 @@ static int knav_queue_load_pdsp(struct knav_device *kdev,
|
|||
int i, ret, fwlen;
|
||||
const struct firmware *fw;
|
||||
bool found = false;
|
||||
u32 *fwdata;
|
||||
const __be32 *fwdata;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(knav_acc_firmwares); i++) {
|
||||
if (knav_acc_firmwares[i]) {
|
||||
|
|
@ -1586,9 +1578,9 @@ static int knav_queue_load_pdsp(struct knav_device *kdev,
|
|||
dev_info(kdev->dev, "firmware file %s downloaded for PDSP\n",
|
||||
knav_acc_firmwares[i]);
|
||||
|
||||
writel_relaxed(pdsp->id + 1, pdsp->command + 0x18);
|
||||
writel_relaxed(pdsp->id + 1, pdsp->command + 0x6);
|
||||
/* download the firmware */
|
||||
fwdata = (u32 *)fw->data;
|
||||
fwdata = (const __be32 *)fw->data;
|
||||
fwlen = (fw->size + sizeof(u32) - 1) / sizeof(u32);
|
||||
for (i = 0; i < fwlen; i++)
|
||||
writel_relaxed(be32_to_cpu(fwdata[i]), pdsp->iram + i);
|
||||
|
|
@ -1689,7 +1681,7 @@ static inline struct knav_qmgr_info *knav_find_qmgr(unsigned id)
|
|||
{
|
||||
struct knav_qmgr_info *qmgr;
|
||||
|
||||
for_each_qmgr(kdev, qmgr) {
|
||||
for_each_qmgr(knav_qdev, qmgr) {
|
||||
if ((id >= qmgr->start_queue) &&
|
||||
(id < qmgr->start_queue + qmgr->num_queues))
|
||||
return qmgr;
|
||||
|
|
@ -1781,22 +1773,22 @@ static int knav_queue_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
kdev = devm_kzalloc(dev, sizeof(struct knav_device), GFP_KERNEL);
|
||||
if (!kdev) {
|
||||
knav_qdev = devm_kzalloc(dev, sizeof(struct knav_device), GFP_KERNEL);
|
||||
if (!knav_qdev) {
|
||||
dev_err(dev, "memory allocation failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (device_get_match_data(dev))
|
||||
kdev->version = QMSS_66AK2G;
|
||||
knav_qdev->version = QMSS_66AK2G;
|
||||
|
||||
platform_set_drvdata(pdev, kdev);
|
||||
kdev->dev = dev;
|
||||
INIT_LIST_HEAD(&kdev->queue_ranges);
|
||||
INIT_LIST_HEAD(&kdev->qmgrs);
|
||||
INIT_LIST_HEAD(&kdev->pools);
|
||||
INIT_LIST_HEAD(&kdev->regions);
|
||||
INIT_LIST_HEAD(&kdev->pdsps);
|
||||
platform_set_drvdata(pdev, knav_qdev);
|
||||
knav_qdev->dev = dev;
|
||||
INIT_LIST_HEAD(&knav_qdev->queue_ranges);
|
||||
INIT_LIST_HEAD(&knav_qdev->qmgrs);
|
||||
INIT_LIST_HEAD(&knav_qdev->pools);
|
||||
INIT_LIST_HEAD(&knav_qdev->regions);
|
||||
INIT_LIST_HEAD(&knav_qdev->pdsps);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
ret = pm_runtime_resume_and_get(&pdev->dev);
|
||||
|
|
@ -1811,31 +1803,31 @@ static int knav_queue_probe(struct platform_device *pdev)
|
|||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
kdev->base_id = temp[0];
|
||||
kdev->num_queues = temp[1];
|
||||
knav_qdev->base_id = temp[0];
|
||||
knav_qdev->num_queues = temp[1];
|
||||
|
||||
/* Initialize queue managers using device tree configuration */
|
||||
ret = knav_queue_init_qmgrs(kdev, node);
|
||||
ret = knav_queue_init_qmgrs(knav_qdev, node);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* get pdsp configuration values from device tree */
|
||||
ret = knav_queue_setup_pdsps(kdev, node);
|
||||
ret = knav_queue_setup_pdsps(knav_qdev, node);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* get usable queue range values from device tree */
|
||||
ret = knav_setup_queue_pools(kdev, node);
|
||||
ret = knav_setup_queue_pools(knav_qdev, node);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = knav_get_link_ram(kdev, "linkram0", &kdev->link_rams[0]);
|
||||
ret = knav_get_link_ram(knav_qdev, "linkram0", &knav_qdev->link_rams[0]);
|
||||
if (ret) {
|
||||
dev_err(kdev->dev, "could not setup linking ram\n");
|
||||
dev_err(knav_qdev->dev, "could not setup linking ram\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = knav_get_link_ram(kdev, "linkram1", &kdev->link_rams[1]);
|
||||
ret = knav_get_link_ram(knav_qdev, "linkram1", &knav_qdev->link_rams[1]);
|
||||
if (ret) {
|
||||
/*
|
||||
* nothing really, we have one linking ram already, so we just
|
||||
|
|
@ -1843,15 +1835,15 @@ static int knav_queue_probe(struct platform_device *pdev)
|
|||
*/
|
||||
}
|
||||
|
||||
ret = knav_queue_setup_link_ram(kdev);
|
||||
ret = knav_queue_setup_link_ram(knav_qdev);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = knav_queue_setup_regions(kdev, node);
|
||||
ret = knav_queue_setup_regions(knav_qdev, node);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = knav_queue_init_queues(kdev);
|
||||
ret = knav_queue_init_queues(knav_qdev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "hwqueue initialization failed\n");
|
||||
goto err;
|
||||
|
|
@ -1863,9 +1855,9 @@ static int knav_queue_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
err:
|
||||
knav_queue_stop_pdsps(kdev);
|
||||
knav_queue_free_regions(kdev);
|
||||
knav_free_queue_ranges(kdev);
|
||||
knav_queue_stop_pdsps(knav_qdev);
|
||||
knav_queue_free_regions(knav_qdev);
|
||||
knav_free_queue_ranges(knav_qdev);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return ret;
|
||||
|
|
@ -1873,7 +1865,12 @@ static int knav_queue_probe(struct platform_device *pdev)
|
|||
|
||||
static void knav_queue_remove(struct platform_device *pdev)
|
||||
{
|
||||
/* TODO: Free resources */
|
||||
struct knav_device *kdev = platform_get_drvdata(pdev);
|
||||
|
||||
device_ready = false;
|
||||
knav_queue_stop_pdsps(kdev);
|
||||
knav_queue_free_regions(kdev);
|
||||
knav_free_queue_ranges(kdev);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ enum knav_dma_desc_type {
|
|||
* struct knav_dma_tx_cfg: Tx channel configuration
|
||||
* @filt_einfo: Filter extended packet info
|
||||
* @filt_pswords: Filter PS words present
|
||||
* @knav_dma_tx_priority: Tx channel scheduling priority
|
||||
* @priority: Tx channel scheduling priority
|
||||
*/
|
||||
struct knav_dma_tx_cfg {
|
||||
bool filt_einfo;
|
||||
|
|
@ -87,13 +87,13 @@ struct knav_dma_tx_cfg {
|
|||
* struct knav_dma_rx_cfg: Rx flow configuration
|
||||
* @einfo_present: Extended packet info present
|
||||
* @psinfo_present: PS words present
|
||||
* @knav_dma_rx_err_mode: Error during buffer starvation
|
||||
* @knav_dma_desc_type: Host or Monolithic desc
|
||||
* @err_mode: Error during buffer starvation
|
||||
* @desc_type: Host or Monolithic desc
|
||||
* @psinfo_at_sop: PS word located at start of packet
|
||||
* @sop_offset: Start of packet offset
|
||||
* @dst_q: Destination queue for a given flow
|
||||
* @thresh: Rx flow size threshold
|
||||
* @fdq[]: Free desc Queue array
|
||||
* @fdq: Free desc Queue array
|
||||
* @sz_thresh0: RX packet size threshold 0
|
||||
* @sz_thresh1: RX packet size threshold 1
|
||||
* @sz_thresh2: RX packet size threshold 2
|
||||
|
|
@ -115,7 +115,8 @@ struct knav_dma_rx_cfg {
|
|||
|
||||
/**
|
||||
* struct knav_dma_cfg: Pktdma channel configuration
|
||||
* @sl_cfg: Slave configuration
|
||||
* @direction: DMA transfer mode and direction
|
||||
* @u: union containing @tx or @rx
|
||||
* @tx: Tx channel configuration
|
||||
* @rx: Rx flow configuration
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user