mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
freertos: add freertos support [1/1]
PD#SWPL-71741 PD#SWPL-128739 Problem: 1 add freertos support 2 rtos mipi irq miss frequently when booting kernel Solution: 1 add freertos support 2 mark gic distributor disable Verify: C2 T7 Change-Id: Ib2b18fbcb026afa8df7654eac90355f080e9a74b Signed-off-by: wanwei.jiang <wanwei.jiang@amlogic.com>
This commit is contained in:
committed by
Dongjin Kim
parent
d7bfa70f25
commit
9512f6d7f0
@@ -48,6 +48,10 @@
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mpu.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
#include <linux/amlogic/freertos.h>
|
||||
#endif
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/ipi.h>
|
||||
|
||||
@@ -76,6 +80,9 @@ enum ipi_msg_type {
|
||||
IPI_IRQ_WORK,
|
||||
IPI_COMPLETION,
|
||||
NR_IPI,
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
IPI_FREERTOS = NR_IPI,
|
||||
#endif
|
||||
/*
|
||||
* CPU_BACKTRACE is special and not included in NR_IPI
|
||||
* or tracable with trace_ipi_*
|
||||
@@ -687,6 +694,13 @@ static void do_handle_IPI(int ipinr)
|
||||
break;
|
||||
|
||||
case IPI_CPU_BACKTRACE:
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS_NOFITIER) && IS_ENABLED(CONFIG_AMLOGIC_FREERTOS_C3)
|
||||
call_freertos_notifiers(1, NULL);
|
||||
#endif
|
||||
if (!freertos_finish())
|
||||
break;
|
||||
#endif
|
||||
printk_deferred_enter();
|
||||
nmi_cpu_backtrace(get_irq_regs());
|
||||
printk_deferred_exit();
|
||||
@@ -771,6 +785,14 @@ void smp_send_reschedule(int cpu)
|
||||
smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS_IPI_SEND)
|
||||
void arch_send_ipi_rtos(int cpu)
|
||||
{
|
||||
smp_cross_call(cpumask_of(cpu), IPI_FREERTOS);
|
||||
}
|
||||
EXPORT_SYMBOL(arch_send_ipi_rtos);
|
||||
#endif
|
||||
|
||||
void smp_send_stop(void)
|
||||
{
|
||||
unsigned long timeout;
|
||||
|
||||
@@ -59,6 +59,10 @@
|
||||
#undef CREATE_TRACE_POINTS
|
||||
#include <trace/hooks/debug.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
#include <linux/amlogic/freertos.h>
|
||||
#endif
|
||||
|
||||
DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number);
|
||||
EXPORT_PER_CPU_SYMBOL(cpu_number);
|
||||
EXPORT_TRACEPOINT_SYMBOL_GPL(ipi_raise);
|
||||
@@ -82,6 +86,9 @@ enum ipi_msg_type {
|
||||
IPI_TIMER,
|
||||
IPI_IRQ_WORK,
|
||||
IPI_WAKEUP,
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
IPI_FREERTOS = 7,
|
||||
#endif
|
||||
NR_IPI
|
||||
};
|
||||
|
||||
@@ -810,6 +817,9 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
|
||||
[IPI_TIMER] = "Timer broadcast interrupts",
|
||||
[IPI_IRQ_WORK] = "IRQ work interrupts",
|
||||
[IPI_WAKEUP] = "CPU wake-up interrupts",
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
[IPI_FREERTOS] = "CPU freertos interrupts",
|
||||
#endif
|
||||
};
|
||||
|
||||
static void smp_cross_call(const struct cpumask *target, unsigned int ipinr);
|
||||
@@ -856,6 +866,13 @@ void arch_irq_work_raise(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS_IPI_SEND)
|
||||
void arch_send_ipi_rtos(int cpu)
|
||||
{
|
||||
smp_cross_call(cpumask_of(cpu), IPI_FREERTOS);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void local_cpu_stop(void)
|
||||
{
|
||||
set_cpu_online(smp_processor_id(), false);
|
||||
@@ -949,6 +966,12 @@ static void do_handle_IPI(int ipinr)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
case IPI_FREERTOS:
|
||||
freertos_finish();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
|
||||
break;
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
|
||||
#include "irq-gic-common.h"
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
#include <linux/amlogic/freertos.h>
|
||||
#endif
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
|
||||
|
||||
void gic_enable_of_quirks(const struct device_node *np,
|
||||
@@ -94,30 +98,62 @@ void gic_dist_config(void __iomem *base, int gic_irqs,
|
||||
void (*sync_access)(void))
|
||||
{
|
||||
unsigned int i;
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
u32 tmp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set all global interrupts to be level triggered, active low.
|
||||
*/
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
for (i = 32; i < gic_irqs; i += 16) {
|
||||
tmp = readl_relaxed(base + GIC_DIST_CONFIG + i / 4);
|
||||
tmp = freertos_get_irqregval
|
||||
(GICD_INT_ACTLOW_LVLTRIG, tmp, i, 16);
|
||||
writel_relaxed(tmp, base + GIC_DIST_CONFIG + i / 4);
|
||||
}
|
||||
#else
|
||||
for (i = 32; i < gic_irqs; i += 16)
|
||||
writel_relaxed(GICD_INT_ACTLOW_LVLTRIG,
|
||||
base + GIC_DIST_CONFIG + i / 4);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set priority on all global interrupts.
|
||||
*/
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
for (i = 32; i < gic_irqs; i += 4) {
|
||||
tmp = readl_relaxed(base + GIC_DIST_PRI + i);
|
||||
tmp = freertos_get_irqregval
|
||||
(GICD_INT_DEF_PRI_X4, tmp, i, 4);
|
||||
writel_relaxed(tmp, base + GIC_DIST_PRI + i);
|
||||
}
|
||||
#else
|
||||
for (i = 32; i < gic_irqs; i += 4)
|
||||
writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Deactivate and disable all SPIs. Leave the PPI and SGIs
|
||||
* alone as they are in the redistributor registers on GICv3.
|
||||
*/
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
for (i = 32; i < gic_irqs; i += 32) {
|
||||
writel_relaxed
|
||||
(freertos_get_irqregval(GICD_INT_EN_CLR_X32, 0, i, 32),
|
||||
base + GIC_DIST_ACTIVE_CLEAR + i / 8);
|
||||
writel_relaxed
|
||||
(freertos_get_irqregval(GICD_INT_EN_CLR_X32, 0, i, 32),
|
||||
base + GIC_DIST_ENABLE_CLEAR + i / 8);
|
||||
}
|
||||
#else
|
||||
for (i = 32; i < gic_irqs; i += 32) {
|
||||
writel_relaxed(GICD_INT_EN_CLR_X32,
|
||||
base + GIC_DIST_ACTIVE_CLEAR + i / 8);
|
||||
writel_relaxed(GICD_INT_EN_CLR_X32,
|
||||
base + GIC_DIST_ENABLE_CLEAR + i / 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sync_access)
|
||||
sync_access();
|
||||
|
||||
@@ -48,6 +48,10 @@
|
||||
|
||||
#include "irq-gic-common.h"
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
#include <linux/amlogic/freertos.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
#include <asm/cpufeature.h>
|
||||
|
||||
@@ -466,15 +470,21 @@ static void gic_cpu_if_up(struct gic_chip_data *gic)
|
||||
writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
|
||||
}
|
||||
|
||||
|
||||
static void gic_dist_init(struct gic_chip_data *gic)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 cpumask;
|
||||
unsigned int gic_irqs = gic->gic_irqs;
|
||||
void __iomem *base = gic_data_dist_base(gic);
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
u32 tmp;
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
/*disable gic distributor will result in freertos lost interrupt*/
|
||||
#else
|
||||
writel_relaxed(GICD_DISABLE, base + GIC_DIST_CTRL);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set all global interrupts to this CPU only.
|
||||
@@ -482,8 +492,16 @@ static void gic_dist_init(struct gic_chip_data *gic)
|
||||
cpumask = gic_get_cpumask(gic);
|
||||
cpumask |= cpumask << 8;
|
||||
cpumask |= cpumask << 16;
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_FREERTOS)
|
||||
for (i = 32; i < gic_irqs; i += 4) {
|
||||
tmp = readl_relaxed(base + GIC_DIST_TARGET + i * 4 / 4);
|
||||
tmp = freertos_get_irqregval(cpumask, tmp, i, 4);
|
||||
writel_relaxed(tmp, base + GIC_DIST_TARGET + i * 4 / 4);
|
||||
}
|
||||
#else
|
||||
for (i = 32; i < gic_irqs; i += 4)
|
||||
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
|
||||
#endif
|
||||
|
||||
gic_dist_config(base, gic_irqs, NULL);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user