Commit bbf5ebde authored by Gilles Chanteperdrix's avatar Gilles Chanteperdrix Committed by Philippe Gerum

ARM: l2x0: ipipe: shorten non-preemptible sections

parent a133d6d0
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kconfig.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
...@@ -48,9 +49,23 @@ struct l2c_init_data { ...@@ -48,9 +49,23 @@ struct l2c_init_data {
#define CACHE_LINE_SIZE 32 #define CACHE_LINE_SIZE 32
#ifdef CONFIG_IPIPE
#define CACHE_RANGE_ATOMIC_MAX 512UL
static int l2x0_wa = -1;
static int __init l2x0_setup_wa(char *str)
{
l2x0_wa = !!simple_strtol(str, NULL, 0);
return 0;
}
early_param("l2x0_write_allocate", l2x0_setup_wa);
#else
#define CACHE_RANGE_ATOMIC_MAX 4096UL
static int l2x0_wa = 1;
#endif
static void __iomem *l2x0_base; static void __iomem *l2x0_base;
static const struct l2c_init_data *l2x0_data; static const struct l2c_init_data *l2x0_data;
static DEFINE_RAW_SPINLOCK(l2x0_lock); static IPIPE_DEFINE_RAW_SPINLOCK(l2x0_lock);
static u32 l2x0_way_mask; /* Bitmask of active ways */ static u32 l2x0_way_mask; /* Bitmask of active ways */
static u32 l2x0_size; static u32 l2x0_size;
static unsigned long sync_reg_offset = L2X0_CACHE_SYNC; static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
...@@ -296,10 +311,10 @@ static void l2c220_op_way(void __iomem *base, unsigned reg) ...@@ -296,10 +311,10 @@ static void l2c220_op_way(void __iomem *base, unsigned reg)
static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long start, static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long start,
unsigned long end, unsigned long flags) unsigned long end, unsigned long flags)
{ {
raw_spinlock_t *lock = &l2x0_lock; typeof(l2x0_lock) *lock = &l2x0_lock;
while (start < end) { while (start < end) {
unsigned long blk_end = start + min(end - start, 4096UL); unsigned long blk_end = start + min(end - start, CACHE_RANGE_ATOMIC_MAX);
while (start < blk_end) { while (start < blk_end) {
l2c_wait_mask(reg, 1); l2c_wait_mask(reg, 1);
...@@ -510,13 +525,13 @@ static void l2c310_inv_range_erratum(unsigned long start, unsigned long end) ...@@ -510,13 +525,13 @@ static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
static void l2c310_flush_range_erratum(unsigned long start, unsigned long end) static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
{ {
raw_spinlock_t *lock = &l2x0_lock; typeof(l2x0_lock) *lock = &l2x0_lock;
unsigned long flags; unsigned long flags;
void __iomem *base = l2x0_base; void __iomem *base = l2x0_base;
raw_spin_lock_irqsave(lock, flags); raw_spin_lock_irqsave(lock, flags);
while (start < end) { while (start < end) {
unsigned long blk_end = start + min(end - start, 4096UL); unsigned long blk_end = start + min(end - start, CACHE_RANGE_ATOMIC_MAX);
l2c_set_debug(base, 0x03); l2c_set_debug(base, 0x03);
while (start < blk_end) { while (start < blk_end) {
...@@ -812,6 +827,28 @@ static int __init __l2c_init(const struct l2c_init_data *data, ...@@ -812,6 +827,28 @@ static int __init __l2c_init(const struct l2c_init_data *data,
if (aux_val & aux_mask) if (aux_val & aux_mask)
pr_alert("L2C: platform provided aux values permit register corruption.\n"); pr_alert("L2C: platform provided aux values permit register corruption.\n");
if (IS_ENABLED(CONFIG_IPIPE)) {
switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
case L2X0_CACHE_ID_PART_L310:
if ((cache_id & L2X0_CACHE_ID_RTL_MASK)
>= L310_CACHE_ID_RTL_R3P2) {
l2x0_wa = 1;
pr_alert("L2C: I-pipe: revision >= L310-r3p2 detected, forcing WA.\n");
}
case L2X0_CACHE_ID_PART_L220:
if (l2x0_wa < 0) {
l2x0_wa = 0;
pr_alert("L2C: I-pipe: l2x0_write_allocate= not specified, defaults to 0 (disabled).\n");
}
if (!l2x0_wa) {
aux_mask &= ~L220_AUX_CTRL_FWA_MASK;
aux_val &= ~L220_AUX_CTRL_FWA_MASK;
aux_val |= 1 << L220_AUX_CTRL_FWA_SHIFT;
} else
pr_alert("L2C: I-pipe: write-allocate enabled, induces high latencies.\n");
}
}
old_aux = aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); old_aux = aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
aux &= aux_mask; aux &= aux_mask;
aux |= aux_val; aux |= aux_val;
......
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