[U-Boot] [PATCH v3 3/6] pwm, imx6: add support for pwm modul on imx6
Stefano Babic
sbabic at denx.de
Wed Jul 16 11:14:24 CEST 2014
Hi Heiko,
On 16/07/2014 10:51, Heiko Schocher wrote:
> add basic support for the pwm modul found on imx6.
>
> Signed-off-by: Heiko Schocher <hs at denx.de>
> Cc: Stefano Babic <sbabic at denx.de>
>
> ---
> - changes for v3:
> new in v3, as Stefano Babic suggested
>
> README | 4 ++
> drivers/Makefile | 1 +
> drivers/pwm/Makefile | 13 ++++++
> drivers/pwm/pwm-imx.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 127 insertions(+)
> create mode 100644 drivers/pwm/Makefile
> create mode 100644 drivers/pwm/pwm-imx.c
>
> diff --git a/README b/README
> index 1eecba6..9f07831 100644
> --- a/README
> +++ b/README
> @@ -1377,6 +1377,10 @@ The following options need to be configured:
> CONFIG_SH_ETHER_CACHE_WRITEBACK
> If this option is set, the driver enables cache flush.
>
> +- PWM Support:
> + CONFIG_PWM_IMX
> + Support for PWM modul on the imx6.
> +
> - TPM Support:
> CONFIG_TPM
> Support TPM devices.
> diff --git a/drivers/Makefile b/drivers/Makefile
> index b23076f..b22b109 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -15,3 +15,4 @@ obj-y += video/
> obj-y += watchdog/
> obj-$(CONFIG_QE) += qe/
> obj-y += memory/
> +obj-y += pwm/
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> new file mode 100644
> index 0000000..3173e20
> --- /dev/null
> +++ b/drivers/pwm/Makefile
> @@ -0,0 +1,13 @@
> +#
> +# (C) Copyright 2006
> +# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> +#
> +# (C) Copyright 2001
> +# Erik Theisen, Wave 7 Optics, etheisen at mindspring.com.
> +#
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +
> +#ccflags-y += -DDEBUG
> +
> +obj-$(CONFIG_PWM_IMX) += pwm-imx.o
> diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
> new file mode 100644
> index 0000000..c70e150
> --- /dev/null
> +++ b/drivers/pwm/pwm-imx.c
> @@ -0,0 +1,109 @@
> +/*
> + * (C) Copyright 2014
> + * Heiko Schocher, DENX Software Engineering, hs at denx.de.
> + *
> + * Basic support for the pwm modul on imx6.
> + *
> + * Based on linux:drivers/pwm/pwm-imx.c
> + * from
> + * Sascha Hauer <s.hauer at pengutronix.de>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <div64.h>
> +#include <pwm.h>
> +#include <asm/arch/imx-regs.h>
> +#include <asm/io.h>
> +
> +/* pwm_id from 0..3 */
> +static struct pwm_regs *pwm_id_to_reg(int pwm_id)
> +{
> + switch (pwm_id) {
> + case 0:
> + return (struct pwm_regs *)PWM1_BASE_ADDR;
> + break;
> + case 1:
> + return (struct pwm_regs *)PWM2_BASE_ADDR;
> + break;
> + case 2:
> + return (struct pwm_regs *)PWM3_BASE_ADDR;
> + break;
> + case 3:
> + return (struct pwm_regs *)PWM4_BASE_ADDR;
> + break;
> + default:
> + printf("unknown pwm_id: %d\n", pwm_id);
> + break;
> + }
> + return NULL;
> +}
> +
> +int pwm_init(int pwm_id, int div, int invert)
> +{
> + struct pwm_regs *pwm = (struct pwm_regs *)pwm_id_to_reg(pwm_id);
> +
> + writel(0, &pwm->ir);
> + return 0;
> +}
> +
> +int pwm_config(int pwm_id, int duty_ns, int period_ns)
> +{
> + struct pwm_regs *pwm = (struct pwm_regs *)pwm_id_to_reg(pwm_id);
> + unsigned long long c;
> + unsigned long period_cycles, duty_cycles, prescale;
> + u32 cr;
> +
> + /*
> + * we have not yet a clock framework for imx6, so add the clock
> + * value here as a define. Replace it when we have the clock
> + * framework.
> + */
> + c = CONFIG_IMX6_PWM_PER_CLK;
> + c = c * period_ns;
> + do_div(c, 1000000000);
> + period_cycles = c;
> +
> + prescale = period_cycles / 0x10000 + 1;
> +
> + period_cycles /= prescale;
> + c = (unsigned long long)period_cycles * duty_ns;
> + do_div(c, period_ns);
> + duty_cycles = c;
> +
> + /*
> + * according to imx pwm RM, the real period value should be
> + * PERIOD value in PWMPR plus 2.
> + */
> + if (period_cycles > 2)
> + period_cycles -= 2;
> + else
> + period_cycles = 0;
> +
> + cr = PWMCR_PRESCALER(prescale) |
> + PWMCR_DOZEEN | PWMCR_WAITEN |
> + PWMCR_DBGEN | PWMCR_CLKSRC_IPG_HIGH;
> +
> + writel(cr, &pwm->cr);
> + /* set duty cycles */
> + writel(duty_cycles, &pwm->sar);
> + /* set period cycles */
> + writel(period_cycles, &pwm->pr);
> + return 0;
> +}
> +
> +int pwm_enable(int pwm_id)
> +{
> + struct pwm_regs *pwm = (struct pwm_regs *)pwm_id_to_reg(pwm_id);
> +
> + setbits_le32(&pwm->cr, PWMCR_EN);
> + return 0;
> +}
> +
> +void pwm_disable(int pwm_id)
> +{
> + struct pwm_regs *pwm = (struct pwm_regs *)pwm_id_to_reg(pwm_id);
> +
> + clrbits_le32(&pwm->cr, PWMCR_EN);
> +}
>
Nice ! Should we also add in the commit message that the code is
directly taken from kernel driver ?
Acked-by: Stefano Babic <sbabic at denx.de>
Best regards,
Stefano Babic
--
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
More information about the U-Boot
mailing list