Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:56

0001 /*
0002  *  Baud rate generator management functions.
0003  *
0004  *  This file contains routines for allocating baud rate generators
0005  *  and clock sources to the SCCs and FCCs on the MPC8260.  The
0006  *  allocation is a little more complex on this processor because
0007  *  there are restrictions on which brgs and clks can be assigned to
0008  *  a particular port.  Rather than coming up with a fixed assignment
0009  *  these routines try to allocate resources sensibly.
0010  *
0011  *  *** All attempts to allocate a BRG or CLK line should be made via
0012  *      calls to these routines or they simply won't work.
0013  */
0014 
0015 /*
0016  *  Author: Andy Dachs <a.dachs@sstl.co.uk>
0017  *  Copyright Surrey Satellite Technology Limited (SSTL), 2001
0018  *
0019  *  Derived in part from work by:
0020  *
0021  *    Author: Jay Monkman (jmonkman@frasca.com)
0022  *    Copyright (C) 1998 by Frasca International, Inc.
0023  *  and
0024  *    Eric Norum <eric.norum.ca>
0025  *
0026  *  The license and distribution terms for this file may be
0027  *  found in the file LICENSE in this distribution or at
0028  *  http://www.rtems.org/license/LICENSE.
0029  */
0030 
0031 #include <bsp.h>
0032 #include <mpc8260.h>
0033 #include <mpc8260/cpm.h>
0034 #include <rtems/bspIo.h>
0035 
0036 #define NUM_BRGS 8
0037 #define NUM_CLKS 20
0038 
0039 /* Used to track the usage of the baud rate generators */
0040 /* (initialised to zeros) */
0041 static unsigned long brg_spd[NUM_BRGS];
0042 static unsigned int brg_use_count[NUM_BRGS];
0043 
0044 /* Used to track the usage of the clock inputs */
0045 /* (initialised to zeros) */
0046 static unsigned int clk_use_count[NUM_BRGS];
0047 
0048 /*
0049  * Compute baud-rate-generator configuration register value
0050  */
0051 int
0052 m8xx_get_brg_cd (int baud)
0053 {
0054   int divisor;
0055   int div16 = 0;
0056 
0057   divisor = ((bsp_serial_per_sec) + (baud / 2)) / baud;
0058   if (divisor > 4096) {
0059     div16 = 1;
0060     divisor = (divisor + 8) / 16;
0061   }
0062   return M8260_BRG_EN | M8260_BRG_EXTC_BRGCLK |
0063     ((divisor - 1) << 1) | div16;
0064 }
0065 
0066 /*
0067  *  Allocates an existing brg if one is already programmed for the same
0068  *  baud rate.  Otherwise a new brg is assigned
0069  *  AFD: on the mpc8260 only some combinations of SCC/SMC and BRG are allowed
0070  *  so add a mask which specifies which of the BRGs we can choose from
0071  */
0072 int
0073 m8xx_get_brg(unsigned brgmask, int baud)
0074 {
0075   int i;
0076 
0077   /* first try to find a BRG that is already at the right speed */
0078   for ( i = 0; i < NUM_BRGS; i++ ) {
0079     if ( (1 << i) & brgmask )    /* is this brg allowed? */
0080       if ( brg_spd[i] == baud ) {
0081         break;
0082     }
0083   }
0084 
0085   if ( i == NUM_BRGS ) { /* I guess we didn't find one */
0086     for ( i = 0; i < NUM_BRGS; i++ ) {
0087       if (((1<<i) & brgmask) && (brg_use_count[i] == 0)) {
0088          break;
0089       }
0090     }
0091   }
0092   if (i != NUM_BRGS) {
0093     brg_use_count[i]++;
0094     brg_spd[i]=baud;
0095     switch (i) {
0096       case 0:
0097         m8260.brgc1 = M8260_BRG_RST;
0098         m8260.brgc1 = m8xx_get_brg_cd(baud);
0099         break;
0100       case 1:
0101         m8260.brgc2 = M8260_BRG_RST;
0102         m8260.brgc2 = m8xx_get_brg_cd(baud);
0103         break;
0104       case 2:
0105         m8260.brgc3 = M8260_BRG_RST;
0106         m8260.brgc3 = m8xx_get_brg_cd(baud);
0107         break;
0108       case 3:
0109         m8260.brgc4 = M8260_BRG_RST;
0110         m8260.brgc4 = m8xx_get_brg_cd(baud);
0111         break;
0112       case 4:
0113         m8260.brgc5 = M8260_BRG_RST;
0114         m8260.brgc5 = m8xx_get_brg_cd(baud);
0115         break;
0116       case 5:
0117         m8260.brgc6 = M8260_BRG_RST;
0118         m8260.brgc6 = m8xx_get_brg_cd(baud);
0119         break;
0120       case 6:
0121         m8260.brgc7 = M8260_BRG_RST;
0122         m8260.brgc7 = m8xx_get_brg_cd(baud);
0123         break;
0124       case 7:
0125         m8260.brgc8 = M8260_BRG_RST;
0126         m8260.brgc8 = m8xx_get_brg_cd(baud);
0127         break;
0128     }
0129     return i;
0130   }
0131 
0132   else {
0133     printk( "Could not assign a brg for %d\n", baud );
0134     return -1;
0135   }
0136 }
0137 
0138 
0139 /*
0140  * When the brg is no longer needed call this routine to free the
0141  * resource for re--use.
0142  */
0143 void
0144 m8xx_free_brg( int brg_num )
0145 {
0146   if ( (brg_num>=0) && (brg_num<NUM_BRGS) )
0147     if (brg_use_count[brg_num] > 0 )
0148       brg_use_count[brg_num]--;
0149 }
0150 
0151 #ifdef DEBUG_BRG
0152 static void m8xx_dump_brgs( void )
0153 {
0154   int i;
0155   for (i=0; i<NUM_BRGS; i++ )
0156     printk( "Brg[%d]: %d %d\n", i, brg_use_count[i], brg_spd[i] );
0157 }
0158 #endif
0159 
0160 /*
0161  * Reserve one of a range of clock inputs
0162  */
0163 int
0164 m8xx_get_clk( unsigned clkmask )
0165 {
0166   int i;
0167 
0168   for ( i = 0; i < NUM_CLKS; i++ ) {
0169     if (((1<<i) & clkmask) && (clk_use_count[i] == 0)) {
0170        break;
0171     }
0172   }
0173 
0174   if (i != NUM_CLKS) {
0175     clk_use_count[i]++;
0176     return i;
0177   } else {
0178     printk( "Could not assign clock in the range %X\n", clkmask );
0179     return -1;
0180   }
0181 }
0182 
0183 
0184 /*
0185  * When the clock is no longer needed call this routine to free the
0186  * resource for re--use.
0187  */
0188 void
0189 m8xx_free_clk( int clk_num )
0190 {
0191   if ( (clk_num>=0) && (clk_num<NUM_BRGS) )
0192      if (clk_use_count[clk_num] > 0 )
0193        clk_use_count[clk_num]--;
0194 }