arm: Nxp imx6sx added PWM support
This commit adds support for IMX6SX PWM. The PWM module is the same module present on the IMX7D and so dts bindings has been renamed following the one present on linux. Signed-off-by: Antonio Tessarolo <anthonytexdev@gmail.com>
This commit is contained in:
parent
ee6c552805
commit
cc1cd4d65b
10 changed files with 311 additions and 9 deletions
|
@ -172,7 +172,7 @@ static const struct pwm_driver_api imx_pwm_driver_api = {
|
|||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
|
||||
&imx_pwm_driver_api);
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(fsl_imx7d_pwm)
|
||||
#define DT_DRV_COMPAT fsl_imx7d_pwm
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(fsl_imx27_pwm)
|
||||
#define DT_DRV_COMPAT fsl_imx27_pwm
|
||||
DT_INST_FOREACH_STATUS_OKAY(PWM_IMX_INIT)
|
||||
#endif
|
||||
|
|
|
@ -339,6 +339,119 @@
|
|||
label = "I2C_4";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm1: pwm@42080000 {
|
||||
compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x42080000 0x4000>;
|
||||
interrupts = <83 0>;
|
||||
rdc = <(RDC_DOMAIN_PERM(A9_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW)|\
|
||||
RDC_DOMAIN_PERM(M4_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW))>;
|
||||
label = "PWM_1";
|
||||
prescaler = <0>;
|
||||
#pwm-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm2: pwm@42084000 {
|
||||
compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x42084000 0x4000>;
|
||||
interrupts = <84 0>;
|
||||
rdc = <(RDC_DOMAIN_PERM(A9_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW)|\
|
||||
RDC_DOMAIN_PERM(M4_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW))>;
|
||||
label = "PWM_2";
|
||||
prescaler = <0>;
|
||||
#pwm-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm3: pwm@42088000 {
|
||||
compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x42088000 0x4000>;
|
||||
interrupts = <85 0>;
|
||||
rdc = <(RDC_DOMAIN_PERM(A9_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW)|\
|
||||
RDC_DOMAIN_PERM(M4_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW))>;
|
||||
label = "PWM_3";
|
||||
prescaler = <0>;
|
||||
#pwm-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm4: pwm@4208c000 {
|
||||
compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x4208c000 0x4000>;
|
||||
interrupts = <86 0>;
|
||||
rdc = <(RDC_DOMAIN_PERM(A9_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW)|\
|
||||
RDC_DOMAIN_PERM(M4_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW))>;
|
||||
label = "PWM_4";
|
||||
prescaler = <0>;
|
||||
#pwm-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
pwm5: pwm@422a4000 {
|
||||
compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x422a4000 0x4000>;
|
||||
interrupts = <83 0>;
|
||||
rdc = <(RDC_DOMAIN_PERM(A9_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW)|\
|
||||
RDC_DOMAIN_PERM(M4_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW))>;
|
||||
label = "PWM_5";
|
||||
prescaler = <0>;
|
||||
#pwm-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm6: pwm@422a8000 {
|
||||
compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x422a8000 0x4000>;
|
||||
interrupts = <84 0>;
|
||||
rdc = <(RDC_DOMAIN_PERM(A9_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW)|\
|
||||
RDC_DOMAIN_PERM(M4_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW))>;
|
||||
label = "PWM_6";
|
||||
prescaler = <0>;
|
||||
#pwm-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm7: pwm@422ac000 {
|
||||
compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x422ac000 0x4000>;
|
||||
interrupts = <85 0>;
|
||||
rdc = <(RDC_DOMAIN_PERM(A9_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW)|\
|
||||
RDC_DOMAIN_PERM(M4_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW))>;
|
||||
label = "PWM_7";
|
||||
prescaler = <0>;
|
||||
#pwm-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm8: pwm@422ab000 {
|
||||
compatible = "fsl,imx6sx-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x422ab000 0x4000>;
|
||||
interrupts = <86 0>;
|
||||
rdc = <(RDC_DOMAIN_PERM(A9_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW)|\
|
||||
RDC_DOMAIN_PERM(M4_DOMAIN_ID,\
|
||||
RDC_DOMAIN_PERM_RW))>;
|
||||
label = "PWM_8";
|
||||
prescaler = <0>;
|
||||
#pwm-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -331,7 +331,7 @@
|
|||
};
|
||||
|
||||
pwm1: pwm@30660000 {
|
||||
compatible = "fsl,imx7d-pwm";
|
||||
compatible = "fsl,imx7d-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x30660000 0x10000>;
|
||||
interrupts = <81 0>;
|
||||
prescaler = <0>;
|
||||
|
@ -345,7 +345,7 @@
|
|||
};
|
||||
|
||||
pwm2: pwm@30670000 {
|
||||
compatible = "fsl,imx7d-pwm";
|
||||
compatible = "fsl,imx7d-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x30670000 0x10000>;
|
||||
interrupts = <82 0>;
|
||||
prescaler = <0>;
|
||||
|
@ -359,7 +359,7 @@
|
|||
};
|
||||
|
||||
pwm3: pwm@30680000 {
|
||||
compatible = "fsl,imx7d-pwm";
|
||||
compatible = "fsl,imx7d-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x30680000 0x10000>;
|
||||
interrupts = <83 0>;
|
||||
prescaler = <0>;
|
||||
|
@ -373,7 +373,7 @@
|
|||
};
|
||||
|
||||
pwm4: pwm@30690000 {
|
||||
compatible = "fsl,imx7d-pwm";
|
||||
compatible = "fsl,imx7d-pwm", "fsl,imx27-pwm";
|
||||
reg = <0x30690000 0x10000>;
|
||||
interrupts = <84 0>;
|
||||
prescaler = <0>;
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
# Copyright (c) 2018, Diego Sueiro <diego.sueiro@gmail.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: i.MX7D PWM
|
||||
description: |
|
||||
This driver supports both i.MX6SX and i.MX7D PWM.
|
||||
The compatible string is named "imx27" because the hardware module is the
|
||||
same module present starting from imx27 CPUs and this driver can potentially
|
||||
support other CPUs with imx27 module. This is also the same string used
|
||||
in the Linux kernel.
|
||||
|
||||
compatible: "fsl,imx7d-pwm"
|
||||
compatible: "fsl,imx27-pwm"
|
||||
|
||||
include: [pwm-controller.yaml, base.yaml]
|
||||
|
|
@ -4,4 +4,7 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
zephyr_sources(soc.c)
|
||||
zephyr_sources(
|
||||
soc.c
|
||||
soc_clk_freq.c
|
||||
)
|
||||
|
|
|
@ -31,4 +31,8 @@ config COUNTER_IMX_EPIT
|
|||
default y
|
||||
depends on COUNTER
|
||||
|
||||
config PWM_IMX
|
||||
default y
|
||||
depends on PWM
|
||||
|
||||
endif # SOC_MCIMX6X_M4
|
||||
|
|
|
@ -104,6 +104,39 @@ static void SOC_RdcInit(void)
|
|||
/* Set access to I2C-4 for M4 core */
|
||||
RDC_SetPdapAccess(RDC, rdcPdapI2c4, RDC_DT_VAL(i2c4), false, false);
|
||||
#endif
|
||||
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay)
|
||||
/* Set access to PWM-1 for M4 core */
|
||||
RDC_SetPdapAccess(RDC, rdcPdapPwm1, RDC_DT_VAL(pwm1), false, false);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay)
|
||||
/* Set access to PWM-2 for M4 core */
|
||||
RDC_SetPdapAccess(RDC, rdcPdapPwm2, RDC_DT_VAL(pwm2), false, false);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm3), okay)
|
||||
/* Set access to PWM-3 for M4 core */
|
||||
RDC_SetPdapAccess(RDC, rdcPdapPwm3, RDC_DT_VAL(pwm3), false, false);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm4), okay)
|
||||
/* Set access to PWM-4 for M4 core */
|
||||
RDC_SetPdapAccess(RDC, rdcPdapPwm4, RDC_DT_VAL(pwm4), false, false);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm5), okay)
|
||||
/* Set access to PWM-5 for M4 core */
|
||||
RDC_SetPdapAccess(RDC, rdcPdapPwm5, RDC_DT_VAL(pwm5), false, false);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm6), okay)
|
||||
/* Set access to PWM-6 for M4 core */
|
||||
RDC_SetPdapAccess(RDC, rdcPdapPwm6, RDC_DT_VAL(pwm6), false, false);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm7), okay)
|
||||
/* Set access to PWM-7 for M4 core */
|
||||
RDC_SetPdapAccess(RDC, rdcPdapPwm7, RDC_DT_VAL(pwm7), false, false);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm8), okay)
|
||||
/* Set access to PWM-8 for M4 core */
|
||||
RDC_SetPdapAccess(RDC, rdcPdapPwm8, RDC_DT_VAL(pwm8), false, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize cache. */
|
||||
|
@ -196,7 +229,41 @@ static void SOC_ClockInit(void)
|
|||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c4), okay)
|
||||
CCM_ControlGate(CCM, ccmCcgrGateI2c4Serialclk, ccmClockNeededAll);
|
||||
#endif
|
||||
#endif /* CONFIG_I2C_IMX */
|
||||
|
||||
#ifdef CONFIG_PWM_IMX
|
||||
/* Select PWM clock is derived from OSC (24M) */
|
||||
CCM_SetRootMux(CCM, ccmRootPerclkClkSel, ccmRootmuxPerclkClkOsc24m);
|
||||
|
||||
/* Set relevant divider = 1. */
|
||||
CCM_SetRootDivider(CCM, ccmRootPerclkPodf, 0);
|
||||
|
||||
/* Enable PWM clock */
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay)
|
||||
CCM_ControlGate(CCM, ccmCcgrGatePwm1Clk, ccmClockNeededAll);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay)
|
||||
CCM_ControlGate(CCM, ccmCcgrGatePwm2Clk, ccmClockNeededAll);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm3), okay)
|
||||
CCM_ControlGate(CCM, ccmCcgrGatePwm3Clk, ccmClockNeededAll);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm4), okay)
|
||||
CCM_ControlGate(CCM, ccmCcgrGatePwm4Clk, ccmClockNeededAll);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm5), okay)
|
||||
CCM_ControlGate(CCM, ccmCcgrGatePwm5Clk, ccmClockNeededAll);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm6), okay)
|
||||
CCM_ControlGate(CCM, ccmCcgrGatePwm6Clk, ccmClockNeededAll);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm7), okay)
|
||||
CCM_ControlGate(CCM, ccmCcgrGatePwm7Clk, ccmClockNeededAll);
|
||||
#endif
|
||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm8), okay)
|
||||
CCM_ControlGate(CCM, ccmCcgrGatePwm8Clk, ccmClockNeededAll);
|
||||
#endif
|
||||
#endif /* CONFIG_PWM_IMX */
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "rdc_defs_imx6sx.h"
|
||||
#include "ccm_imx6sx.h"
|
||||
#include "clock_freq.h"
|
||||
#include "soc_clk_freq.h"
|
||||
|
||||
#endif /* !_ASMLANGUAGE */
|
||||
|
||||
|
|
79
soc/arm/nxp_imx/mcimx6x_m4/soc_clk_freq.c
Normal file
79
soc/arm/nxp_imx/mcimx6x_m4/soc_clk_freq.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Antonio Tessarolo
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <ccm_imx6sx.h>
|
||||
#include <ccm_analog_imx6sx.h>
|
||||
#include "soc_clk_freq.h"
|
||||
|
||||
#ifdef CONFIG_PWM_IMX
|
||||
|
||||
uint32_t get_pwm_clock_freq(PWM_Type *base)
|
||||
{
|
||||
uint32_t root;
|
||||
uint32_t hz;
|
||||
uint32_t divPerclkPodf, divIpgPodf, divAhbPodf, divPeriphClk2Podf;
|
||||
|
||||
/* Different instance has the same clock root, it's different from i.mx7d. */
|
||||
/* Get the clock root according to the mux node of clock tree. */
|
||||
if (CCM_GetRootMux(CCM, ccmRootPerclkClkSel) ==
|
||||
ccmRootmuxPerclkClkOsc24m) {
|
||||
root = ccmRootmuxPerclkClkOsc24m;
|
||||
hz = 24000000;
|
||||
divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
|
||||
divIpgPodf = 0;
|
||||
divAhbPodf = 0;
|
||||
divPeriphClk2Podf = 0;
|
||||
} else if (CCM_GetRootMux(CCM, ccmRootPeriphClkSel) ==
|
||||
ccmRootmuxPeriphClkPrePeriphClkSel) {
|
||||
root = CCM_GetRootMux(CCM, ccmRootPrePeriphClkSel);
|
||||
/* Here do not show all the clock root source,
|
||||
* if user use other clock root source, such as PLL2_PFD2, please
|
||||
* add it as follows according to the clock tree of CCM in reference manual.
|
||||
*/
|
||||
switch (root) {
|
||||
case ccmRootmuxPrePeriphClkPll2:
|
||||
hz = CCM_ANALOG_GetPllFreq(CCM_ANALOG, ccmAnalogPllSysControl);
|
||||
divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
|
||||
divIpgPodf = CCM_GetRootDivider(CCM, ccmRootIpgPodf);
|
||||
divAhbPodf = CCM_GetRootDivider(CCM, ccmRootAhbPodf);
|
||||
divPeriphClk2Podf = 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
} else if (CCM_GetRootMux(CCM, ccmRootPeriphClk2Sel) ==
|
||||
ccmRootmuxPeriphClk2OSC24m) {
|
||||
root = ccmRootmuxPeriphClk2OSC24m;
|
||||
hz = 24000000;
|
||||
divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
|
||||
divIpgPodf = CCM_GetRootDivider(CCM, ccmRootIpgPodf);
|
||||
divAhbPodf = CCM_GetRootDivider(CCM, ccmRootAhbPodf);
|
||||
divPeriphClk2Podf = CCM_GetRootDivider(CCM, ccmRootPeriphClk2Podf);
|
||||
} else {
|
||||
root = CCM_GetRootMux(CCM, ccmRootPll3SwClkSel);
|
||||
/* Here do not show all the clock root source,
|
||||
* if user use other clock root source, such as PLL3_BYP, please
|
||||
* add it as follows according to the clock tree of CCM in reference manual.
|
||||
*/
|
||||
switch (root) {
|
||||
case ccmRootmuxPll3SwClkPll3:
|
||||
hz = CCM_ANALOG_GetPllFreq(CCM_ANALOG, ccmAnalogPllUsb1Control);
|
||||
divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
|
||||
divIpgPodf = CCM_GetRootDivider(CCM, ccmRootIpgPodf);
|
||||
divAhbPodf = CCM_GetRootDivider(CCM, ccmRootAhbPodf);
|
||||
divPeriphClk2Podf =
|
||||
CCM_GetRootDivider(CCM, ccmRootPeriphClk2Podf);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return hz / (divPerclkPodf + 1) / (divIpgPodf + 1) /
|
||||
(divAhbPodf + 1) / (divPeriphClk2Podf + 1);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PWM_IMX */
|
30
soc/arm/nxp_imx/mcimx6x_m4/soc_clk_freq.h
Normal file
30
soc/arm/nxp_imx/mcimx6x_m4/soc_clk_freq.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Antonio Tessarolo
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
uint32_t get_pwm_clock_freq(PWM_Type *base);
|
||||
#endif /* CONFIG_PWM_IMX */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* __SOC_CLOCK_FREQ_H__ */
|
Loading…
Add table
Add a link
Reference in a new issue