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

Marek Vasut marex at denx.de
Fri Sep 14 20:03:00 CEST 2012


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 at 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.


More information about the U-Boot mailing list