diff options
author | Yuri Tikhonov <yur@emcraft.com> | 2007-08-10 08:25:22 +0200 |
---|---|---|
committer | Stefan Roese <sr@denx.de> | 2007-08-10 08:25:22 +0200 |
commit | 29cb25da56afe18cf5e7072a92a9d98ea8af1fd4 (patch) | |
tree | 2d7027e23b03068f08e7aaf6b965d3aa111bb619 /post | |
parent | 537223afa61f64480df31ce440a9cb386df4a814 (diff) | |
download | bootable_bootloader_goldelico_gta04-29cb25da56afe18cf5e7072a92a9d98ea8af1fd4.zip bootable_bootloader_goldelico_gta04-29cb25da56afe18cf5e7072a92a9d98ea8af1fd4.tar.gz bootable_bootloader_goldelico_gta04-29cb25da56afe18cf5e7072a92a9d98ea8af1fd4.tar.bz2 |
POST: Add ppc4xx UART POST support without external uart clock (lwmon5)
The patch adds support for UART POST on ppc44x-based boards with no
external serial clocks installed.
Signed-off-by: Yuri Tikhonov <yur@emcraft.com>
Acked-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'post')
-rw-r--r-- | post/cpu/ppc4xx/uart.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/post/cpu/ppc4xx/uart.c b/post/cpu/ppc4xx/uart.c index b047d42..0aeed75 100644 --- a/post/cpu/ppc4xx/uart.c +++ b/post/cpu/ppc4xx/uart.c @@ -84,6 +84,49 @@ DECLARE_GLOBAL_DATA_PTR; +#if !defined(CFG_EXT_SERIAL_CLOCK) +static void serial_divs (int baudrate, unsigned long *pudiv, + unsigned short *pbdiv) +{ + sys_info_t sysinfo; + unsigned long div; /* total divisor udiv * bdiv */ + unsigned long umin; /* minimum udiv */ + unsigned short diff; /* smallest diff */ + unsigned long udiv; /* best udiv */ + unsigned short idiff; /* current diff */ + unsigned short ibdiv; /* current bdiv */ + unsigned long i; + unsigned long est; /* current estimate */ + + get_sys_info(&sysinfo); + + udiv = 32; /* Assume lowest possible serial clk */ + div = sysinfo.freqPLB / (16 * baudrate); /* total divisor */ + umin = sysinfo.pllOpbDiv << 1; /* 2 x OPB divisor */ + diff = 32; /* highest possible */ + + /* i is the test udiv value -- start with the largest + * possible (32) to minimize serial clock and constrain + * search to umin. + */ + for (i = 32; i > umin; i--) { + ibdiv = div / i; + est = i * ibdiv; + idiff = (est > div) ? (est-div) : (div-est); + if (idiff == 0) { + udiv = i; + break; /* can't do better */ + } else if (idiff < diff) { + udiv = i; /* best so far */ + diff = idiff; /* update lowest diff*/ + } + } + + *pudiv = udiv; + *pbdiv = div / udiv; +} +#endif + static int uart_post_init (unsigned long dev_base) { unsigned long reg; |