diff options
author | Jason M. Bills <jason.m.bills@linux.intel.com> | 2020-05-06 01:31:17 +0300 |
---|---|---|
committer | Jason M. Bills <jason.m.bills@linux.intel.com> | 2020-05-14 21:54:34 +0300 |
commit | eda2c7c523d858d25fe25052254a7f393767310b (patch) | |
tree | 7c14ec3de42b7fc6c86bc3b0f9ecb4b9f21a5d14 /meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0005-Ast2600-Enable-interrupt-in-u-boot.patch | |
parent | 794d26fa53ad7e8cb54a3a5773436b1d8e813f35 (diff) | |
download | openbmc-eda2c7c523d858d25fe25052254a7f393767310b.tar.xz |
Update to internal 0.53
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0005-Ast2600-Enable-interrupt-in-u-boot.patch')
-rw-r--r-- | meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0005-Ast2600-Enable-interrupt-in-u-boot.patch | 435 |
1 files changed, 0 insertions, 435 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0005-Ast2600-Enable-interrupt-in-u-boot.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0005-Ast2600-Enable-interrupt-in-u-boot.patch deleted file mode 100644 index 66f3d3b12..000000000 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0005-Ast2600-Enable-interrupt-in-u-boot.patch +++ /dev/null @@ -1,435 +0,0 @@ -From 143fb89b03af61bd807b0d6f9f11d6801cf8fe69 Mon Sep 17 00:00:00 2001 -From: Kuiying Wang <kuiying.wang@intel.com> -Date: Fri, 3 Jan 2020 12:52:29 +0800 -Subject: [PATCH] Enable interrupt in u-boot. - -Ast2600 is Cortex-A7 -GIC V2 is used as the interrupt controller -GIC includes GICD and GICC - -Testedby: -1. Enable interrupt based SW handshake for ESPI -2. Both ArcherCity and Ast2600 EVB are working well. - -Signed-off-by: Kuiying Wang <kuiying.wang@intel.com> ---- - arch/arm/lib/vectors.S | 31 ++++++- - board/aspeed/ast2600_intel/ast-irq.c | 154 +++++++++++++++++------------------ - 2 files changed, 105 insertions(+), 80 deletions(-) - -diff --git a/arch/arm/lib/vectors.S b/arch/arm/lib/vectors.S -index 2ca6e2494a7a..e2ed04a204de 100644 ---- a/arch/arm/lib/vectors.S -+++ b/arch/arm/lib/vectors.S -@@ -13,7 +13,7 @@ - */ - - #include <config.h> -- -+#define CONFIG_USE_IRQ - /* - * A macro to allow insertion of an ARM exception vector either - * for the non-boot0 case or by a boot0-header. -@@ -145,6 +145,17 @@ fiq: - - #else /* !CONFIG_SPL_BUILD */ - -+#ifdef CONFIG_USE_IRQ -+/* IRQ stack memory (calculated at run-time) */ -+.globl IRQ_STACK_START -+IRQ_STACK_START: -+ .word 0x0badc0de -+/* IRQ stack memory (calculated at run-time) */ -+.globl FIQ_STACK_START -+FIQ_STACK_START: -+ .word 0x0badc0de -+#endif -+ - /* IRQ stack memory (calculated at run-time) + 8 bytes */ - .globl IRQ_STACK_START_IN - IRQ_STACK_START_IN: -@@ -277,17 +288,31 @@ not_used: - bad_save_user_regs - bl do_not_used - -+ .align 5 -+#ifdef CONFIG_USE_IRQ -+irq: -+ get_irq_stack -+ irq_save_user_regs -+ bl do_irq -+ irq_restore_user_regs -+ .align 5 -+fiq: -+ get_fiq_stack -+ /* someone ought to write a more effective fiq_save_user_regs */ -+ irq_save_user_regs -+ bl do_fiq -+ irq_restore_user_regs - - .align 5 -+#else - irq: - get_bad_stack - bad_save_user_regs - bl do_irq -- - .align 5 - fiq: - get_bad_stack - bad_save_user_regs - bl do_fiq -- -+#endif /* CONFIG_USE_IRQ */ - #endif /* CONFIG_SPL_BUILD */ -diff --git a/board/aspeed/ast2600_intel/ast-irq.c b/board/aspeed/ast2600_intel/ast-irq.c -index f817f8cd7c81..6e91b17ab186 100644 ---- a/board/aspeed/ast2600_intel/ast-irq.c -+++ b/board/aspeed/ast2600_intel/ast-irq.c -@@ -18,19 +18,6 @@ DECLARE_GLOBAL_DATA_PTR; - #define GIC_INTERFACE_OFFSET 0x4000 - #define GIC_VIRT_OFFSET 0x6000 - --#define VIC_STATUS_L 0x80 --#define VIC_STATUS_H 0x84 --#define VIC_IRQ_SELECTION_L 0x98 --#define VIC_IRQ_SELECTION_H 0x9C --#define VIC_ENABLE_L 0xA0 --#define VIC_ENABLE_H 0xA4 --#define VIC_ENABLE_CLEAR_L 0xA8 --#define VIC_ENABLE_CLEAR_H 0xAC --#define VIC_INTERRUPT_CLEAR_L 0xD8 --#define VIC_INTERRUPT_CLEAR_H 0xDC -- --#define VIC_CLEAR_ALL (~0) -- - /* GIC_DISTRIBUTOR_OFFSET register offsets */ - #define GICD_CTLR 0x000 - #define GICD_TYPER 0x004 -@@ -82,7 +69,9 @@ DECLARE_GLOBAL_DATA_PTR; - #define GICC_IIDR 0x00fc - #define GICC_DIR 0x1000 - --#define GIC_CPU_IMPLEMENTER_MAGIC 0x0102143b -+#define GIC_CPU_IMPLEMENTER_MAGIC 0x0102143b -+#define GICC_IAR_INT_ID_MASK 0x3ff -+#define GIC_CPU_DEACTIVATE 0x1000 - - /* GIC_INTERFACE_OFFSET register offsets */ - #define GICH_HCR 0x000 -@@ -116,9 +105,10 @@ DECLARE_GLOBAL_DATA_PTR; - - #define GIC_VIRT_CPU_IMPLEMENTER_MAGIC 0x0102143b - --#define GICD_CTLR_ENABLE 0x03 -- --#define GICD_INT_DEF_PRI 0xa0 -+#define GICD_CTLR_ENABLE 0x03 /*enable group 0 and 1*/ -+#define GICC_CTLR_ENABLE 0x03 -+#define GICD_ITARGET_ALL 0xffffffff -+#define GICD_INT_DEF_PRI 0xa0 - #define GICD_INT_DEF_PRI_X4 (\ - (GICD_INT_DEF_PRI << 24) |\ - (GICD_INT_DEF_PRI << 16) |\ -@@ -129,20 +119,30 @@ DECLARE_GLOBAL_DATA_PTR; - #define GICD_INT_EN_CLR_X32 0xffffffff - #define GICD_INT_EN_CLR_PPI 0xffff0000 - #define GICD_INT_EN_SET_SGI 0x0000ffff -+#define GICD_ICFG_LEVEL_TRIGGER 0x55555555 -+#define GICC_UNMASK_ALL_PRIORITY 0xff - - #define gicd_readl(OFFSET) readl(gbase + GIC_DISTRIBUTOR_OFFSET + (OFFSET)) - #define gicd_writel(VALUE, OFFSET) \ - writel((VALUE), gbase + GIC_DISTRIBUTOR_OFFSET + (OFFSET)) - #define gicc_readl(OFFSET) readl(gbase + GIC_CPU_OFFSET + (OFFSET)) -+#define gicc_writel(VALUE, OFFSET) \ -+ writel((VALUE), gbase + GIC_CPU_OFFSET + (OFFSET)) - #define gich_readl(OFFSET) readl(gbase + GIC_INTERFACE_OFFSET + (OFFSET)) - #define gicv_readl(OFFSET) readl(gbase + GIC_VIRT_OFFSET + (OFFSET)) -- --static size_t max_irq = 0; -- - #define ITLINES_MASK 0x1f - #define ITLINES_SHIFT 5 -- - #define GIC_MAX_IRQ 1020 -+#define SPI_INT_NUM_MIN 32 -+#define MAX_IRQ 0xfffffffe -+#define DEBUG_IRQ_ENABLED 0 -+#if DEBUG_IRQ_ENABLED -+#define DBG_IRQ printf -+#else -+#define DBG_IRQ(...) -+#endif -+ -+static size_t max_irq = 0; - static interrupt_handler_t *handlers[GIC_MAX_IRQ] = {NULL}; - static unsigned long irq_total = 0; - static unsigned long irq_counts[GIC_MAX_IRQ] = {0}; -@@ -159,31 +159,40 @@ static inline uint32_t gic_base(void) - - static void enable_gic(void) - { -- uint32_t gicd_ctlr; -+ uint32_t gicd_ctlr, gicc_ctlr; - -+ DBG_IRQ(" %s()\n", __FUNCTION__); - /* add GIC offset ref table 1-3 for interrupt distributor address */ - gicd_ctlr = gicd_readl(GICD_CTLR); -+ gicc_ctlr = gicc_readl(GICC_CTLR); - gicd_writel(gicd_ctlr | GICD_CTLR_ENABLE, GICD_CTLR); -+ gicc_writel(gicc_ctlr | GICC_CTLR_ENABLE, GICC_CTLR); - } - - static void disable_gic(void) - { -- uint32_t gicd_ctlr; -- -+ uint32_t gicd_ctlr, gicc_ctlr; -+ DBG_IRQ(" %s()\n", __FUNCTION__); - /* add GIC offset ref table 1-3 for interrupt distributor address */ - gicd_ctlr = gicd_readl(GICD_CTLR); - gicd_writel(gicd_ctlr & ~GICD_CTLR_ENABLE, GICD_CTLR); -+ gicc_ctlr = gicc_readl(GICC_CTLR); -+ gicc_writel(gicc_ctlr & ~GICC_CTLR_ENABLE, GICC_CTLR); - } - - static void enable_irq_id(unsigned int id) - { -+ DBG_IRQ(" %s()\n", __FUNCTION__); -+ - uint32_t grp = id >> ITLINES_SHIFT; - uint32_t grp_bit = 1 << (id & ITLINES_MASK); - gicd_writel(grp_bit, GICD_ISENABLERn + grp * sizeof(uint32_t)); -+ gicd_writel(GICD_ITARGET_ALL, GICD_ITARGETSRn + id / 4 * 4); - } - - static void disable_irq_id(unsigned int id) - { -+ DBG_IRQ(" %s()\n", __FUNCTION__); - uint32_t grp = id >> ITLINES_SHIFT; - uint32_t grp_bit = 1 << (id & ITLINES_MASK); - gicd_writel(grp_bit, GICD_ICENABLERn + grp * sizeof(uint32_t)); -@@ -193,22 +202,29 @@ static int gic_probe(void) - { - int i; - gbase = gic_base(); -+ DBG_IRQ("gic_probe GIC base = 0x%x, magicd=0x%x\n", -+ gbase, gicd_readl(GICD_IIDR)); - enable_gic(); - - if (gicd_readl(GICD_IIDR) != GIC_DISTRIBUTOR_IMPLEMENTER_MAGIC && - gicc_readl(GICC_IIDR) != GIC_CPU_IMPLEMENTER_MAGIC && - gicv_readl(GICV_IIDR) != GIC_VIRT_CPU_IMPLEMENTER_MAGIC) - { -+ printf("error: magic check \n"); - return 0; - } - /* GIC supports up to 1020 lines */ -- max_irq = ((gicd_readl(GICD_TYPER) & ITLINES_MASK) + 1) << ITLINES_SHIFT; -+ max_irq = (((gicd_readl(GICD_TYPER) & ITLINES_MASK) + 1) * 32) - 1; - if (max_irq > GIC_MAX_IRQ) - max_irq = GIC_MAX_IRQ; - /* set all lines to be level triggered N-N */ - for (i = 32; i < max_irq; i += 16) -- gicd_writel(0, GICD_ICFGRn + i / 4); -+ gicd_writel(GICD_ICFG_LEVEL_TRIGGER, GICD_ICFGRn + i / 4); - -+ DBG_IRQ("max_irq = 0x%x, typer=0x%x, config=0x%x, maxirq=0x%x\n", max_irq, -+ (gicd_readl(GICD_TYPER) & ITLINES_MASK) + 1, -+ gicd_readl(GICD_ICFGRn + 0x8), -+ ((gicd_readl(GICD_TYPER) & ITLINES_MASK) + 1) * 0x20); - /* Set priority on all interrupts. */ - for (i = 0; i < max_irq; i += 4) - gicd_writel(GICD_INT_DEF_PRI_X4, GICD_IPRIORITYRn + i); -@@ -218,9 +234,11 @@ static int gic_probe(void) - gicd_writel(GICD_INT_EN_CLR_X32, GICD_ICACTIVERn + i / 8); - gicd_writel(GICD_INT_EN_CLR_X32, GICD_ICENABLERn + i / 8); - } -- gicd_writel(GICD_INT_EN_CLR_X32, GICD_ICACTIVERn); -- gicd_writel(GICD_INT_EN_CLR_PPI, GICD_ICENABLERn); -+ gicd_writel(GICD_INT_EN_CLR_X32, GICD_ICACTIVERn); -+ gicd_writel(GICD_INT_EN_CLR_PPI, GICD_ICENABLERn); - gicd_writel(GICD_INT_EN_SET_SGI, GICD_ISENABLERn); -+ /* unmask all priority */ -+ gicc_writel(GICC_UNMASK_ALL_PRIORITY, GICC_PMRn); - - return 0; - } -@@ -228,6 +246,7 @@ static int gic_probe(void) - void irq_free_handler (int irq); - static void gic_shutdown(void) - { -+ DBG_IRQ(" %s()\n", __FUNCTION__); - int i; - for (i = 0; i < max_irq; i++) - { -@@ -238,6 +257,7 @@ static void gic_shutdown(void) - - int arch_interrupt_init_early(void) - { -+ DBG_IRQ(" %s()\n", __FUNCTION__); - return 0; - } - -@@ -249,11 +269,13 @@ int arch_interrupt_init(void) - handlers[i] = NULL; - irq_counts[i] = 0; - } -+ DBG_IRQ("arch_interrupt_init\n"); - return gic_probe(); - } - - int arch_interrupt_fini(void) - { -+ DBG_IRQ(" %s()\n", __FUNCTION__); - gic_shutdown(); - return 0; - } -@@ -261,14 +283,12 @@ int arch_interrupt_fini(void) - int interrupt_init (void) - { - /* -- * setup up stacks if necessary -- */ -+ * setup up stacks if necessary*/ -+ IRQ_STACK_START = gd->irq_sp + 8; - IRQ_STACK_START_IN = gd->irq_sp + 8; - -- printf("%s()\n", __FUNCTION__); -+ DBG_IRQ(" %s()\n", __FUNCTION__); - return arch_interrupt_init(); -- -- return 0; - } - - int global_interrupts_enabled (void) -@@ -286,12 +306,12 @@ void enable_interrupts (void) - { - unsigned long cpsr; - __asm__ __volatile__("mrs %0, cpsr\n" -- "bic %0, %0, #0x80\n" -+ "bic %0, %0, #0x1c0\n" - "msr cpsr_c, %0" - : "=r" (cpsr) - : - : "memory"); -- -+ DBG_IRQ(" %s()\n", __FUNCTION__); - return; - } - -@@ -304,11 +324,13 @@ int disable_interrupts (void) - : "=r" (cpsr), "=r" (temp) - : - : "memory"); -+ DBG_IRQ(" %s()\n", __FUNCTION__); - return (cpsr & 0x80) == 0; - } - - void irq_install_handler(int irq, interrupt_handler_t *handler, void *ctx) - { -+ DBG_IRQ(" %s()\n", __FUNCTION__); - if (irq > max_irq) { - printf("irq %d out of range\n", irq); - return; -@@ -317,13 +339,14 @@ void irq_install_handler(int irq, interrupt_handler_t *handler, void *ctx) - printf("irq %d already in use (%p)\n", irq, handlers[irq]); - return; - } -- printf("registering handler for irq %d\n", irq); -+ DBG_IRQ("registering handler for irq %d\n", irq); - handlers[irq] = handler; - enable_irq_id(irq); - } - - void irq_free_handler (int irq) - { -+ DBG_IRQ(" %s()\n", __FUNCTION__); - if (irq >= max_irq) { - printf("irq %d out of range\n", irq); - return; -@@ -338,9 +361,10 @@ int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) - { - int i; - int enabled = global_interrupts_enabled(); -- printf("GIC base = 0x%x\n", gbase); -- printf("interrupts %sabled\n", (enabled ? "en" : "dis")); -+ DBG_IRQ("GIC base = 0x%x\n", gbase); -+ DBG_IRQ("interrupts %sabled\n", (enabled ? "en" : "dis")); - uint32_t grp_en = 0; -+ - for (i = 0; i < max_irq; i++) { - if ((i & ITLINES_MASK) == 0) - grp_en = gicd_readl(GICD_ISENABLERn + -@@ -348,52 +372,28 @@ int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) - int irq_enabled = grp_en & (1 << (i & ITLINES_MASK)); - if (!irq_enabled) - continue; -- printf("% 2i (% 3s): %lu\n", i, -+ DBG_IRQ("%2d (%3s): %lu\n", i, - (irq_enabled ? "on" : "off"), irq_counts[i]); - } -- printf("total: %lu\n", irq_total); -+ DBG_IRQ("total: %lu\n", irq_total); - return 0; - } - - void do_irq(struct pt_regs *pt_regs) - { -- int i; -- if (!gbase) { -- static int printed_msg = 0; -- if (!printed_msg) -- { -- printed_msg = 1; -- printf("interrupt before configured!\n"); -- } -- return; -- } -- irq_total++; -- uint32_t grp_pend = 0; -- for (i = 0; i < max_irq; i++) { -- /* limit reads of the pending register to once in 32 */ -- if ((i & ITLINES_MASK) == 0) -- grp_pend = gicd_readl(GICD_ISPENDRn + -- (i >> ITLINES_SHIFT) * sizeof(uint32_t)); -- uint32_t pending = grp_pend & (1 << (i & ITLINES_MASK)); -- if (pending) { -- irq_counts[i]++; -- /* mask via GICD_ICENABLERn */ -- gicd_writel(pending, GICD_ICENABLERn + -- (i >> ITLINES_SHIFT) * sizeof(uint32_t)); -- if (handlers[i]) { -- handlers[i](pt_regs); -- /* unmask via GICD_ISENABLERn */ -- gicd_writel(pending, GICD_ISENABLERn + -- (i >> ITLINES_SHIFT) * sizeof(uint32_t)); -- /* clear pending via GICD_ICPENDRn */ -- gicd_writel(pending, GICD_ICPENDRn + -- (i >> ITLINES_SHIFT) * sizeof(uint32_t)); -- } else { -- printf("unexpected interrupt %i; masking\n", i); -- /* clear pending via GICD_ICPENDRn */ -- gicd_writel(pending, GICD_ISPENDRn + -- (i >> ITLINES_SHIFT) * sizeof(uint32_t)); -- } -+ uint32_t irqstat = 0, irqnr = 0; -+ -+ if (irq_total < MAX_IRQ) -+ irq_total++; -+ irqstat = gicc_readl(GICC_IAR); -+ irqnr = irqstat & GICC_IAR_INT_ID_MASK; -+ -+ if (irqnr > SPI_INT_NUM_MIN && irqnr < GIC_MAX_IRQ) { -+ gicc_writel(irqnr, GICC_EOIR); -+ if (irq_counts[irqnr] < MAX_IRQ) -+ irq_counts[irqnr]++; -+ if (handlers[irqnr]) { -+ handlers[irqnr](NULL); - } - } - } --- -2.7.4 - |