forked from Imagelibrary/rtems
bsps/powerpc: Add PPC405 support for shared clock
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Obere Lagerstr. 30
|
||||||
@@ -36,6 +36,8 @@
|
|||||||
*/
|
*/
|
||||||
extern uint32_t bsp_time_base_frequency;
|
extern uint32_t bsp_time_base_frequency;
|
||||||
|
|
||||||
|
#define PPC405_PIT 0x3db
|
||||||
|
|
||||||
#define PPC_CLOCK_DECREMENTER_MAX UINT32_MAX
|
#define PPC_CLOCK_DECREMENTER_MAX UINT32_MAX
|
||||||
|
|
||||||
volatile uint32_t Clock_driver_ticks = 0;
|
volatile uint32_t Clock_driver_ticks = 0;
|
||||||
@@ -132,6 +134,28 @@ static int ppc_clock_exception_handler_booke( BSP_Exception_frame *frame, unsign
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ppc_clock_exception_handler_ppc405(BSP_Exception_frame *frame, unsigned number)
|
||||||
|
{
|
||||||
|
uint32_t msr;
|
||||||
|
|
||||||
|
/* Acknowledge PIT request */
|
||||||
|
PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_TSR, BOOKE_TSR_DIS);
|
||||||
|
|
||||||
|
/* Increment clock ticks */
|
||||||
|
Clock_driver_ticks += 1;
|
||||||
|
|
||||||
|
/* Enable external exceptions */
|
||||||
|
msr = ppc_external_exceptions_enable();
|
||||||
|
|
||||||
|
/* Call clock ticker */
|
||||||
|
ppc_clock_tick();
|
||||||
|
|
||||||
|
/* Restore machine state */
|
||||||
|
ppc_external_exceptions_disable(msr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t ppc_clock_nanoseconds_since_last_tick(void)
|
static uint32_t ppc_clock_nanoseconds_since_last_tick(void)
|
||||||
{
|
{
|
||||||
uint64_t k = ppc_clock_factor;
|
uint64_t k = ppc_clock_factor;
|
||||||
@@ -141,6 +165,19 @@ static uint32_t ppc_clock_nanoseconds_since_last_tick(void)
|
|||||||
return (uint32_t) (((i - c) * k) >> 32);
|
return (uint32_t) (((i - c) * k) >> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t ppc_clock_nanoseconds_since_last_tick_ppc405(void)
|
||||||
|
{
|
||||||
|
uint64_t k = ppc_clock_factor;
|
||||||
|
uint32_t i = ppc_clock_decrementer_value;
|
||||||
|
uint32_t c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT);
|
||||||
|
|
||||||
|
if ((PPC_SPECIAL_PURPOSE_REGISTER(PPC405_TSR) & BOOKE_TSR_DIS) != 0) {
|
||||||
|
c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT) + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint32_t) ((c * k) >> 32);
|
||||||
|
}
|
||||||
|
|
||||||
void Clock_exit(void)
|
void Clock_exit(void)
|
||||||
{
|
{
|
||||||
/* Set the decrementer to the maximum value */
|
/* Set the decrementer to the maximum value */
|
||||||
@@ -156,9 +193,6 @@ rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_dev
|
|||||||
uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
|
uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
|
||||||
uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
|
uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
|
||||||
|
|
||||||
/* Current CPU type */
|
|
||||||
ppc_cpu_id_t cpu_type = get_ppc_cpu_type();
|
|
||||||
|
|
||||||
/* Make major/minor available to others such as shared memory driver */
|
/* Make major/minor available to others such as shared memory driver */
|
||||||
rtems_clock_major = major;
|
rtems_clock_major = major;
|
||||||
rtems_clock_minor = minor;
|
rtems_clock_minor = minor;
|
||||||
@@ -172,12 +206,10 @@ rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_dev
|
|||||||
*/
|
*/
|
||||||
ppc_clock_tick = (void (*)(void)) rtems_clock_tick;
|
ppc_clock_tick = (void (*)(void)) rtems_clock_tick;
|
||||||
|
|
||||||
/* Set the decrementer to the maximum value */
|
|
||||||
ppc_set_decrementer_register( PPC_CLOCK_DECREMENTER_MAX);
|
|
||||||
|
|
||||||
/* Factor for nano seconds extension */
|
/* Factor for nano seconds extension */
|
||||||
ppc_clock_factor = (1000000000ULL << 32) / frequency;
|
ppc_clock_factor = (1000000000ULL << 32) / frequency;
|
||||||
|
|
||||||
|
if (ppc_cpu_is_bookE() != PPC_BOOKE_405) {
|
||||||
/* Decrementer value */
|
/* Decrementer value */
|
||||||
ppc_clock_decrementer_value = interval - 1;
|
ppc_clock_decrementer_value = interval - 1;
|
||||||
|
|
||||||
@@ -212,6 +244,22 @@ rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_dev
|
|||||||
|
|
||||||
/* Set the decrementer value */
|
/* Set the decrementer value */
|
||||||
ppc_set_decrementer_register( ppc_clock_decrementer_value);
|
ppc_set_decrementer_register( ppc_clock_decrementer_value);
|
||||||
|
} else {
|
||||||
|
/* PIT interval value */
|
||||||
|
ppc_clock_decrementer_value = interval;
|
||||||
|
|
||||||
|
/* Set the nanoseconds since last tick handler */
|
||||||
|
rtems_clock_set_nanoseconds_extension(ppc_clock_nanoseconds_since_last_tick_ppc405);
|
||||||
|
|
||||||
|
/* Install exception handler */
|
||||||
|
ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_ppc405);
|
||||||
|
|
||||||
|
/* Enable PIT and auto-reload */
|
||||||
|
PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(PPC405_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
|
||||||
|
|
||||||
|
/* Set PIT auto-reload and initial value */
|
||||||
|
PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_PIT, interval);
|
||||||
|
}
|
||||||
|
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user