2011-03-04 Till Straumann <strauman@slac.stanford.edu>

PR 1738/bsps
	* clock/clock.c, include/bsp.h, network/network.c: system clock driver
	programs the PIT w/o assuming the CPU clock frequency being a power
	of two.
This commit is contained in:
Joel Sherrill
2011-03-04 16:03:53 +00:00
parent 6481895a2e
commit 8d45df8368
4 changed files with 64 additions and 29 deletions

View File

@@ -1,3 +1,10 @@
2011-03-04 Till Straumann <strauman@slac.stanford.edu>
PR 1738/bsps
* clock/clock.c, include/bsp.h, network/network.c: system clock driver
programs the PIT w/o assuming the CPU clock frequency being a power
of two.
2011-02-17 Till Straumann <strauman@slac.stanford.edu> 2011-02-17 Till Straumann <strauman@slac.stanford.edu>
PR 1738/bsps PR 1738/bsps

View File

@@ -26,19 +26,19 @@
* CPU load counters * CPU load counters
* Place in static RAM so updates don't hit the SDRAM * Place in static RAM so updates don't hit the SDRAM
*/ */
extern int __SRAMBASE[]; #define IDLE_COUNTER __SRAMBASE.idle_counter
#define IDLE_COUNTER __SRAMBASE[0] #define FILTERED_IDLE __SRAMBASE.filtered_idle
#define FILTERED_IDLE __SRAMBASE[1] #define MAX_IDLE_COUNT __SRAMBASE.max_idle_count
#define MAX_IDLE_COUNT __SRAMBASE[2] #define PITC_PER_TICK __SRAMBASE.pitc_per_tick
#define USEC_PER_TICK __SRAMBASE[3] #define NSEC_PER_PITC __SRAMBASE.nsec_per_pitc
#define FILTER_SHIFT 6 #define FILTER_SHIFT 6
uint32_t bsp_clock_nanoseconds_since_last_tick(void) uint32_t bsp_clock_nanoseconds_since_last_tick(void)
{ {
int i = MCF5282_PIT3_PCNTR; int i = MCF5282_PIT3_PCNTR;
if (MCF5282_PIT3_PCSR & MCF5282_PIT_PCSR_PIF) if (MCF5282_PIT3_PCSR & MCF5282_PIT_PCSR_PIF)
i = MCF5282_PIT3_PCNTR - USEC_PER_TICK; i = MCF5282_PIT3_PCNTR - PITC_PER_TICK;
return (USEC_PER_TICK - i) * 1000; return (PITC_PER_TICK - i) * NSEC_PER_PITC;
} }
#define Clock_driver_nanoseconds_since_last_tick bsp_clock_nanoseconds_since_last_tick #define Clock_driver_nanoseconds_since_last_tick bsp_clock_nanoseconds_since_last_tick
@@ -48,7 +48,7 @@ uint32_t bsp_clock_nanoseconds_since_last_tick(void)
*/ */
#define Clock_driver_support_at_tick() \ #define Clock_driver_support_at_tick() \
do { \ do { \
int idle = IDLE_COUNTER; \ unsigned idle = IDLE_COUNTER; \
IDLE_COUNTER = 0; \ IDLE_COUNTER = 0; \
if (idle > MAX_IDLE_COUNT) \ if (idle > MAX_IDLE_COUNT) \
MAX_IDLE_COUNT = idle; \ MAX_IDLE_COUNT = idle; \
@@ -75,18 +75,29 @@ uint32_t bsp_clock_nanoseconds_since_last_tick(void)
/* /*
* Set up the clock hardware * Set up the clock hardware
* *
* Prescale so that it counts in microseconds * f_pit = f_clk / 2^(preScaleCode+1) / N = 1/(us_per_tick/us_per_s)
* System clock frequency better be 2**n (1<=n<=16) MHz! *
* N = f_clk / 2^(preScaleCode+1) * us_per_tick / us_per_s
*
* ns_per_pit_clk = ns_per_s / (f_clk / 2^(preScaleCode+1))
* = ns_per_s * 2^(preScaleCode+1) / f_clk;
*/ */
#define Clock_driver_support_initialize_hardware() \ #define Clock_driver_support_initialize_hardware() \
do { \ do { \
unsigned long long N; \
int level; \ int level; \
int preScaleCode = -2; \ int preScaleCode = 0; \
int preScaleDivisor = bsp_get_CPU_clock_speed() / 1000000; \ N = bsp_get_CPU_clock_speed(); \
while (preScaleDivisor) { \ N *= rtems_configuration_get_microseconds_per_tick(); \
preScaleDivisor >>= 1; \ N /= 2*1000000; /* min_prescale * us_per_s */ \
while ( N > 0x10000 ) { \
preScaleCode++; \ preScaleCode++; \
N >>= 1; \
} \ } \
PITC_PER_TICK = N; \
N = 2000000000ULL << preScaleCode; \
N /= bsp_get_CPU_clock_speed(); \
NSEC_PER_PITC = N; \
IDLE_COUNTER = 0; \ IDLE_COUNTER = 0; \
FILTERED_IDLE = 0; \ FILTERED_IDLE = 0; \
MAX_IDLE_COUNT = 0; \ MAX_IDLE_COUNT = 0; \
@@ -101,8 +112,7 @@ uint32_t bsp_clock_nanoseconds_since_last_tick(void)
MCF5282_PIT_PCSR_OVW | \ MCF5282_PIT_PCSR_OVW | \
MCF5282_PIT_PCSR_PIE | \ MCF5282_PIT_PCSR_PIE | \
MCF5282_PIT_PCSR_RLD; \ MCF5282_PIT_PCSR_RLD; \
USEC_PER_TICK = rtems_configuration_get_microseconds_per_tick(); \ MCF5282_PIT3_PMR = PITC_PER_TICK - 1; \
MCF5282_PIT3_PMR = USEC_PER_TICK - 1; \
MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) | \ MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) | \
MCF5282_PIT_PCSR_PIE | \ MCF5282_PIT_PCSR_PIE | \
MCF5282_PIT_PCSR_RLD | \ MCF5282_PIT_PCSR_RLD | \
@@ -115,7 +125,7 @@ uint32_t bsp_clock_nanoseconds_since_last_tick(void)
Thread bsp_idle_thread(uint32_t ignored) Thread bsp_idle_thread(uint32_t ignored)
{ {
for(;;) for(;;)
asm volatile ("addq.l #1,__SRAMBASE"); /* Atomic increment */ asm volatile ("addq.l #1,%0"::"m"(IDLE_COUNTER)); /* Atomic increment */
} }
int rtems_bsp_cpu_load_percentage(void) int rtems_bsp_cpu_load_percentage(void)

View File

@@ -134,6 +134,31 @@ int BSP_vme2local_adrs(unsigned am, unsigned long vmeaddr, unsigned long *plocal
void *bsp_idle_thread( uintptr_t ignored ); void *bsp_idle_thread( uintptr_t ignored );
#define BSP_IDLE_TASK_BODY bsp_idle_thread #define BSP_IDLE_TASK_BODY bsp_idle_thread
/*
* SRAM. The BSP uses SRAM for maintaining some clock-driver data
* and for ethernet descriptors (and the initial stack during
* early boot).
*/
typedef struct mcf5282BufferDescriptor_ {
volatile uint16_t status;
uint16_t length;
volatile void *buffer;
} mcf5282BufferDescriptor_t;
extern struct {
uint32_t idle_counter;
uint32_t filtered_idle;
uint32_t max_idle_count;
uint32_t pitc_per_tick;
uint32_t nsec_per_pitc;
uint32_t pad[3]; /* align to 16-bytes for descriptors */
mcf5282BufferDescriptor_t fec_descriptors[];
/* buffer descriptors are allocated from here */
/* initial stack is at top of SRAM (start.S) */
} __SRAMBASE;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -81,12 +81,6 @@
#error "Driver must have MCLBYTES > RBUF_SIZE" #error "Driver must have MCLBYTES > RBUF_SIZE"
#endif #endif
typedef struct mcf5282BufferDescriptor_ {
volatile uint16_t status;
uint16_t length;
volatile void *buffer;
} mcf5282BufferDescriptor_t;
/* /*
* Per-device data * Per-device data
*/ */
@@ -197,11 +191,10 @@ mcf5282_mii_interrupt_handler( rtems_vector_number v )
* Ensure 128-bit (16-byte) alignment * Ensure 128-bit (16-byte) alignment
* Allow some space at the beginning for other diagnostic counters * Allow some space at the beginning for other diagnostic counters
*/ */
extern char __SRAMBASE[];
static mcf5282BufferDescriptor_t * static mcf5282BufferDescriptor_t *
mcf5282_bd_allocate(unsigned int count) mcf5282_bd_allocate(unsigned int count)
{ {
static mcf5282BufferDescriptor_t *bdp = (mcf5282BufferDescriptor_t *)(__SRAMBASE+16); static mcf5282BufferDescriptor_t *bdp = __SRAMBASE.fec_descriptors;
mcf5282BufferDescriptor_t *p = bdp; mcf5282BufferDescriptor_t *p = bdp;
bdp += count; bdp += count;