[U-Boot] Configuring BRGs and BRG input clock on an MPC875

Hello, I thought I'd ask here before I go and make a mess of my code: what's the easiest way to configure my board to have SMC1 use BRG1, SCC4 use BRG2, and make my BRG1 and BRG2 use CLK2 as an input clock?
I looked over the code and it looked like most of this is hard-coded in the "serial.c" file to use BRG1 for everything and I think to use BRGCLK as the BRG clock source ("serial_setdivisor" function).
My board is similar to the EP88xc by the way.
Thanks, Mikhail Zaturenskiy

Hello, I thought I'd ask here before I go and make a mess of my code: what's the easiest way to configure my board to have SMC1 use BRG1, SCC4 use BRG2, and make my BRG1 and BRG2 use CLK2 as an input clock?
I looked over the code and it looked like most of this is hard-coded in the "serial.c" file to use BRG1 for everything and I think to use BRGCLK as the BRG clock source ("serial_setdivisor" function).
My board is similar to the EP88xc by the way.
Thanks, Mikhail Zaturenskiy
I decided to first try to switch over my BRG1 to use CLK2 as the input clock, it looks like by default it is using BRGCLK. I modified the "serial_setdivisor" function in cpu/mpc8xx/serial.c to be the following (CONFIG_PPC_OPS1 is defined): ******************************************************************************* static void serial_setdivisor(volatile cpm8xx_t *cp) { #if defined CONFIG_PPC_OPS1 int divisor=(48000000 + 8*gd->baudrate)/16/gd->baudrate; // MZ - CLK2 is 48MHz #else int divisor=(gd->cpu_clk + 8*gd->baudrate)/16/gd->baudrate; // MZ - note: divisor = 70 or 71 at 130MHz and 115200bps #endif if(divisor/16>0x1000) { /* bad divisor, assume 50MHz clock and 9600 baud */ divisor=(50*1000*1000 + 8*9600)/16/9600; }
#ifdef CONFIG_SYS_BRGCLK_PRESCALE divisor /= CONFIG_SYS_BRGCLK_PRESCALE; #endif
if(divisor<=0x1000) { cp->cp_brgc1=((divisor-1)<<1) | CPM_BRG_EN; } else { cp->cp_brgc1=((divisor/16-1)<<1) | CPM_BRG_EN | CPM_BRG_DIV16; }
#if defined CONFIG_PPC_OPS1 cp->cp_brgc1 |= CPM_BRG_EXTC_CLK2; // MZ - this line is an attempt at switching BRG1 input clock to CLK2 #endif } ***************************************************************************
However, now my board is stuck in an infinite loop in "serial.c" function "smc_putc", when it tries to send the first character: ************************************************************ while (rtx->txbd.cbd_sc & BD_SC_READY) { WATCHDOG_RESET (); __asm__("eieio"); } ***********************************
Anybody have an idea as to what I'm doing wrong? Could there be something wrong with my CLK2?
Thanks, Mikhail Zaturenskiy

Anybody have an idea as to what I'm doing wrong? Could there be something wrong with my CLK2?
Once again I'm going to answer my own question. The problem WAS with CLK2 not being properly initialized. I had to do the following to get everything working:
1. To get BRG1 to use CLK2, made change to "serial_setdivisor" function in cpu/mpc8xx/serial.c: ************************************************************************ static void serial_setdivisor(volatile cpm8xx_t *cp) { // MZ - Note: the CONFIG_USE_CLK2 flag is invented by me to allow the BRG input clock to be CLK2
#if defined CONFIG_USE_CLK2 // MZ - CLK2 is 48MHz // - Note: divisor = 26 at 115200bps // - Note: divisor = 52 at 57600bps int divisor=(48000000 + 8*gd->baudrate)/16/gd->baudrate; #else // MZ // - Note: divisor = 71 at 130MHz and 115200bps // - Note: divisor = 141 at 130MHz and 57600bps int divisor=(gd->cpu_clk + 8*gd->baudrate)/16/gd->baudrate; #endif if(divisor/16>0x1000) { /* bad divisor, assume 50MHz clock and 9600 baud */ divisor=(50*1000*1000 + 8*9600)/16/9600; }
#ifdef CONFIG_SYS_BRGCLK_PRESCALE divisor /= CONFIG_SYS_BRGCLK_PRESCALE; #endif
if(divisor<=0x1000) { cp->cp_brgc1=((divisor-1)<<1) | CPM_BRG_EN; } else { cp->cp_brgc1=((divisor/16-1)<<1) | CPM_BRG_EN | CPM_BRG_DIV16; }
#if defined CONFIG_USE_CLK2 // MZ - switching BRG1 input clock to CLK2 cp->cp_brgc1 |= CPM_BRG_EXTC_CLK2; #endif } ******************************************************************************
2. To get BRG4 to use CLK2 and to set SCC4 to use BRG4 (decided to use BRG4 for SCC4 instead of BRG2), I made change to "board_early_init_f" in my board's board/ops1/ops1.c file: ****************************************************************************** int board_early_init_f (void) { volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; volatile cpm8xx_t *cp = &(im->im_cpm); volatile iop8xx_t *iop = &(im->im_ioport);
// Set PA6 to switch PAPAR to get CLK2 working iop->iop_papar |= 0x0200;
// Set SCC4 to use BRG4 as clock source for Rx and Tx cp->cp_sicr = 0x1B000000;
#if defined CONFIG_USE_CLK2 // Set BRG4 to use CLK2 and enable it cp->cp_brgc4 = CPM_BRG_EN | CPM_BRG_EXTC_CLK2; #endif
return 0; } **********************************************************************************
Maybe there's a better place to do this than board_early_init_f, but it worked for me, and defining/undefining the CONFIG_USE_CLK2 flag allows me to easily switch between BRGCLK and CLK2 as input clock to my BRG1 and BRG4 if I ever decide to do so.
Hope somebody finds this useful. Mikhail Zaturenskiy
participants (1)
-
Mikhail Zaturenskiy