Commit deb0df1a authored by Olof Johansson's avatar Olof Johansson

Merge tag 'soc-fsl-next-v5.3-2' of...

Merge tag 'soc-fsl-next-v5.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux into arm/drivers

NXP/FSL SoC driver updates for v5.3 (take 2)

DPAA2 Console driver
- Add driver to export two char devices to dump logs for MC and
  AIOP

DPAA2 DPIO driver
- Add support for memory backed QBMan portals
- Increase the timeout period to prevent false error
- Add APIs to retrieve QBMan portal probing status

DPAA Qman driver
- Only make liodn fixup on powerpc SoCs with PAMU iommu

QUICC Engine
- Add support for importing qe-snums through device tree
- Some cleanups and foot print optimzation

* tag 'soc-fsl-next-v5.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux:
  soc: fsl: qe: fold qe_get_num_of_snums into qe_snums_init
  soc: fsl: qe: support fsl,qe-snums property
  dt-bindings: soc: fsl: qe: document new fsl,qe-snums binding
  soc: fsl: qe: introduce qe_get_device_node helper
  soc: fsl: qe: reduce static memory footprint by 1.7K
  soc: fsl: qe: drop useless static qualifier
  soc: fsl: fix spelling mistake "Firmaware" -> "Firmware"

Link: https://lore.kernel.org/r/20190605194511.12127-1-leoyang.li@nxp.comSigned-off-by: default avatarOlof Johansson <olof@lixom.net>
parents 5f9e832c 21560067
...@@ -18,7 +18,8 @@ Required properties: ...@@ -18,7 +18,8 @@ Required properties:
- reg : offset and length of the device registers. - reg : offset and length of the device registers.
- bus-frequency : the clock frequency for QUICC Engine. - bus-frequency : the clock frequency for QUICC Engine.
- fsl,qe-num-riscs: define how many RISC engines the QE has. - fsl,qe-num-riscs: define how many RISC engines the QE has.
- fsl,qe-num-snums: define how many serial number(SNUM) the QE can use for the - fsl,qe-snums: This property has to be specified as '/bits/ 8' value,
defining the array of serial number (SNUM) values for the virtual
threads. threads.
Optional properties: Optional properties:
...@@ -34,6 +35,11 @@ Recommended properties ...@@ -34,6 +35,11 @@ Recommended properties
- brg-frequency : the internal clock source frequency for baud-rate - brg-frequency : the internal clock source frequency for baud-rate
generators in Hz. generators in Hz.
Deprecated properties
- fsl,qe-num-snums: define how many serial number(SNUM) the QE can use
for the threads. Use fsl,qe-snums instead to not only specify the
number of snums, but also their values.
Example: Example:
qe@e0100000 { qe@e0100000 {
#address-cells = <1>; #address-cells = <1>;
...@@ -44,6 +50,11 @@ Example: ...@@ -44,6 +50,11 @@ Example:
reg = <e0100000 480>; reg = <e0100000 480>;
brg-frequency = <0>; brg-frequency = <0>;
bus-frequency = <179A7B00>; bus-frequency = <179A7B00>;
fsl,qe-snums = /bits/ 8 <
0x04 0x05 0x0C 0x0D 0x14 0x15 0x1C 0x1D
0x24 0x25 0x2C 0x2D 0x34 0x35 0x88 0x89
0x98 0x99 0xA8 0xA9 0xB8 0xB9 0xC8 0xC9
0xD8 0xD9 0xE8 0xE9>;
} }
* Multi-User RAM (MURAM) * Multi-User RAM (MURAM)
......
...@@ -73,7 +73,7 @@ static u64 get_mc_fw_base_address(void) ...@@ -73,7 +73,7 @@ static u64 get_mc_fw_base_address(void)
mcfbaregs = ioremap(mc_base_addr.start, resource_size(&mc_base_addr)); mcfbaregs = ioremap(mc_base_addr.start, resource_size(&mc_base_addr));
if (!mcfbaregs) { if (!mcfbaregs) {
pr_err("could not map MC Firmaware Base registers\n"); pr_err("could not map MC Firmware Base registers\n");
return 0; return 0;
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* General Purpose functions for the global management of the * General Purpose functions for the global management of the
* QUICC Engine (QE). * QUICC Engine (QE).
*/ */
#include <linux/bitmap.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -39,29 +40,32 @@ static DEFINE_SPINLOCK(qe_lock); ...@@ -39,29 +40,32 @@ static DEFINE_SPINLOCK(qe_lock);
DEFINE_SPINLOCK(cmxgcr_lock); DEFINE_SPINLOCK(cmxgcr_lock);
EXPORT_SYMBOL(cmxgcr_lock); EXPORT_SYMBOL(cmxgcr_lock);
/* QE snum state */
enum qe_snum_state {
QE_SNUM_STATE_USED,
QE_SNUM_STATE_FREE
};
/* QE snum */
struct qe_snum {
u8 num;
enum qe_snum_state state;
};
/* We allocate this here because it is used almost exclusively for /* We allocate this here because it is used almost exclusively for
* the communication processor devices. * the communication processor devices.
*/ */
struct qe_immap __iomem *qe_immr; struct qe_immap __iomem *qe_immr;
EXPORT_SYMBOL(qe_immr); EXPORT_SYMBOL(qe_immr);
static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */ static u8 snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */
static DECLARE_BITMAP(snum_state, QE_NUM_OF_SNUM);
static unsigned int qe_num_of_snum; static unsigned int qe_num_of_snum;
static phys_addr_t qebase = -1; static phys_addr_t qebase = -1;
static struct device_node *qe_get_device_node(void)
{
struct device_node *qe;
/*
* Newer device trees have an "fsl,qe" compatible property for the QE
* node, but we still need to support older device trees.
*/
qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
if (qe)
return qe;
return of_find_node_by_type(NULL, "qe");
}
static phys_addr_t get_qe_base(void) static phys_addr_t get_qe_base(void)
{ {
struct device_node *qe; struct device_node *qe;
...@@ -71,12 +75,9 @@ static phys_addr_t get_qe_base(void) ...@@ -71,12 +75,9 @@ static phys_addr_t get_qe_base(void)
if (qebase != -1) if (qebase != -1)
return qebase; return qebase;
qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); qe = qe_get_device_node();
if (!qe) {
qe = of_find_node_by_type(NULL, "qe");
if (!qe) if (!qe)
return qebase; return qebase;
}
ret = of_address_to_resource(qe, 0, &res); ret = of_address_to_resource(qe, 0, &res);
if (!ret) if (!ret)
...@@ -170,12 +171,9 @@ unsigned int qe_get_brg_clk(void) ...@@ -170,12 +171,9 @@ unsigned int qe_get_brg_clk(void)
if (brg_clk) if (brg_clk)
return brg_clk; return brg_clk;
qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); qe = qe_get_device_node();
if (!qe) {
qe = of_find_node_by_type(NULL, "qe");
if (!qe) if (!qe)
return brg_clk; return brg_clk;
}
prop = of_get_property(qe, "brg-frequency", &size); prop = of_get_property(qe, "brg-frequency", &size);
if (prop && size == sizeof(*prop)) if (prop && size == sizeof(*prop))
...@@ -281,7 +279,6 @@ EXPORT_SYMBOL(qe_clock_source); ...@@ -281,7 +279,6 @@ EXPORT_SYMBOL(qe_clock_source);
*/ */
static void qe_snums_init(void) static void qe_snums_init(void)
{ {
int i;
static const u8 snum_init_76[] = { static const u8 snum_init_76[] = {
0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89, 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
...@@ -302,19 +299,39 @@ static void qe_snums_init(void) ...@@ -302,19 +299,39 @@ static void qe_snums_init(void)
0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59, 0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
0x68, 0x69, 0x78, 0x79, 0x80, 0x81, 0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
}; };
static const u8 *snum_init; struct device_node *qe;
const u8 *snum_init;
int i;
qe_num_of_snum = qe_get_num_of_snums(); bitmap_zero(snum_state, QE_NUM_OF_SNUM);
qe_num_of_snum = 28; /* The default number of snum for threads is 28 */
qe = qe_get_device_node();
if (qe) {
i = of_property_read_variable_u8_array(qe, "fsl,qe-snums",
snums, 1, QE_NUM_OF_SNUM);
if (i > 0) {
of_node_put(qe);
qe_num_of_snum = i;
return;
}
/*
* Fall back to legacy binding of using the value of
* fsl,qe-num-snums to choose one of the static arrays
* above.
*/
of_property_read_u32(qe, "fsl,qe-num-snums", &qe_num_of_snum);
of_node_put(qe);
}
if (qe_num_of_snum == 76) if (qe_num_of_snum == 76) {
snum_init = snum_init_76; snum_init = snum_init_76;
else } else if (qe_num_of_snum == 28 || qe_num_of_snum == 46) {
snum_init = snum_init_46; snum_init = snum_init_46;
} else {
for (i = 0; i < qe_num_of_snum; i++) { pr_err("QE: unsupported value of fsl,qe-num-snums: %u\n", qe_num_of_snum);
snums[i].num = snum_init[i]; return;
snums[i].state = QE_SNUM_STATE_FREE;
} }
memcpy(snums, snum_init, qe_num_of_snum);
} }
int qe_get_snum(void) int qe_get_snum(void)
...@@ -324,12 +341,10 @@ int qe_get_snum(void) ...@@ -324,12 +341,10 @@ int qe_get_snum(void)
int i; int i;
spin_lock_irqsave(&qe_lock, flags); spin_lock_irqsave(&qe_lock, flags);
for (i = 0; i < qe_num_of_snum; i++) { i = find_first_zero_bit(snum_state, qe_num_of_snum);
if (snums[i].state == QE_SNUM_STATE_FREE) { if (i < qe_num_of_snum) {
snums[i].state = QE_SNUM_STATE_USED; set_bit(i, snum_state);
snum = snums[i].num; snum = snums[i];
break;
}
} }
spin_unlock_irqrestore(&qe_lock, flags); spin_unlock_irqrestore(&qe_lock, flags);
...@@ -339,14 +354,10 @@ EXPORT_SYMBOL(qe_get_snum); ...@@ -339,14 +354,10 @@ EXPORT_SYMBOL(qe_get_snum);
void qe_put_snum(u8 snum) void qe_put_snum(u8 snum)
{ {
int i; const u8 *p = memchr(snums, snum, qe_num_of_snum);
for (i = 0; i < qe_num_of_snum; i++) { if (p)
if (snums[i].num == snum) { clear_bit(p - snums, snum_state);
snums[i].state = QE_SNUM_STATE_FREE;
break;
}
}
} }
EXPORT_SYMBOL(qe_put_snum); EXPORT_SYMBOL(qe_put_snum);
...@@ -572,16 +583,9 @@ struct qe_firmware_info *qe_get_firmware_info(void) ...@@ -572,16 +583,9 @@ struct qe_firmware_info *qe_get_firmware_info(void)
initialized = 1; initialized = 1;
/* qe = qe_get_device_node();
* Newer device trees have an "fsl,qe" compatible property for the QE
* node, but we still need to support older device trees.
*/
qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
if (!qe) {
qe = of_find_node_by_type(NULL, "qe");
if (!qe) if (!qe)
return NULL; return NULL;
}
/* Find the 'firmware' child node */ /* Find the 'firmware' child node */
fw = of_get_child_by_name(qe, "firmware"); fw = of_get_child_by_name(qe, "firmware");
...@@ -627,16 +631,9 @@ unsigned int qe_get_num_of_risc(void) ...@@ -627,16 +631,9 @@ unsigned int qe_get_num_of_risc(void)
unsigned int num_of_risc = 0; unsigned int num_of_risc = 0;
const u32 *prop; const u32 *prop;
qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); qe = qe_get_device_node();
if (!qe) {
/* Older devices trees did not have an "fsl,qe"
* compatible property, so we need to look for
* the QE node by name.
*/
qe = of_find_node_by_type(NULL, "qe");
if (!qe) if (!qe)
return num_of_risc; return num_of_risc;
}
prop = of_get_property(qe, "fsl,qe-num-riscs", &size); prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
if (prop && size == sizeof(*prop)) if (prop && size == sizeof(*prop))
...@@ -650,37 +647,7 @@ EXPORT_SYMBOL(qe_get_num_of_risc); ...@@ -650,37 +647,7 @@ EXPORT_SYMBOL(qe_get_num_of_risc);
unsigned int qe_get_num_of_snums(void) unsigned int qe_get_num_of_snums(void)
{ {
struct device_node *qe; return qe_num_of_snum;
int size;
unsigned int num_of_snums;
const u32 *prop;
num_of_snums = 28; /* The default number of snum for threads is 28 */
qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
if (!qe) {
/* Older devices trees did not have an "fsl,qe"
* compatible property, so we need to look for
* the QE node by name.
*/
qe = of_find_node_by_type(NULL, "qe");
if (!qe)
return num_of_snums;
}
prop = of_get_property(qe, "fsl,qe-num-snums", &size);
if (prop && size == sizeof(*prop)) {
num_of_snums = *prop;
if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
/* No QE ever has fewer than 28 SNUMs */
pr_err("QE: number of snum is invalid\n");
of_node_put(qe);
return -EINVAL;
}
}
of_node_put(qe);
return num_of_snums;
} }
EXPORT_SYMBOL(qe_get_num_of_snums); EXPORT_SYMBOL(qe_get_num_of_snums);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment