Skip to content

drivers: add imx7d pwm driver #8794

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion arch/arm/soc/nxp_imx/mcimx7_m4/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@
# SPDX-License-Identifier: Apache-2.0
#

zephyr_sources(soc.c)
zephyr_sources(
soc.c
soc_clk_freq.c
)
7 changes: 7 additions & 0 deletions arch/arm/soc/nxp_imx/mcimx7_m4/Kconfig.defconfig.mcimx7_m4
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ config I2C_IMX

endif # I2C

if PWM

config PWM_IMX
def_bool y

endif # PWM

config DOMAIN_ID
int
default 1
Expand Down
59 changes: 59 additions & 0 deletions arch/arm/soc/nxp_imx/mcimx7_m4/soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,61 @@ static void nxp_mcimx7_i2c_config(void)
}
#endif /* CONFIG_I2C_IMX */

#ifdef CONFIG_PWM_IMX
static void nxp_mcimx7_pwm_config(void)
{

#ifdef CONFIG_PWM_1
/* We need to grasp board pwm exclusively */
RDC_SetPdapAccess(RDC, rdcPdapPwm1,
RDC_DOMAIN_PERM(CONFIG_DOMAIN_ID, RDC_DOMAIN_PERM_RW),
false, false);
/* Select clock derived from OSC clock(24M) */
CCM_UpdateRoot(CCM, ccmRootPwm1, ccmRootmuxPwmOsc24m, 0, 0);
/* Enable pwm clock */
CCM_EnableRoot(CCM, ccmRootPwm1);
CCM_ControlGate(CCM, ccmCcgrGatePwm1, ccmClockNeededAll);
#endif /* #ifdef CONFIG_PWM_1 */

#ifdef CONFIG_PWM_2
/* We need to grasp board pwm exclusively */
RDC_SetPdapAccess(RDC, rdcPdapPwm2,
RDC_DOMAIN_PERM(CONFIG_DOMAIN_ID, RDC_DOMAIN_PERM_RW),
false, false);
/* Select clock derived from OSC clock(24M) */
CCM_UpdateRoot(CCM, ccmRootPwm2, ccmRootmuxPwmOsc24m, 0, 0);
/* Enable pwm clock */
CCM_EnableRoot(CCM, ccmRootPwm2);
CCM_ControlGate(CCM, ccmCcgrGatePwm2, ccmClockNeededAll);
#endif /* #ifdef CONFIG_PWM_2 */

#ifdef CONFIG_PWM_3
/* We need to grasp board pwm exclusively */
RDC_SetPdapAccess(RDC, rdcPdapPwm3,
RDC_DOMAIN_PERM(CONFIG_DOMAIN_ID, RDC_DOMAIN_PERM_RW),
false, false);
/* Select clock derived from OSC clock(24M) */
CCM_UpdateRoot(CCM, ccmRootPwm3, ccmRootmuxPwmOsc24m, 0, 0);
/* Enable pwm clock */
CCM_EnableRoot(CCM, ccmRootPwm3);
CCM_ControlGate(CCM, ccmCcgrGatePwm3, ccmClockNeededAll);
#endif /* #ifdef CONFIG_PWM_3 */

#ifdef CONFIG_PWM_4
/* We need to grasp board pwm exclusively */
RDC_SetPdapAccess(RDC, rdcPdapPwm4,
RDC_DOMAIN_PERM(CONFIG_DOMAIN_ID, RDC_DOMAIN_PERM_RW),
false, false);
/* Select clock derived from OSC clock(24M) */
CCM_UpdateRoot(CCM, ccmRootPwm4, ccmRootmuxPwmOsc24m, 0, 0);
/* Enable pwm clock */
CCM_EnableRoot(CCM, ccmRootPwm4);
CCM_ControlGate(CCM, ccmCcgrGatePwm4, ccmClockNeededAll);
#endif /* #ifdef CONFIG_PWM_4 */

}
#endif /* CONFIG_PWM_IMX */

static int nxp_mcimx7_init(struct device *arg)
{
ARG_UNUSED(arg);
Expand All @@ -177,6 +232,10 @@ static int nxp_mcimx7_init(struct device *arg)
nxp_mcimx7_i2c_config();
#endif /* CONFIG_I2C_IMX */

#ifdef CONFIG_PWM_IMX
nxp_mcimx7_pwm_config();
#endif /* CONFIG_PWM_IMX */

return 0;
}

