i.MX31: Make some style changes to some driver code so that hardware vs. variable access is more obvious to the eye. Change a few data types and qualifiers. No functional differences.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25865 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sevakis 2010-05-07 02:29:18 +00:00
parent 13b8e3d66d
commit affea5fe9e
6 changed files with 130 additions and 287 deletions

View file

@ -25,7 +25,23 @@
#include "panic.h"
#include "debug.h"
static const char * avic_int_names[64] =
#define avic ((unsigned long * const)AVIC_BASE_ADDR)
#define INTCNTL (0x000 / sizeof (unsigned long)) /* 000h */
#define NIMASK (0x004 / sizeof (unsigned long)) /* 004h */
#define INTENNUM (0x008 / sizeof (unsigned long)) /* 008h */
#define INTDISNUM (0x00c / sizeof (unsigned long)) /* 00Ch */
#define INTENABLE (0x010 / sizeof (unsigned long)) /* 010h H,L */
#define INTTYPE (0x018 / sizeof (unsigned long)) /* 018h H,L */
#define NIPRIORITY (0x020 / sizeof (unsigned long)) /* 020h 7-0 */
#define NIVECSR (0x040 / sizeof (unsigned long)) /* 040h */
#define FIVECSR (0x044 / sizeof (unsigned long)) /* 044h */
#define INTSRC (0x048 / sizeof (unsigned long)) /* 048h H,L */
#define INTFRC (0x050 / sizeof (unsigned long)) /* 050h H,L */
#define NIPND (0x058 / sizeof (unsigned long)) /* 058h H,L */
#define FIPND (0x060 / sizeof (unsigned long)) /* 060h H,L */
#define VECTOR (0x100 / sizeof (unsigned long)) /* 100h */
static const char * const avic_int_names[64] =
{
"RESERVED0", "RESERVED1", "RESERVED2", "I2C3",
"I2C2", "MPEG4_ENCODER", "RTIC", "FIR",
@ -47,7 +63,7 @@ static const char * avic_int_names[64] =
void UIE_VECTOR(void)
{
int mode;
unsigned long mode;
int offset;
asm volatile (
@ -58,8 +74,7 @@ void UIE_VECTOR(void)
: "=&r"(mode)
);
offset = mode == 0x11 ?
(int32_t)AVIC_FIVECSR : ((int32_t)AVIC_NIVECSR >> 16);
offset = mode == 0x11 ? (long)avic[FIVECSR] : ((long)avic[NIVECSR] >> 16);
panicf("Unhandled %s %d: %s",
mode == 0x11 ? "FIQ" : "IRQ", offset,
@ -70,7 +85,7 @@ void UIE_VECTOR(void)
/* We use the AVIC */
void __attribute__((interrupt("IRQ"))) irq_handler(void)
{
const int offset = (int32_t)AVIC_NIVECSR >> 16;
int offset = (long)avic[NIVECSR] >> 16;
if (offset == -1)
{
@ -103,26 +118,25 @@ 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(INT_ALL);
/* Reset AVIC control */
avic->intcntl = 0;
avic[INTCNTL] = 0;
/* Init all interrupts to type IRQ */
avic_set_int_type(INT_ALL, INT_TYPE_IRQ);
/* Set all normal to lowest priority */
for (i = 0; i < 8; i++)
avic->nipriority[i] = 0;
avic[NIPRIORITY + i] = 0;
/* Set NM bit to enable VIC. Mask fast interrupts. Core arbiter rise
* for normal interrupts (for lowest latency). */
avic->intcntl |= AVIC_INTCNTL_NM | AVIC_INTCNTL_FIDIS |
AVIC_INTCNTL_NIAD;
avic[INTCNTL] |= AVIC_INTCNTL_NM | AVIC_INTCNTL_FIDIS |
AVIC_INTCNTL_NIAD;
/* Enable VE bit in CP15 Control reg to enable VIC */
asm volatile (
@ -132,30 +146,28 @@ void avic_init(void)
: : : "r0");
/* Enable normal interrupts at all priorities */
avic->nimask = AVIC_NIL_ENABLE;
avic[NIMASK] = AVIC_NIL_ENABLE;
}
void avic_set_int_priority(enum IMX31_INT_LIST ints,
unsigned long ni_priority)
{
struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
volatile uint32_t *reg = &avic->nipriority[7 - (ints >> 3)];
volatile unsigned long * const reg = &avic[NIPRIORITY + 7 - (ints >> 3)];
unsigned int shift = (ints & 0x7) << 2;
uint32_t mask = 0xful << shift;
unsigned long 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 != INT_ALL) /* No mass-enable allowed */
{
avic_set_int_type(ints, intstype);
avic->vector[ints] = (long)handler;
avic->intennum = ints;
avic[VECTOR + ints] = (unsigned long)handler;
avic[INTENNUM] = ints;
avic_set_int_priority(ints, ni_priority);
}
@ -164,30 +176,27 @@ void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype,
void avic_disable_int(enum IMX31_INT_LIST ints)
{
struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
uint32_t i;
if (ints == INT_ALL)
{
int i;
for (i = 0; i < 64; i++)
{
avic->intdisnum = i;
avic->vector[i] = (long)UIE_VECTOR;
avic[INTDISNUM] = i;
avic[VECTOR + i] = (unsigned long)UIE_VECTOR;
}
}
else
{
avic->intdisnum = ints;
avic->vector[ints] = (long)UIE_VECTOR;
avic[INTDISNUM] = ints;
avic[VECTOR + ints] = (unsigned long)UIE_VECTOR;
}
}
static void set_int_type(int i, enum INT_TYPE intstype)
{
/* 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);
volatile unsigned long * const reg = &avic[INTTYPE + 1 - (i >> 5)];
unsigned long val = 1L << (i & 0x1f);
if (intstype == INT_TYPE_IRQ)
val = *reg & ~val;
@ -222,5 +231,5 @@ void avic_set_ni_level(int level)
else if (level > 15)
level = 15;
AVIC_NIMASK = level;
avic[NIMASK] = level;
}

View file

@ -21,157 +21,6 @@
#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 */
};
};
/* #define IRQ priorities for different modules (0-15) */
#define INT_PRIO_DEFAULT 7
#define INT_PRIO_DVFS (INT_PRIO_DEFAULT+1)

View file

@ -37,25 +37,31 @@ static __attribute__((interrupt("IRQ"))) void I2C2_HANDLER(void);
static __attribute__((interrupt("IRQ"))) void I2C3_HANDLER(void);
#endif
#define IADR (0x00 / sizeof (unsigned short)) /* 00h */
#define IFDR (0x04 / sizeof (unsigned short)) /* 04h */
#define I2CR (0x08 / sizeof (unsigned short)) /* 08h */
#define I2SR (0x0c / sizeof (unsigned short)) /* 0ch */
#define I2DR (0x10 / sizeof (unsigned short)) /* 10h */
static struct i2c_module_descriptor
{
struct i2c_map *base; /* Module base address */
enum IMX31_CG_LIST cg; /* Clock gating index */
enum IMX31_INT_LIST ints; /* Module interrupt number */
int enable; /* Enable count */
void (*handler)(void); /* Module interrupt handler */
struct mutex m; /* Node mutual-exclusion */
struct wakeup w; /* I2C done signal */
unsigned char *addr_data; /* Additional addressing data */
int addr_count; /* Addressing byte count */
unsigned char *data; /* TX/RX buffer (actual data) */
int data_count; /* TX/RX byte count */
unsigned char addr; /* Address + r/w bit */
volatile unsigned short * const base; /* Module base address */
void (* const handler)(void); /* Module interrupt handler */
struct mutex m; /* Node mutual-exclusion */
struct wakeup w; /* I2C done signal */
unsigned char *addr_data; /* Additional addressing data */
int addr_count; /* Addressing byte count */
unsigned char *data; /* TX/RX buffer (actual data) */
int data_count; /* TX/RX byte count */
unsigned char addr; /* Address + r/w bit */
uint8_t enable; /* Enable count */
const uint8_t cg; /* Clock gating index */
const uint8_t ints; /* Module interrupt number */
} i2c_descs[I2C_NUM_I2C] =
{
#if (I2C_MODULE_MASK & USE_I2C1_MODULE)
{
.base = (struct i2c_map *)I2C1_BASE_ADDR,
.base = (unsigned short *)I2C1_BASE_ADDR,
.cg = CG_I2C1,
.ints = INT_I2C1,
.handler = I2C1_HANDLER,
@ -63,7 +69,7 @@ static struct i2c_module_descriptor
#endif
#if (I2C_MODULE_MASK & USE_I2C2_MODULE)
{
.base = (struct i2c_map *)I2C2_BASE_ADDR,
.base = (unsigned short *)I2C2_BASE_ADDR,
.cg = CG_I2C2,
.ints = INT_I2C2,
.handler = I2C2_HANDLER,
@ -71,7 +77,7 @@ static struct i2c_module_descriptor
#endif
#if (I2C_MODULE_MASK & USE_I2C3_MODULE)
{
.base = (struct i2c_map *)I2C3_BASE_ADDR,
.base = (unsigned short *)I2C3_BASE_ADDR,
.cg = CG_I2C3,
.ints = INT_I2C3,
.handler = I2C3_HANDLER,
@ -81,11 +87,11 @@ static struct i2c_module_descriptor
static void i2c_interrupt(enum i2c_module_number i2c)
{
struct i2c_module_descriptor *const desc = &i2c_descs[i2c];
struct i2c_map * const base = desc->base;
uint16_t i2sr = base->i2sr;
struct i2c_module_descriptor * const desc = &i2c_descs[i2c];
volatile unsigned short * const base = desc->base;
unsigned short i2sr = base[I2SR];
base->i2sr = 0; /* Clear IIF */
base[I2SR] = 0; /* Clear IIF */
if (desc->addr_count >= 0)
{
@ -100,8 +106,8 @@ static void i2c_interrupt(enum i2c_module_number i2c)
/* Switching to data cycle */
if (desc->addr & 0x1)
{
base->i2cr &= ~I2C_I2CR_MTX; /* Switch to RX mode */
base->i2dr; /* Dummy read */
base[I2CR] &= ~I2C_I2CR_MTX; /* Switch to RX mode */
base[I2DR]; /* Dummy read */
return;
}
/* else remaining data is TX - handle below */
@ -109,12 +115,12 @@ static void i2c_interrupt(enum i2c_module_number i2c)
}
else
{
base->i2dr = *desc->addr_data++; /* Send next addressing byte */
base[I2DR] = *desc->addr_data++; /* Send next addressing byte */
return;
}
}
if (base->i2cr & I2C_I2CR_MTX)
if (base[I2CR] & I2C_I2CR_MTX)
{
/* Transmitting data */
if ((i2sr & I2C_I2SR_RXAK) == 0)
@ -123,7 +129,7 @@ i2c_transmit:
if (desc->data_count > 0)
{
/* More bytes to send, got ACK from previous byte */
base->i2dr = *desc->data++;
base[I2DR] = *desc->data++;
desc->data_count--;
return;
}
@ -138,24 +144,24 @@ i2c_transmit:
if (desc->data_count == 1)
{
/* 2nd to Last byte - NACK */
base->i2cr |= I2C_I2CR_TXAK;
base[I2CR] |= I2C_I2CR_TXAK;
}
*desc->data++ = base->i2dr; /* Read data from I2DR and store */
*desc->data++ = base[I2DR]; /* Read data from I2DR and store */
return;
}
else
{
/* Generate STOP signal before reading data */
base->i2cr &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
*desc->data++ = base->i2dr; /* Read data from I2DR and store */
base[I2CR] &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
*desc->data++ = base[I2DR]; /* Read data from I2DR and store */
goto i2c_done;
}
}
i2c_stop:
/* Generate STOP signal */
base->i2cr &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
base[I2CR] &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
i2c_done:
/* Signal thread we're done */
wakeup_signal(&desc->w);
@ -183,18 +189,18 @@ static __attribute__((interrupt("IRQ"))) void I2C3_HANDLER(void)
static int i2c_transfer(struct i2c_node * const node,
struct i2c_module_descriptor *const desc)
{
struct i2c_map * const base = desc->base;
volatile unsigned short * const base = desc->base;
int count = desc->data_count;
uint16_t i2cr;
/* Make sure bus is idle. */
while (base->i2sr & I2C_I2SR_IBB);
while (base[I2SR] & I2C_I2SR_IBB);
/* Set speed */
base->ifdr = node->ifdr;
base[IFDR] = node->ifdr;
/* Enable module */
base->i2cr = I2C_I2CR_IEN;
base[I2CR] = I2C_I2CR_IEN;
/* Enable Interrupt, Master */
i2cr = I2C_I2CR_IEN | I2C_I2CR_IIEN | I2C_I2CR_MTX;
@ -206,13 +212,13 @@ static int i2c_transfer(struct i2c_node * const node,
}
/* Set config */
base->i2cr = i2cr;
base[I2CR] = i2cr;
/* Generate START */
base->i2cr = i2cr | I2C_I2CR_MSTA;
base[I2CR] = i2cr | I2C_I2CR_MSTA;
/* Address slave (first byte sent) and begin session. */
base->i2dr = desc->addr;
base[I2DR] = desc->addr;
/* Wait for transfer to complete */
if (wakeup_wait(&desc->w, HZ) == OBJ_WAIT_SUCCEEDED)
@ -222,7 +228,7 @@ static int i2c_transfer(struct i2c_node * const node,
else
{
/* Generate STOP if timeout */
base->i2cr &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
base[I2CR] &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
count = -1;
}
@ -289,7 +295,7 @@ void i2c_init(void)
ccm_module_clock_gating(desc->cg, CGM_ON_RUN_WAIT);
mutex_init(&desc->m);
wakeup_init(&desc->w);
desc->base->i2cr = 0;
desc->base[I2CR] = 0;
ccm_module_clock_gating(desc->cg, CGM_OFF);
}
}
@ -315,8 +321,8 @@ void i2c_enable_node(struct i2c_node *node, bool enable)
if (desc->enable > 0 && --desc->enable == 0)
{
/* Last enable */
while (desc->base->i2sr & I2C_I2SR_IBB); /* Wait for STOP */
desc->base->i2cr &= ~I2C_I2CR_IEN;
while (desc->base[I2SR] & I2C_I2SR_IBB); /* Wait for STOP */
desc->base[I2CR] &= ~I2C_I2CR_IEN;
avic_disable_int(desc->ints);
ccm_module_clock_gating(desc->cg, CGM_OFF);
}

View file

@ -43,20 +43,6 @@ enum i2c_module_number
I2C_NUM_I2C,
};
/* Module interface map structure */
struct i2c_map
{
volatile uint16_t iadr; /* 0x00 */
volatile uint16_t unused1;
volatile uint16_t ifdr; /* 0x04 */
volatile uint16_t unused2;
volatile uint16_t i2cr; /* 0x08 */
volatile uint16_t unused3;
volatile uint16_t i2sr; /* 0x0C */
volatile uint16_t unused4;
volatile uint16_t i2dr; /* 0x10 */
};
struct i2c_node
{
enum i2c_module_number num; /* Module that this node uses */

View file

@ -37,25 +37,34 @@ static __attribute__((interrupt("IRQ"))) void CSPI2_HANDLER(void);
static __attribute__((interrupt("IRQ"))) void CSPI3_HANDLER(void);
#endif
#define RXDATA (0x000 / sizeof (unsigned long)) /* 000h */
#define TXDATA (0x004 / sizeof (unsigned long)) /* 004h */
#define CONREG (0x008 / sizeof (unsigned long)) /* 008h */
#define INTREG (0x00c / sizeof (unsigned long)) /* 00Ch */
#define DMAREG (0x010 / sizeof (unsigned long)) /* 010h */
#define STATREG (0x014 / sizeof (unsigned long)) /* 014h */
#define PERIODREG (0x01c / sizeof (unsigned long)) /* 018h */
#define TESTREG (0x1c0 / sizeof (unsigned long)) /* 1C0h */
/* State data associatated with each CSPI module */
static struct spi_module_desc
{
struct cspi_map * const base; /* CSPI module address */
struct spi_transfer_desc *head; /* Running job */
struct spi_transfer_desc *tail; /* Most recent job added */
const struct spi_node *last_node; /* Last node used for module */
void (*handler)(void); /* Interrupt handler */
int rxcount; /* Independent copy of txcount */
int8_t enab; /* Enable count */
int8_t byte_size; /* Size of transfers in bytes */
int8_t cg; /* Clock-gating value */
int8_t ints; /* AVIC vector number */
volatile unsigned long * const base; /* CSPI module address */
struct spi_transfer_desc *head; /* Running job */
struct spi_transfer_desc *tail; /* Most recent job added */
const struct spi_node *last_node; /* Last node used for module */
void (* const handler)(void); /* Interrupt handler */
int rxcount; /* Independent copy of txcount */
int8_t enab; /* Enable count */
int8_t byte_size; /* Size of transfers in bytes */
const int8_t cg; /* Clock-gating value */
const int8_t ints; /* AVIC vector number */
} spi_descs[SPI_NUM_CSPI] =
/* Init non-zero members */
{
#if (SPI_MODULE_MASK & USE_CSPI1_MODULE)
{
.base = (struct cspi_map *)CSPI1_BASE_ADDR,
.base = (unsigned long *)CSPI1_BASE_ADDR,
.cg = CG_CSPI1,
.ints = INT_CSPI1,
.handler = CSPI1_HANDLER,
@ -63,7 +72,7 @@ static struct spi_module_desc
#endif
#if (SPI_MODULE_MASK & USE_CSPI2_MODULE)
{
.base = (struct cspi_map *)CSPI2_BASE_ADDR,
.base = (unsigned long *)CSPI2_BASE_ADDR,
.cg = CG_CSPI2,
.ints = INT_CSPI2,
.handler = CSPI2_HANDLER,
@ -71,7 +80,7 @@ static struct spi_module_desc
#endif
#if (SPI_MODULE_MASK & USE_CSPI3_MODULE)
{
.base = (struct cspi_map *)CSPI3_BASE_ADDR,
.base = (unsigned long *)CSPI3_BASE_ADDR,
.cg = CG_CSPI3,
.ints = INT_CSPI3,
.handler = CSPI3_HANDLER,
@ -83,8 +92,7 @@ static struct spi_module_desc
static void spi_reset(struct spi_module_desc * const desc)
{
/* Reset by leaving it disabled */
struct cspi_map * const base = desc->base;
base->conreg &= ~CSPI_CONREG_EN;
desc->base[CONREG] &= ~CSPI_CONREG_EN;
}
/* Write the context for the node and remember it to avoid unneeded reconfigure */
@ -92,7 +100,7 @@ static bool spi_set_context(struct spi_module_desc *desc,
struct spi_transfer_desc *xfer)
{
const struct spi_node * const node = xfer->node;
struct cspi_map * const base = desc->base;
volatile unsigned long * const base = desc->base;
if (desc->enab == 0)
return false;
@ -101,17 +109,17 @@ static bool spi_set_context(struct spi_module_desc *desc,
return true;
/* Errata says CSPI should be disabled when writing PERIODREG. */
base->conreg &= ~CSPI_CONREG_EN;
base[CONREG] &= ~CSPI_CONREG_EN;
/* Switch the module's node */
desc->last_node = node;
desc->byte_size = (((node->conreg >> 8) & 0x1f) + 1 + 7) / 8 - 1;
/* Set the wait-states */
base->periodreg = node->periodreg & 0xffff;
base[PERIODREG] = node->periodreg & 0xffff;
/* Keep reserved and start bits cleared. Keep enabled bit. */
base->conreg =
base[CONREG] =
(node->conreg & ~(0xfcc8e000 | CSPI_CONREG_XCH | CSPI_CONREG_SMC));
return true;
}
@ -119,13 +127,13 @@ static bool spi_set_context(struct spi_module_desc *desc,
/* Fill the TX fifo. Returns the number of remaining words. */
static int tx_fill_fifo(struct spi_module_desc * const desc,
struct cspi_map * const base,
volatile unsigned long * const base,
struct spi_transfer_desc * const xfer)
{
int count = xfer->count;
int size = desc->byte_size;
while ((base->statreg & CSPI_STATREG_TF) == 0)
while ((base[STATREG] & CSPI_STATREG_TF) == 0)
{
uint32_t word = 0;
@ -143,7 +151,7 @@ static int tx_fill_fifo(struct spi_module_desc * const desc,
xfer->txbuf += size + 1; /* Increment buffer */
base->txdata = word; /* Write to FIFO */
base[TXDATA] = word; /* Write to FIFO */
if (--count == 0)
break;
@ -158,13 +166,13 @@ static int tx_fill_fifo(struct spi_module_desc * const desc,
static bool start_transfer(struct spi_module_desc * const desc,
struct spi_transfer_desc * const xfer)
{
struct cspi_map * const base = desc->base;
volatile unsigned long * const base = desc->base;
unsigned long intreg;
if (!spi_set_context(desc, xfer))
return false;
base->conreg |= CSPI_CONREG_EN; /* Enable module */
base[CONREG] |= CSPI_CONREG_EN; /* Enable module */
desc->rxcount = xfer->count;
@ -178,9 +186,9 @@ static bool start_transfer(struct spi_module_desc * const desc,
tx_fill_fifo(desc, base, xfer);
base->statreg = CSPI_STATREG_TC; /* Ack 'complete' */
base->intreg = intreg; /* Enable interrupts */
base->conreg |= CSPI_CONREG_XCH; /* Begin transfer */
base[STATREG] = CSPI_STATREG_TC; /* Ack 'complete' */
base[INTREG] = intreg; /* Enable interrupts */
base[CONREG] |= CSPI_CONREG_XCH; /* Begin transfer */
return true;
}
@ -189,15 +197,15 @@ static bool start_transfer(struct spi_module_desc * const desc,
static void spi_interrupt(enum spi_module_number spi)
{
struct spi_module_desc *desc = &spi_descs[spi];
struct cspi_map * const base = desc->base;
unsigned long intreg = base->intreg;
volatile unsigned long * const base = desc->base;
unsigned long intreg = base[INTREG];
struct spi_transfer_desc *xfer = desc->head;
int inc = desc->byte_size + 1;
/* Data received - empty out RXFIFO */
while ((base->statreg & CSPI_STATREG_RR) != 0)
while ((base[STATREG] & CSPI_STATREG_RR) != 0)
{
uint32_t word = base->rxdata;
uint32_t word = base[RXDATA];
if (desc->rxcount <= 0)
continue;
@ -226,14 +234,14 @@ static void spi_interrupt(enum spi_module_number spi)
{
/* No more to receive - stop RX interrupts */
intreg &= ~(CSPI_INTREG_RHEN | CSPI_INTREG_RREN);
base->intreg = intreg;
base[INTREG] = intreg;
}
else if (intreg & CSPI_INTREG_RHEN)
{
/* < 4 words expected - switch to RX ready */
intreg &= ~CSPI_INTREG_RHEN;
intreg |= CSPI_INTREG_RREN;
base->intreg = intreg;
base[INTREG] = intreg;
}
}
}
@ -247,15 +255,15 @@ static void spi_interrupt(enum spi_module_number spi)
/* Out of data - stop TX interrupts, enable TC interrupt. */
intreg &= ~CSPI_INTREG_THEN;
intreg |= CSPI_INTREG_TCEN;
base->intreg = intreg;
base[INTREG] = intreg;
}
if ((intreg & CSPI_INTREG_TCEN) && (base->statreg & CSPI_STATREG_TC))
if ((intreg & CSPI_INTREG_TCEN) && (base[STATREG] & CSPI_STATREG_TC))
{
/* Outbound transfer is complete. */
intreg &= ~CSPI_INTREG_TCEN;
base->intreg = intreg;
base->statreg = CSPI_STATREG_TC; /* Ack 'complete' */
base[INTREG] = intreg;
base[STATREG] = CSPI_STATREG_TC; /* Ack 'complete' */
}
if (intreg != 0)
@ -268,7 +276,7 @@ static void spi_interrupt(enum spi_module_number spi)
spi_transfer_cb_fn_type callback = xfer->callback;
xfer->next = NULL;
base->conreg &= ~CSPI_CONREG_EN; /* Disable module */
base[CONREG] &= ~CSPI_CONREG_EN; /* Disable module */
if (next == xfer)
{
@ -361,8 +369,6 @@ void spi_disable_module(const struct spi_node *node)
if (desc->enab > 0 && --desc->enab == 0)
{
/* Last enable for this module */
struct cspi_map * const base = desc->base;
/* Wait for outstanding transactions */
while (*(void ** volatile)&desc->head != NULL);
@ -370,7 +376,7 @@ void spi_disable_module(const struct spi_node *node)
avic_disable_int(desc->ints);
/* Disable interface */
base->conreg &= ~CSPI_CONREG_EN;
desc->base[CONREG] &= ~CSPI_CONREG_EN;
/* Disable interface clock */
ccm_module_clock_gating(desc->cg, CGM_OFF);

View file

@ -41,19 +41,6 @@ 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) */