
Dear José Miguel Gonçalves,
It's getting better :)
[...]
+typedef ulong(*getfreq) (void);
Is this used?
+static const getfreq freq_f[] = {
const array const members, no?
- get_FCLK,
- get_HCLK,
- get_PCLK,
- get_UCLK,
+};
+static const char freq_c[] = { 'F', 'H', 'P', 'U' };
Same here.
+int print_cpuinfo(void) +{
- int i;
- char buf[32];
- ulong cpuid;
- struct s3c24xx_gpio *const gpio = s3c24xx_get_base_gpio();
- cpuid = readl(&gpio->gstatus[1]);
- printf("CPU: %8s (id %08lX) @ %s MHz\n", s3c24xx_get_cpu_name(),
cpuid, strmhz(buf, get_ARMCLK()));
- for (i = 0; i < ARRAY_SIZE(freq_f); i++)
printf("%cCLK: %8s MHz\n", freq_c[i],
strmhz(buf, freq_f[i] ()));
- return 0;
+}
[...]
+ulong get_HCLK(void) +{
- struct s3c2412_sysctl *const sysctl = s3c2412_get_base_sysctl();
- u32 clkdivn;
- u16 hclk_div, arm_div;
- clkdivn = readl(&sysctl->clkdivn);
- hclk_div = (clkdivn & 0x3) + 1;
- arm_div = ((clkdivn >> 3) & 0x1) + 1;
Magic.
- return get_FCLK() / (hclk_div * arm_div);
+}
+/* return PCLK frequency */ +ulong get_PCLK(void) +{
- struct s3c2412_sysctl *const sysctl = s3c2412_get_base_sysctl();
- u32 clkdivn;
- clkdivn = readl(&sysctl->clkdivn);
- return (clkdivn & 0x4) ? get_HCLK() / 2 : get_HCLK();
Magic
+}
+/* return UCLK frequency */ +ulong get_UCLK(void) +{
- return get_PLLCLK(UPLL);
+}
+/* return ARMCORE frequency */ +ulong get_ARMCLK(void) +{
- struct s3c2412_sysctl *const sysctl = s3c2412_get_base_sysctl();
- u32 clkdivn;
- clkdivn = readl(&sysctl->clkdivn);
- if (clkdivn & 0x10)
return get_FCLK();
Magic above and below and in the following file
- return (clkdivn & 0x8) ? get_FCLK() / 2 : get_FCLK();
+}
[...]
diff --git a/arch/arm/cpu/arm926ejs/s3c24xx/timer.c b/arch/arm/cpu/arm926ejs/s3c24xx/timer.c new file mode 100644 index 0000000..23d3343 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/s3c24xx/timer.c @@ -0,0 +1,152 @@ +/*
- (C) Copyright 2012 INOV - INESC Inovacao
- Jose Goncalves jose.goncalves@inov.pt
- Based on arch/arm/cpu/armv7/s5p-common/timer.c and U-Boot 1.3.4 from
Samsung. + *
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/arch/s3c24xx_cpu.h>
+DECLARE_GLOBAL_DATA_PTR;
+static ulong get_current_tick(void) +{
- struct s3c24xx_timers *const timers = s3c24xx_get_base_timers();
- ulong now = readl(&timers->tcnto4);
- if (gd->lastinc >= now)
gd->tbl += gd->lastinc - now;
- else
gd->tbl += gd->lastinc + gd->tbu - now;
- gd->lastinc = now;
- return gd->tbl;
+}
+int timer_init(void) +{
- struct s3c24xx_timers *const timers = s3c24xx_get_base_timers();
- /* use PWM Timer 4 because it has no output */
- if (gd->tbu == 0) {
/* set divider value for Timer 4 to 2 */
clrsetbits_le32(&timers->tcfg1, TCFG1_MUX4_MASK,
TCFG1_MUX4_DIV2);
/* set prescaler value for Timer 4 to 15 */
clrsetbits_le32(&timers->tcfg0, TCFG0_PRESCALER1_MASK,
TCFG0_PRESCALER1(15));
/*
* Timer Freq(HZ) =
* PCLK / (prescaler_value + 1) / (divider_value)
*/
gd->timer_rate_hz = get_PCLK() / (15 + 1) / 2;
gd->tbu = gd->timer_rate_hz / CONFIG_SYS_HZ;
- }
- /* load value for selected timeout */
- writel(gd->tbu, &timers->tcntb4);
- /* auto reload, manual update of timer 4 */
- clrsetbits_le32(&timers->tcon, TCON_T4START,
TCON_T4RELOAD | TCON_T4MANUALUPD);
- /* auto reload, start timer 4 */
- clrsetbits_le32(&timers->tcon, TCON_T4MANUALUPD,
TCON_T4RELOAD | TCON_T4START);
- gd->lastinc = 0;
- gd->tbl = 0;
- return 0;
+}
+ulong get_timer(ulong base) +{
- return get_timer_masked() - base;
+}
+void __udelay(unsigned long usec) +{
- ulong tmo, tmp;
- if (usec >= 1000) {
/*
* if "big" number, spread normalization
* to seconds
* 1. start to normalize for usec to ticks per sec
* 2. find number of "ticks" to wait to achieve target
* 3. finish normalize.
*/
tmo = usec / 1000;
tmo *= gd->timer_rate_hz;
tmo /= 1000;
- } else {
/* else small number, don't kill it prior to HZ multiply */
tmo = usec * gd->timer_rate_hz;
tmo /= (1000 * 1000);
- }
- /* get current timestamp */
- tmp = get_current_tick();
- /* if setting this fordward will roll time stamp */
- /* reset "advancing" timestamp to 0, set lastinc value */
- /* else, set advancing stamp wake up time */
/* * multi * line * comment */
- if ((tmo + tmp + 1) < tmp)
reset_timer_masked();
- else
tmo += tmp;
- /* loop till event */
- while (get_current_tick() < tmo)
/* NOP */;
+}
+void reset_timer_masked(void) +{
- struct s3c24xx_timers *const timers = s3c24xx_get_base_timers();
- /* reset time */
- gd->lastinc = readl(&timers->tcnto4);
- gd->tbl = 0;
+}
+ulong get_timer_masked(void) +{
- return get_current_tick() / gd->tbu;
+}
+/*
- This function is derived from PowerPC code (read timebase as long
long). + * On ARM it just returns the timer value.
- */
+unsigned long long get_ticks(void) +{
- return get_timer_masked();
+}
+/*
- This function is derived from PowerPC code (timebase clock frequency).
- On ARM it returns the number of timer ticks per second.
- */
+ulong get_tbclk(void) +{
- return CONFIG_SYS_HZ;
+}
[...]
diff --git a/include/common.h b/include/common.h index 55025c0..36f0636 100644 --- a/include/common.h +++ b/include/common.h @@ -628,6 +628,7 @@ ulong get_OPB_freq (void); ulong get_PCI_freq (void); #endif #if defined(CONFIG_S3C24X0) || \
- defined(CONFIG_S3C24XX) || \ defined(CONFIG_LH7A40X) || \ defined(CONFIG_S3C6400) || \ defined(CONFIG_EP93XX)
What's this change? Split into different patch please.