Expand Down
1 change: 1 addition & 0 deletions arch/arm/soc/nxp_imx/mcimx7_m4/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ extern "C" {
#include "rdc_defs_imx7d.h"
#include "ccm_imx7d.h"
#include "clock_freq.h"
#include "soc_clk_freq.h"

#define RDC_DOMAIN_PERM_NONE (0x0)
#define RDC_DOMAIN_PERM_W (0x1)
Expand Down
52 changes: 52 additions & 0 deletions arch/arm/soc/nxp_imx/mcimx7_m4/soc_clk_freq.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2018, Diego Sueiro
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <ccm_imx7d.h>
#include <ccm_analog_imx7d.h>
#include "soc_clk_freq.h"

#ifdef CONFIG_PWM_IMX
u32_t get_pwm_clock_freq(PWM_Type *base)
{
u32_t root;
u32_t hz;
u32_t pre, post;

switch ((u32_t)base) {
case PWM1_BASE:
root = CCM_GetRootMux(CCM, ccmRootPwm1);
CCM_GetRootDivider(CCM, ccmRootPwm1, &pre, &post);
break;
case PWM2_BASE:
root = CCM_GetRootMux(CCM, ccmRootPwm2);
CCM_GetRootDivider(CCM, ccmRootPwm2, &pre, &post);
break;
case PWM3_BASE:
root = CCM_GetRootMux(CCM, ccmRootPwm3);
CCM_GetRootDivider(CCM, ccmRootPwm3, &pre, &post);
break;
case PWM4_BASE:
root = CCM_GetRootMux(CCM, ccmRootPwm4);
CCM_GetRootDivider(CCM, ccmRootPwm4, &pre, &post);
break;
default:
return 0;
}

switch (root) {
case ccmRootmuxPwmOsc24m:
hz = 24000000;
break;
case ccmRootmuxPwmSysPllDiv4:
hz = CCM_ANALOG_GetSysPllFreq(CCM_ANALOG) >> 2;
break;
default:
return 0;
}

return hz / (pre + 1) / (post + 1);
}
#endif /* CONFIG_PWM_IMX */
58 changes: 58 additions & 0 deletions arch/arm/soc/nxp_imx/mcimx7_m4/soc_clk_freq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2018, Diego Sueiro
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef __SOC_CLOCK_FREQ_H__
#define __SOC_CLOCK_FREQ_H__

#include "device_imx.h"
#include <zephyr/types.h>

#if defined(__cplusplus)
extern "C" {
#endif

#ifdef CONFIG_PWM_IMX
/*!
* @brief Get clock frequency applies to the PWM module
*
* @param base PWM base pointer.
* @return clock frequency (in HZ) applies to the PWM module
*/
u32_t get_pwm_clock_freq(PWM_Type *base);
#endif /* CONFIG_PWM_IMX */

#if defined(__cplusplus)
}
#endif

/*! @brief Root control names for root clock setting. */
enum _ccm_root_control_extra {
ccmRootPwm1 = (u32_t)(&CCM_TARGET_ROOT106),
ccmRootPwm2 = (u32_t)(&CCM_TARGET_ROOT107),
ccmRootPwm3 = (u32_t)(&CCM_TARGET_ROOT108),
ccmRootPwm4 = (u32_t)(&CCM_TARGET_ROOT109),
};

/*! @brief Clock source enumeration for PWM peripheral. */
enum _ccm_rootmux_pwm {
ccmRootmuxPwmOsc24m = 0U,
ccmRootmuxPwmEnetPllDiv10 = 1U,
ccmRootmuxPwmSysPllDiv4 = 2U,
ccmRootmuxPwmEnetPllDiv25 = 3U,
ccmRootmuxPwmAudioPll = 4U,
ccmRootmuxPwmExtClk2 = 5U,
ccmRootmuxPwmRef1m = 6U,
ccmRootmuxPwmVideoPll = 7U,
};

/*! @brief CCM CCGR gate control. */
enum _ccm_ccgr_gate_extra {
ccmCcgrGatePwm1 = (u32_t)(&CCM_CCGR132),
ccmCcgrGatePwm2 = (u32_t)(&CCM_CCGR133),
ccmCcgrGatePwm3 = (u32_t)(&CCM_CCGR134),
ccmCcgrGatePwm4 = (u32_t)(&CCM_CCGR135),
};
#endif /* __SOC_CLOCK_FREQ_H__ */
7 changes: 7 additions & 0 deletions boards/arm/colibri_imx7d_m4/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,12 @@ config I2C_4

endif # I2C_IMX

if PWM_IMX

config PWM_1
def_bool y

endif # PWM_IMX


endif # BOARD_COLIBRI_IMX7D_M4
5 changes: 5 additions & 0 deletions boards/arm/colibri_imx7d_m4/colibri_imx7d_m4.dts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
led0 = &green_led;
sw0 = &user_switch_1;
i2c-4 = &i2c4;
pwm-1 = &pwm1;
};

