Skip to content

Commit

Permalink
pwm, imx6: add support for pwm modul on imx6
Browse files Browse the repository at this point in the history
add basic support for the pwm modul found on imx6.
Pieces of this code are based on linux code from drivers/pwm/pwm-imx.c
Commit "cd3de83f1476 Linux 3.16-rc4"

Signed-off-by: Heiko Schocher <[email protected]>
Acked-by: Stefano Babic <[email protected]>
Cc: Wolfgang Denk <[email protected]>
  • Loading branch information
hsdenx authored and sbabic committed Jul 23, 2014
1 parent aafe402 commit b2f97cf
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions drivers/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ obj-y += video/
obj-y += watchdog/
obj-$(CONFIG_QE) += qe/
obj-y += memory/
obj-y += pwm/
13 changes: 13 additions & 0 deletions drivers/pwm/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#
# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, [email protected].
#
# (C) Copyright 2001
# Erik Theisen, Wave 7 Optics, [email protected].
#
# SPDX-License-Identifier: GPL-2.0+
#

#ccflags-y += -DDEBUG

obj-$(CONFIG_PWM_IMX) += pwm-imx.o pwm-imx-util.o
73 changes: 73 additions & 0 deletions drivers/pwm/pwm-imx-util.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* (C) Copyright 2014
* Heiko Schocher, DENX Software Engineering, [email protected].
*
* Basic support for the pwm modul on imx6.
*
* Based on linux:drivers/pwm/pwm-imx.c
* from
* Sascha Hauer <[email protected]>
*
* SPDX-License-Identifier: GPL-2.0
*/

#include <common.h>
#include <div64.h>
#include <asm/arch/imx-regs.h>

/* pwm_id from 0..3 */
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_imx_get_parms(int period_ns, int duty_ns, unsigned long *period_c,
unsigned long *duty_c, unsigned long *prescale)
{
unsigned long long c;

/*
* 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_c = c;

*prescale = *period_c / 0x10000 + 1;

*period_c /= *prescale;
c = (unsigned long long)(*period_c * duty_ns);
do_div(c, period_ns);
*duty_c = c;

/*
* according to imx pwm RM, the real period value should be
* PERIOD value in PWMPR plus 2.
*/
if (*period_c > 2)
*period_c -= 2;
else
*period_c = 0;

return 0;
}
16 changes: 16 additions & 0 deletions drivers/pwm/pwm-imx-util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* (C) Copyright 2014
* Heiko Schocher, DENX Software Engineering, [email protected].
*
* Basic support for the pwm modul on imx6.
*
* SPDX-License-Identifier: GPL-2.0
*/

#ifndef _pwm_imx_util_h_
#define _pwm_imx_util_h_

struct pwm_regs *pwm_id_to_reg(int pwm_id);
int pwm_imx_get_parms(int period_ns, int duty_ns, unsigned long *period_c,
unsigned long *duty_c, unsigned long *prescale);
#endif
59 changes: 59 additions & 0 deletions drivers/pwm/pwm-imx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* (C) Copyright 2014
* Heiko Schocher, DENX Software Engineering, [email protected].
*
* Basic support for the pwm modul on imx6.
*
* 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>
#include "pwm-imx-util.h"

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 period_cycles, duty_cycles, prescale;
u32 cr;

pwm_imx_get_parms(period_ns, duty_ns, &period_cycles, &duty_cycles,
&prescale);

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);
}

0 comments on commit b2f97cf

Please sign in to comment.