[U-Boot] [PATCH v2 02/11] S3C24XX: Add core support for Samsung's S3C24XX SoCs

Marek Vasut
2012-09-14T18:03:00Z

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.