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
This commit is contained in:
parent
e23ea5d2a9
commit
88451d59c4
7 changed files with 297 additions and 143 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) */
|
||||
|
|
Loading…
Reference in a new issue