Changeset 67bcd81 in mainline
- Timestamp:
- 2019-01-28T15:41:15Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8d2289c
- Parents:
- 3fea752
- git-author:
- Jiri Svoboda <jiri@…> (2018-01-28 07:51:09)
- git-committer:
- Jiri Svoboda <jiri@…> (2019-01-28 15:41:15)
- Location:
- kernel/genarch
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/Makefile.inc
r3fea752 r67bcd81 117 117 ifeq ($(CONFIG_BCM2835_MAILBOX),y) 118 118 GENARCH_SOURCES += \ 119 genarch/src/drivers/bcm2835/mbox.c 119 genarch/src/drivers/bcm2835/irc.c \ 120 genarch/src/drivers/bcm2835/mbox.c \ 121 genarch/src/drivers/bcm2835/timer.c 120 122 endif 121 123 -
kernel/genarch/include/genarch/drivers/bcm2835/irc.h
r3fea752 r67bcd81 1 1 /* 2 * Copyright (c) 2019 Jiri Svoboda 2 3 * Copyright (c) 2012 Jan Vesely 3 4 * Copyright (c) 2013 Beniamino Galvani … … 59 60 #define IRQ_PEND_SHORT_S 10 60 61 61 unsigned shortcut_inums[] = { 7, 9, 10, 18, 19, 53, 54, 55, 56, 57, 62 };62 63 62 typedef struct { 64 63 ioport32_t irq_basic_pending; … … 75 74 #define BCM2835_IRQ_COUNT 96 76 75 77 static inline void bcm2835_irc_dump(bcm2835_irc_t *regs) 78 { 79 #define DUMP_REG(name) \ 80 printf("%s : %08x\n", #name, regs->name); 81 82 DUMP_REG(irq_basic_pending); 83 DUMP_REG(irq_pending1); 84 DUMP_REG(irq_pending2); 85 DUMP_REG(fiq_control); 86 87 for (int i = 0; i < 3; ++i) { 88 DUMP_REG(irq_enable[i]); 89 DUMP_REG(irq_disable[i]); 90 } 91 #undef DUMP_REG 92 } 93 94 static inline void bcm2835_irc_init(bcm2835_irc_t *regs) 95 { 96 /* Disable all interrupts */ 97 regs->irq_disable[BANK_GPU0] = 0xffffffff; 98 regs->irq_disable[BANK_GPU1] = 0xffffffff; 99 regs->irq_disable[BANK_ARM] = 0xffffffff; 100 101 /* Disable FIQ generation */ 102 regs->fiq_control = 0; 103 } 104 105 static inline int ffs(unsigned int x) 106 { 107 int ret; 108 109 asm volatile ( 110 "clz r0, %[x]\n" 111 "rsb %[ret], r0, #32\n" 112 : [ret] "=r" (ret) 113 : [x] "r" (x) 114 : "r0" 115 ); 116 117 return ret; 118 } 119 120 static inline unsigned bcm2835_irc_inum_get(bcm2835_irc_t *regs) 121 { 122 uint32_t pending; 123 int inum = -1; 124 125 pending = regs->irq_basic_pending; 126 127 /* 128 * The basic pending register shows interrupts pending from ARM 129 * peripherals and it also contains, in order to speed up processing, 130 * additional information about pending GPU interrupts: 131 * 132 * - bits 0-7 are associated to ARM peripherals 133 * - bit 8 is 1 when at least one bit is set in pending register 1 134 * - bit 9 is 1 when at least one bit is set in pending register 2 135 * - bits 10-20 indicate pending status of selected GPU peripherals 136 * 137 * Reference: BCM2835 ARM Peripherals, p.113 138 */ 139 140 if (pending & IRQ_PEND_ARM_M) { 141 inum = MAKE_IRQ(BANK_ARM, ffs(pending & IRQ_PEND_ARM_M) - 1); 142 } else if (pending & IRQ_PEND_SHORT_M) { 143 int pos = (pending & IRQ_PEND_SHORT_M) >> IRQ_PEND_SHORT_S; 144 inum = shortcut_inums[ffs(pos) - 1]; 145 } else if (pending & IRQ_PEND_GPU0_M) { 146 inum = MAKE_IRQ(BANK_GPU0, ffs(regs->irq_pending1) - 1); 147 } else if (pending & IRQ_PEND_GPU1_M) { 148 inum = MAKE_IRQ(BANK_GPU1, ffs(regs->irq_pending2) - 1); 149 } 150 151 if (inum < 0) { 152 printf("Spurious interrupt!\n"); 153 bcm2835_irc_dump(regs); 154 inum = 0; 155 } 156 157 return inum; 158 } 159 160 static inline void bcm2835_irc_enable(bcm2835_irc_t *regs, unsigned inum) 161 { 162 assert(inum < BCM2835_IRQ_COUNT); 163 regs->irq_enable[IRQ_TO_BANK(inum)] |= (1 << IRQ_TO_NUM(inum)); 164 } 165 166 static inline void bcm2835_irc_disable(bcm2835_irc_t *regs, unsigned inum) 167 { 168 assert(inum < BCM2835_IRQ_COUNT); 169 regs->irq_disable[IRQ_TO_BANK(inum)] |= (1 << IRQ_TO_NUM(inum)); 170 } 76 extern void bcm2835_irc_init(bcm2835_irc_t *); 77 extern unsigned bcm2835_irc_inum_get(bcm2835_irc_t *); 78 extern void bcm2835_irc_enable(bcm2835_irc_t *, unsigned); 79 extern void bcm2835_irc_disable(bcm2835_irc_t *, unsigned); 171 80 172 81 #endif /* KERN_BCM2835_IRQC_H_ */ -
kernel/genarch/include/genarch/drivers/bcm2835/mbox.h
r3fea752 r67bcd81 134 134 } bcm2835_fb_desc_t; 135 135 136 bool bcm2835_prop_get_memory(uint32_t *base, uint32_t *size);137 bool bcm2835_fb_init(fb_properties_t *prop);136 extern bool bcm2835_prop_get_memory(uint32_t *base, uint32_t *size); 137 extern bool bcm2835_fb_init(fb_properties_t *prop); 138 138 139 139 #endif 140 140 141 /** 141 142 * @} -
kernel/genarch/include/genarch/drivers/bcm2835/timer.h
r3fea752 r67bcd81 64 64 } bcm2835_timer_t; 65 65 66 static inline void bcm2835_timer_start(bcm2835_timer_t *timer) 67 { 68 assert(timer); 69 /* Clear pending interrupt on channel 1 */ 70 timer->cs |= BCM2835_TIMER_CS_M1; 71 /* Initialize compare value for match channel 1 */ 72 timer->c1 = timer->clo + (BCM2835_CLOCK_FREQ / HZ); 73 } 74 75 static inline void bcm2835_timer_irq_ack(bcm2835_timer_t *timer) 76 { 77 assert(timer); 78 /* Clear pending interrupt on channel 1 */ 79 timer->cs |= BCM2835_TIMER_CS_M1; 80 /* Reprogram compare value for match channel 1 */ 81 timer->c1 = timer->clo + (BCM2835_CLOCK_FREQ / HZ); 82 } 66 extern void bcm2835_timer_start(bcm2835_timer_t *); 67 extern void bcm2835_timer_irq_ack(bcm2835_timer_t *); 83 68 84 69 #endif /* KERN_BCM2835_TIMER_H_ */ 70 71 /** 72 * @} 73 */
Note:
See TracChangeset
for help on using the changeset viewer.