From 88451d59c41251794b59dc31d9dfaa1c7e1881eb Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Sun, 27 Apr 2008 21:32:10 +0000 Subject: [PATCH] IMX31: Use template structures to access modules' registers from a base address (as for i2c) which makes drivers look nicer and makes array accesses of registers simpler. Throw in minor fix to fiq_handler dispatcher, otherwise no functional changes. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17270 a1c6a512-1295-4272-9138-f99709370657 --- firmware/export/imx31l.h | 107 ++++++------- .../target/arm/imx31/gigabeat-s/avic-imx31.c | 53 +++--- .../target/arm/imx31/gigabeat-s/avic-imx31.h | 151 ++++++++++++++++++ .../target/arm/imx31/gigabeat-s/gpio-imx31.c | 38 ++--- .../target/arm/imx31/gigabeat-s/gpio-imx31.h | 11 ++ .../target/arm/imx31/gigabeat-s/spi-imx31.c | 67 ++++---- .../target/arm/imx31/gigabeat-s/spi-imx31.h | 13 ++ 7 files changed, 297 insertions(+), 143 deletions(-) diff --git a/firmware/export/imx31l.h b/firmware/export/imx31l.h index 777fa6981c..9fc51337b1 100755 --- a/firmware/export/imx31l.h +++ b/firmware/export/imx31l.h @@ -494,74 +494,57 @@ #define EPITSR_OCIF (1 << 0) /* GPIO */ -#define GPIO_DR_I 0x00 /* Offset - 0x00 */ -#define GPIO_GDIR_I 0x01 /* Offset - 0x04 */ -#define GPIO_PSR_I 0x02 /* Offset - 0x08 */ -#define GPIO_ICR1_I 0x03 /* Offset - 0x0C */ -#define GPIO_ICR2_I 0x04 /* Offset - 0x10 */ -#define GPIO_IMR_I 0x05 /* Offset - 0x14 */ -#define GPIO_ISR_I 0x06 /* Offset - 0x18 */ +#define GPIO1_DR (*(REG32_PTR_T)(GPIO1_BASE_ADDR+0x00)) +#define GPIO1_GDIR (*(REG32_PTR_T)(GPIO1_BASE_ADDR+0x04)) +#define GPIO1_PSR (*(REG32_PTR_T)(GPIO1_BASE_ADDR+0x08)) +#define GPIO1_ICR1 (*(REG32_PTR_T)(GPIO1_BASE_ADDR+0x0C)) +#define GPIO1_ICR2 (*(REG32_PTR_T)(GPIO1_BASE_ADDR+0x10)) +#define GPIO1_IMR (*(REG32_PTR_T)(GPIO1_BASE_ADDR+0x14)) +#define GPIO1_ISR (*(REG32_PTR_T)(GPIO1_BASE_ADDR+0x18)) -#define GPIO1_DR (((REG32_PTR_T)GPIO1_BASE_ADDR)[GPIO_DR_I]) -#define GPIO1_GDIR (((REG32_PTR_T)GPIO1_BASE_ADDR)[GPIO_GDIR_I]) -#define GPIO1_PSR (((REG32_PTR_T)GPIO1_BASE_ADDR)[GPIO_PSR_I]) -#define GPIO1_ICR1 (((REG32_PTR_T)GPIO1_BASE_ADDR)[GPIO_ICR1_I]) -#define GPIO1_ICR2 (((REG32_PTR_T)GPIO1_BASE_ADDR)[GPIO_ICR2_I]) -#define GPIO1_IMR (((REG32_PTR_T)GPIO1_BASE_ADDR)[GPIO_IMR_I]) -#define GPIO1_ISR (((REG32_PTR_T)GPIO1_BASE_ADDR)[GPIO_ISR_I]) +#define GPIO2_DR (*(REG32_PTR_T)(GPIO2_BASE_ADDR+0x00)) +#define GPIO2_GDIR (*(REG32_PTR_T)(GPIO2_BASE_ADDR+0x04)) +#define GPIO2_PSR (*(REG32_PTR_T)(GPIO2_BASE_ADDR+0x08)) +#define GPIO2_ICR1 (*(REG32_PTR_T)(GPIO2_BASE_ADDR+0x0C)) +#define GPIO2_ICR2 (*(REG32_PTR_T)(GPIO2_BASE_ADDR+0x10)) +#define GPIO2_IMR (*(REG32_PTR_T)(GPIO2_BASE_ADDR+0x14)) +#define GPIO2_ISR (*(REG32_PTR_T)(GPIO2_BASE_ADDR+0x18)) -#define GPIO2_DR (((REG32_PTR_T)GPIO2_BASE_ADDR)[GPIO_DR_I]) -#define GPIO2_GDIR (((REG32_PTR_T)GPIO2_BASE_ADDR)[GPIO_GDIR_I]) -#define GPIO2_PSR (((REG32_PTR_T)GPIO2_BASE_ADDR)[GPIO_PSR_I]) -#define GPIO2_ICR1 (((REG32_PTR_T)GPIO2_BASE_ADDR)[GPIO_ICR1_I]) -#define GPIO2_ICR2 (((REG32_PTR_T)GPIO2_BASE_ADDR)[GPIO_ICR2_I]) -#define GPIO2_IMR (((REG32_PTR_T)GPIO2_BASE_ADDR)[GPIO_IMR_I]) -#define GPIO2_ISR (((REG32_PTR_T)GPIO2_BASE_ADDR)[GPIO_ISR_I]) - -#define GPIO3_DR (((REG32_PTR_T)GPIO3_BASE_ADDR)[GPIO_DR_I]) -#define GPIO3_GDIR (((REG32_PTR_T)GPIO3_BASE_ADDR)[GPIO_GDIR_I]) -#define GPIO3_PSR (((REG32_PTR_T)GPIO3_BASE_ADDR)[GPIO_PSR_I]) -#define GPIO3_ICR1 (((REG32_PTR_T)GPIO3_BASE_ADDR)[GPIO_ICR1_I]) -#define GPIO3_ICR2 (((REG32_PTR_T)GPIO3_BASE_ADDR)[GPIO_ICR2_I]) -#define GPIO3_IMR (((REG32_PTR_T)GPIO3_BASE_ADDR)[GPIO_IMR_I]) -#define GPIO3_ISR (((REG32_PTR_T)GPIO3_BASE_ADDR)[GPIO_ISR_I]) +#define GPIO3_DR (*(REG32_PTR_T)(GPIO3_BASE_ADDR+0x00)) +#define GPIO3_GDIR (*(REG32_PTR_T)(GPIO3_BASE_ADDR+0x04)) +#define GPIO3_PSR (*(REG32_PTR_T)(GPIO3_BASE_ADDR+0x08)) +#define GPIO3_ICR1 (*(REG32_PTR_T)(GPIO3_BASE_ADDR+0x0C)) +#define GPIO3_ICR2 (*(REG32_PTR_T)(GPIO3_BASE_ADDR+0x10)) +#define GPIO3_IMR (*(REG32_PTR_T)(GPIO3_BASE_ADDR+0x14)) +#define GPIO3_ISR (*(REG32_PTR_T)(GPIO3_BASE_ADDR+0x18)) /* CSPI */ -#define CSPI_RXDATA_I 0x00 /* Offset - 0x00 */ -#define CSPI_TXDATA_I 0x01 /* Offset - 0x04 */ -#define CSPI_CONREG_I 0x02 /* Offset - 0x08 */ -#define CSPI_INTREG_I 0x03 /* Offset - 0x0C */ -#define CSPI_DMAREG_I 0x04 /* Offset - 0x10 */ -#define CSPI_STATREG_I 0x05 /* Offset - 0x14 */ -#define CSPI_PERIODREG_I 0x06 /* Offset - 0x18 */ -#define CSPI_TESTREG_I 0x70 /* Offset - 0x1C0 */ +#define CSPI_RXDATA1 (*(REG32_PTR_T)(CSPI1_BASE_ADDR+0x00)) +#define CSPI_TXDATA1 (*(REG32_PTR_T)(CSPI1_BASE_ADDR+0x04)) +#define CSPI_CONREG1 (*(REG32_PTR_T)(CSPI1_BASE_ADDR+0x08)) +#define CSPI_INTREG1 (*(REG32_PTR_T)(CSPI1_BASE_ADDR+0x0C)) +#define CSPI_DMAREG1 (*(REG32_PTR_T)(CSPI1_BASE_ADDR+0x10)) +#define CSPI_STATREG1 (*(REG32_PTR_T)(CSPI1_BASE_ADDR+0x14)) +#define CSPI_PERIODREG1 (*(REG32_PTR_T)(CSPI1_BASE_ADDR+0x18)) +#define CSPI_TESTREG1 (*(REG32_PTR_T)(CSPI1_BASE_ADDR+0x1C0)) -#define CSPI_RXDATA1 (((REG32_PTR_T)CSPI1_BASE_ADDR)[CSPI_RXDATA_I]) -#define CSPI_TXDATA1 (((REG32_PTR_T)CSPI1_BASE_ADDR)[CSPI_TXDATA_I]) -#define CSPI_CONREG1 (((REG32_PTR_T)CSPI1_BASE_ADDR)[CSPI_CONREG_I]) -#define CSPI_INTREG1 (((REG32_PTR_T)CSPI1_BASE_ADDR)[CSPI_INTREG_I]) -#define CSPI_DMAREG1 (((REG32_PTR_T)CSPI1_BASE_ADDR)[CSPI_DMAREG_I]) -#define CSPI_STATREG1 (((REG32_PTR_T)CSPI1_BASE_ADDR)[CSPI_STATREG_I]) -#define CSPI_PERIODREG1 (((REG32_PTR_T)CSPI1_BASE_ADDR)[CSPI_PERIODREG_I]) -#define CSPI_TESTREG1 (((REG32_PTR_T)CSPI1_BASE_ADDR)[CSPI_TESTREG_I]) +#define CSPI_RXDATA2 (*(REG32_PTR_T)(CSPI2_BASE_ADDR+0x00)) +#define CSPI_TXDATA2 (*(REG32_PTR_T)(CSPI2_BASE_ADDR+0x04)) +#define CSPI_CONREG2 (*(REG32_PTR_T)(CSPI2_BASE_ADDR+0x08)) +#define CSPI_INTREG2 (*(REG32_PTR_T)(CSPI2_BASE_ADDR+0x0C)) +#define CSPI_DMAREG2 (*(REG32_PTR_T)(CSPI2_BASE_ADDR+0x10)) +#define CSPI_STATREG2 (*(REG32_PTR_T)(CSPI2_BASE_ADDR+0x14)) +#define CSPI_PERIODREG2 (*(REG32_PTR_T)(CSPI2_BASE_ADDR+0x18)) +#define CSPI_TESTREG2 (*(REG32_PTR_T)(CSPI2_BASE_ADDR+0x1C0)) -#define CSPI_RXDATA2 (((REG32_PTR_T)CSPI2_BASE_ADDR)[CSPI_RXDATA_I]) -#define CSPI_TXDATA2 (((REG32_PTR_T)CSPI2_BASE_ADDR)[CSPI_TXDATA_I]) -#define CSPI_CONREG2 (((REG32_PTR_T)CSPI2_BASE_ADDR)[CSPI_CONREG_I]) -#define CSPI_INTREG2 (((REG32_PTR_T)CSPI2_BASE_ADDR)[CSPI_INTREG_I]) -#define CSPI_DMAREG2 (((REG32_PTR_T)CSPI2_BASE_ADDR)[CSPI_DMAREG_I]) -#define CSPI_STATREG2 (((REG32_PTR_T)CSPI2_BASE_ADDR)[CSPI_STATREG_I]) -#define CSPI_PERIODREG2 (((REG32_PTR_T)CSPI2_BASE_ADDR)[CSPI_PERIODREG_I]) -#define CSPI_TESTREG2 (((REG32_PTR_T)CSPI2_BASE_ADDR)[CSPI_TESTREG_I]) - -#define CSPI_RXDATA3 (((REG32_PTR_T)CSPI3_BASE_ADDR)[CSPI_RXDATA_I]) -#define CSPI_TXDATA3 (((REG32_PTR_T)CSPI3_BASE_ADDR)[CSPI_TXDATA_I]) -#define CSPI_CONREG3 (((REG32_PTR_T)CSPI3_BASE_ADDR)[CSPI_CONREG_I]) -#define CSPI_INTREG3 (((REG32_PTR_T)CSPI3_BASE_ADDR)[CSPI_INTREG_I]) -#define CSPI_DMAREG3 (((REG32_PTR_T)CSPI3_BASE_ADDR)[CSPI_DMAREG_I]) -#define CSPI_STATREG3 (((REG32_PTR_T)CSPI3_BASE_ADDR)[CSPI_STATREG_I]) -#define CSPI_PERIODREG3 (((REG32_PTR_T)CSPI3_BASE_ADDR)[CSPI_PERIODREG_I]) -#define CSPI_TESTREG3 (((REG32_PTR_T)CSPI3_BASE_ADDR)[CSPI_TESTREG_I]) +#define CSPI_RXDATA3 (*(REG32_PTR_T)(CSPI3_BASE_ADDR+0x00)) +#define CSPI_TXDATA3 (*(REG32_PTR_T)(CSPI3_BASE_ADDR+0x04)) +#define CSPI_CONREG3 (*(REG32_PTR_T)(CSPI3_BASE_ADDR+0x08)) +#define CSPI_INTREG3 (*(REG32_PTR_T)(CSPI3_BASE_ADDR+0x0C)) +#define CSPI_DMAREG3 (*(REG32_PTR_T)(CSPI3_BASE_ADDR+0x10)) +#define CSPI_STATREG3 (*(REG32_PTR_T)(CSPI3_BASE_ADDR+0x14)) +#define CSPI_PERIODREG3 (*(REG32_PTR_T)(CSPI3_BASE_ADDR+0x18)) +#define CSPI_TESTREG3 (*(REG32_PTR_T)(CSPI3_BASE_ADDR+0x1C0)) /* CSPI CONREG flags/fields */ #define CSPI_CONREG_CHIP_SELECT_SS0 (0 << 24) diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c index 6b64bfad77..ce2932a13f 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c @@ -74,9 +74,9 @@ void __attribute__((naked)) irq_handler(void) void __attribute__((naked)) fiq_handler(void) { asm volatile ( - "mov r10, #0x6c000000 \n" /* load AVIC base address */ + "mov r10, #0x68000000 \n" /* load AVIC base address */ "ldr r9, [r10, #0x44] \n" /* read FIVECSR of AVIC */ - "add r10, r10, #100 \n" /* move pointer to base of VECTOR table */ + "add r10, r10, #0x100 \n" /* move pointer to base of VECTOR table */ "ldr r8, [r10, r9, lsl #2] \n" /* read FIQ vector from VECTOR table */ "bx r8 \n" /* jump to FIQ service routine */ ); @@ -84,23 +84,24 @@ void __attribute__((naked)) fiq_handler(void) void avic_init(void) { + struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; int i; /* Disable all interrupts and set to unhandled */ avic_disable_int(ALL); /* Reset AVIC control */ - INTCNTL = 0; + avic->intcntl = 0; /* Init all interrupts to type IRQ */ avic_set_int_type(ALL, IRQ); /* Set all normal to lowest priority */ for (i = 0; i < 8; i++) - NIPRIORITY(i) = 0; + avic->nipriority[i] = 0; /* Set NM bit to enable VIC */ - INTCNTL |= INTCNTL_NM; + avic->intcntl |= INTCNTL_NM; /* Enable VE bit in CP15 Control reg to enable VIC */ asm volatile ( @@ -110,28 +111,30 @@ void avic_init(void) : : : "r0"); /* Enable normal interrupts at all priorities */ - NIMASK = 0x1f; + avic->nimask = 0x1f; } void avic_set_int_priority(enum IMX31_INT_LIST ints, unsigned long ni_priority) { - volatile unsigned long *reg = &NIPRIORITY((63 - ints) / 8); - unsigned int shift = 4*(ints % 8); - unsigned long mask = 0xful << shift; + struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; + volatile uint32_t *reg = &avic->nipriority[7 - (ints >> 3)]; + unsigned int shift = (ints & 0x7) << 2; + uint32_t mask = 0xful << shift; *reg = (*reg & ~mask) | ((ni_priority << shift) & mask); } void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, unsigned long ni_priority, void (*handler)(void)) { + struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); if (ints != ALL) /* No mass-enable allowed */ { avic_set_int_type(ints, intstype); - VECTOR(ints) = (long)handler; - INTENNUM = ints; + avic->vector[ints] = (long)handler; + avic->intennum = ints; avic_set_int_priority(ints, ni_priority); } @@ -140,38 +143,30 @@ void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, void avic_disable_int(enum IMX31_INT_LIST ints) { - long i; + struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; + uint32_t i; if (ints == ALL) { for (i = 0; i < 64; i++) { - INTDISNUM = i; - VECTOR(i) = (long)UIE_VECTOR; + avic->intdisnum = i; + avic->vector[i] = (long)UIE_VECTOR; } } else { - INTDISNUM = ints; - VECTOR(ints) = (long)UIE_VECTOR; + avic->intdisnum = ints; + avic->vector[ints] = (long)UIE_VECTOR; } } static void set_int_type(int i, enum INT_TYPE intstype) { - volatile unsigned long *reg; - long val; - - if (i >= 32) - { - reg = &INTTYPEH; - val = 1L << (i - 32); - } - else - { - reg = &INTTYPEL; - val = 1L << i; - } + /* INTTYPEH: vectors 63-32, INTTYPEL: vectors 31-0 */ + struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; + volatile uint32_t *reg = &avic->inttype[1 - (i >> 5)]; + uint32_t val = 1L << (i & 0x1f); if (intstype == IRQ) val = *reg & ~val; diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h index 7bb7c09da7..a2e1b3496d 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h @@ -19,6 +19,157 @@ #ifndef AVIC_IMX31_H #define AVIC_IMX31_H +struct avic_map +{ + volatile uint32_t intcntl; /* 00h */ + volatile uint32_t nimask; /* 04h */ + volatile uint32_t intennum; /* 08h */ + volatile uint32_t intdisnum; /* 0Ch */ + union /* 10h */ + { + struct + { + volatile uint32_t intenableh; /* 10h */ + volatile uint32_t intenablel; /* 14h */ + }; + volatile uint32_t intenable[2]; /* H,L */ + }; + union + { + struct + { + volatile uint32_t inttypeh; /* 18h */ + volatile uint32_t inttypel; /* 1Ch */ + }; + volatile uint32_t inttype[2]; /* H,L */ + }; + union + { + struct + { + volatile uint32_t nipriority7; /* 20h */ + volatile uint32_t nipriority6; /* 24h */ + volatile uint32_t nipriority5; /* 28h */ + volatile uint32_t nipriority4; /* 2Ch */ + volatile uint32_t nipriority3; /* 30h */ + volatile uint32_t nipriority2; /* 34h */ + volatile uint32_t nipriority1; /* 38h */ + volatile uint32_t nipriority0; /* 3Ch */ + }; + volatile uint32_t nipriority[8]; /* 7-0 */ + }; + volatile uint32_t nivecsr; /* 40h */ + volatile uint32_t fivecsr; /* 44h */ + union + { + struct + { + volatile uint32_t intsrch; /* 48h */ + volatile uint32_t intsrcl; /* 4Ch */ + }; + volatile uint32_t intsrc[2]; /* H,L */ + }; + union + { + struct + { + volatile uint32_t intfrch; /* 50h */ + volatile uint32_t intfrcl; /* 54h */ + }; + volatile uint32_t intfrc[2]; /* H,L */ + }; + union + { + struct + { + volatile uint32_t nipndh; /* 58h */ + volatile uint32_t nipndl; /* 5Ch */ + }; + volatile uint32_t nipnd[2]; /* H,L */ + }; + union + { + struct + { + volatile uint32_t fipndh; /* 60h */ + volatile uint32_t fipndl; /* 64h */ + }; + volatile uint32_t fipnd[2]; /* H,L */ + }; + volatile uint32_t skip1[0x26]; /* 68h */ + union /* 100h */ + { + struct + { + volatile uint32_t reserved0; + volatile uint32_t reserved1; + volatile uint32_t reserved2; + volatile uint32_t i2c3; + volatile uint32_t i2c2; + volatile uint32_t mpeg4encoder; + volatile uint32_t rtic; + volatile uint32_t fir; + volatile uint32_t mmc_sdhc2; + volatile uint32_t mmc_sdhc1; + volatile uint32_t i2c1; + volatile uint32_t ssi2; + volatile uint32_t ssi1; + volatile uint32_t cspi2; + volatile uint32_t cspi1; + volatile uint32_t ata; + volatile uint32_t mbx; + volatile uint32_t cspi3; + volatile uint32_t uart3; + volatile uint32_t iim; + volatile uint32_t sim1; + volatile uint32_t sim2; + volatile uint32_t rnga; + volatile uint32_t evtmon; + volatile uint32_t kpp; + volatile uint32_t rtc; + volatile uint32_t pwn; + volatile uint32_t epit2; + volatile uint32_t epit1; + volatile uint32_t gpt; + volatile uint32_t pwr_fail; + volatile uint32_t ccm_dvfs; + volatile uint32_t uart2; + volatile uint32_t nandfc; + volatile uint32_t sdma; + volatile uint32_t usb_host1; + volatile uint32_t usb_host2; + volatile uint32_t usb_otg; + volatile uint32_t reserved3; + volatile uint32_t mshc1; + volatile uint32_t mshc2; + volatile uint32_t ipu_err; + volatile uint32_t ipu; + volatile uint32_t reserved4; + volatile uint32_t reserved5; + volatile uint32_t uart1; + volatile uint32_t uart4; + volatile uint32_t uart5; + volatile uint32_t etc_irq; + volatile uint32_t scc_scm; + volatile uint32_t scc_smn; + volatile uint32_t gpio2; + volatile uint32_t gpio1; + volatile uint32_t ccm_clk; + volatile uint32_t pcmcia; + volatile uint32_t wdog; + volatile uint32_t gpio3; + volatile uint32_t reserved6; + volatile uint32_t ext_pwmg; + volatile uint32_t ext_temp; + volatile uint32_t ext_sense1; + volatile uint32_t ext_sense2; + volatile uint32_t ext_wdog; + volatile uint32_t ext_tv; + }; + volatile uint32_t vector[0x40]; /* 100h */ + }; +}; + enum INT_TYPE { IRQ = 0, diff --git a/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.c b/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.c index a7427f16c0..0b76b84d36 100644 --- a/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.c @@ -44,7 +44,7 @@ extern const struct gpio_event_list gpio3_event_list; static struct gpio_module_descriptor { - volatile unsigned long *base; /* Module base address */ + struct gpio_map * const base; /* Module base address */ enum IMX31_INT_LIST ints; /* AVIC int number */ void (*handler)(void); /* Interrupt function */ const struct gpio_event_list *list; /* Event handler list */ @@ -52,21 +52,21 @@ static struct gpio_module_descriptor { #if (GPIO_EVENT_MASK & USE_GPIO1_EVENTS) { - .base = (unsigned long *)GPIO1_BASE_ADDR, + .base = (struct gpio_map *)GPIO1_BASE_ADDR, .ints = GPIO1, .handler = GPIO1_HANDLER, }, #endif #if (GPIO_EVENT_MASK & USE_GPIO2_EVENTS) { - .base = (unsigned long *)GPIO2_BASE_ADDR, + .base = (struct gpio_map *)GPIO2_BASE_ADDR, .ints = GPIO2, .handler = GPIO2_HANDLER, }, #endif #if (GPIO_EVENT_MASK & USE_GPIO3_EVENTS) { - .base = (unsigned long *)GPIO3_BASE_ADDR, + .base = (struct gpio_map *)GPIO3_BASE_ADDR, .ints = GPIO3, .handler = GPIO3_HANDLER, }, @@ -77,17 +77,17 @@ static void gpio_call_events(enum gpio_module_number gpio) { const struct gpio_module_descriptor * const desc = &gpio_descs[gpio]; const struct gpio_event_list * const list = desc->list; - volatile unsigned long * const base = desc->base; + struct gpio_map * const base = desc->base; unsigned i; /* Intersect pending and unmasked bits */ - unsigned long pending = base[GPIO_ISR_I] & base[GPIO_IMR_I]; + uint32_t pending = base->isr & base->imr; /* Call each event handler in order */ for (i = 0; i < list->count; i++) { const struct gpio_event * const event = &list->events[i]; - unsigned long bit = 1ul << event->line; + uint32_t bit = 1ul << event->line; if ((pending & bit) && event->callback()) pending &= ~bit; @@ -144,10 +144,10 @@ bool gpio_enable_event(enum gpio_module_number gpio, unsigned id) { const struct gpio_module_descriptor * const desc = &gpio_descs[gpio]; const struct gpio_event * const event = &desc->list->events[id]; - volatile unsigned long * const base = desc->base; - volatile unsigned long * icr; - unsigned long mask; - unsigned long imr; + struct gpio_map * const base = desc->base; + volatile uint32_t *icr; + uint32_t mask; + uint32_t imr; int shift; if (id >= desc->list->count) @@ -155,7 +155,7 @@ bool gpio_enable_event(enum gpio_module_number gpio, unsigned id) int oldlevel = disable_irq_save(); - imr = base[GPIO_IMR_I]; + imr = base->imr; if (imr == 0) { @@ -165,14 +165,14 @@ bool gpio_enable_event(enum gpio_module_number gpio, unsigned id) } /* Set the line sense */ - icr = &base[GPIO_ICR1_I] + event->line / 16; - shift = 2*(event->line % 16); + icr = &base->icr[event->line >> 4]; + shift = (event->line & 15) << 1; mask = GPIO_SENSE_CONFIG_MASK << shift; *icr = (*icr & ~mask) | ((event->sense << shift) & mask); /* Unmask the line */ - base[GPIO_IMR_I] = imr | (1ul << event->line); + base->imr = imr | (1ul << event->line); restore_irq(oldlevel); @@ -183,8 +183,8 @@ void gpio_disable_event(enum gpio_module_number gpio, unsigned id) { const struct gpio_module_descriptor * const desc = &gpio_descs[gpio]; const struct gpio_event * const event = &desc->list->events[id]; - volatile unsigned long * const base = desc->base; - unsigned long imr; + struct gpio_map * const base = desc->base; + uint32_t imr; if (id >= desc->list->count) return; @@ -192,10 +192,10 @@ void gpio_disable_event(enum gpio_module_number gpio, unsigned id) int oldlevel = disable_irq_save(); /* Remove bit from mask */ - imr = base[GPIO_IMR_I] & ~(1ul << event->line); + imr = base->imr & ~(1ul << event->line); /* Mask the line */ - base[GPIO_IMR_I] = imr; + base->imr = imr; if (imr == 0) { diff --git a/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.h b/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.h index a197558ad4..f6e07309e5 100644 --- a/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.h +++ b/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.h @@ -51,6 +51,17 @@ enum gpio_int_sense_enum #define GPIO_SENSE_CONFIG_MASK 0x3 +/* Register map for each module */ +struct gpio_map +{ + volatile uint32_t dr; /* 00h */ + volatile uint32_t gdir; /* 04h */ + volatile uint32_t psr; /* 08h */ + volatile uint32_t icr[2]; /* 0Ch */ + volatile uint32_t imr; /* 14h */ + volatile uint32_t isr; /* 18h */ +}; + /* Pending events will be called in array order */ /* Describes a single event for a pin */ diff --git a/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c index bcbe85a76b..415511e7c7 100644 --- a/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c @@ -16,7 +16,8 @@ * KIND, either express or implied. * ****************************************************************************/ -#include "cpu.h" +#include "config.h" +#include "system.h" #include "spi-imx31.h" #include "avic-imx31.h" #include "clkctl-imx31.h" @@ -37,7 +38,7 @@ static __attribute__((interrupt("IRQ"))) void CSPI3_HANDLER(void); /* State data associatated with each CSPI module */ static struct spi_module_descriptor { - volatile unsigned long *base; + struct cspi_map * const base; int enab; struct spi_node *last; enum IMX31_CG_LIST cg; @@ -53,7 +54,7 @@ static struct spi_module_descriptor { #if (SPI_MODULE_MASK & USE_CSPI1_MODULE) { - .base = (unsigned long *)CSPI1_BASE_ADDR, + .base = (struct cspi_map *)CSPI1_BASE_ADDR, .cg = CG_CSPI1, .ints = CSPI1, .handler = CSPI1_HANDLER, @@ -61,7 +62,7 @@ static struct spi_module_descriptor #endif #if (SPI_MODULE_MASK & USE_CSPI2_MODULE) { - .base = (unsigned long *)CSPI2_BASE_ADDR, + .base = (struct cspi_map *)CSPI2_BASE_ADDR, .cg = CG_CSPI2, .ints = CSPI2, .handler = CSPI2_HANDLER, @@ -69,7 +70,7 @@ static struct spi_module_descriptor #endif #if (SPI_MODULE_MASK & USE_CSPI3_MODULE) { - .base = (unsigned long *)CSPI3_BASE_ADDR, + .base = (struct cspi_map *)CSPI3_BASE_ADDR, .cg = CG_CSPI3, .ints = CSPI3, .handler = CSPI3_HANDLER, @@ -81,16 +82,16 @@ static struct spi_module_descriptor static void spi_interrupt(enum spi_module_number spi) { struct spi_module_descriptor *desc = &spi_descs[spi]; - volatile unsigned long * const base = desc->base; + struct cspi_map * const base = desc->base; struct spi_transfer *trans = desc->trans; int inc = desc->byte_size + 1; if (desc->rxcount > 0) { /* Data received - empty out RXFIFO */ - while ((base[CSPI_STATREG_I] & CSPI_STATREG_RR) != 0) + while ((base->statreg & CSPI_STATREG_RR) != 0) { - uint32_t word = base[CSPI_RXDATA_I]; + uint32_t word = base->rxdata; switch (desc->byte_size & 3) { @@ -108,20 +109,20 @@ static void spi_interrupt(enum spi_module_number spi) if (--desc->rxcount < 4) { - unsigned long intreg = base[CSPI_INTREG_I]; + unsigned long intreg = base->intreg; if (desc->rxcount <= 0) { /* No more to receive - stop RX interrupts */ intreg &= ~(CSPI_INTREG_RHEN | CSPI_INTREG_RREN); - base[CSPI_INTREG_I] = intreg; + base->intreg = intreg; break; } else if (!(intreg & CSPI_INTREG_RREN)) { /* < 4 words expected - switch to RX ready */ intreg &= ~CSPI_INTREG_RHEN; - base[CSPI_INTREG_I] = intreg | CSPI_INTREG_RREN; + base->intreg = intreg | CSPI_INTREG_RREN; } } } @@ -130,7 +131,7 @@ static void spi_interrupt(enum spi_module_number spi) if (trans->count > 0) { /* Data to transmit - fill TXFIFO or write until exhausted */ - while ((base[CSPI_STATREG_I] & CSPI_STATREG_TF) == 0) + while ((base->statreg & CSPI_STATREG_TF) == 0) { uint32_t word = 0; @@ -148,21 +149,21 @@ static void spi_interrupt(enum spi_module_number spi) trans->txbuf += inc; - base[CSPI_TXDATA_I] = word; + base->txdata = word; if (--trans->count <= 0) { /* Out of data - stop TX interrupts */ - base[CSPI_INTREG_I] &= ~CSPI_INTREG_THEN; + base->intreg &= ~CSPI_INTREG_THEN; break; } } } /* If all interrupts have been remasked - we're done */ - if (base[CSPI_INTREG_I] == 0) + if (base->intreg == 0) { - base[CSPI_STATREG_I] = CSPI_STATREG_TC | CSPI_STATREG_BO; + base->statreg = CSPI_STATREG_TC | CSPI_STATREG_BO; wakeup_signal(&desc->w); } } @@ -193,9 +194,9 @@ static __attribute__((interrupt("IRQ"))) void CSPI3_HANDLER(void) static bool spi_set_context(struct spi_node *node, struct spi_module_descriptor *desc) { - volatile unsigned long * const base = desc->base; + struct cspi_map * const base = desc->base; - if ((base[CSPI_CONREG_I] & CSPI_CONREG_EN) == 0) + if ((base->conreg & CSPI_CONREG_EN) == 0) return false; if (node != desc->last) @@ -205,13 +206,13 @@ static bool spi_set_context(struct spi_node *node, desc->byte_size = (((node->conreg >> 8) & 0x1f) + 1 + 7) / 8 - 1; /* Keep reserved and start bits cleared. Keep enabled bit. */ - base[CSPI_CONREG_I] = + base->conreg = (node->conreg & ~(0xfcc8e000 | CSPI_CONREG_XCH | CSPI_CONREG_SMC)) | CSPI_CONREG_EN; /* Set the wait-states */ - base[CSPI_PERIODREG_I] = node->periodreg & 0xffff; + base->periodreg = node->periodreg & 0xffff; /* Clear out any spuriously-pending interrupts */ - base[CSPI_STATREG_I] = CSPI_STATREG_TC | CSPI_STATREG_BO; + base->statreg = CSPI_STATREG_TC | CSPI_STATREG_BO; } return true; @@ -252,16 +253,16 @@ void spi_enable_module(struct spi_node *node) if (++desc->enab == 1) { /* First enable for this module */ - volatile unsigned long * const base = desc->base; + struct cspi_map * const base = desc->base; /* Enable clock-gating register */ imx31_clkctl_module_clock_gating(desc->cg, CGM_ON_ALL); /* Reset */ - base[CSPI_CONREG_I] &= ~CSPI_CONREG_EN; - base[CSPI_CONREG_I] |= CSPI_CONREG_EN; - base[CSPI_INTREG_I] = 0; - base[CSPI_STATREG_I] = CSPI_STATREG_TC | CSPI_STATREG_BO; + base->conreg &= ~CSPI_CONREG_EN; + base->conreg |= CSPI_CONREG_EN; + base->intreg = 0; + base->statreg = CSPI_STATREG_TC | CSPI_STATREG_BO; /* Enable interrupt at controller level */ avic_enable_int(desc->ints, IRQ, 6, desc->handler); @@ -280,13 +281,13 @@ void spi_disable_module(struct spi_node *node) if (desc->enab > 0 && --desc->enab == 0) { /* Last enable for this module */ - volatile unsigned long * const base = desc->base; + struct cspi_map * const base = desc->base; /* Disable interrupt at controller level */ avic_disable_int(desc->ints); /* Disable interface */ - base[CSPI_CONREG_I] &= ~CSPI_CONREG_EN; + base->conreg &= ~CSPI_CONREG_EN; /* Disable interface clock */ imx31_clkctl_module_clock_gating(desc->cg, CGM_OFF); @@ -310,7 +311,7 @@ int spi_transfer(struct spi_node *node, struct spi_transfer *trans) if (retval) { - volatile unsigned long * const base = desc->base; + struct cspi_map * const base = desc->base; unsigned long intreg; desc->trans = trans; @@ -323,15 +324,15 @@ int spi_transfer(struct spi_node *node, struct spi_transfer *trans) CSPI_INTREG_RREN : /* Must grab data on every word */ CSPI_INTREG_RHEN; /* Enough data to wait for half-full */ - base[CSPI_INTREG_I] = intreg; + base->intreg = intreg; /* Start transfer */ - base[CSPI_CONREG_I] |= CSPI_CONREG_XCH; + base->conreg |= CSPI_CONREG_XCH; if (wakeup_wait(&desc->w, HZ) != OBJ_WAIT_SUCCEEDED) { - base[CSPI_INTREG_I] = 0; - base[CSPI_CONREG_I] &= ~CSPI_CONREG_XCH; + base->intreg = 0; + base->conreg &= ~CSPI_CONREG_XCH; retval = false; } } diff --git a/firmware/target/arm/imx31/gigabeat-s/spi-imx31.h b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.h index 07084832ad..2e104595f6 100644 --- a/firmware/target/arm/imx31/gigabeat-s/spi-imx31.h +++ b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.h @@ -39,6 +39,19 @@ enum spi_module_number SPI_NUM_CSPI, }; +struct cspi_map +{ + volatile uint32_t rxdata; /* 00h */ + volatile uint32_t txdata; /* 04h */ + volatile uint32_t conreg; /* 08h */ + volatile uint32_t intreg; /* 0Ch */ + volatile uint32_t dmareg; /* 10h */ + volatile uint32_t statreg; /* 14h */ + volatile uint32_t periodreg; /* 18h */ + volatile uint32_t skip1[0x69]; /* 1Ch */ + volatile uint32_t testreg; /* 1C0h */ +}; + struct spi_node { enum spi_module_number num; /* Module number (CSPIx_NUM) */