Hi Minkyu,

I notice this patch are delegated to you. But the patchwork miss the
patch 4.

If you need me to do anything, Please let me know.

Thanks,
hongbo

On 07/14/2012 12:11 AM, Zhong Hongbo wrote:
> From: Zhong Hongbo <bocui...@gmail.com>
> 
> Signed-off-by: Zhong Hongbo <bocui...@gmail.com>
> ---
> Change for V2:
>       - Change the type of the return value from unsinged int
>         to unsinged long for s3c64xx_get_base_nand function.
> ---
>  arch/arm/cpu/arm1176/s3c64xx/Makefile       |    1 +
>  arch/arm/cpu/arm1176/s3c64xx/pwm.c          |  189 
> +++++++++++++++++++++++++++
>  arch/arm/include/asm/arch-s3c64xx/pwm.h     |   70 ++++++++++
>  arch/arm/include/asm/arch-s3c64xx/s3c6400.h |   56 ++-------
>  arch/arm/include/asm/arch-s3c64xx/s3c64x0.h |   59 ---------
>  include/configs/smdk6400.h                  |    3 +
>  6 files changed, 272 insertions(+), 106 deletions(-)
>  create mode 100644 arch/arm/cpu/arm1176/s3c64xx/pwm.c
>  create mode 100644 arch/arm/include/asm/arch-s3c64xx/pwm.h
>  delete mode 100644 arch/arm/include/asm/arch-s3c64xx/s3c64x0.h
> 
> diff --git a/arch/arm/cpu/arm1176/s3c64xx/Makefile 
> b/arch/arm/cpu/arm1176/s3c64xx/Makefile
> index 0785b19..966663f 100644
> --- a/arch/arm/cpu/arm1176/s3c64xx/Makefile
> +++ b/arch/arm/cpu/arm1176/s3c64xx/Makefile
> @@ -32,6 +32,7 @@ SOBJS       = reset.o
>  
>  COBJS-$(CONFIG_S3C6400)      += cpu_init.o speed.o
>  COBJS-y      += timer.o
> +COBJS-$(CONFIG_PWM) += pwm.o
>  
>  OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
>  
> diff --git a/arch/arm/cpu/arm1176/s3c64xx/pwm.c 
> b/arch/arm/cpu/arm1176/s3c64xx/pwm.c
> new file mode 100644
> index 0000000..d1d70ff
> --- /dev/null
> +++ b/arch/arm/cpu/arm1176/s3c64xx/pwm.c
> @@ -0,0 +1,189 @@
> +/*
> + * Copyright (C) 2012
> + *
> + * Zhong Hongbo <bocui...@gmail.com>
> + *
> + * based on arch/arm/cpu/armv7/s5p-common/sromc.c
> + *
> + * 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 <errno.h>
> +#include <pwm.h>
> +#include <asm/io.h>
> +#include <asm/arch/s3c6400.h>
> +#include <asm/arch/pwm.h>
> +
> +int pwm_enable(int pwm_id)
> +{
> +     const struct s3c_timer *pwm =
> +                     (struct s3c_timer *)s3c64xx_get_base_timer();
> +     unsigned long tcon;
> +
> +     tcon = readl(&pwm->tcon);
> +     tcon |= TCON_START(pwm_id);
> +
> +     writel(tcon, &pwm->tcon);
> +
> +     return 0;
> +}
> +
> +void pwm_disable(int pwm_id)
> +{
> +     const struct s3c_timer *pwm =
> +                     (struct s3c_timer *)s3c64xx_get_base_timer();
> +     unsigned long tcon;
> +
> +     tcon = readl(&pwm->tcon);
> +     tcon &= ~TCON_START(pwm_id);
> +
> +     writel(tcon, &pwm->tcon);
> +}
> +
> +static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq)
> +{
> +     unsigned long tin_parent_rate;
> +     unsigned int div;
> +
> +     tin_parent_rate = get_PCLK();
> +
> +     for (div = 2; div <= 16; div *= 2) {
> +             if ((tin_parent_rate / (div << 16)) < freq)
> +                     return tin_parent_rate / div;
> +     }
> +
> +     return tin_parent_rate / 16;
> +}
> +
> +#define NS_IN_HZ (1000000000UL)
> +
> +int pwm_config(int pwm_id, int duty_ns, int period_ns)
> +{
> +     const struct s3c_timer *pwm =
> +                     (struct s3c_timer *)s3c64xx_get_base_timer();
> +     unsigned int offset;
> +     unsigned long tin_rate;
> +     unsigned long tin_ns;
> +     unsigned long period;
> +     unsigned long tcon;
> +     unsigned long tcnt;
> +     unsigned long tcmp;
> +
> +     /*
> +      * We currently avoid using 64bit arithmetic by using the
> +      * fact that anything faster than 1GHz is easily representable
> +      * by 32bits.
> +      */
> +     if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
> +             return -ERANGE;
> +
> +     if (duty_ns > period_ns)
> +             return -EINVAL;
> +
> +     period = NS_IN_HZ / period_ns;
> +
> +     /* Check to see if we are changing the clock rate of the PWM */
> +     tin_rate = pwm_calc_tin(pwm_id, period);
> +
> +     tin_ns = NS_IN_HZ / tin_rate;
> +     tcnt = period_ns / tin_ns;
> +
> +     /* Note, counters count down */
> +     tcmp = duty_ns / tin_ns;
> +     tcmp = tcnt - tcmp;
> +
> +     /*
> +      * the pwm hw only checks the compare register after a decrement,
> +      * so the pin never toggles if tcmp = tcnt
> +      */
> +     if (tcmp == tcnt)
> +             tcmp--;
> +
> +     if (tcmp < 0)
> +             tcmp = 0;
> +
> +     /* Update the PWM register block. */
> +     offset = pwm_id * 3;
> +     if (pwm_id < 4) {
> +             writel(tcnt, &pwm->tcntb0 + offset);
> +             writel(tcmp, &pwm->tcmpb0 + offset);
> +     }
> +
> +     tcon = readl(&pwm->tcon);
> +     tcon |= TCON_UPDATE(pwm_id);
> +     if (pwm_id < 4)
> +             tcon |= TCON_AUTO_RELOAD(pwm_id);
> +     else
> +             tcon |= TCON4_AUTO_RELOAD;
> +     writel(tcon, &pwm->tcon);
> +
> +     tcon &= ~TCON_UPDATE(pwm_id);
> +     writel(tcon, &pwm->tcon);
> +
> +     return 0;
> +}
> +
> +int pwm_init(int pwm_id, int div, int invert)
> +{
> +     u32 val;
> +     const struct s3c_timer *pwm =
> +                     (struct s3c_timer *)s3c64xx_get_base_timer();
> +     unsigned long timer_rate_hz;
> +     unsigned int offset, prescaler;
> +
> +     /*
> +      * Timer Freq(HZ) =
> +      *      PWM_CLK / { (prescaler_value + 1) * (divider_value) }
> +      */
> +
> +     val = readl(&pwm->tcfg0);
> +     if (pwm_id < 2) {
> +             prescaler = PRESCALER_0;
> +             val &= ~0xff;
> +             val |= (prescaler & 0xff);
> +     } else {
> +             prescaler = PRESCALER_1;
> +             val &= ~(0xff << 8);
> +             val |= (prescaler & 0xff) << 8;
> +     }
> +     writel(val, &pwm->tcfg0);
> +     val = readl(&pwm->tcfg1);
> +     val &= ~(0xf << MUX_DIV_SHIFT(pwm_id));
> +     val |= (div & 0xf) << MUX_DIV_SHIFT(pwm_id);
> +     writel(val, &pwm->tcfg1);
> +
> +     timer_rate_hz = get_PCLK() / ((prescaler + 1) *
> +                     (div + 1));
> +
> +     timer_rate_hz = timer_rate_hz / CONFIG_SYS_HZ;
> +
> +     /* set count value */
> +     offset = pwm_id * 3;
> +     writel(timer_rate_hz, &pwm->tcntb0 + offset);
> +
> +     val = readl(&pwm->tcon) & ~(0xf << TCON_OFFSET(pwm_id));
> +     if (invert && (pwm_id < 4))
> +             val |= TCON_INVERTER(pwm_id);
> +     writel(val, &pwm->tcon);
> +
> +     pwm_enable(pwm_id);
> +
> +     return 0;
> +}
> diff --git a/arch/arm/include/asm/arch-s3c64xx/pwm.h 
> b/arch/arm/include/asm/arch-s3c64xx/pwm.h
> new file mode 100644
> index 0000000..1e18f8c
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-s3c64xx/pwm.h
> @@ -0,0 +1,70 @@
> +/*
> + * Copyright (C) 2012
> + * Zhong Hongbo <bocui...@gmail.com>
> + *
> + * based on arch/arm/include/asm/arch-s5pc1xx/pwm.h
> + *
> + * 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
> + */
> +
> +#ifndef __ASM_ARM_ARCH_PWM_H_
> +#define __ASM_ARM_ARCH_PWM_H_
> +
> +#define PRESCALER_0          (8 - 1)         /* prescaler of timer 0, 1 */
> +#define PRESCALER_1          (16 - 1)        /* prescaler of timer 2, 3, 4 */
> +
> +/* Divider MUX */
> +#define MUX_DIV_1            0               /* 1/1 period */
> +#define MUX_DIV_2            1               /* 1/2 period */
> +#define MUX_DIV_4            2               /* 1/4 period */
> +#define MUX_DIV_8            3               /* 1/8 period */
> +#define MUX_DIV_16           4               /* 1/16 period */
> +
> +#define MUX_DIV_SHIFT(x)     (x * 4)
> +
> +#define TCON_OFFSET(x)               ((x + 1) * (!!x) << 2)
> +
> +#define TCON_START(x)                (1 << TCON_OFFSET(x))
> +#define TCON_UPDATE(x)               (1 << (TCON_OFFSET(x) + 1))
> +#define TCON_INVERTER(x)     (1 << (TCON_OFFSET(x) + 2))
> +#define TCON_AUTO_RELOAD(x)  (1 << (TCON_OFFSET(x) + 3))
> +#define TCON4_AUTO_RELOAD    (1 << 22)
> +
> +#define TCFG1_DMA(x)         (x << 20)
> +
> +#ifndef __ASSEMBLY__
> +struct s3c_timer {
> +     unsigned int    tcfg0;
> +     unsigned int    tcfg1;
> +     unsigned int    tcon;
> +     unsigned int    tcntb0;
> +     unsigned int    tcmpb0;
> +     unsigned int    tcnto0;
> +     unsigned int    tcntb1;
> +     unsigned int    tcmpb1;
> +     unsigned int    tcnto1;
> +     unsigned int    tcntb2;
> +     unsigned int    res1;
> +     unsigned int    tcnto2;
> +     unsigned int    tcntb3;
> +     unsigned int    res2;
> +     unsigned int    tcnto3;
> +     unsigned int    tcntb4;
> +     unsigned int    tcnto4;
> +     unsigned int    tint_cstat;
> +};
> +#endif
> +#endif
> diff --git a/arch/arm/include/asm/arch-s3c64xx/s3c6400.h 
> b/arch/arm/include/asm/arch-s3c64xx/s3c6400.h
> index 77b9509..b884763 100644
> --- a/arch/arm/include/asm/arch-s3c64xx/s3c6400.h
> +++ b/arch/arm/include/asm/arch-s3c64xx/s3c6400.h
> @@ -31,6 +31,10 @@
>  #ifndef __S3C6400_H__
>  #define __S3C6400_H__
>  
> +#if defined(CONFIG_SYNC_MODE) && defined(CONFIG_S3C6400)
> +#error CONFIG_SYNC_MODE unavailable on S3C6400, please, fix your 
> configuration!
> +#endif
> +
>  #define S3C64XX_UART_CHANNELS        3
>  #define S3C64XX_SPI_CHANNELS 2
>  
> @@ -587,51 +591,6 @@
>   */
>  #define ELFIN_TIMER_BASE     0x7F006000
>  
> -#define TCFG0_REG    __REG(0x7F006000)
> -#define TCFG1_REG    __REG(0x7F006004)
> -#define TCON_REG     __REG(0x7F006008)
> -#define TCNTB0_REG   __REG(0x7F00600c)
> -#define TCMPB0_REG   __REG(0x7F006010)
> -#define TCNTO0_REG   __REG(0x7F006014)
> -#define TCNTB1_REG   __REG(0x7F006018)
> -#define TCMPB1_REG   __REG(0x7F00601c)
> -#define TCNTO1_REG   __REG(0x7F006020)
> -#define TCNTB2_REG   __REG(0x7F006024)
> -#define TCMPB2_REG   __REG(0x7F006028)
> -#define TCNTO2_REG   __REG(0x7F00602c)
> -#define TCNTB3_REG   __REG(0x7F006030)
> -#define TCMPB3_REG   __REG(0x7F006034)
> -#define TCNTO3_REG   __REG(0x7F006038)
> -#define TCNTB4_REG   __REG(0x7F00603c)
> -#define TCNTO4_REG   __REG(0x7F006040)
> -
> -/* Fields */
> -#define fTCFG0_DZONE         Fld(8, 16) /* the dead zone length (=timer 0) */
> -#define fTCFG0_PRE1          Fld(8, 8)  /* prescaler value for time 2,3,4 */
> -#define fTCFG0_PRE0          Fld(8, 0)  /* prescaler value for time 0,1 */
> -#define fTCFG1_MUX4          Fld(4, 16)
> -/* bits */
> -#define TCFG0_DZONE(x)               FInsrt((x), fTCFG0_DZONE)
> -#define TCFG0_PRE1(x)                FInsrt((x), fTCFG0_PRE1)
> -#define TCFG0_PRE0(x)                FInsrt((x), fTCFG0_PRE0)
> -#define TCON_4_AUTO          (1 << 22)  /* auto reload on/off for Timer 4 */
> -#define TCON_4_UPDATE                (1 << 21)  /* manual Update TCNTB4 */
> -#define TCON_4_ONOFF         (1 << 20)  /* 0: Stop, 1: start Timer 4 */
> -#define COUNT_4_ON           (TCON_4_ONOFF * 1)
> -#define COUNT_4_OFF          (TCON_4_ONOFF * 0)
> -#define TCON_3_AUTO          (1 << 19)  /* auto reload on/off for Timer 3 */
> -#define TIMER3_ATLOAD_ON     (TCON_3_AUTO * 1)
> -#define TIMER3_ATLAOD_OFF    FClrBit(TCON, TCON_3_AUTO)
> -#define TCON_3_INVERT                (1 << 18)  /* 1: Inverter on for TOUT3 
> */
> -#define TIMER3_IVT_ON                (TCON_3_INVERT * 1)
> -#define TIMER3_IVT_OFF               (FClrBit(TCON, TCON_3_INVERT))
> -#define TCON_3_MAN           (1 << 17)  /* manual Update TCNTB3,TCMPB3 */
> -#define TIMER3_MANUP         (TCON_3_MAN*1)
> -#define TIMER3_NOP           (FClrBit(TCON, TCON_3_MAN))
> -#define TCON_3_ONOFF         (1 << 16)  /* 0: Stop, 1: start Timer 3 */
> -#define TIMER3_ON            (TCON_3_ONOFF * 1)
> -#define TIMER3_OFF           (FClrBit(TCON, TCON_3_ONOFF))
> -
>  #if defined(CONFIG_CLK_400_100_50)
>  #define STARTUP_AMDIV                400
>  #define STARTUP_MDIV         400
> @@ -749,8 +708,6 @@
>  
>  #ifndef __ASSEMBLY__
>  
> -#include "s3c64x0.h"
> -
>  static inline unsigned long s3c64xx_get_base_uart(void)
>  {
>       return ELFIN_UART_BASE;
> @@ -760,6 +717,11 @@ static inline unsigned long s3c64xx_get_base_nand(void)
>  {
>       return ELFIN_NAND_BASE;
>  }
> +
> +static inline unsigned long s3c64xx_get_base_timer(void)
> +{
> +     return ELFIN_TIMER_BASE;
> +}
>  #endif
>  
>  #endif /*__S3C6400_H__*/
> diff --git a/arch/arm/include/asm/arch-s3c64xx/s3c64x0.h 
> b/arch/arm/include/asm/arch-s3c64xx/s3c64x0.h
> deleted file mode 100644
> index 7add68c..0000000
> --- a/arch/arm/include/asm/arch-s3c64xx/s3c64x0.h
> +++ /dev/null
> @@ -1,59 +0,0 @@
> -/*
> - * (C) Copyright 2003
> - * David MÃŒller ELSOFT AG Switzerland. d.muel...@elsoft.ch
> - *
> - * (C) Copyright 2008
> - * Guennadi Liakhovetki, DENX Software Engineering, <l...@denx.de>
> - *
> - * 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
> - */
> -
> -/************************************************
> - * NAME          : S3C64XX.h
> - * Version  : 31.3.2003
> - *
> - * common stuff for SAMSUNG S3C64XX SoC
> - ************************************************/
> -
> -#ifndef __S3C64XX_H__
> -#define __S3C64XX_H__
> -
> -#if defined(CONFIG_SYNC_MODE) && defined(CONFIG_S3C6400)
> -#error CONFIG_SYNC_MODE unavailable on S3C6400, please, fix your 
> configuration!
> -#endif
> -
> -#include <asm/types.h>
> -
> -/* PWM TIMER (see manual chapter 10) */
> -typedef struct {
> -     volatile u32    TCNTB;
> -     volatile u32    TCMPB;
> -     volatile u32    TCNTO;
> -} s3c64xx_timer;
> -
> -typedef struct {
> -     volatile u32    TCFG0;
> -     volatile u32    TCFG1;
> -     volatile u32    TCON;
> -     s3c64xx_timer   ch[4];
> -     volatile u32    TCNTB4;
> -     volatile u32    TCNTO4;
> -} s3c64xx_timers;
> -
> -#endif /*__S3C64XX_H__*/
> diff --git a/include/configs/smdk6400.h b/include/configs/smdk6400.h
> index 47326d6..3642a5c 100644
> --- a/include/configs/smdk6400.h
> +++ b/include/configs/smdk6400.h
> @@ -141,6 +141,9 @@
>  
>  #define CONFIG_SYS_HZ                        1000
>  
> +/* PWM */
> +#define CONFIG_PWM                     1
> +
>  /*-----------------------------------------------------------------------
>   * Stack sizes
>   *
> 


_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to