chosen {
Expand Down Expand Up @@ -63,3 +64,7 @@
&i2c4 {
status = "ok";
};

&pwm1 {
status = "ok";
};
4 changes: 4 additions & 0 deletions boards/arm/colibri_imx7d_m4/doc/colibri_imx7d_m4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ supports the following hardware features on the Cortex M4 Core:
+-----------+------------+-------------------------------------+
| I2C | on-chip | i2c |
+-----------+------------+-------------------------------------+
| PWM | on-chip | pwm |
+-----------+------------+-------------------------------------+
| UART | on-chip | serial port-polling; |
| | | serial port-interrupt |
+-----------+------------+-------------------------------------+
Expand Down Expand Up @@ -115,6 +117,8 @@ was tested with the following pinmux controller configuration.
+---------------+-----------------+---------------------------+
| SODIMM_196 | I2C4_SCL | I2C_SCL |
+---------------+-----------------+---------------------------+
| SODIMM_59 | PWM1/GPIO1_IO08 | PWM |
+---------------+-----------------+---------------------------+

System Clock
============
Expand Down
40 changes: 40 additions & 0 deletions boards/arm/colibri_imx7d_m4/pinmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,46 @@ static int colibri_imx7d_m4_pinmux_init(struct device *dev)
IOMUXC_SW_PAD_CTL_PAD_ENET1_RGMII_TD3_HYS_MASK;
#endif /* CONFIG_I2C_4 */

#ifdef CONFIG_PWM_1
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO08 =
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO08_MUX_MODE(7);
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO08 =
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO08_PE_MASK |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO08_PS(3) |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO08_DSE(0) |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO08_HYS_MASK;
#endif /* CONFIG_PWM_1 */

#ifdef CONFIG_PWM_2
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO09 =
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO09_MUX_MODE(7);
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO09 =
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO09_PE_MASK |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO09_PS(3) |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO09_DSE(0) |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO09_HYS_MASK;
#endif /* CONFIG_PWM_2 */

#ifdef CONFIG_PWM_3
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO10 =
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO10_MUX_MODE(7);
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO10 =
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO10_PE_MASK |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO10_PS(3) |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO10_DSE(0) |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO10_HYS_MASK;
#endif /* CONFIG_PWM_3 */

#ifdef CONFIG_PWM_4
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO11 =
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO11_MUX_MODE(7);
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO11 =
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO11_PE_MASK |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO11_PS(3) |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO11_DSE(0) |
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO11_HYS_MASK;
#endif /* CONFIG_PWM_4 */

return 0;

}
Expand Down
1 change: 1 addition & 0 deletions drivers/pwm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ zephyr_library_sources_ifdef(CONFIG_PWM_STM32 pwm_stm32.c)
zephyr_library_sources_ifdef(CONFIG_PWM_NRF5_SW pwm_nrf5_sw.c)
zephyr_library_sources_ifdef(CONFIG_PWM_NRFX pwm_nrfx.c)
zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_FTM pwm_mcux_ftm.c)
zephyr_library_sources_ifdef(CONFIG_PWM_IMX pwm_imx.c)
zephyr_library_sources_ifdef(CONFIG_PWM_LED_ESP32 pwm_led_esp32.c)

zephyr_library_sources_ifdef(CONFIG_USERSPACE pwm_handlers.c)
5 changes: 5 additions & 0 deletions drivers/pwm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ config PWM_2
config PWM_3
bool "Enable PWM port 3"

config PWM_4
bool "Enable PWM port 4"

source "drivers/pwm/Kconfig.pca9685"

source "drivers/pwm/Kconfig.qmsi"
Expand All @@ -54,6 +57,8 @@ source "drivers/pwm/Kconfig.nrfx"

source "drivers/pwm/Kconfig.mcux_ftm"

source "drivers/pwm/Kconfig.imx"

source "drivers/pwm/Kconfig.esp32"

endif # PWM
20 changes: 20 additions & 0 deletions drivers/pwm/Kconfig.imx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Kconfig - i.MX PWM Config
#
# Copyright (c) 2018, Diego Sueiro
#
# SPDX-License-Identifier: Apache-2.0
#

menuconfig PWM_IMX
bool
prompt "i.MX PWM Driver"
depends on PWM
help
Enable support for i.MX pwm driver.

config PWM_PWMSWR_LOOP
int "Loop count for PWM Software Reset"
default 5
depends on PWM_IMX
help
Loop count for PWM Software Reset when disabling PWM channel.
Loading