Ignore:
Timestamp:
Jan 23, 2012, 10:19:22 AM (9 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, 5, master
Children:
f4491f94
Parents:
9bf3a868
Message:

Support for MPC5643L.

Rework of the start sequence to reduce the amount assembler code and to
support configuration tables which may be provided by the application.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c

    r9bf3a868 ra762dc2  
    88
    99/*
    10  * Copyright (c) 2009
    11  * embedded brains GmbH
    12  * Obere Lagerstr. 30
    13  * D-82178 Puchheim
    14  * Germany
    15  * <rtems@embedded-brains.de>
     10 * Copyright (c) 2009-2011 embedded brains GmbH.  All rights reserved.
     11 *
     12 *  embedded brains GmbH
     13 *  Obere Lagerstr. 30
     14 *  82178 Puchheim
     15 *  Germany
     16 *  <rtems@embedded-brains.de>
    1617 *
    1718 * The license and distribution terms for this file may be
     
    2021 */
    2122
    22 #include <mpc55xx/regs.h>
    23 #include <mpc55xx/emios.h>
    24 
    25 #include <rtems.h>
    26 
    2723#include <bsp.h>
    2824#include <bsp/irq.h>
    2925
    30 #define RTEMS_STATUS_CHECKS_USE_PRINTK
    31 
    32 #include <rtems/status-checks.h>
    33 
    34 /* This is defined in clockdrv_shell.h */
    35 rtems_isr Clock_isr( rtems_vector_number vector);
    36 
    37 #define Clock_driver_support_at_tick() \
    38  do { \
    39     union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS; \
    40     csr.B.FLAG = 1; \
    41     EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.R = csr.R; \
    42  } while (0)
     26#include <mpc55xx/regs.h>
    4327
    4428static uint64_t mpc55xx_clock_factor;
    4529
    46 static void mpc55xx_clock_handler_install( rtems_isr_entry isr,
    47                                            rtems_isr_entry *old_isr)
     30#if defined(MPC55XX_CLOCK_EMIOS_CHANNEL)
     31
     32#include <mpc55xx/emios.h>
     33
     34static void mpc55xx_clock_at_tick(void)
     35{
     36  union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
     37  csr.B.FLAG = 1;
     38  EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.R = csr.R;
     39}
     40
     41static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
    4842{
    4943  rtems_status_code sc = RTEMS_SUCCESSFUL;
    5044
    5145  sc = mpc55xx_interrupt_handler_install(
    52     MPC55XX_IRQ_EMIOS( MPC55XX_CLOCK_EMIOS_CHANNEL),
     46    MPC55XX_IRQ_EMIOS(MPC55XX_CLOCK_EMIOS_CHANNEL),
    5347    "clock",
    5448    RTEMS_INTERRUPT_UNIQUE,
     
    5751    NULL
    5852  );
    59  *old_isr = NULL;
    60   RTEMS_CHECK_SC_VOID( sc, "install clock interrupt handler");
    61 }
    62 
    63 static void mpc55xx_clock_initialize( void)
     53  if (sc != RTEMS_SUCCESSFUL) {
     54    rtems_fatal_error_occurred(0xdeadbeef);
     55  }
     56}
     57
     58static void mpc55xx_clock_initialize(void)
    6459{
    6560  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
     
    6762  union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
    6863  unsigned prescaler = mpc55xx_emios_global_prescaler();
    69   uint64_t interval = ((uint64_t) bsp_clock_speed
    70     * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000;
    71 
    72   mpc55xx_clock_factor = (1000000000ULL << 32) / bsp_clock_speed;
     64  uint64_t reference_clock = bsp_clock_speed;
     65  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
     66  uint64_t interval = (reference_clock * us_per_tick) / 1000000;
     67
     68  mpc55xx_clock_factor = (1000000000ULL << 32) / reference_clock;
    7369
    7470  /* Apply prescaler */
     
    7672    interval /= (uint64_t) prescaler;
    7773  } else {
    78     RTEMS_SYSLOG_ERROR( "unexpected global eMIOS prescaler\n");
     74    rtems_fatal_error_occurred(0xdeadbeef);
    7975  }
    8076
    8177  /* Check interval */
    8278  if (interval == 0 || interval > MPC55XX_EMIOS_VALUE_MAX) {
    83     interval = MPC55XX_EMIOS_VALUE_MAX;
    84     RTEMS_SYSLOG_ERROR( "clock timer interval out of range\n");
     79    rtems_fatal_error_occurred(0xdeadbeef);
    8580  }
    8681
     
    10499
    105100  /* Set control register */
    106 #if MPC55XX_CHIP_TYPE / 10 == 551
    107   ccr.B.MODE = MPC55XX_EMIOS_MODE_MCB_UP_INT_CLK;
    108 #else
    109   ccr.B.MODE = MPC55XX_EMIOS_MODE_MC_UP_INT_CLK;
    110 #endif
     101  #if MPC55XX_CHIP_TYPE / 10 == 551
     102    ccr.B.MODE = MPC55XX_EMIOS_MODE_MCB_UP_INT_CLK;
     103  #else
     104    ccr.B.MODE = MPC55XX_EMIOS_MODE_MC_UP_INT_CLK;
     105  #endif
    111106  ccr.B.UCPREN = 1;
    112107  ccr.B.FEN = 1;
     
    115110}
    116111
    117 static void mpc55xx_clock_cleanup( void)
    118 {
    119   rtems_status_code sc = RTEMS_SUCCESSFUL;
     112static void mpc55xx_clock_cleanup(void)
     113{
    120114  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
    121115  union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
     
    124118  ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
    125119  regs->CCR.R = ccr.R;
    126 
    127   /* Remove interrupt handler */
    128   sc = rtems_interrupt_handler_remove(
    129     MPC55XX_IRQ_EMIOS( MPC55XX_CLOCK_EMIOS_CHANNEL),
    130     (rtems_interrupt_handler) Clock_isr,
    131     NULL
    132   );
    133   RTEMS_CHECK_SC_VOID( sc, "remove clock interrupt handler");
    134 }
    135 
    136 static uint32_t mpc55xx_clock_nanoseconds_since_last_tick( void)
     120}
     121
     122static uint32_t mpc55xx_clock_nanoseconds_since_last_tick(void)
    137123{
    138124  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
     
    148134}
    149135
    150 #define Clock_driver_support_initialize_hardware() mpc55xx_clock_initialize()
    151 
    152 #define Clock_driver_support_install_isr( isr, old_isr) \
    153   mpc55xx_clock_handler_install(isr,&old_isr)
    154 
    155 #define Clock_driver_support_shutdown_hardware() mpc55xx_clock_cleanup()
    156 
     136#elif defined(MPC55XX_CLOCK_PIT_CHANNEL)
     137
     138static void mpc55xx_clock_at_tick(void)
     139{
     140  volatile PIT_RTI_CHANNEL_tag *channel =
     141    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
     142  PIT_RTI_TFLG_32B_tag tflg = { .B = { .TIF = 1 } };
     143
     144  channel->TFLG.R = tflg.R;
     145}
     146
     147static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
     148{
     149  rtems_status_code sc = RTEMS_SUCCESSFUL;
     150
     151  sc = mpc55xx_interrupt_handler_install(
     152    MPC55XX_IRQ_PIT_CHANNEL(MPC55XX_CLOCK_PIT_CHANNEL),
     153    "clock",
     154    RTEMS_INTERRUPT_UNIQUE,
     155    MPC55XX_INTC_MIN_PRIORITY,
     156    (rtems_interrupt_handler) isr,
     157    NULL
     158  );
     159  if (sc != RTEMS_SUCCESSFUL) {
     160    rtems_fatal_error_occurred(0xdeadbeef);
     161  }
     162}
     163
     164static void mpc55xx_clock_initialize(void)
     165{
     166  volatile PIT_RTI_CHANNEL_tag *channel =
     167    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
     168  uint64_t reference_clock = bsp_clock_speed;
     169  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
     170  uint64_t interval = (reference_clock * us_per_tick) / 1000000;
     171  PIT_RTI_PITMCR_32B_tag pitmcr = { .B = { .FRZ = 1 } };
     172  PIT_RTI_TCTRL_32B_tag tctrl = { .B = { .TIE = 1, .TEN = 1 } };
     173
     174  mpc55xx_clock_factor = (1000000000ULL << 32) / reference_clock;
     175
     176  PIT_RTI.PITMCR.R = pitmcr.R;
     177  channel->LDVAL.R = interval;
     178  channel->TCTRL.R = tctrl.R;
     179}
     180
     181static void mpc55xx_clock_cleanup(void)
     182{
     183  volatile PIT_RTI_CHANNEL_tag *channel =
     184    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
     185
     186  channel->TCTRL.R = 0;
     187}
     188
     189static uint32_t mpc55xx_clock_nanoseconds_since_last_tick(void)
     190{
     191  volatile PIT_RTI_CHANNEL_tag *channel =
     192    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
     193  uint32_t c = channel->CVAL.R;
     194  uint32_t i = channel->LDVAL.R;
     195  uint64_t k = mpc55xx_clock_factor;
     196
     197  if (channel->TFLG.B.TIF != 0) {
     198    c = channel->CVAL.R - i;
     199  }
     200
     201  return (uint32_t) (((i - c) * k) >> 32);
     202}
     203
     204#endif
     205
     206#define Clock_driver_support_at_tick() \
     207  mpc55xx_clock_at_tick()
     208#define Clock_driver_support_initialize_hardware() \
     209  mpc55xx_clock_initialize()
     210#define Clock_driver_support_install_isr(isr, old_isr) \
     211  do { \
     212    mpc55xx_clock_handler_install(isr); \
     213    old_isr = NULL; \
     214  } while (0)
     215#define Clock_driver_support_shutdown_hardware() \
     216  mpc55xx_clock_cleanup()
    157217#define Clock_driver_nanoseconds_since_last_tick \
    158218  mpc55xx_clock_nanoseconds_since_last_tick
Note: See TracChangeset for help on using the changeset viewer.